Merge branch 'develop' into feature/admin-properties

This commit is contained in:
Armin Schrenk
2026-02-09 15:03:06 +01:00
80 changed files with 453 additions and 196 deletions

View File

@@ -44,9 +44,9 @@ jobs:
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-aarch64_bin-jmods.zip'
openjfx-sha: '9ad4ca7b769ca4ee6419f1e99143dd6ff812f8be4fddb46a7d7cacbeea148af4'
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Java
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
@@ -175,7 +175,7 @@ jobs:
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage.zsync
- name: Upload artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: appimage-${{ matrix.appimage-suffix }}
path: |
@@ -201,7 +201,7 @@ jobs:
if: github.event_name == 'release' && needs.get-version.outputs.versionType == 'stable'
steps:
- name: Download AppImages
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
path: downloads/
merge-multiple: true
@@ -212,7 +212,7 @@ jobs:
echo "x64-sha256sum=${X64_SHA256}" >> "$GITHUB_OUTPUT"
AARCH64_SHA256=$(sha256sum downloads/cryptomator-*-aarch64.AppImage | cut -d ' ' -f1)
echo "aarch64-sha256sum=${AARCH64_SHA256}" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: 'cryptomator/aur-bin'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}

View File

@@ -48,7 +48,7 @@ jobs:
env:
AUR_PR_URL: tbd
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: 'cryptomator/aur'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}

View File

@@ -51,7 +51,7 @@ jobs:
- name: Download file
run: curl "${INPUT_URL}" -L -o "${{steps.extractName.outputs.fileName}}" --fail-with-body
- name: Upload artifact
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: ${{ steps.extractName.outputs.fileName }}
path: ${{ steps.extractName.outputs.fileName }}
@@ -63,7 +63,7 @@ jobs:
if: inputs.kaspersky
steps:
- name: Download artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ${{ needs.download-file.outputs.fileName }}
path: upload
@@ -83,7 +83,7 @@ jobs:
if: inputs.avast
steps:
- name: Download artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ${{ needs.download-file.outputs.fileName }}
path: upload

View File

@@ -22,14 +22,14 @@ jobs:
name: Compile and Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
cache: 'maven'
- name: Cache SonarCloud packages
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar

View File

@@ -26,7 +26,7 @@ jobs:
run: echo 'JDK_MAJOR_VERSION=${{ env.JDK_VERSION }}'.substring(0,2) >> "$env:GITHUB_ENV"
shell: pwsh
- name: Checkout latest JDK ${{ env.JDK_MAJOR_VERSION }}
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: ${{ env.JDK_MAJOR_VERSION}}
distribution: ${{ env.JDK_VENDOR }}

View File

@@ -43,7 +43,7 @@ jobs:
env:
INPUT_PPAVER: ${{ inputs.ppaver }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- id: deb-version
name: Determine deb-version
run: |
@@ -60,7 +60,7 @@ jobs:
env:
DEB_BUILD_DEPENDS: ${{ env.DEB_BUILD_DEPENDS }}
- name: Setup Java
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
@@ -143,7 +143,7 @@ jobs:
run: |
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb
- name: Upload artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: linux-deb-package
path: |

View File

@@ -7,7 +7,7 @@ on:
jobs:
check-dependencies:
uses: skymatic/workflows/.github/workflows/run-dependency-check.yml@1074588008ae3326a2221ea451783280518f0366 # v3.0.1
uses: skymatic/workflows/.github/workflows/run-dependency-check.yml@957d3c2c08c56855fdac41e5afb9a7aca8c30dd9 # v3.0.3
with:
runner-os: 'ubuntu-latest'
java-distribution: 'temurin'
@@ -16,4 +16,4 @@ jobs:
nvd-api-key: ${{ secrets.NVD_API_KEY }}
ossindex-username: ${{ secrets.OSSINDEX_USERNAME }}
ossindex-token: ${{ secrets.OSSINDEX_API_TOKEN }}
slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_CRYPTOMATOR_DESKTOP }}

View File

@@ -53,7 +53,7 @@ jobs:
INTERVAL: 900
JSON_DATA: ${{ steps.get-stats.outputs.result }}
- name: Upload Results
uses: fjogeleit/http-request-action@c0b95d02a088b47c1f2f4db04fd8af8bd19eee54 # v1.16.6
uses: fjogeleit/http-request-action@551353b829c3646756b2ec2b3694f819d7957495 # v2.0.0
with:
url: 'https://graphite-us-central1.grafana.net/metrics'
method: 'POST'

View File

@@ -43,7 +43,7 @@ jobs:
env:
FLATHUB_PR_URL: tbd
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: 'flathub/org.cryptomator.Cryptomator'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}

View File

@@ -35,11 +35,11 @@ jobs:
revNum: ${{ steps.versions.outputs.revNum }}
type: ${{ steps.versions.outputs.type}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Setup Java
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}

