diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 1261224f2..e791b5c49 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -98,7 +98,8 @@ jobs: run: | cp -r dist/linux/debian/ pkgdir export RFC2822_TIMESTAMP=`date --rfc-2822` - envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM}' < dist/linux/debian/rules > pkgdir/debian/rules + export DISABLE_UPDATE_CHECK=${{ inputs.dput }} + envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM} ${DISABLE_UPDATE_CHECK}' < dist/linux/debian/rules > pkgdir/debian/rules envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog find . -name "*.jar" >> pkgdir/debian/source/include-binaries mv pkgdir cryptomator_${{ inputs.ppaver }} diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index fc8f3d8fa..1e32b7960 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -62,7 +62,7 @@ jobs: curl -L ${{ matrix.openjfx-url }} -o openjfx-jmods.zip echo "${{ matrix.openjfx-sha }} *openjfx-jmods.zip" | shasum -a256 --check mkdir -p openjfx-jmods/ - unzip -j openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods + unzip -jo openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods - name: Ensure major jfx version in pom and in jmods is the same run: | JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1) @@ -72,7 +72,7 @@ jobs: POM_JFX_VERSION=${POM_JFX_VERSION#*@} POM_JFX_VERSION=${POM_JFX_VERSION%%.*} - if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then + if [ "${POM_JFX_VERSION}" -ne "${JMOD_VERSION}" ]; then >&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})" exit 1 fi @@ -222,7 +222,6 @@ jobs: --app-drop-link 512 245 --eula "dist/mac/dmg/resources/license.rtf" --icon ".background" 128 758 - --icon ".fseventsd" 320 758 --icon ".VolumeIcon.icns" 512 758 Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg env: diff --git a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml index 596ebea4a..6e4873712 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/linux/debian/rules b/dist/linux/debian/rules index 912395bce..d0a12e380 100755 --- a/dist/linux/debian/rules +++ b/dist/linux/debian/rules @@ -59,6 +59,7 @@ override_dh_auto_build: --java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"/usr/share/icons/hicolor/symbolic/apps\"" \ --java-options "-Dcryptomator.buildNumber=\"deb-${REVISION_NUM}\"" \ --java-options "-Dcryptomator.appVersion=\"${SEMVER_STR}\"" \ + --java-options "-Dcryptomator.disableUpdateCheck=\"${DISABLE_UPDATE_CHECK}\"" \ --app-version "${VERSION_NUM}.${REVISION_NUM}" \ --resource-dir resources \ --verbose diff --git a/dist/mac/dmg/build.sh b/dist/mac/dmg/build.sh index 6d586f02c..b2c8d55e3 100755 --- a/dist/mac/dmg/build.sh +++ b/dist/mac/dmg/build.sh @@ -49,21 +49,22 @@ fi # download and check jmods curl -L ${OPENJFX_JMODS} -o openjfx-jmods.zip mkdir -p openjfx-jmods/ -unzip -j openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods/ +unzip -jo openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1) JMOD_VERSION=${JMOD_VERSION#*@} JMOD_VERSION=${JMOD_VERSION%%.*} -POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) +POM_JFX_VERSION=$(mvn -f../../../pom.xml help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) POM_JFX_VERSION=${POM_JFX_VERSION#*@} POM_JFX_VERSION=${POM_JFX_VERSION%%.*} -if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then ->&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})" -exit 1 +if [ "${POM_JFX_VERSION}" -ne "${JMOD_VERSION}" ]; then + >&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})" + exit 1 fi # compile mvn -B -f../../../pom.xml clean package -DskipTests -Pmac +cp ../../../LICENSE.txt ../../../target cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods # add runtime @@ -168,6 +169,5 @@ create-dmg \ --app-drop-link 512 245 \ --eula "resources/license.rtf" \ --icon ".background" 128 758 \ - --icon ".fseventsd" 320 758 \ --icon ".VolumeIcon.icns" 512 758 \ ${APP_NAME}-${VERSION_NO}.dmg dmg diff --git a/pom.xml b/pom.xml index a62120a4d..3617a9378 100644 --- a/pom.xml +++ b/pom.xml @@ -35,8 +35,8 @@ 2.6.7 1.3.0 - 1.2.2 - 1.2.1 + 1.2.3 + 1.2.2 1.4.0-beta1 4.0.0-beta1 2.0.0 diff --git a/src/main/java/org/cryptomator/common/Environment.java b/src/main/java/org/cryptomator/common/Environment.java index 17816df96..981b3729b 100644 --- a/src/main/java/org/cryptomator/common/Environment.java +++ b/src/main/java/org/cryptomator/common/Environment.java @@ -32,6 +32,7 @@ public class Environment { private static final String BUILD_NUMBER_PROP_NAME = "cryptomator.buildNumber"; private static final String PLUGIN_DIR_PROP_NAME = "cryptomator.pluginDir"; private static final String TRAY_ICON_PROP_NAME = "cryptomator.showTrayIcon"; + private static final String DISABLE_UPDATE_CHECK_PROP_NAME = "cryptomator.disableUpdateCheck"; private Environment() {} @@ -53,6 +54,7 @@ public class Environment { logCryptomatorSystemProperty(BUILD_NUMBER_PROP_NAME); logCryptomatorSystemProperty(PLUGIN_DIR_PROP_NAME); logCryptomatorSystemProperty(TRAY_ICON_PROP_NAME); + logCryptomatorSystemProperty(DISABLE_UPDATE_CHECK_PROP_NAME); } public static Environment getInstance() { @@ -124,6 +126,10 @@ public class Environment { return Boolean.getBoolean(TRAY_ICON_PROP_NAME); } + public boolean disableUpdateCheck() { + return Boolean.getBoolean(DISABLE_UPDATE_CHECK_PROP_NAME); + } + private Optional getPath(String propertyName) { String value = System.getProperty(propertyName); return Optional.ofNullable(value).map(Paths::get); diff --git a/src/main/java/org/cryptomator/ui/error/ErrorController.java b/src/main/java/org/cryptomator/ui/error/ErrorController.java index 3feb3ff44..61f2b0e10 100644 --- a/src/main/java/org/cryptomator/ui/error/ErrorController.java +++ b/src/main/java/org/cryptomator/ui/error/ErrorController.java @@ -42,7 +42,8 @@ public class ErrorController implements FxController { private static final ObjectMapper JSON = new ObjectMapper(); private static final Logger LOG = LoggerFactory.getLogger(ErrorController.class); - private static final String ERROR_CODES_URL = "https://api.cryptomator.org/desktop/error-codes.json"; + private static final String USER_AGENT_FORMAT = "Cryptomator/%s (Build %s) (%s %s %s)"; + private static final String ERROR_CODES_URL_FORMAT = "https://api.cryptomator.org/desktop/error-codes.json?error-code=%s"; private static final String SEARCH_URL_FORMAT = "https://github.com/cryptomator/cryptomator/discussions/categories/errors?discussions_q=category:Errors+%s"; private static final String REPORT_URL_FORMAT = "https://github.com/cryptomator/cryptomator/discussions/new?category=Errors&title=Error+%s&body=%s"; private static final String SEARCH_ERRORCODE_DELIM = " OR "; @@ -142,11 +143,18 @@ public class ErrorController implements FxController { @FXML public void lookUpSolution() { + String userAgent = USER_AGENT_FORMAT.formatted( // + environment.getAppVersion(), // + environment.getBuildNumber().orElse("undefined"), // + System.getProperty("os.name"), // + System.getProperty("os.version"), // + System.getProperty("os.arch")); isLoadingHttpResponse.set(true); askedForLookupDatabasePermission.set(true); HttpClient httpClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build(); HttpRequest httpRequest = HttpRequest.newBuilder()// - .uri(URI.create(ERROR_CODES_URL))// + .header("User-Agent", userAgent) + .uri(URI.create(ERROR_CODES_URL_FORMAT.formatted(URLEncoder.encode(errorCode.toString(),StandardCharsets.UTF_8))))// .build(); httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofInputStream())// .thenAcceptAsync(this::loadHttpResponse, executorService)// diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index d845655cf..711a0fa44 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -1,6 +1,7 @@ package org.cryptomator.ui.fxapp; import dagger.Lazy; +import org.cryptomator.common.Environment; import org.cryptomator.common.settings.Settings; import org.cryptomator.ui.traymenu.TrayMenuComponent; import org.slf4j.Logger; @@ -17,6 +18,7 @@ public class FxApplication { private static final Logger LOG = LoggerFactory.getLogger(FxApplication.class); private final long startupTime; + private final Environment environment; private final Settings settings; private final AppLaunchEventHandler launchEventHandler; private final Lazy trayMenu; @@ -26,8 +28,9 @@ public class FxApplication { private final AutoUnlocker autoUnlocker; @Inject - FxApplication(@Named("startupTime") long startupTime, Settings settings, AppLaunchEventHandler launchEventHandler, Lazy trayMenu, FxApplicationWindows appWindows, FxApplicationStyle applicationStyle, FxApplicationTerminator applicationTerminator, AutoUnlocker autoUnlocker) { + FxApplication(@Named("startupTime") long startupTime, Environment environment, Settings settings, AppLaunchEventHandler launchEventHandler, Lazy trayMenu, FxApplicationWindows appWindows, FxApplicationStyle applicationStyle, FxApplicationTerminator applicationTerminator, AutoUnlocker autoUnlocker) { this.startupTime = startupTime; + this.environment = environment; this.settings = settings; this.launchEventHandler = launchEventHandler; this.trayMenu = trayMenu; @@ -68,7 +71,9 @@ public class FxApplication { return null; }); - appWindows.checkAndShowUpdateReminderWindow(); + if (!environment.disableUpdateCheck()) { + appWindows.checkAndShowUpdateReminderWindow(); + } launchEventHandler.startHandlingLaunchEvents(); autoUnlocker.tryUnlockForTimespan(2, TimeUnit.MINUTES); diff --git a/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java b/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java index 4418f79b5..709eb2fe7 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java +++ b/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java @@ -22,23 +22,23 @@ public class UpdateChecker { private static final Logger LOG = LoggerFactory.getLogger(UpdateChecker.class); private static final Duration AUTOCHECK_DELAY = Duration.seconds(5); + private final Environment env; private final Settings settings; - private final String currentVersion; private final StringProperty latestVersionProperty; private final Comparator semVerComparator; private final ScheduledService updateCheckerService; @Inject UpdateChecker(Settings settings, Environment env, @Named("latestVersion") StringProperty latestVersionProperty, @Named("SemVer") Comparator semVerComparator, ScheduledService updateCheckerService) { + this.env = env; this.settings = settings; this.latestVersionProperty = latestVersionProperty; this.semVerComparator = semVerComparator; this.updateCheckerService = updateCheckerService; - this.currentVersion = env.getAppVersion(); } public void automaticallyCheckForUpdatesIfEnabled() { - if (settings.checkForUpdates.get()) { + if (!env.disableUpdateCheck() && settings.checkForUpdates.get()) { startCheckingForUpdates(AUTOCHECK_DELAY); } } @@ -63,9 +63,9 @@ public class UpdateChecker { private void checkSucceeded(WorkerStateEvent event) { String latestVersion = updateCheckerService.getValue(); - LOG.info("Current version: {}, lastest version: {}", currentVersion, latestVersion); + LOG.info("Current version: {}, lastest version: {}", getCurrentVersion(), latestVersion); - if (semVerComparator.compare(currentVersion, latestVersion) < 0) { + if (semVerComparator.compare(getCurrentVersion(), latestVersion) < 0) { // update is available latestVersionProperty.set(latestVersion); } else { @@ -88,7 +88,7 @@ public class UpdateChecker { } public String getCurrentVersion() { - return currentVersion; + return env.getAppVersion(); } } diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index 357222b33..8f0a91d58 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -20,9 +20,10 @@ import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; -import javafx.event.Event; import javafx.fxml.FXML; +import javafx.geometry.Side; import javafx.scene.control.Button; +import javafx.scene.control.ContextMenu; import javafx.scene.control.ListView; import javafx.scene.input.ContextMenuEvent; import javafx.scene.input.DragEvent; @@ -67,6 +68,8 @@ public class VaultListController implements FxController { public ListView vaultList; public StackPane root; public Button addVaultBtn; + @FXML + private ContextMenu addVaultContextMenu; @Inject VaultListController(@MainWindow Stage mainWindow, // @@ -140,15 +143,15 @@ public class VaultListController implements FxController { root.setOnDragOver(this::handleDragEvent); root.setOnDragDropped(this::handleDragEvent); root.setOnDragExited(this::handleDragEvent); - - addVaultBtn.addEventFilter(ContextMenuEvent.CONTEXT_MENU_REQUESTED, Event::consume); } @FXML - private void showMenu() { - double screenX = addVaultBtn.localToScreen(addVaultBtn.getBoundsInLocal()).getMinX(); - double screenY = addVaultBtn.localToScreen(addVaultBtn.getBoundsInLocal()).getMaxY(); - addVaultBtn.getContextMenu().show(addVaultBtn, screenX, screenY); + private void toggleMenu() { + if (addVaultContextMenu.isShowing()) { + addVaultContextMenu.hide(); + } else { + addVaultContextMenu.show(addVaultBtn, Side.BOTTOM, 0.0, 0.0); + } } private void deselect(MouseEvent released) { diff --git a/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java index caaaf7d80..0937fccd9 100644 --- a/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java +++ b/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java @@ -1,5 +1,6 @@ package org.cryptomator.ui.preferences; +import org.cryptomator.common.Environment; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.fxapp.UpdateChecker; import org.slf4j.Logger; @@ -19,6 +20,7 @@ public class PreferencesController implements FxController { private static final Logger LOG = LoggerFactory.getLogger(PreferencesController.class); + private final Environment env; private final Stage window; private final ObjectProperty selectedTabProperty; private final BooleanBinding updateAvailable; @@ -31,7 +33,8 @@ public class PreferencesController implements FxController { public Tab aboutTab; @Inject - public PreferencesController(@PreferencesWindow Stage window, ObjectProperty selectedTabProperty, UpdateChecker updateChecker) { + public PreferencesController(Environment env, @PreferencesWindow Stage window, ObjectProperty selectedTabProperty, UpdateChecker updateChecker) { + this.env = env; this.window = window; this.selectedTabProperty = selectedTabProperty; this.updateAvailable = updateChecker.latestVersionProperty().isNotNull(); @@ -42,6 +45,9 @@ public class PreferencesController implements FxController { window.setOnShowing(this::windowWillAppear); selectedTabProperty.addListener(observable -> this.selectChosenTab()); tabPane.getSelectionModel().selectedItemProperty().addListener(observable -> this.selectedTabChanged()); + if (env.disableUpdateCheck()) { + tabPane.getTabs().remove(updatesTab); + } } private void selectChosenTab() { diff --git a/src/main/resources/fxml/vault_list.fxml b/src/main/resources/fxml/vault_list.fxml index 146fa877c..f9cb29258 100644 --- a/src/main/resources/fxml/vault_list.fxml +++ b/src/main/resources/fxml/vault_list.fxml @@ -28,27 +28,27 @@ - + + + + + + + + + + + + + + + + diff --git a/src/main/resources/i18n/strings_bg.properties b/src/main/resources/i18n/strings_bg.properties index ace7569d6..172b27b5c 100644 --- a/src/main/resources/i18n/strings_bg.properties +++ b/src/main/resources/i18n/strings_bg.properties @@ -153,6 +153,7 @@ hub.invalidLicense.message=Лиценза за Hub е недействителе # Lock ## Force +lock.forced.retryBtn=Повторен опит ## Failure # Migration diff --git a/src/main/resources/i18n/strings_zh_TW.properties b/src/main/resources/i18n/strings_zh_TW.properties index 0aede0ed4..3f2ee62fd 100644 --- a/src/main/resources/i18n/strings_zh_TW.properties +++ b/src/main/resources/i18n/strings_zh_TW.properties @@ -22,6 +22,9 @@ error.hyperlink.report=回報錯誤 error.technicalDetails=詳情: error.existingSolutionDescription=Cryptomator 沒有預料到會發生這種情況。但我們找到了一個現有的解決方案來解決這個錯誤。請查看以下連結。 error.hyperlink.solution=查詢解決方案 +error.lookupPermissionMessage=Cryptomator 可以在線查找此問題的解決方案。 這將從您的 IP 地址向我們的問題數據庫發送請求。 +error.dismiss=忽略 +error.lookUpSolution=查詢解決方案 # Defaults defaults.vault.vaultName=加密檔案庫 @@ -134,6 +137,7 @@ unlock.error.customPath.message=無法將檔案庫掛載至自訂路徑 unlock.error.customPath.description.notSupported=如果要繼續使用自訂的掛載路徑,必須變更成支援的磁區空間類型,不然就必須使用不同的掛載路徑 unlock.error.customPath.description.notExists=自訂的掛載路徑並不存在‧ 請在本機創立該路徑,或者在加密庫選項中更改 unlock.error.customPath.description.inUse=磁碟代號或自訂掛載路徑「%s」已被使用。 +unlock.error.customPath.description.hideawayNotDir=無法移除用於解鎖的臨時隱藏檔案「%3$s」。請檢查該檔案,然後手動刪除。 unlock.error.customPath.description.couldNotBeCleaned=無法將您的保險庫掛載至路徑「%s」。請再試一次或選擇不同的路徑。 unlock.error.customPath.description.notEmptyDir=自訂掛載路徑「%s」不是一個空資料夾。請選擇一個空資料夾並重試。 unlock.error.customPath.description.generic=您為此保險庫選擇了自訂掛載路徑,但使用時出現了錯誤訊息:%2$s