diff --git a/.github/workflows/dl-stats.yml b/.github/workflows/dl-stats.yml
new file mode 100644
index 000000000..0d9ca5dd7
--- /dev/null
+++ b/.github/workflows/dl-stats.yml
@@ -0,0 +1,63 @@
+name: Report Download Stats
+
+on:
+ schedule:
+ - cron: '0/15 * * * *' # run every 15 min - don't forget to adjust the "interval" in the json sent to the metrics endpoint
+
+jobs:
+ report-download-stats:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Get download count of latest releases
+ id: get-stats
+ uses: actions/github-script@v6
+ with:
+ script: |
+ const query = `query($owner:String!, $name:String!) {
+ repository(owner:$owner, name:$name){
+ releases(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) {
+ nodes {
+ isPrerelease
+ tagName
+ releaseAssets(first: 20) {
+ nodes {
+ name
+ downloadCount
+ }
+ }
+ }
+ }
+ }
+ }`;
+ const variables = {
+ owner: context.repo.owner,
+ name: context.repo.repo
+ }
+ return await github.graphql(query, variables)
+ - name: Transform Results
+ id: transform-stats
+ run: |
+ TIME=$(($(date +%s) / $INTERVAL * $INTERVAL))
+ echo ${JSON_DATA} | jq --arg TIME "$TIME" --arg INTERVAL "$INTERVAL" -c '.repository.releases.nodes[] | select(.isPrerelease == false) | .tagName as $tagName | .releaseAssets.nodes[] | {filename: .name, downloads: .downloadCount, release: $tagName, time: ($TIME|tonumber), interval: ($INTERVAL|tonumber)}' > input.json
+
+ jq -c 'select(.filename|endswith("-x86_64.AppImage")) | {name: "github.releases.downloads", tags: ["file=AppImage", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
+ jq -c 'select(.filename|endswith("_amd64.deb")) | {name: "github.releases.downloads", tags: ["file=deb", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
+ jq -c 'select(.filename|endswith("-x64.msi")) | {name: "github.releases.downloads", tags: ["file=msi", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
+ jq -c 'select(.filename|endswith("-x64.exe")) | {name: "github.releases.downloads", tags: ["file=exe", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
+ jq -c 'select(.filename|endswith("-arm64.dmg")) | {name: "github.releases.downloads", tags: ["file=dmg", "version=\(.release)", "arch=arm64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
+ jq -c 'select(.filename|endswith(".dmg")) | select(.filename|endswith("-arm64.dmg")|not) | {name: "github.releases.downloads", tags: ["file=dmg", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
+
+ RESULT=$(jq -s -c "." output.json)
+ echo "::set-output name=result::${RESULT}"
+ env:
+ INTERVAL: 900
+ JSON_DATA: ${{ steps.get-stats.outputs.result }}
+ - name: Upload Results
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: 'https://graphite-us-central1.grafana.net/metrics'
+ method: 'POST'
+ contentType: 'application/json'
+ bearerToken: ${{ secrets.GRAFANA_GRAPHITE_TOKEN }}
+ data: ${{ steps.transform-stats.outputs.result }}
+ continue-on-error: true # currently there seems to be a problem with the metrics endpoint, failing every now and then
diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml
index 56ea3e94a..1ba5822e3 100644
--- a/.github/workflows/mac-dmg.yml
+++ b/.github/workflows/mac-dmg.yml
@@ -91,6 +91,7 @@ jobs:
--java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\""
--java-options "-Dcryptomator.p12Path=\"~/Library/Application Support/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\""
+ --java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"dmg-${{ steps.versions.outputs.revNum }}\""
--mac-package-identifier org.cryptomator
@@ -188,33 +189,14 @@ jobs:
Cryptomator-${VERSION_NO}.dmg dmg
env:
VERSION_NO: ${{ steps.versions.outputs.semVerNum }}
- - name: Install notarization credentials
- if: startsWith(github.ref, 'refs/tags/')
- run: |
- # create temporary keychain
- KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
- security create-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
- security set-keychain-settings -lut 900 ${KEYCHAIN_PATH}
- security unlock-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
-
- # import credentials from secrets
- sudo xcode-select -s /Applications/Xcode_13.0.app
- xcrun notarytool store-credentials "${NOTARIZATION_KEYCHAIN_PROFILE}" --apple-id "${NOTARIZATION_APPLE_ID}" --password "${NOTARIZATION_PW}" --team-id "${NOTARIZATION_TEAM_ID}" --keychain "${KEYCHAIN_PATH}"
- env:
- NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
- NOTARIZATION_APPLE_ID: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
- NOTARIZATION_PW: ${{ secrets.MACOS_NOTARIZATION_PW }}
- NOTARIZATION_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
- NOTARIZATION_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_NOTARIZATION_TMP_KEYCHAIN_PW }}
- name: Notarize .dmg
if: startsWith(github.ref, 'refs/tags/')
- run: |
- KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
- sudo xcode-select -s /Applications/Xcode_13.0.app
- xcrun notarytool submit Cryptomator-*.dmg --keychain-profile "${NOTARIZATION_KEYCHAIN_PROFILE}" --keychain "${KEYCHAIN_PATH}" --wait
- xcrun stapler staple Cryptomator-*.dmg
- env:
- NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
+ uses: cocoalibs/xcode-notarization-action@v1
+ with:
+ app-path: 'Cryptomator-*.dmg'
+ apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
+ password: ${{ secrets.MACOS_NOTARIZATION_PW }}
+ team-id: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
- name: Add possible alpha/beta tags to installer name
run: mv Cryptomator-*.dmg Cryptomator-${{ steps.versions.outputs.semVerStr }}.dmg
- name: Create detached GPG signature with key 615D449FE6E6A235
@@ -228,10 +210,6 @@ jobs:
if: ${{ always() }}
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
continue-on-error: true
- - name: Clean up notarization credentials
- if: ${{ always() }}
- run: security delete-keychain $RUNNER_TEMP/notarization.keychain-db
- continue-on-error: true
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml
index 94e13c514..1c9195c43 100644
--- a/.github/workflows/win-exe.yml
+++ b/.github/workflows/win-exe.yml
@@ -98,6 +98,7 @@ jobs:
--java-options "-Dcryptomator.mountPointsDir=\"~/Cryptomator\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"msi-${{ steps.versions.outputs.revNum }}\""
+ --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
--resource-dir dist/win/resources
--icon dist/win/resources/Cryptomator.ico
- name: Patch Application Directory
@@ -189,6 +190,19 @@ jobs:
semVerStr: ${{ steps.versions.outputs.semVerStr }}
revNum: ${{ steps.versions.outputs.revNum }}
+ publish-winget:
+ name: Publish on winget repo
+ runs-on: windows-latest
+ needs: [build-msi]
+ steps:
+ - name: Submit package to Windows Package Manager Community Repository
+ run: |
+ iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
+ $github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json
+ $installerUrl = $github.release.assets | Where-Object -Property name -match 'Cryptomator-*.msi' | Select -ExpandProperty browser_download_url -First 1
+ .\wingetcreate.exe update Cryptomator.Cryptomator -s -v $github.release.tag_name -u $installerUrl -t ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
+ shell: pwsh
+
build-exe:
name: Build .exe installer
runs-on: windows-latest
diff --git a/.gitignore b/.gitignore
index 5c84c0dfb..796458fe6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,25 +5,9 @@
*.war
*.ear
-# Eclipse Settings Files #
-.settings
-.project
-.classpath
-
# Maven #
target/
pom.xml.versionsBackup
-# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) #
-.idea/**/workspace.xml
-.idea/**/tasks.xml
-.idea/**/shelf
-.idea/dictionaries/**
-!.idea/dictionaries/dict_*
-.idea/compiler.xml
-.idea/jarRepositories.xml
-.idea/uiDesigner.xml
-.idea/**/libraries/
-*.iml
-
+# Java Crash Logs
hs_err_pid*.log
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 000000000..8e78cfe58
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,13 @@
+# see https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems
+
+# Default ignored files
+/shelf/
+/workspace.xml
+/usage.statistics.xml
+/dictionaries/
+
+# generated from Maven
+/jarRepositories.xml
+/modules.xml
+/*.iml
+/libraries/*.xml
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 000000000..18be437d6
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml
index 865ac739e..329e03d0b 100644
--- a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml
+++ b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml
@@ -66,6 +66,7 @@
+
diff --git a/dist/mac/dmg/build.sh b/dist/mac/dmg/build.sh
index 0d2db1219..76606b51f 100755
--- a/dist/mac/dmg/build.sh
+++ b/dist/mac/dmg/build.sh
@@ -14,9 +14,17 @@ while getopts ":s:" o; do
done
shift "$((OPTIND-1))"
-# prepare working dir and variables
+# prepare working dir
cd $(dirname $0)
-rm -rf runtime dmg
+rm -rf runtime dmg *.app *.dmg
+
+# set variables
+APP_NAME="Cryptomator"
+VENDOR="Skymatic GmbH"
+COPYRIGHT_YEARS="2016 - 2022"
+PACKAGE_IDENTIFIER="org.cryptomator"
+MAIN_JAR_GLOB="cryptomator-*.jar"
+MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
REVISION_NO=`git rev-list --count HEAD`
VERSION_NO=`mvn -f../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout | sed -rn 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p'`
@@ -31,7 +39,7 @@ fi
# compile
mvn -B -f../../../pom.xml clean package -DskipTests -Pmac
-cp ../../../target/cryptomator-*.jar ../../../target/mods
+cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
# add runtime
${JAVA_HOME}/bin/jlink \
@@ -51,11 +59,11 @@ ${JAVA_HOME}/bin/jpackage \
--runtime-image runtime \
--input ../../../target/libs \
--module-path ../../../target/mods \
- --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator \
+ --module ${MODULE_AND_MAIN_CLASS} \
--dest . \
- --name Cryptomator \
- --vendor "Skymatic GmbH" \
- --copyright "(C) 2016 - 2022 Skymatic GmbH" \
+ --name ${APP_NAME} \
+ --vendor "${VENDOR}" \
+ --copyright "(C) ${COPYRIGHT_YEARS} ${VENDOR}" \
--app-version "${VERSION_NO}" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
@@ -63,20 +71,21 @@ ${JAVA_HOME}/bin/jpackage \
--java-options "-Dapple.awt.enableTemplateImages=true" \
--java-options "-Dsun.java2d.metal=true" \
--java-options "-Dcryptomator.appVersion=\"${VERSION_NO}\"" \
- --java-options "-Dcryptomator.logDir=\"~/Library/Logs/Cryptomator\"" \
- --java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/Cryptomator/Plugins\"" \
- --java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\"" \
- --java-options "-Dcryptomator.p12Path=\"~/Library/Application Support/Cryptomator/key.p12\"" \
- --java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\"" \
+ --java-options "-Dcryptomator.logDir=\"~/Library/Logs/${APP_NAME}\"" \
+ --java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/${APP_NAME}/Plugins\"" \
+ --java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/${APP_NAME}/settings.json\"" \
+ --java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/${APP_NAME}/ipc.socket\"" \
+ --java-options "-Dcryptomator.p12Path=\"~/Library/Application Support/${APP_NAME}/key.p12\"" \
+ --java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"${APP_NAME}\"" \
--java-options "-Dcryptomator.showTrayIcon=true" \
--java-options "-Dcryptomator.buildNumber=\"dmg-${REVISION_NO}\"" \
- --mac-package-identifier org.cryptomator \
+ --mac-package-identifier ${PACKAGE_IDENTIFIER} \
--resource-dir ../resources
# transform app dir
-cp ../resources/Cryptomator-Vault.icns Cryptomator.app/Contents/Resources/
-sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist
-sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist
+cp ../resources/${APP_NAME}-Vault.icns ${APP_NAME}.app/Contents/Resources/
+sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" ${APP_NAME}.app/Contents/Info.plist
+sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" ${APP_NAME}.app/Contents/Info.plist
# generate license
mvn -B -f../../../pom.xml license:add-third-party \
@@ -90,8 +99,8 @@ mvn -B -f../../../pom.xml license:add-third-party \
# codesign
if [ -n "${CODESIGN_IDENTITY}" ]; then
- find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
- for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do
+ find ${APP_NAME}.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
+ for JAR_PATH in `find ${APP_NAME}.app -name "*.jar"`; do
if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
JAR_FILENAME=$(basename ${JAR_PATH})
OUTPUT_PATH=${JAR_PATH%.*}
@@ -106,25 +115,25 @@ if [ -n "${CODESIGN_IDENTITY}" ]; then
rm -r ${OUTPUT_PATH}
fi
done
- echo "Codesigning Cryptomator.app..."
- codesign --force --deep --entitlements ../Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app
+ echo "Codesigning ${APP_NAME}.app..."
+ codesign --force --deep --entitlements ../${APP_NAME}.entitlements -o runtime -s ${CODESIGN_IDENTITY} ${APP_NAME}.app
fi
# prepare dmg contents
mkdir dmg
-mv Cryptomator.app dmg
+mv ${APP_NAME}.app dmg
cp resources/macFUSE.webloc dmg
# create dmg
create-dmg \
- --volname Cryptomator \
- --volicon "resources/Cryptomator-Volume.icns" \
- --background "resources/Cryptomator-background.tiff" \
+ --volname ${APP_NAME} \
+ --volicon "resources/${APP_NAME}-Volume.icns" \
+ --background "resources/${APP_NAME}-background.tiff" \
--window-pos 400 100 \
--window-size 640 694 \
--icon-size 128 \
- --icon "Cryptomator.app" 128 245 \
- --hide-extension "Cryptomator.app" \
+ --icon "${APP_NAME}.app" 128 245 \
+ --hide-extension "${APP_NAME}.app" \
--icon "macFUSE.webloc" 320 501 \
--hide-extension "macFUSE.webloc" \
--app-drop-link 512 245 \
@@ -132,4 +141,4 @@ create-dmg \
--icon ".background" 128 758 \
--icon ".fseventsd" 320 758 \
--icon ".VolumeIcon.icns" 512 758 \
- Cryptomator-${VERSION_NO}.dmg dmg
+ ${APP_NAME}-${VERSION_NO}.dmg dmg
diff --git a/dist/win/build.bat b/dist/win/build.bat
index 8ca9183b4..c97ebbb35 100644
--- a/dist/win/build.bat
+++ b/dist/win/build.bat
@@ -1,2 +1,23 @@
@echo off
-powershell -NoLogo -NoExit -ExecutionPolicy Unrestricted -Command .\build.ps1
\ No newline at end of file
+:: Default values for Cryptomator builds
+SET APPNAME="Cryptomator"
+SET MAIN_JAR_GLOB="cryptomator-*"
+SET UPGRADE_UUID="bda45523-42b1-4cae-9354-a45475ed4775"
+SET VENDOR="Skymatic GmbH"
+SET FIRST_COPYRIGHT_YEAR=2016
+SET ABOUT_URL="https://cryptomator.org"
+SET UPDATE_URL="https://cryptomator.org/downloads/"
+SET HELP_URL="https://cryptomator.org/contact/"
+SET MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
+
+powershell -NoLogo -NoExit -ExecutionPolicy Unrestricted -Command .\build.ps1^
+ -AppName %APPNAME%^
+ -MainJarGlob "%MAIN_JAR_GLOB%"^
+ -ModuleAndMainClass "%MODULE_AND_MAIN_CLASS%"^
+ -UpgradeUUID "%UPGRADE_UUID%"^
+ -Vendor ""%VENDOR%""^
+ -CopyrightStartYear %FIRST_COPYRIGHT_YEAR%^
+ -AboutUrl "%ABOUT_URL%"^
+ -HelpUrl "%HELP_URL%"^
+ -UpdateUrl "%UPDATE_URL%"^
+ -Clean 1
\ No newline at end of file
diff --git a/dist/win/build.ps1 b/dist/win/build.ps1
index e491769e1..38c4dc4ae 100644
--- a/dist/win/build.ps1
+++ b/dist/win/build.ps1
@@ -1,5 +1,15 @@
-# check parameters
-$clean = $args[0] -eq "fresh"
+Param(
+ [Parameter(Mandatory, HelpMessage="Please provide a name for the app")][string] $AppName,
+ [Parameter(Mandatory, HelpMessage="Please provide the glob pattern to identify the main jar")][string] $MainJarGlob,
+ [Parameter(Mandatory, HelpMessage="Please provide the module- and main class path to start the app")][string] $ModuleAndMainClass,
+ [Parameter(Mandatory, HelpMessage="Please provide the windows upgrade uuid for the installer")][string] $UpgradeUUID,
+ [Parameter(Mandatory, HelpMessage="Please provide the name of the vendor")][string] $Vendor,
+ [Parameter(Mandatory, HelpMessage="Please provide the starting year for the copyright notice")][int] $CopyrightStartYear,
+ [Parameter(Mandatory, HelpMessage="Please provide a help url")][string] $HelpUrl,
+ [Parameter(Mandatory, HelpMessage="Please provide an update url")][string] $UpdateUrl,
+ [Parameter(Mandatory, HelpMessage="Please provide an about url")][string] $AboutUrl,
+ [bool] $clean
+)
# check preconditions
if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
@@ -24,12 +34,11 @@ Write-Output "`$revisionNo=$revisionNo"
Write-Output "`$buildDir=$buildDir"
Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME"
-$vendor = "Skymatic GmbH"
-$copyright = "(C) 2016 - 2022 Skymatic GmbH"
+$copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor"
# compile
&mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin
-Copy-Item "$buildDir\..\..\target\cryptomator-*.jar" -Destination "$buildDir\..\..\target\mods"
+Copy-Item "$buildDir\..\..\target\$MainJarGlob.jar" -Destination "$buildDir\..\..\target\mods"
# add runtime
$runtimeImagePath = '.\runtime'
@@ -48,7 +57,7 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
--strip-debug `
--compress=1
-$appPath = '.\Cryptomator'
+$appPath = ".\$AppName"
if ($clean -and (Test-Path -Path $appPath)) {
Remove-Item -Path $appPath -Force -Recurse
}
@@ -60,27 +69,28 @@ if ($clean -and (Test-Path -Path $appPath)) {
--runtime-image runtime `
--input ../../target/libs `
--module-path ../../target/mods `
- --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator `
+ --module $ModuleAndMainClass `
--dest . `
- --name Cryptomator `
- --vendor $vendor `
+ --name $AppName `
+ --vendor $Vendor `
--copyright $copyright `
--java-options "-Xss5m" `
--java-options "-Xmx256m" `
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
--app-version "$semVerNo.$revisionNo" `
--java-options "-Dfile.encoding=`"utf-8`"" `
- --java-options "-Dcryptomator.logDir=`"~/AppData/Roaming/Cryptomator`"" `
- --java-options "-Dcryptomator.pluginDir=`"~/AppData/Roaming/Cryptomator/Plugins`"" `
- --java-options "-Dcryptomator.settingsPath=`"~/AppData/Roaming/Cryptomator/settings.json`"" `
- --java-options "-Dcryptomator.p12Path=`"~/AppData/Roaming/Cryptomator/key.p12`"" `
- --java-options "-Dcryptomator.ipcSocketPath=`"~/AppData/Roaming/Cryptomator/ipc.socket`"" `
- --java-options "-Dcryptomator.keychainPath=`"~/AppData/Roaming/Cryptomator/keychain.json`"" `
- --java-options "-Dcryptomator.mountPointsDir=`"~/Cryptomator`"" `
+ --java-options "-Dcryptomator.logDir=`"~/AppData/Roaming/$AppName`"" `
+ --java-options "-Dcryptomator.pluginDir=`"~/AppData/Roaming/$AppName/Plugins`"" `
+ --java-options "-Dcryptomator.settingsPath=`"~/AppData/Roaming/$AppName/settings.json`"" `
+ --java-options "-Dcryptomator.ipcSocketPath=`"~/AppData/Roaming/$AppName/ipc.socket`"" `
+ --java-options "-Dcryptomator.keychainPath=`"~/AppData/Roaming/$AppName/keychain.json`"" `
+ --java-options "-Dcryptomator.p12Path=`"~/AppData/Roaming/$AppName/key.p12`"" `
+ --java-options "-Dcryptomator.mountPointsDir=`"~/$AppName`"" `
+ --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
--java-options "-Dcryptomator.showTrayIcon=true" `
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
--resource-dir resources `
- --icon resources/Cryptomator.ico
+ --icon resources/$AppName.ico
#Create RTF license for msi
&mvn -B -f $buildDir/../../pom.xml license:add-third-party `
@@ -93,33 +103,29 @@ if ($clean -and (Test-Path -Path $appPath)) {
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
# patch app dir
-Copy-Item "contrib\*" -Destination "Cryptomator"
-attrib -r "Cryptomator\Cryptomator.exe"
-
-$aboutUrl="https://cryptomator.org"
-$updateUrl="https://cryptomator.org/downloads/"
-$helpUrl="https://cryptomator.org/contact/"
+Copy-Item "contrib\*" -Destination "$AppName"
+attrib -r "$AppName\$AppName.exe"
# create .msi
$Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
& "$Env:JAVA_HOME\bin\jpackage" `
--verbose `
--type msi `
- --win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775 `
- --app-image Cryptomator `
+ --win-upgrade-uuid $UpgradeUUID `
+ --app-image $AppName `
--dest installer `
- --name Cryptomator `
- --vendor $vendor `
+ --name $AppName `
+ --vendor $Vendor `
--copyright $copyright `
--app-version "$semVerNo" `
--win-menu `
--win-dir-chooser `
--win-shortcut-prompt `
- --win-update-url $updateUrl `
- --win-menu-group Cryptomator `
+ --win-menu-group $AppName `
--resource-dir resources `
- --about-url $aboutUrl `
--license-file resources/license.rtf `
+ --win-update-url $UpdateUrl `
+ --about-url $AboutUrl `
--file-associations resources/FAvaultFile.properties
#Create RTF license for bundle
@@ -140,14 +146,14 @@ Write-Output "Downloading ${winfspMsiUrl}..."
Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default
# copy MSI to bundle resources
-Copy-Item ".\installer\Cryptomator-*.msi" -Destination ".\bundle\resources\Cryptomator.msi"
+Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi"
# create bundle including winfsp
& "$env:WIX\bin\candle.exe" .\bundle\bundleWithWinfsp.wxs -ext WixBalExtension -out bundle\ `
-dBundleVersion="$semVerNo.$revisionNo" `
- -dBundleVendor="$vendor" `
+ -dBundleVendor="$Vendor" `
-dBundleCopyright="$copyright" `
- -dAboutUrl="$aboutUrl" `
- -dHelpUrl="$helpUrl" `
- -dUpdateUrl="$updateUrl"
-& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -out installer\Cryptomator-Installer.exe
\ No newline at end of file
+ -dAboutUrl="$AboutUrl" `
+ -dHelpUrl="$HelpUrl" `
+ -dUpdateUrl="$UpdateUrl"
+& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -out installer\$AppName-Installer.exe
\ No newline at end of file
diff --git a/dist/win/contrib/patchWebDAV.bat b/dist/win/contrib/patchWebDAV.bat
index e31249831..1726147d2 100644
--- a/dist/win/contrib/patchWebDAV.bat
+++ b/dist/win/contrib/patchWebDAV.bat
@@ -1,3 +1,7 @@
@echo off
+:: Default values for Cryptomator builds
+SET LOOPBACK_ALIAS="cryptomator-vault"
+
cd %~dp0
-powershell -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -Command .\patchWebDAV.ps1
\ No newline at end of file
+powershell -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -Command .\patchWebDAV.ps1^
+ -LoopbackAlias %LOOPBACK_ALIAS%
\ No newline at end of file
diff --git a/dist/win/contrib/patchWebDAV.ps1 b/dist/win/contrib/patchWebDAV.ps1
index 51b063560..9d79ab900 100644
--- a/dist/win/contrib/patchWebDAV.ps1
+++ b/dist/win/contrib/patchWebDAV.ps1
@@ -1,10 +1,16 @@
#Requires -RunAsAdministrator
+Param(
+ [Parameter(Mandatory, HelpMessage="Please provide an alias for 127.0.0.1")][string] $LoopbackAlias
+)
-# Adds for address 127.0.0.1 the 'cryptomator-vault' alias to the hosts file
+# Adds an alias for 127.0.0.1 to the hosts file
function Add-AliasToHost {
+ param (
+ [string]$LoopbackAlias
+ )
$sysdir = [Environment]::SystemDirectory
$hostsFile = "$sysdir\drivers\etc\hosts"
- $aliasLine = '127.0.0.1 cryptomator-vault'
+ $aliasLine = "127.0.0.1 $LoopbackAlias"
foreach ($line in Get-Content $hostsFile) {
if ($line -eq $aliasLine){
@@ -49,7 +55,7 @@ function Edit-ProviderOrder {
}
-Add-AliasToHost
+Add-AliasToHost $LoopbackAlias
Write-Output 'Ensured alias exists in hosts file'
Set-WebDAVFileSizeLimit
diff --git a/dist/win/resources/customWizard.wxi b/dist/win/resources/customWizard.wxi
index ce82c2933..0cd34e44f 100644
--- a/dist/win/resources/customWizard.wxi
+++ b/dist/win/resources/customWizard.wxi
@@ -91,7 +91,7 @@
FOUNDRUNNINGAPP
- Cryptomator was still running during installation.
+ Application to update was still running during installation.
FOUNDRUNNINGAPP
diff --git a/dist/win/resources/main.wxs b/dist/win/resources/main.wxs
index 09b555caa..b8703a14d 100644
--- a/dist/win/resources/main.wxs
+++ b/dist/win/resources/main.wxs
@@ -86,12 +86,12 @@
-
-
-
-
+
+
+
+
-
+
@@ -130,12 +130,12 @@
diff --git a/dist/win/resources/overrides.wxi b/dist/win/resources/overrides.wxi
new file mode 100644
index 000000000..60133a35b
--- /dev/null
+++ b/dist/win/resources/overrides.wxi
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 23a97717d..2be9cc560 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,12 +28,12 @@
2.1.0-beta3
- 2.4.1
+ 2.4.2
1.1.0
- 1.1.0
- 1.1.0
+ 1.1.1
+ 1.1.1
1.1.0
- 1.3.3
+ 1.3.4
1.3.3
1.2.7
diff --git a/src/main/java/org/cryptomator/common/CatchingExecutors.java b/src/main/java/org/cryptomator/common/CatchingExecutors.java
new file mode 100644
index 000000000..900f81ec9
--- /dev/null
+++ b/src/main/java/org/cryptomator/common/CatchingExecutors.java
@@ -0,0 +1,92 @@
+package org.cryptomator.common;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javafx.application.Platform;
+import javafx.concurrent.Task;
+import java.util.Objects;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+//Inspired by: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/ThreadPoolExecutor.html#afterExecute(java.lang.Runnable,java.lang.Throwable)
+public final class CatchingExecutors {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CatchingExecutors.class);
+
+ private CatchingExecutors() { /* NO-OP */ }
+
+ public static class CatchingScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
+
+ public CatchingScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) {
+ super(corePoolSize, threadFactory);
+ }
+
+ @Override
+ protected void afterExecute(Runnable runnable, Throwable throwable) {
+ super.afterExecute(runnable, throwable);
+ afterExecuteInternal(runnable, throwable);
+ }
+ }
+
+ public static class CatchingThreadPoolExecutor extends ThreadPoolExecutor {
+
+ public CatchingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
+ }
+
+ @Override
+ protected void afterExecute(Runnable runnable, Throwable throwable) {
+ super.afterExecute(runnable, throwable);
+ afterExecuteInternal(runnable, throwable);
+ }
+ }
+
+ private static void afterExecuteInternal(Runnable runnable, Throwable throwable) {
+ if (throwable != null) {
+ callHandler(Thread.currentThread(), throwable);
+ } else if (runnable instanceof Task> t) {
+ afterExecuteTask(t);
+ } else if (runnable instanceof Future> f) {
+ afterExecuteFuture(f);
+ }
+ //Errors in this method are delegated to the UncaughtExceptionHandler of the current thread
+ }
+
+ private static void callHandler(Thread thread, Throwable throwable) {
+ Objects.requireNonNullElseGet(thread.getUncaughtExceptionHandler(), CatchingExecutors::fallbackHandler).uncaughtException(thread, throwable);
+ }
+
+ private static Thread.UncaughtExceptionHandler fallbackHandler() {
+ return (thread, throwable) -> LOG.error("FALLBACK: Uncaught exception in " + thread.getName(), throwable);
+ }
+
+ private static void afterExecuteTask(Task> task) {
+ var caller = Thread.currentThread();
+ Platform.runLater(() -> {
+ if (task.getOnFailed() == null) {
+ callHandler(caller, task.getException());
+ }
+ });
+ }
+
+ private static void afterExecuteFuture(Future> future) {
+ assert future.isDone();
+ try {
+ future.get();
+ } catch (CancellationException ce) {
+ callHandler(Thread.currentThread(), ce);
+ } catch (ExecutionException ee) {
+ callHandler(Thread.currentThread(), ee.getCause());
+ } catch (InterruptedException ie) {
+ //Ignore/Reset
+ Thread.currentThread().interrupt();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/common/CommonsModule.java b/src/main/java/org/cryptomator/common/CommonsModule.java
index eb7e6cd13..edb4f063b 100644
--- a/src/main/java/org/cryptomator/common/CommonsModule.java
+++ b/src/main/java/org/cryptomator/common/CommonsModule.java
@@ -12,9 +12,7 @@ import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.keychain.KeychainModule;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider;
-import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultComponent;
-import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.common.vaults.VaultListModule;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.frontend.webdav.WebDavServer;
@@ -25,16 +23,13 @@ import javax.inject.Named;
import javax.inject.Singleton;
import javafx.beans.binding.Binding;
import javafx.beans.binding.Bindings;
-import javafx.collections.ObservableList;
import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Comparator;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -93,7 +88,7 @@ public abstract class CommonsModule {
@Singleton
static ScheduledExecutorService provideScheduledExecutorService(ShutdownHook shutdownHook) {
final AtomicInteger threadNumber = new AtomicInteger(1);
- ScheduledExecutorService executorService = Executors.newScheduledThreadPool(NUM_SCHEDULER_THREADS, r -> {
+ ScheduledExecutorService executorService = new CatchingExecutors.CatchingScheduledThreadPoolExecutor(NUM_SCHEDULER_THREADS, r -> {
String name = String.format("App Scheduled Executor %02d", threadNumber.getAndIncrement());
Thread t = new Thread(r);
t.setName(name);
@@ -110,7 +105,7 @@ public abstract class CommonsModule {
@Singleton
static ExecutorService provideExecutorService(ShutdownHook shutdownHook) {
final AtomicInteger threadNumber = new AtomicInteger(1);
- ExecutorService executorService = new ThreadPoolExecutor(NUM_CORE_BG_THREADS, Integer.MAX_VALUE, BG_THREAD_KEEPALIVE_SECONDS, TimeUnit.SECONDS, new SynchronousQueue<>(), r -> {
+ ExecutorService executorService = new CatchingExecutors.CatchingThreadPoolExecutor(NUM_CORE_BG_THREADS, Integer.MAX_VALUE, BG_THREAD_KEEPALIVE_SECONDS, TimeUnit.SECONDS, new SynchronousQueue<>(), r -> {
String name = String.format("App Background Thread %03d", threadNumber.getAndIncrement());
Thread t = new Thread(r);
t.setName(name);
diff --git a/src/main/java/org/cryptomator/common/Constants.java b/src/main/java/org/cryptomator/common/Constants.java
index 90bd3c8ec..5069002e7 100644
--- a/src/main/java/org/cryptomator/common/Constants.java
+++ b/src/main/java/org/cryptomator/common/Constants.java
@@ -6,6 +6,7 @@ public interface Constants {
String MASTERKEY_BACKUP_SUFFIX = ".bkup";
String VAULTCONFIG_FILENAME = "vault.cryptomator";
String CRYPTOMATOR_FILENAME_EXT = ".cryptomator";
+ String CRYPTOMATOR_FILENAME_GLOB = "*.cryptomator";
byte[] PEPPER = new byte[0];
}
diff --git a/src/main/java/org/cryptomator/common/LocationPreset.java b/src/main/java/org/cryptomator/common/LocationPreset.java
new file mode 100644
index 000000000..17d276bf8
--- /dev/null
+++ b/src/main/java/org/cryptomator/common/LocationPreset.java
@@ -0,0 +1,64 @@
+package org.cryptomator.common;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Enum of common cloud providers and their default local storage location path.
+ */
+public enum LocationPreset {
+
+ DROPBOX("Dropbox", "~/Dropbox"),
+ ICLOUDDRIVE("iCloud Drive", "~/Library/Mobile Documents/com~apple~CloudDocs", "~/iCloudDrive"),
+ GDRIVE("Google Drive", "~/Google Drive/My Drive", "~/Google Drive"),
+ MEGA("MEGA", "~/MEGA"),
+ ONEDRIVE("OneDrive", "~/OneDrive"),
+ PCLOUD("pCloud", "~/pCloudDrive"),
+
+ LOCAL("local");
+
+ private final String name;
+ private final List candidates;
+
+ LocationPreset(String name, String... candidates) {
+ this.name = name;
+ this.candidates = Arrays.stream(candidates).map(UserHome::resolve).map(Path::of).toList();
+ }
+
+ /**
+ * Checks for this LocationPreset if any of the associated paths exist.
+ *
+ * @return the first existing path or null, if none exists.
+ */
+ public Path existingPath() {
+ return candidates.stream().filter(Files::isDirectory).findFirst().orElse(null);
+ }
+
+ public String getDisplayName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return getDisplayName();
+ }
+
+ //this contruct is needed, since static members are initialized after every enum member is initialized
+ //TODO: refactor this to normal class and use this also in different parts of the project
+ private static class UserHome {
+
+ private static final String USER_HOME = System.getProperty("user.home");
+
+ private static String resolve(String path) {
+ if (path.startsWith("~/")) {
+ return UserHome.USER_HOME + path.substring(1);
+ } else {
+ return path;
+ }
+ }
+ }
+
+}
+
diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java
index 8cc23bbfc..36d4d16aa 100644
--- a/src/main/java/org/cryptomator/common/settings/Settings.java
+++ b/src/main/java/org/cryptomator/common/settings/Settings.java
@@ -36,7 +36,7 @@ public class Settings {
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final WebDavUrlScheme DEFAULT_GVFS_SCHEME = WebDavUrlScheme.DAV;
public static final boolean DEFAULT_DEBUG_MODE = false;
- public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = SystemUtils.IS_OS_WINDOWS ? VolumeImpl.DOKANY : VolumeImpl.FUSE;
+ public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = VolumeImpl.FUSE;
public static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
@Deprecated // to be changed to "whatever is available" eventually
public static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : "org.cryptomator.linux.keychain.SecretServiceKeychainAccess";
diff --git a/src/main/java/org/cryptomator/common/vaults/Vault.java b/src/main/java/org/cryptomator/common/vaults/Vault.java
index 96bf3b252..5bba0b79b 100644
--- a/src/main/java/org/cryptomator/common/vaults/Vault.java
+++ b/src/main/java/org/cryptomator/common/vaults/Vault.java
@@ -10,6 +10,7 @@ package org.cryptomator.common.vaults;
import com.google.common.base.Strings;
import org.apache.commons.lang3.SystemUtils;
+import org.cryptomator.common.Constants;
import org.cryptomator.common.mountpoint.InvalidMountPointException;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.vaults.Volume.VolumeException;
@@ -125,6 +126,7 @@ public class Vault {
.withKeyLoader(keyLoader) //
.withFlags(flags) //
.withMaxCleartextNameLength(vaultSettings.maxCleartextFilenameLength().get()) //
+ .withVaultConfigFilename(Constants.VAULTCONFIG_FILENAME) //
.build();
return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
}
diff --git a/src/main/java/org/cryptomator/common/vaults/VaultComponent.java b/src/main/java/org/cryptomator/common/vaults/VaultComponent.java
index be844f510..ae525d7b0 100644
--- a/src/main/java/org/cryptomator/common/vaults/VaultComponent.java
+++ b/src/main/java/org/cryptomator/common/vaults/VaultComponent.java
@@ -19,22 +19,13 @@ public interface VaultComponent {
Vault vault();
- @Subcomponent.Builder
- interface Builder {
+ @Subcomponent.Factory
+ interface Factory {
- @BindsInstance
- Builder vaultSettings(VaultSettings vaultSettings);
+ VaultComponent create(@BindsInstance VaultSettings vaultSettings, //
+ @BindsInstance VaultConfigCache configCache, //
+ @BindsInstance VaultState.Value vaultState, //
+ @BindsInstance @Nullable @Named("lastKnownException") Exception initialErrorCause);
- @BindsInstance
- Builder vaultConfigCache(VaultConfigCache configCache);
-
- @BindsInstance
- Builder initialVaultState(VaultState.Value vaultState);
-
- @BindsInstance
- Builder initialErrorCause(@Nullable @Named("lastKnownException") Exception initialErrorCause);
-
- VaultComponent build();
}
-
-}
+}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/common/vaults/VaultListManager.java b/src/main/java/org/cryptomator/common/vaults/VaultListManager.java
index 6a8c31d4f..138d74e36 100644
--- a/src/main/java/org/cryptomator/common/vaults/VaultListManager.java
+++ b/src/main/java/org/cryptomator/common/vaults/VaultListManager.java
@@ -38,15 +38,15 @@ public class VaultListManager {
private static final Logger LOG = LoggerFactory.getLogger(VaultListManager.class);
private final AutoLocker autoLocker;
- private final VaultComponent.Builder vaultComponentBuilder;
+ private final VaultComponent.Factory vaultComponentFactory;
private final ObservableList vaultList;
private final String defaultVaultName;
@Inject
- public VaultListManager(ObservableList vaultList, AutoLocker autoLocker, VaultComponent.Builder vaultComponentBuilder, ResourceBundle resourceBundle, Settings settings) {
+ public VaultListManager(ObservableList vaultList, AutoLocker autoLocker, VaultComponent.Factory vaultComponentFactory, ResourceBundle resourceBundle, Settings settings) {
this.vaultList = vaultList;
this.autoLocker = autoLocker;
- this.vaultComponentBuilder = vaultComponentBuilder;
+ this.vaultComponentFactory = vaultComponentFactory;
this.defaultVaultName = resourceBundle.getString("defaults.vault.vaultName");
addAll(settings.getDirectories());
@@ -93,21 +93,17 @@ public class VaultListManager {
}
private Vault create(VaultSettings vaultSettings) {
- VaultComponent.Builder compBuilder = vaultComponentBuilder.vaultSettings(vaultSettings);
+ var wrapper = new VaultConfigCache(vaultSettings);
try {
- VaultState.Value vaultState = determineVaultState(vaultSettings.path().get());
- VaultConfigCache wrapper = new VaultConfigCache(vaultSettings);
- compBuilder.vaultConfigCache(wrapper); //first set the wrapper in the builder, THEN try to load config
+ var vaultState = determineVaultState(vaultSettings.path().get());
if (vaultState == LOCKED) { //for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
wrapper.reloadConfig();
}
- compBuilder.initialVaultState(vaultState);
+ return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
} catch (IOException e) {
LOG.warn("Failed to determine vault state for " + vaultSettings.path().get(), e);
- compBuilder.initialVaultState(ERROR);
- compBuilder.initialErrorCause(e);
+ return vaultComponentFactory.create(vaultSettings, wrapper, ERROR, e).vault();
}
- return compBuilder.build().vault();
}
public static VaultState.Value redetermineVaultState(Vault vault) {
diff --git a/src/main/java/org/cryptomator/common/vaults/VaultState.java b/src/main/java/org/cryptomator/common/vaults/VaultState.java
index 51365fbd2..ff09c8b82 100644
--- a/src/main/java/org/cryptomator/common/vaults/VaultState.java
+++ b/src/main/java/org/cryptomator/common/vaults/VaultState.java
@@ -83,7 +83,7 @@ public class VaultState extends ObservableValueBase implements
if (success) {
fireValueChangedEvent();
} else {
- LOG.debug("Failed transiting into state {}: Expected state was not{}.", fromState, toState);
+ LOG.debug("Failed transiting into state {}: Expected state was not {}.", fromState, toState);
}
return success;
}
diff --git a/src/main/java/org/cryptomator/launcher/SupportedLanguages.java b/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
index d473dcdf8..ffff48a8a 100644
--- a/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
+++ b/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
@@ -17,7 +17,7 @@ public class SupportedLanguages {
// these are BCP 47 language codes, not ISO. Note the "-" instead of the "_":
public static final List LANGUAGAE_TAGS = List.of("en", "ar", "bn", "bs", "ca", "cs", "de", "el", "es", "fil", "fr", "gl", "he", //
"hi", "hr", "hu", "id", "it", "ja", "ko", "lv", "mk", "nb", "nl", "nn", "no", "pa", "pl", "pt", "pt-BR", "ro", "ru", "sk", "sr", //
- "sr-Latn", "sv", "ta", "te", "th", "tr", "uk", "zh", "zh-HK", "zh-TW");
+ "sr-Latn", "sv", "sw", "ta", "te", "th", "tr", "uk", "zh", "zh-HK", "zh-TW");
@Nullable
private final String preferredLanguage;
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java
index e9b5865d5..432007c99 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java
@@ -25,6 +25,8 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.ResourceBundle;
+import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
+
@AddVaultWizardScoped
public class ChooseExistingVaultController implements FxController {
@@ -73,7 +75,7 @@ public class ChooseExistingVaultController implements FxController {
public void chooseFileAndNext() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("addvaultwizard.existing.filePickerTitle"));
- fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Vault", "*.cryptomator"));
+ fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(resourceBundle.getString("addvaultwizard.existing.filePickerMimeDesc"), CRYPTOMATOR_FILENAME_GLOB));
File masterkeyFile = fileChooser.showOpenDialog(window);
if (masterkeyFile != null) {
vaultPath.setValue(masterkeyFile.toPath().toAbsolutePath().getParent());
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java
index 1fd463432..cadccc091 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java
@@ -46,7 +46,7 @@ public class CreateNewVaultLocationController implements FxController {
private final Stage window;
private final Lazy chooseNameScene;
private final Lazy choosePasswordScene;
- private final LocationPresets locationPresets;
+ private final ObservedLocationPresets locationPresets;
private final ObjectProperty vaultPath;
private final StringProperty vaultName;
private final ResourceBundle resourceBundle;
@@ -71,7 +71,7 @@ public class CreateNewVaultLocationController implements FxController {
public FontAwesome5IconView badLocation;
@Inject
- CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy choosePasswordScene, LocationPresets locationPresets, ObjectProperty vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
+ CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy choosePasswordScene, ObservedLocationPresets locationPresets, ObjectProperty vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
this.window = window;
this.chooseNameScene = chooseNameScene;
this.choosePasswordScene = choosePasswordScene;
@@ -197,7 +197,7 @@ public class CreateNewVaultLocationController implements FxController {
return validVaultPath.get();
}
- public LocationPresets getLocationPresets() {
+ public ObservedLocationPresets getObservedLocationPresets() {
return locationPresets;
}
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/LocationPresets.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ObservedLocationPresets.java
similarity index 64%
rename from src/main/java/org/cryptomator/ui/addvaultwizard/LocationPresets.java
rename to src/main/java/org/cryptomator/ui/addvaultwizard/ObservedLocationPresets.java
index 313a31dc9..1c988dc04 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/LocationPresets.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ObservedLocationPresets.java
@@ -1,23 +1,15 @@
package org.cryptomator.ui.addvaultwizard;
+import org.cryptomator.common.LocationPreset;
+
import javax.inject.Inject;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
-import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
@AddVaultWizardScoped
-public class LocationPresets {
-
- private static final String USER_HOME = System.getProperty("user.home");
- private static final String[] ICLOUDDRIVE_LOCATIONS = {"~/Library/Mobile Documents/iCloud~com~setolabs~Cryptomator/Documents", "~/iCloudDrive/iCloud~com~setolabs~Cryptomator"};
- private static final String[] DROPBOX_LOCATIONS = {"~/Dropbox"};
- private static final String[] GDRIVE_LOCATIONS = {"~/Google Drive/My Drive", "~/Google Drive"};
- private static final String[] ONEDRIVE_LOCATIONS = {"~/OneDrive"};
- private static final String[] MEGA_LOCATIONS = {"~/MEGA"};
- private static final String[] PCLOUD_LOCATIONS = {"~/pCloudDrive"};
+public class ObservedLocationPresets {
private final ReadOnlyObjectProperty iclouddriveLocation;
private final ReadOnlyObjectProperty dropboxLocation;
@@ -33,13 +25,13 @@ public class LocationPresets {
private final BooleanBinding foundPcloud;
@Inject
- public LocationPresets() {
- this.iclouddriveLocation = new SimpleObjectProperty<>(existingWritablePath(ICLOUDDRIVE_LOCATIONS));
- this.dropboxLocation = new SimpleObjectProperty<>(existingWritablePath(DROPBOX_LOCATIONS));
- this.gdriveLocation = new SimpleObjectProperty<>(existingWritablePath(GDRIVE_LOCATIONS));
- this.onedriveLocation = new SimpleObjectProperty<>(existingWritablePath(ONEDRIVE_LOCATIONS));
- this.megaLocation = new SimpleObjectProperty<>(existingWritablePath(MEGA_LOCATIONS));
- this.pcloudLocation = new SimpleObjectProperty<>(existingWritablePath(PCLOUD_LOCATIONS));
+ public ObservedLocationPresets() {
+ this.iclouddriveLocation = new SimpleObjectProperty<>(LocationPreset.ICLOUDDRIVE.existingPath());
+ this.dropboxLocation = new SimpleObjectProperty<>(LocationPreset.DROPBOX.existingPath());
+ this.gdriveLocation = new SimpleObjectProperty<>(LocationPreset.GDRIVE.existingPath());
+ this.onedriveLocation = new SimpleObjectProperty<>(LocationPreset.ONEDRIVE.existingPath());
+ this.megaLocation = new SimpleObjectProperty<>(LocationPreset.MEGA.existingPath());
+ this.pcloudLocation = new SimpleObjectProperty<>(LocationPreset.PCLOUD.existingPath());
this.foundIclouddrive = iclouddriveLocation.isNotNull();
this.foundDropbox = dropboxLocation.isNotNull();
this.foundGdrive = gdriveLocation.isNotNull();
@@ -48,24 +40,6 @@ public class LocationPresets {
this.foundPcloud = pcloudLocation.isNotNull();
}
- private static Path existingWritablePath(String... candidates) {
- for (String candidate : candidates) {
- Path path = Paths.get(resolveHomePath(candidate));
- if (Files.isDirectory(path)) {
- return path;
- }
- }
- return null;
- }
-
- private static String resolveHomePath(String path) {
- if (path.startsWith("~/")) {
- return USER_HOME + path.substring(1);
- } else {
- return path;
- }
- }
-
/* Observables */
public ReadOnlyObjectProperty iclouddriveLocationProperty() {
diff --git a/src/main/java/org/cryptomator/ui/fxapp/UpdateCheckerModule.java b/src/main/java/org/cryptomator/ui/fxapp/UpdateCheckerModule.java
index 8c9f7fb20..58b8653da 100644
--- a/src/main/java/org/cryptomator/ui/fxapp/UpdateCheckerModule.java
+++ b/src/main/java/org/cryptomator/ui/fxapp/UpdateCheckerModule.java
@@ -43,7 +43,9 @@ public abstract class UpdateCheckerModule {
@FxApplicationScoped
static Optional provideHttpClient() {
try {
- return Optional.of(HttpClient.newHttpClient());
+ return Optional.of(HttpClient.newBuilder() //
+ .followRedirects(HttpClient.Redirect.NORMAL) // from version 1.6.11 onwards, Cryptomator can follow redirects, in case this URL ever changes
+ .build());
} catch (UncheckedIOException e) {
LOG.error("HttpClient for update check cannot be created.", e);
return Optional.empty();
diff --git a/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/ChooseMasterkeyFileController.java b/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/ChooseMasterkeyFileController.java
index 11cf7bd6b..d47f4e5b3 100644
--- a/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/ChooseMasterkeyFileController.java
+++ b/src/main/java/org/cryptomator/ui/keyloading/masterkeyfile/ChooseMasterkeyFileController.java
@@ -15,6 +15,8 @@ import java.nio.file.Path;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;
+import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
+
@ChooseMasterkeyFileScoped
public class ChooseMasterkeyFileController implements FxController {
@@ -46,7 +48,7 @@ public class ChooseMasterkeyFileController implements FxController {
LOG.trace("proceed()");
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("unlock.chooseMasterkey.filePickerTitle"));
- fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Masterkey", "*.cryptomator"));
+ fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(resourceBundle.getString("unlock.chooseMasterkey.filePickerMimeDesc"), CRYPTOMATOR_FILENAME_GLOB));
File masterkeyFile = fileChooser.showOpenDialog(window);
if (masterkeyFile != null) {
LOG.debug("Chose masterkey file: {}", masterkeyFile);
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailLockedController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailLockedController.java
index dab1f7a54..cf1009ea9 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailLockedController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailLockedController.java
@@ -21,13 +21,13 @@ public class VaultDetailLockedController implements FxController {
private final ReadOnlyObjectProperty vault;
private final FxApplicationWindows appWindows;
- private final VaultOptionsComponent.Builder vaultOptionsWindow;
+ private final VaultOptionsComponent.Factory vaultOptionsWindow;
private final KeychainManager keychain;
private final Stage mainWindow;
private final BooleanExpression passwordSaved;
@Inject
- VaultDetailLockedController(ObjectProperty vault, FxApplicationWindows appWindows, VaultOptionsComponent.Builder vaultOptionsWindow, KeychainManager keychain, @MainWindow Stage mainWindow) {
+ VaultDetailLockedController(ObjectProperty vault, FxApplicationWindows appWindows, VaultOptionsComponent.Factory vaultOptionsWindow, KeychainManager keychain, @MainWindow Stage mainWindow) {
this.vault = vault;
this.appWindows = appWindows;
this.vaultOptionsWindow = vaultOptionsWindow;
@@ -47,12 +47,12 @@ public class VaultDetailLockedController implements FxController {
@FXML
public void showVaultOptions() {
- vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
+ vaultOptionsWindow.create(vault.get()).showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
}
@FXML
public void showKeyVaultOptions() {
- vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow(SelectedVaultOptionsTab.KEY);
+ vaultOptionsWindow.create(vault.get()).showVaultOptionsWindow(SelectedVaultOptionsTab.KEY);
}
/* Getter/Setter */
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java
index 8d9f192b5..bc372341a 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java
@@ -13,6 +13,8 @@ import javafx.stage.Stage;
import java.io.File;
import java.util.ResourceBundle;
+import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
+
@MainWindowScoped
public class VaultDetailMissingVaultController implements FxController {
@@ -45,7 +47,7 @@ public class VaultDetailMissingVaultController implements FxController {
// copied from ChooseExistingVaultController class
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("addvaultwizard.existing.filePickerTitle"));
- fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Masterkey", "*.cryptomator"));
+ fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(resourceBundle.getString("addvaultwizard.existing.filePickerMimeDesc"), CRYPTOMATOR_FILENAME_GLOB));
File masterkeyFile = fileChooser.showOpenDialog(window);
if (masterkeyFile != null) {
vault.get().getVaultSettings().path().setValue(masterkeyFile.toPath().toAbsolutePath().getParent());
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java
index c9d788b90..23f8e889d 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java
@@ -31,7 +31,7 @@ public class VaultListContextMenuController implements FxController {
private final VaultService vaultService;
private final KeychainManager keychain;
private final RemoveVaultComponent.Builder removeVault;
- private final VaultOptionsComponent.Builder vaultOptionsWindow;
+ private final VaultOptionsComponent.Factory vaultOptionsWindow;
private final OptionalBinding selectedVaultState;
private final Binding selectedVaultPassphraseStored;
private final Binding selectedVaultRemovable;
@@ -39,7 +39,7 @@ public class VaultListContextMenuController implements FxController {
private final Binding selectedVaultLockable;
@Inject
- VaultListContextMenuController(ObjectProperty selectedVault, @MainWindow Stage mainWindow, FxApplicationWindows appWindows, VaultService vaultService, KeychainManager keychain, RemoveVaultComponent.Builder removeVault, VaultOptionsComponent.Builder vaultOptionsWindow) {
+ VaultListContextMenuController(ObjectProperty selectedVault, @MainWindow Stage mainWindow, FxApplicationWindows appWindows, VaultService vaultService, KeychainManager keychain, RemoveVaultComponent.Builder removeVault, VaultOptionsComponent.Factory vaultOptionsWindow) {
this.selectedVault = EasyBind.wrapNullable(selectedVault);
this.mainWindow = mainWindow;
this.appWindows = appWindows;
@@ -69,7 +69,7 @@ public class VaultListContextMenuController implements FxController {
@FXML
public void didClickShowVaultOptions() {
selectedVault.ifValuePresent(v -> {
- vaultOptionsWindow.vault(v).build().showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
+ vaultOptionsWindow.create(v).showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
});
}
diff --git a/src/main/java/org/cryptomator/ui/preferences/VolumePreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/VolumePreferencesController.java
index 8f9f6f6da..4af86dc85 100644
--- a/src/main/java/org/cryptomator/ui/preferences/VolumePreferencesController.java
+++ b/src/main/java/org/cryptomator/ui/preferences/VolumePreferencesController.java
@@ -48,11 +48,6 @@ public class VolumePreferencesController implements FxController {
webDavPortField.setText(String.valueOf(settings.port().get()));
changeWebDavPortButton.visibleProperty().bind(settings.port().asString().isNotEqualTo(webDavPortField.textProperty()));
changeWebDavPortButton.disableProperty().bind(Bindings.createBooleanBinding(this::validateWebDavPort, webDavPortField.textProperty()).not());
- webDavPortField.focusedProperty().addListener((observableValue, wasFocused, isFocused) -> {
- if(!isFocused) {
- webDavPortField.setText(String.valueOf(settings.port().get()));
- }
- });
webDavUrlSchemeChoiceBox.getItems().addAll(WebDavUrlScheme.values());
webDavUrlSchemeChoiceBox.valueProperty().bindBidirectional(settings.preferredGvfsScheme());
diff --git a/src/main/java/org/cryptomator/ui/vaultoptions/VaultOptionsComponent.java b/src/main/java/org/cryptomator/ui/vaultoptions/VaultOptionsComponent.java
index e56c30f5c..ac749132a 100644
--- a/src/main/java/org/cryptomator/ui/vaultoptions/VaultOptionsComponent.java
+++ b/src/main/java/org/cryptomator/ui/vaultoptions/VaultOptionsComponent.java
@@ -36,13 +36,10 @@ public interface VaultOptionsComponent {
stage.requestFocus();
}
- @Subcomponent.Builder
- interface Builder {
+ @Subcomponent.Factory
+ interface Factory {
- @BindsInstance
- Builder vault(@VaultOptionsWindow Vault vault);
-
- VaultOptionsComponent build();
+ VaultOptionsComponent create(@BindsInstance @VaultOptionsWindow Vault vault);
}
}
diff --git a/src/main/resources/css/dark_theme.css b/src/main/resources/css/dark_theme.css
index a00e46845..f55509cd8 100644
--- a/src/main/resources/css/dark_theme.css
+++ b/src/main/resources/css/dark_theme.css
@@ -16,10 +16,6 @@
src: url('opensans-bold.ttf');
}
-@font-face {
- src: url('quicksand-bold.ttf');
-}
-
/*******************************************************************************
* *
* Root Styling & Colors *
@@ -46,6 +42,8 @@
GRAY_8: #D3DCE1;
GRAY_9: #EDF3F7;
+ GREEN_3: PRIMARY_D1;
+ GREEN_5: PRIMARY;
RED_5: #E74C3C;
ORANGE_5: #E67E22;
YELLOW_5: #F1C40F;
@@ -179,14 +177,6 @@
-fx-background-insets: 0, 0 0 1px 0;
}
-.main-window .title .label {
- -fx-font-family: 'Quicksand';
- -fx-font-size: 16px;
- -fx-font-style: normal;
- -fx-font-weight: 700;
- -fx-text-fill: TITLE_TEXT_FILL;
-}
-
.main-window .title .button {
-fx-pref-height: 30px;
-fx-pref-width: 30px;
@@ -405,7 +395,6 @@
-fx-background-color: MUTED_BG;
}
-
/* Note: These values below are kinda random such that it looks ok. I'm pretty sure there is room for improvement. Additionally, fx-text-fill does not work*/
.badge-debug {
-fx-font-family: 'Open Sans Bold';
@@ -439,11 +428,11 @@
}
.password-strength-indicator.strength-3 .segment.active {
- -fx-background-color: PRIMARY;
+ -fx-background-color: GREEN_5;
}
.password-strength-indicator.strength-4 .segment.active {
- -fx-background-color: PRIMARY_D1;
+ -fx-background-color: GREEN_3;
}
/*******************************************************************************
@@ -834,6 +823,7 @@
-fx-background-color: PROGRESS_BAR_BG;
-fx-background-radius: 4px;
}
+
/*******************************************************************************
* *
* I/O Statistics *
@@ -884,6 +874,7 @@
.default-color0.chart-series-area-line {
-fx-stroke: PRIMARY;
}
+
.default-color0.chart-series-area-fill {
-fx-fill: linear-gradient(to bottom, PRIMARY, transparent);
-fx-stroke: transparent;
diff --git a/src/main/resources/css/light_theme.css b/src/main/resources/css/light_theme.css
index 09c743705..06899c907 100644
--- a/src/main/resources/css/light_theme.css
+++ b/src/main/resources/css/light_theme.css
@@ -16,10 +16,6 @@
src: url('opensans-bold.ttf');
}
-@font-face {
- src: url('quicksand-bold.ttf');
-}
-
/*******************************************************************************
* *
* Root Styling & Colors *
@@ -46,6 +42,8 @@
GRAY_8: #E1E1E1;
GRAY_9: #F7F7F7;
+ GREEN_3: PRIMARY_D1;
+ GREEN_5: PRIMARY;
RED_5: #E74C3C;
ORANGE_5: #E67E22;
YELLOW_5: #F1C40F;
@@ -178,14 +176,6 @@
-fx-background-color: TITLE_BG;
}
-.main-window .title .label {
- -fx-font-family: 'Quicksand';
- -fx-font-size: 16px;
- -fx-font-style: normal;
- -fx-font-weight: 700;
- -fx-text-fill: TITLE_TEXT_FILL;
-}
-
.main-window .title .button {
-fx-pref-height: 30px;
-fx-pref-width: 30px;
@@ -437,11 +427,11 @@
}
.password-strength-indicator.strength-3 .segment.active {
- -fx-background-color: PRIMARY;
+ -fx-background-color: GREEN_5;
}
.password-strength-indicator.strength-4 .segment.active {
- -fx-background-color: PRIMARY_D1;
+ -fx-background-color: GREEN_3;
}
/*******************************************************************************
@@ -832,22 +822,12 @@
-fx-background-color: PROGRESS_BAR_BG;
-fx-background-radius: 4px;
}
+
/*******************************************************************************
* *
* I/O Statistics *
* *
******************************************************************************/
-.chart {
- -fx-padding: 10px;
-}
-
-.chart-plot-background {
- -fx-background-color: MAIN_BG;
- -fx-padding: 20px;
-}
-
-/* content */
-
.cache-arc-background {
-fx-fill: transparent;
@@ -893,6 +873,7 @@
.default-color0.chart-series-area-line {
-fx-stroke: PRIMARY;
}
+
.default-color0.chart-series-area-fill {
-fx-fill: linear-gradient(to bottom, PRIMARY, transparent);
-fx-stroke: transparent;
diff --git a/src/main/resources/fxml/addvault_new_location.fxml b/src/main/resources/fxml/addvault_new_location.fxml
index 3c25ba569..343a2d580 100644
--- a/src/main/resources/fxml/addvault_new_location.fxml
+++ b/src/main/resources/fxml/addvault_new_location.fxml
@@ -31,12 +31,12 @@
-
-
-
-
-
-
+
+
+
+
+
+