View File

@@ -47,9 +47,9 @@ jobs:
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_osx-x64_bin-jmods.zip'
openjfx-sha: '0eba73fb28a24c845175d16fa2f8c081c936ce6de1be9b79eb6119fa32e53d52'
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Java
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
@@ -283,7 +283,7 @@ jobs:
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
continue-on-error: true
- name: Upload artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: dmg-${{ matrix.output-suffix }}
path: |

View File

@@ -45,9 +45,9 @@ jobs:
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_osx-aarch64_bin-jmods.zip'
openjfx-sha: '13f8c0513c40c95881479fbcf0465a29a60217393fb0656f5e4eab78a9442fba'
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Java
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
@@ -282,7 +282,7 @@ jobs:
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
continue-on-error: true
- name: Upload artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: dmg-${{ matrix.output-suffix }}
path: |

View File

@@ -16,8 +16,8 @@ jobs:
name: Compile and Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}

View File

@@ -19,9 +19,9 @@ jobs:
name: Validate commits pushed to release/hotfix branch to fulfill release requirements
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Java
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
@@ -49,7 +49,7 @@ jobs:
exit 1
fi
- name: Cache NVD DB
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ~/.m2/repository/org/owasp/dependency-check-data/
key: dependency-check-${{ github.run_id }}

View File

@@ -51,9 +51,9 @@ jobs:
java-version: '25.0.1+8'
java-package: 'jdk'
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Java
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ matrix.java-dist }}
java-version: ${{ matrix.java-version }}
@@ -200,7 +200,7 @@ jobs:
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
- name: Sign DLLs with Actalis CodeSigner
if: inputs.sign || github.event_name == 'release'
uses: skymatic/workflows/.github/actions/win-sign-action@1074588008ae3326a2221ea451783280518f0366 # no specific version
uses: skymatic/workflows/.github/actions/win-sign-action@957d3c2c08c56855fdac41e5afb9a7aca8c30dd9 # no specific version
with:
base-dir: 'appdir'
file-extensions: 'dll,exe,ps1'
@@ -277,7 +277,7 @@ jobs:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Upload artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: msi-${{ matrix.arch }}
path: |
@@ -299,21 +299,21 @@ jobs:
java-version: '24.0.1+9'
java-package: 'jdk'
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install wix and extensions
run: |
dotnet tool install --global wix --version 6.0.0
wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
- name: Download .msi
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: msi-${{ matrix.arch }}
path: dist/win/bundle/resources
- name: Strip version info from msi file name
run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
- name: Setup Java
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ matrix.java-dist }}
java-version: ${{ matrix.java-version }}
@@ -376,7 +376,7 @@ jobs:
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
- name: Sign burn engine with Actalis CodeSigner
if: inputs.sign || github.event_name == 'release'
uses: skymatic/workflows/.github/actions/win-sign-action@1074588008ae3326a2221ea451783280518f0366 # no specific version
uses: skymatic/workflows/.github/actions/win-sign-action@957d3c2c08c56855fdac41e5afb9a7aca8c30dd9 # no specific version
with:
base-dir: 'tmp'
file-extensions: 'exe'
@@ -400,7 +400,7 @@ jobs:
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
- name: Sign installer with Actalis CodeSigner
if: inputs.sign || github.event_name == 'release'
uses: skymatic/workflows/.github/actions/win-sign-action@1074588008ae3326a2221ea451783280518f0366 # no specific version
uses: skymatic/workflows/.github/actions/win-sign-action@957d3c2c08c56855fdac41e5afb9a7aca8c30dd9 # no specific version
with:
base-dir: 'installer'
file-extensions: 'exe'
@@ -418,7 +418,7 @@ jobs:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Upload artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: exe-${{ matrix.executable-suffix }}
path: |
@@ -436,7 +436,7 @@ jobs:
download-url-exe-x64: ${{ fromJSON(steps.publish.outputs.assets)[2].browser_download_url }}
steps:
- name: Download installers
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
merge-multiple: true
- name: Publish installers on GitHub Releases

View File

@@ -15,10 +15,11 @@ Changes to prior versions can be found on the [Github release page](https://gith
* Implemented Flatpak update mechanism
* App notifications ([#4069](https://github.com/cryptomator/cryptomator/pull/4069))
* Mark files in-use for Hub vaults ([#4078](https://github.com/cryptomator/cryptomator/pull/4078))
* Accessibility labels for GUI elements ([#4064](https://github.com/cryptomator/cryptomator/issues/4064), [#4066](https://github.com/cryptomator/cryptomator/pull/4066), [#4055](https://github.com/cryptomator/cryptomator/issues/4055))
* Accessibility: Adjust app to be used with a screen reader ([#547](https://github.com/cryptomator/cryptomator/issues/547))
* Show Archived Vault Dialog on unlock when Hub returns 410 ([#4081](https://github.com/cryptomator/cryptomator/pull/4081))
* Admin configuration: Allow overwriting certain app properties by external config file ([#4105](https://github.com/cryptomator/cryptomator/pull/4105))
### Changed
* Built using JDK 25 ([#4031](https://github.com/cryptomator/cryptomator/issues/4031))
* Modernized Template for GitHub Releases
* Modernized Template for GitHub Releases
* Disable user defined app start config on Windows ([#4132](https://github.com/cryptomator/cryptomator/issues/4132))

12
dist/win/contrib/disableUserConfig.bat vendored Normal file
View File

@@ -0,0 +1,12 @@
@echo off
:: Batch wrapper for PowerShell script to disable user configuration in Cryptomator
:: This is executed as a Custom Action during MSI installation
:: This file must be located in the INSTALLDIR
:: Change to INSTALLDIR
cd %~dp0
:: Execute the PowerShell script
powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -File ".\disableUserConfig.ps1"
:: Return the exit code from PowerShell
exit /b %ERRORLEVEL%

24
dist/win/contrib/disableUserConfig.ps1 vendored Normal file
View File

@@ -0,0 +1,24 @@
# PowerShell script to disable user configuration
# This script is executed as a Custom Action during MSI installation
# It deletes the file .package, effectively disabling user specific jpackage configuration.
# NOTE: This file must be located in the same directory as set in the MSI property INSTALLDIR
try {
# Determine file path
$packageFile = Join-Path $PSScriptRoot 'app\.package'
#check if file exists
if (Test-Path -Path $packageFile) {
Write-Host "Deleting file: $packageFile"
Remove-Item -Path $packageFile -Force -ErrorAction Stop
} else {
Write-Host "File not found: $packageFile. Skipping deletion."
}
exit 0
}
catch {
Write-Error "Error deleting package file: $_"
exit 1
}

View File

@@ -160,6 +160,10 @@
<!-- Property for controlling update check behavior (can be set via command line) -->
<ns0:Property Id="DISABLEUPDATECHECK" Secure="yes" />
<!-- Disable user config -->
<ns0:SetProperty Id="DisableUserConfig" Value="&quot;[INSTALLDIR]disableUserConfig.bat&quot;" Sequence="execute" Before="DisableUserConfig" />
<ns0:CustomAction Id="DisableUserConfig" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
<!-- WebDAV patches -->
<ns0:SetProperty Id="PatchWebDAV" Value="&quot;[INSTALLDIR]patchWebDAV.bat&quot; &quot;$(var.LoopbackAlias)&quot;" Sequence="execute" Before="PatchWebDAV" />
<ns0:CustomAction Id="PatchWebDAV" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
@@ -216,9 +220,10 @@
<ns0:Custom Action="FailOnRunningApp" After="Wix4CloseApplications_$(sys.BUILDARCHSHORT)" Condition="FOUNDRUNNINGAPP" />
<ns0:RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to Wix4CloseApplications_* -->
<ns0:Custom Action="DisableUserConfig" After="InstallFiles" Condition="NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
<!-- Skip action on uninstall -->
<!-- TODO: don't skip action, but remove cryptomator alias from hosts file -->
<ns0:Custom Action="PatchWebDAV" After="InstallFiles" Condition="NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
<ns0:Custom Action="PatchWebDAV" After="DisableUserConfig" Condition="NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
<!-- Configure update check setting if property is provided -->
<ns0:Custom Action="PatchUpdateCheck" After="PatchWebDAV" Condition="DISABLEUPDATECHECK AND NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
</ns0:InstallExecuteSequence>

View File

@@ -4,24 +4,27 @@ import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.AccessibleRole;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import java.util.ResourceBundle;
public class NotificationBar extends HBox {
public class InfoBar extends HBox {
@FXML
private Label notificationLabel;
private Label infoMessage;
private final BooleanProperty dismissable = new SimpleBooleanProperty();
private final BooleanProperty notify = new SimpleBooleanProperty();
public NotificationBar() {
public InfoBar() {
setAlignment(Pos.CENTER);
setStyle("-fx-alignment: center;");
getStyleClass().addAll("info-bar");
Region spacer = new Region();
spacer.setMinWidth(40);
@@ -36,14 +39,21 @@ public class NotificationBar extends HBox {
vbox.setAlignment(Pos.CENTER);
HBox.setHgrow(vbox, javafx.scene.layout.Priority.ALWAYS);
notificationLabel = new Label();
notificationLabel.getStyleClass().add("notification-label");
notificationLabel.setStyle("-fx-alignment: center;");
vbox.getChildren().add(notificationLabel);
infoMessage = new Label();
infoMessage.setFocusTraversable(true);
infoMessage.setAccessibleRole(AccessibleRole.BUTTON);
vbox.getChildren().add(infoMessage);
Button closeButton = new Button("X");
var closeGraphic = new FontAwesome5IconView();
closeGraphic.setGlyph(FontAwesome5Icon.TIMES);
closeGraphic.setGlyphSize(12);
closeGraphic.getStyleClass().add("glyph");
Button closeButton = new Button();
closeButton.setGraphic(closeGraphic);
closeButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
closeButton.setAccessibleText(ResourceBundle.getBundle("i18n.strings").getString("main.notification.closeButton.tooltip"));
closeButton.setMinWidth(40);
closeButton.setStyle("-fx-background-color: transparent; -fx-text-fill: white; -fx-font-weight: bold;");
closeButton.visibleProperty().bind(dismissable);
closeButton.setOnAction(_ -> {
@@ -61,11 +71,11 @@ public class NotificationBar extends HBox {
}
public String getText() {
return notificationLabel.getText();
return infoMessage.getText();
}
public void setText(String text) {
notificationLabel.setText(text);
infoMessage.setText(text);
}
public void setStyleClass(String styleClass) {

View File

@@ -16,6 +16,7 @@ import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.layout.HBox;
import java.util.ResourceBundle;
// unscoped because each cell needs its own controller
public class VaultListCellController implements FxController {
@@ -23,9 +24,12 @@ public class VaultListCellController implements FxController {
private static final Insets COMPACT_INSETS = new Insets(6, 12, 6, 12);
private static final Insets DEFAULT_INSETS = new Insets(12);
private final ResourceBundle resourceBundle;
private final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
private final ObservableValue<VaultState.Value> vaultState;
private final ObservableValue<FontAwesome5Icon> glyph;
private final ObservableValue<Boolean> compactMode;
private final ObservableValue<String> accessibleText;
private AutoAnimator spinAnimation;
@@ -35,17 +39,21 @@ public class VaultListCellController implements FxController {
public HBox vaultListCell;
@Inject
VaultListCellController(Settings settings) {
this.glyph = vault.flatMap(Vault::stateProperty).map(this::getGlyphForVaultState);
VaultListCellController(Settings settings, ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
this.vaultState = vault.flatMap(Vault::stateProperty);
this.glyph = vaultState.map(this::getGlyphForVaultState);
this.accessibleText = vaultState.map(this::getAccessibleTextForVaultState);
this.compactMode = settings.compactMode;
}
public void initialize() {
this.spinAnimation = AutoAnimator.animate(Animations.createDiscrete360Rotation(vaultStateView)) //
.onCondition(vault.flatMap(Vault::stateProperty).map(VaultState.Value.PROCESSING::equals).orElse(false)) //
.onCondition(vaultState.map(VaultState.Value.PROCESSING::equals).orElse(false)) //
.afterStop(() -> vaultStateView.setRotate(0)) //
.build();
this.vaultListCell.paddingProperty().bind(compactMode.map(c -> c ? COMPACT_INSETS : DEFAULT_INSETS));
this.vaultListCell.accessibleTextProperty().bind(accessibleText);
}
// TODO deduplicate w/ VaultDetailController
@@ -62,6 +70,25 @@ public class VaultListCellController implements FxController {
}
}
private String getAccessibleTextForVaultState(VaultState.Value state) {
var v = vault.get();
if (state != null && v != null) {
var translationKey = switch (state) {
case LOCKED -> "vault.state.locked";
case PROCESSING -> "vault.state.processing";
case UNLOCKED -> "vault.state.unlocked";
case NEEDS_MIGRATION -> "vault.state.migrationNeeded";
case MISSING -> "vault.state.missing";
case VAULT_CONFIG_MISSING, ALL_MISSING, ERROR -> "vault.state.error";
};
var localizedState = resourceBundle.getString(translationKey);
return resourceBundle.getString("main.vaultlist.listEntry").formatted(v.getDisplayName(), localizedState);
} else {
return "";
}
}
/* Getter/Setter */
public ObservableValue<FontAwesome5Icon> glyphProperty() {

View File

@@ -104,7 +104,7 @@ public class RecoveryKeyCreationController implements FxController {
descriptionLabel.formatProperty().set(resourceBundle.getString("recoveryKey.recover.description"));
cancelButton.setOnAction((_) -> back());
cancelButton.setText(resourceBundle.getString("generic.button.back"));
nextButton.setOnAction((_) -> restoreWithPassword());
nextButton.setOnAction((_) -> restoreWithPasswordAsync());
}
}
@@ -137,11 +137,47 @@ public class RecoveryKeyCreationController implements FxController {
}
@FXML
public void restoreWithPassword() {
public void restoreWithPasswordAsync() {
Task<Void> task = RecoveryKeyTasks.createTask(this::restoreWithPassword);
task.setOnScheduled(_ -> {
LOG.debug("Restoring vault configuration with password for {}.", vault.getDisplayablePath());
});
task.setOnSucceeded(_ -> {
LOG.debug("Restored vault configuration for {}.", vault.getDisplayablePath());
try {
if (!vaultListManager.isAlreadyAdded(vault.getPath())) {
vaultListManager.add(vault.getPath());
}
window.close();
dialogs.prepareRecoverPasswordSuccess((Stage) window.getOwner()) //
.setTitleKey("recover.recoverVaultConfig.title") //
.setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") //
.setDescriptionKey("recoveryKey.recover.resetMasterkeyFileSuccess.description")
.build().showAndWait();
} catch (IOException e) {
LOG.error("Failed to add vault to list.", e);
appWindows.showErrorWindow(e, window, null);
}
});
task.setOnFailed(_ -> {
if (task.getException() instanceof InvalidPassphraseException e) {
LOG.info("Password invalid", e);
Animations.createShakeWindowAnimation(window).play();
} else {
LOG.error("Recovery process failed.", task.getException());
appWindows.showErrorWindow(task.getException(), window, null);
}
});
executor.submit(task);
}
void restoreWithPassword() throws IOException, CryptoException {
try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) {
Path recoveryPath = recoveryDirectory.getRecoveryPath();
Path masterkeyFilePath = vault.getPath().resolve(MASTERKEY_FILENAME);
try (Masterkey masterkey = MasterkeyService.load(masterkeyFileAccess, masterkeyFilePath, passwordField.getCharacters())) {
@@ -152,23 +188,6 @@ public class RecoveryKeyCreationController implements FxController {
}
recoveryDirectory.moveRecoveredFile(VAULTCONFIG_FILENAME);
if (!vaultListManager.isAlreadyAdded(vault.getPath())) {
vaultListManager.add(vault.getPath());
}
window.close();
dialogs.prepareRecoverPasswordSuccess((Stage)window.getOwner()) //
.setTitleKey("recover.recoverVaultConfig.title") //
.setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") //
.setDescriptionKey("recoveryKey.recover.resetMasterkeyFileSuccess.description")
.build().showAndWait();
} catch (InvalidPassphraseException e) {
LOG.info("Password invalid", e);
Animations.createShakeWindowAnimation(window).play();
} catch (IOException | CryptoException | IllegalStateException e) {
LOG.error("Recovery process failed", e);
appWindows.showErrorWindow(e, window, null);
}
}

View File

@@ -117,14 +117,46 @@ public class RecoveryKeyResetPasswordController implements FxController {
@FXML
public void next() {
switch (recoverType.get()) {
case RESTORE_ALL -> restorePassword();
case RESTORE_ALL -> restorePasswordAsync();
case RESTORE_MASTERKEY, RESET_PASSWORD -> resetPassword();
default -> resetPassword(); // Fallback
}
}
@FXML
public void restorePassword() {
public void restorePasswordAsync() {
Task<Void> task = RecoveryKeyTasks.createTask(this::restorePassword);
task.setOnScheduled(_ -> {
LOG.debug("Restoring vault configuration for {}.", vault.getDisplayablePath());
});
task.setOnSucceeded(_ -> {
LOG.debug("Restored vault configuration for {}.", vault.getDisplayablePath());
try {
if (!vaultListManager.isAlreadyAdded(vault.getPath())) {
vaultListManager.add(vault.getPath());
}
window.close();
dialogs.prepareRecoverPasswordSuccess((Stage) window.getOwner()) //
.setTitleKey("recover.recoverVaultConfig.title") //
.setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") //
.build().showAndWait();
} catch (IOException e) {
LOG.error("Failed to add vault to list.", e);
appWindows.showErrorWindow(e, window, null);
}
});
task.setOnFailed(_ -> {
LOG.error("Recovery process failed.", task.getException());
appWindows.showErrorWindow(task.getException(), window, null);
});
executor.submit(task);
}
void restorePassword() throws IOException, CryptoException {
try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) {
Path recoveryPath = recoveryDirectory.getRecoveryPath();
MasterkeyService.recoverFromRecoveryKey(recoveryKey.get(), recoveryKeyFactory, recoveryPath, newPasswordController.passwordField.getCharacters());
@@ -135,19 +167,6 @@ public class RecoveryKeyResetPasswordController implements FxController {
recoveryDirectory.moveRecoveredFile(MASTERKEY_FILENAME);
recoveryDirectory.moveRecoveredFile(VAULTCONFIG_FILENAME);
if (!vaultListManager.isAlreadyAdded(vault.getPath())) {
vaultListManager.add(vault.getPath());
}
window.close();
dialogs.prepareRecoverPasswordSuccess((Stage)window.getOwner()) //
.setTitleKey("recover.recoverVaultConfig.title") //
.setMessageKey("recoveryKey.recover.resetVaultConfigSuccess.message") //
.build().showAndWait();
} catch (IOException | CryptoException e) {
LOG.error("Recovery process failed", e);
appWindows.showErrorWindow(e, window, null);
}
}

View File

@@ -0,0 +1,25 @@
package org.cryptomator.ui.recoverykey;
import javafx.concurrent.Task;
final class RecoveryKeyTasks {
private RecoveryKeyTasks() {
}
@FunctionalInterface
interface TaskAction {
void run() throws Exception;
}
static Task<Void> createTask(TaskAction action) {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
action.run();
return null;
}
};
}
}

View File

@@ -50,6 +50,7 @@
GREEN_5: PRIMARY;
RED_5: #E74C3C;
ORANGE_5: #E67E22;
YELLOW_4: #C19F0E;
YELLOW_5: #F1C40F;
MAIN_BG: GRAY_1;
@@ -387,37 +388,62 @@
/*******************************************************************************
* *
* NotificationBar *
* InfoBar *
* *
******************************************************************************/
.info-bar {
-fx-alignment: center;
-fx-min-height:24px;
-fx-max-height:24px;
-fx-background-color: -bar-bg;
}
.notification-label {
-fx-text-fill: white;
.info-bar--green {
-bar-bg: GREEN_5;
-button-bg: GREEN_5;
-button-bg-pressed: GREEN_3;
}
.info-bar--yellow {
-bar-bg: YELLOW_5;
-button-bg: YELLOW_5;
-button-bg-pressed: YELLOW_4;
}
.info-bar--red {
-bar-bg: RED_5;
-button-bg: RED_5;
-button-bg-pressed: RED_5;
}
.info-bar .label {
-fx-text-fill: GRAY_9;
-fx-font-weight: bold;
}
.notification-debug {
-fx-min-height:24px;
-fx-max-height:24px;
-fx-background-color: RED_5;
.info-bar--yellow .label {
-fx-text-fill: GRAY_9;
-fx-font-weight: bold;
-fx-effect: dropshadow( gaussian , rgba(0,0,0,0.45) , 2 , 0 , 0 , 1 );
}
.notification-update {
-fx-min-height:24px;
-fx-max-height:24px;
-fx-background-color: YELLOW_5;
.info-bar .glyph {
-fx-fill: GRAY_9;
}
.notification-support {
-fx-min-height:24px;
-fx-max-height:24px;
-fx-background-color: PRIMARY;
.info-bar:hover .label {
-fx-underline:true;
}
.notification-debug:hover .notification-label,
.notification-update:hover .notification-label,
.notification-support:hover .notification-label {
-fx-underline:true;
.info-bar .button {
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-padding: 2 2 2 2;
}
.info-bar .button:armed {
-fx-background-color: -button-bg-pressed;
-fx-background-radius: 8;
}
/*******************************************************************************

View File

@@ -50,6 +50,7 @@
GREEN_5: PRIMARY;
RED_5: #E74C3C;
ORANGE_5: #E67E22;
YELLOW_4: #C19F0E;
YELLOW_5: #F1C40F;
MAIN_BG: GRAY_9;
@@ -387,39 +388,64 @@
/*******************************************************************************
* *
* NotificationBar *
* InfoBar *
* *
******************************************************************************/
.info-bar {
-fx-alignment: center;
-fx-min-height:24px;
-fx-max-height:24px;
-fx-background-color: -bar-bg;
}
.notification-label {
-fx-text-fill: white;
.info-bar--green {
-bar-bg: GREEN_5;
-button-bg: GREEN_5;
-button-bg-pressed: GREEN_3;
}
.info-bar--yellow {
-bar-bg: YELLOW_5;
-button-bg: YELLOW_5;
-button-bg-pressed: YELLOW_4;
}
.info-bar--red {
-bar-bg: RED_5;
-button-bg: RED_5;
-button-bg-pressed: RED_5;
}
.info-bar .label {
-fx-text-fill: GRAY_9;
-fx-font-weight: bold;
}
.notification-debug {
-fx-min-height:24px;
-fx-max-height:24px;
-fx-background-color: RED_5;
.info-bar--yellow .label {
-fx-text-fill: GRAY_9;
-fx-font-weight: bold;
-fx-effect: dropshadow( gaussian , rgba(0,0,0,0.45) , 2 , 0 , 0 , 1 );
}
.notification-update {
-fx-min-height:24px;
-fx-max-height:24px;
-fx-background-color: YELLOW_5;
.info-bar .glyph {
-fx-fill: GRAY_9;
}
.notification-support {
-fx-min-height:24px;
-fx-max-height:24px;
-fx-background-color: PRIMARY;
}
.notification-debug:hover .notification-label,
.notification-update:hover .notification-label,
.notification-support:hover .notification-label {
.info-bar:hover .label {
-fx-underline:true;
}
.info-bar .button {
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-padding: 2 2 2 2;
}
.info-bar .button:armed {
-fx-background-color: -button-bg-pressed;
-fx-background-radius: 8;
}
/*******************************************************************************
* *
* ScrollBar *

View File

@@ -13,7 +13,8 @@
prefWidth="450"
prefHeight="450"
spacing="24"
alignment="CENTER">
alignment="CENTER"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>

View File

@@ -19,7 +19,8 @@
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="CENTER_LEFT">
alignment="CENTER_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>

View File

@@ -19,7 +19,8 @@
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="CENTER_LEFT">
alignment="CENTER_LEFT"
accessibleRole="DIALOG">
<fx:define>
<ToggleGroup fx:id="locationPresetsToggler"/>
<FontAwesome5IconView fx:id="badLocation" styleClass="glyph-icon-red" glyph="TIMES"/>

View File

@@ -17,7 +17,8 @@
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="CENTER_LEFT">
alignment="CENTER_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>

View File

@@ -15,7 +15,8 @@
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="CENTER_LEFT">
alignment="CENTER_LEFT"
accessibleRole="DIALOG">
<fx:define>
<ToggleGroup fx:id="recoveryKeyChoice"/>
</fx:define>

View File

@@ -11,7 +11,8 @@
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="CENTER_LEFT">
alignment="CENTER_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>

View File

@@ -16,7 +16,8 @@
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="TOP_CENTER">
alignment="TOP_CENTER"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>

View File

@@ -13,7 +13,8 @@
fx:controller="org.cryptomator.ui.changepassword.ChangePasswordController"
minWidth="400"
maxWidth="400"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_CENTER">
alignment="TOP_CENTER"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -15,7 +15,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_CENTER">
alignment="TOP_CENTER"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -19,7 +19,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -22,7 +22,8 @@
minHeight="450"
prefWidth="450"
prefHeight="450"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>

View File

@@ -21,7 +21,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -20,7 +20,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -20,7 +20,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -20,7 +20,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -11,6 +11,7 @@
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Circle?>
<!-- TODO: simple dialog -->
<HBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.keyloading.hub.RegisterFailedController"
@@ -18,7 +19,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -21,7 +21,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -19,7 +19,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -19,7 +19,8 @@
maxWidth="500"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -3,7 +3,7 @@
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import org.cryptomator.ui.controls.NotificationBar?>
<?import org.cryptomator.ui.controls.InfoBar?>
<StackPane xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
@@ -11,23 +11,23 @@
fx:controller="org.cryptomator.ui.mainwindow.MainWindowController"
styleClass="main-window">
<VBox minWidth="600">
<NotificationBar onMouseClicked="#showUpdatePreferences"
<InfoBar onMouseClicked="#showUpdatePreferences"
text="%main.notification.updateAvailable"
dismissable="true"
notify="${controller.updateAvailable}"
styleClass="notification-update"/>
<NotificationBar onMouseClicked="#showContributePreferences"
styleClass="info-bar--yellow"/>
<InfoBar onMouseClicked="#showContributePreferences"
text="%main.notification.support"
dismissable="true"
notify="${!controller.licenseValid}"
styleClass="notification-support"/>
styleClass="info-bar--green"/>
<SplitPane dividerPositions="0.33" orientation="HORIZONTAL" VBox.vgrow="ALWAYS">
<fx:include source="vault_list.fxml" SplitPane.resizableWithParent="false"/>
<fx:include source="vault_detail.fxml" SplitPane.resizableWithParent="true"/>
</SplitPane>
<NotificationBar onMouseClicked="#showGeneralPreferences"
<InfoBar onMouseClicked="#showGeneralPreferences"
text="DEBUG MODE"
styleClass="notification-debug"
styleClass="info-bar--red"
notify="${controller.debugModeEnabled}"/>
</VBox>
</StackPane>

View File

@@ -16,7 +16,8 @@
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -19,7 +19,8 @@
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -20,7 +20,8 @@
fx:controller="org.cryptomator.ui.migration.MigrationStartController"
prefWidth="580"
prefHeight="350"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -15,7 +15,8 @@
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -16,7 +16,8 @@
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.notification.NotificationController"
prefHeight="200.0" prefWidth="400.0" maxHeight="200.0" maxWidth="400.0"
styleClass="notification-window">
styleClass="notification-window"
accessibleRole="DIALOG">
<padding>
<Insets top="12" right="12" bottom="12" left="12"/>
</padding>

View File

@@ -19,7 +19,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -19,7 +19,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -20,7 +20,8 @@
maxWidth="400"
minHeight="175"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -14,7 +14,8 @@
minWidth="350"
minHeight="280"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<children>
<FormattedLabel format="%recoveryKey.display.description" arg1="${controller.vaultName}" wrapText="true" labelFor="$textarea"/>

View File

@@ -22,7 +22,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_CENTER">
alignment="TOP_CENTER"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -25,7 +25,8 @@
prefWidth="480"
minHeight="242"
spacing="12"
VBox.vgrow="ALWAYS">
VBox.vgrow="ALWAYS"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -17,7 +17,8 @@
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -17,7 +17,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_CENTER">
alignment="TOP_CENTER"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -12,7 +12,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_CENTER">
alignment="TOP_CENTER"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -10,7 +10,8 @@
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyValidateController"
maxWidth="400"
minHeight="145"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<children>
<FormattedLabel format="%recoveryKey.recover.prompt" arg1="${controller.vault.displayName}" wrapText="true" labelFor="$textarea"/>

View File

@@ -21,7 +21,8 @@
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.sharevault.ShareVaultController"
prefWidth="540"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -17,7 +17,8 @@
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
minWidth="400"
maxWidth="400"
minHeight="145"
spacing="12">
spacing="12"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -19,7 +19,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -19,7 +19,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -20,7 +20,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -21,7 +21,8 @@
maxWidth="400"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,7 +18,8 @@
prefWidth="500"
minHeight="145"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -36,7 +36,7 @@
<Label styleClass="badge,badge-pill,badge-muted" text="…" minWidth="-Infinity" visible="${controller.vault.processing}" managed="${controller.vault.processing}"/>
<Label styleClass="badge,badge-pill,badge-primary" text="%main.vaultDetail.unlockedStatus" minWidth="-Infinity" visible="${controller.vault.unlocked}" managed="${controller.vault.unlocked}"/>
</HBox>
<Hyperlink styleClass="hyperlink-muted,hyperlink-hover-icon" text="${controller.vault.displayablePath}" textOverrun="CENTER_ELLIPSIS" onAction="#revealStorageLocation">
<Hyperlink styleClass="hyperlink-muted,hyperlink-hover-icon" text="${controller.vault.displayablePath}" textOverrun="CENTER_ELLIPSIS" onAction="#revealStorageLocation" accessibleText="%main.vaultDetail.storageLocation" accessibleRole="BUTTON">
<graphic>
<FontAwesome5IconView styleClass="glyph-icon-muted" glyph="EYE"/>
</graphic>

View File

@@ -22,7 +22,7 @@
<VBox>
<StackPane VBox.vgrow="ALWAYS">
<VBox>
<ListView fx:id="vaultList" editable="true" fixedCellSize="${controller.cellSize}">
<ListView fx:id="vaultList" editable="true" fixedCellSize="${controller.cellSize}" accessibleText="%main.vaultlist">
<contextMenu>
<fx:include source="vault_list_contextmenu.fxml"/>
</contextMenu>

View File

@@ -23,7 +23,8 @@
minWidth="-Infinity"
minHeight="-Infinity"
spacing="12"
alignment="TOP_LEFT">
alignment="TOP_LEFT"
accessibleRole="DIALOG">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>

View File

@@ -18,6 +18,14 @@ generic.button.next=Next
generic.button.print=Print
generic.button.remove=Remove
## Vault state
vault.state.locked=Locked
vault.state.unlocked=Unlocked
vault.state.missing=Missing
vault.state.migrationNeeded=Migration required
vault.state.processing=Processing
vault.state.error=Error
# Error
error.message=An error occurred
error.description=Cryptomator didn't expect this to happen. You can look up existing solutions for this error. Or if it has not been reported yet, feel free to do so.
@@ -402,6 +410,8 @@ stats.access.total=Total accesses: %d
# Main Window
## Vault List
main.vaultlist=Vaults
main.vaultlist.listEntry=Vault %s (%s)
main.vaultlist.emptyList.onboardingInstruction=Click here to add a vault
main.vaultlist.contextMenu.remove=Remove…
main.vaultlist.contextMenu.lock=Lock
@@ -416,12 +426,14 @@ main.vaultlist.addVaultBtn.menuItemRecover=Recover Existing Vault…
main.vaultlist.addVaultButton.tooltip=Add Vault
main.vaultlist.showEventsButton.tooltip=Open Event View
main.vaultlist.showPreferencesButton.tooltip=Show Preferences
##Notificaition
##Notification
main.notification.updateAvailable=Update is available.
main.notification.support=Support Cryptomator.
main.notification.closeButton.tooltip=Close info bar
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Thanks for choosing Cryptomator to protect your files. If you need any assistance, check out our getting started guides:
main.vaultDetail.storageLocation=Vault storage location
### Locked
main.vaultDetail.lockedStatus=LOCKED
main.vaultDetail.unlockBtn=Unlock…