소스 검색

Merge branch 'release/1.7.4'

Armin Schrenk 2 년 전
부모
커밋
bf76bad626
37개의 변경된 파일285개의 추가작업 그리고 154개의 파일을 삭제
  1. 35 9
      .github/workflows/win-exe.yml
  2. 0 49
      .github/workflows/winget.yml
  3. 0 1
      README.md
  4. 1 0
      dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml
  5. 3 38
      pom.xml
  6. 12 0
      src/main/java/org/cryptomator/common/ObservableUtil.java
  7. 40 19
      src/main/java/org/cryptomator/common/mount/MountModule.java
  8. 19 1
      src/main/java/org/cryptomator/ui/preferences/VolumePreferencesController.java
  9. 4 0
      src/main/resources/css/dark_theme.css
  10. 4 0
      src/main/resources/css/light_theme.css
  11. 3 1
      src/main/resources/fxml/preferences_volume.fxml
  12. 2 1
      src/main/resources/i18n/strings.properties
  13. 0 1
      src/main/resources/i18n/strings_be.properties
  14. 0 1
      src/main/resources/i18n/strings_ca.properties
  15. 0 1
      src/main/resources/i18n/strings_da.properties
  16. 3 2
      src/main/resources/i18n/strings_de.properties
  17. 2 1
      src/main/resources/i18n/strings_el.properties
  18. 2 1
      src/main/resources/i18n/strings_es.properties
  19. 2 1
      src/main/resources/i18n/strings_fr.properties
  20. 0 1
      src/main/resources/i18n/strings_he.properties
  21. 23 0
      src/main/resources/i18n/strings_hu.properties
  22. 7 1
      src/main/resources/i18n/strings_it.properties
  23. 19 11
      src/main/resources/i18n/strings_ja.properties
  24. 0 1
      src/main/resources/i18n/strings_nb.properties
  25. 2 1
      src/main/resources/i18n/strings_nl.properties
  26. 7 1
      src/main/resources/i18n/strings_pl.properties
  27. 80 1
      src/main/resources/i18n/strings_pt.properties
  28. 0 1
      src/main/resources/i18n/strings_pt_BR.properties
  29. 0 1
      src/main/resources/i18n/strings_ro.properties
  30. 2 1
      src/main/resources/i18n/strings_ru.properties
  31. 2 1
      src/main/resources/i18n/strings_sk.properties
  32. 2 1
      src/main/resources/i18n/strings_sv.properties
  33. 1 1
      src/main/resources/i18n/strings_sw.properties
  34. 2 1
      src/main/resources/i18n/strings_tr.properties
  35. 2 1
      src/main/resources/i18n/strings_zh.properties
  36. 2 1
      src/main/resources/i18n/strings_zh_HK.properties
  37. 2 1
      src/main/resources/i18n/strings_zh_TW.properties

+ 35 - 9
.github/workflows/win-exe.yml

@@ -8,11 +8,17 @@ on:
       version:
         description: 'Version'
         required: false
+      isDebug:
+        description: 'Build debug version with console output'
+        type: boolean 
+
 
 env:
   JAVA_VERSION: 19
-  JAVA_DIST: 'zulu'
+  JAVA_DIST: 'temurin'
   JAVA_CACHE: 'maven'
+  JFX_JMODS_URL: 'https://download2.gluonhq.com/openjfx/19.0.2.1/openjfx-19.0.2.1_windows-x64_bin-jmods.zip'
+  JFX_JMODS_HASH: 'B7CF2CAD2468842B3B78D99F6C0555771499A36FA1F1EE3DD1B9A4597F1FAB86'
 
 defaults:
   run:
@@ -30,6 +36,7 @@ jobs:
     needs: [get-version]
     env:
       LOOPBACK_ALIAS: 'cryptomator-vault'
+      WIN_CONSOLE_FLAG: ''
     steps:
       - uses: actions/checkout@v3
       - name: Setup Java
@@ -37,17 +44,31 @@ jobs:
         with:
           distribution: ${{ env.JAVA_DIST }}
           java-version: ${{ env.JAVA_VERSION }}
-          java-package: 'jdk+fx'
+          java-package: 'jdk'
           cache: ${{ env.JAVA_CACHE }}
-      - name: Ensure major jfx version in pom equals in jdk
+      - name: Download and extract JavaFX jmods from Gluon
+        #In the last step we move all jmods files a dir level up because jmods are placed inside a directory in the zip
+        run: |
+          curl --output jfxjmods.zip -L "${{ env.JFX_JMODS_URL }}"
+          if(!(Get-FileHash -Path jfxjmods.zip -Algorithm SHA256).Hash.equals("${{ env.JFX_JMODS_HASH }}")) {
+            exit 1;
+          }
+          Expand-Archive -Path jfxjmods.zip -DestinationPath jfxjmods
+          Get-ChildItem -Path jfxjmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
         shell: pwsh
+      - name: Ensure major jfx version in pom and in jmods is the same
         run: |
-          $jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\."
-          $jfxJdkVersion = ((Get-Content -path "${env:JAVA_HOME}/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\."
-          if ($jfxPomVersion[0] -ne $jfxJdkVersion[0]) {
-            Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK($($jfxJdkVersion[0])) "
+          JMOD_VERSION_AMD64=$(jmod describe jfxjmods/javafx.base.jmod | head -1)
+          JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
+          JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
+          POM_JFX_VERSION=$(mvn 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_AMD64 ]; then
+            >&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 jmod version (${JMOD_VERSION_AMD64})"
             exit 1
-          }
+          fi
       - name: Set version
         run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
       - name: Run maven
@@ -61,13 +82,16 @@ jobs:
           ${JAVA_HOME}/bin/jlink
           --verbose
           --output runtime
-          --module-path "${JAVA_HOME}/jmods"
+          --module-path "jfxjmods;${JAVA_HOME}/jmods"
           --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
           --strip-native-commands
           --no-header-files
           --no-man-pages
           --strip-debug
           --compress=1
+      - name: Change win-console flag if debug is active
+        if: ${{ inputs.isDebug }}
+        run: echo "WIN_CONSOLE_FLAG=--win-console" >> $GITHUB_ENV
       - name: Run jpackage
         run: >
           ${JAVA_HOME}/bin/jpackage
@@ -99,8 +123,10 @@ jobs:
           --java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
           --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
           --java-options "-Dcryptomator.integrationsWin.keychainPaths=\"~/AppData/Roaming/Cryptomator/keychain.json\""
+          --java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
           --resource-dir dist/win/resources
           --icon dist/win/resources/Cryptomator.ico
+          ${WIN_CONSOLE_FLAG}
       - name: Patch Application Directory
         run: |
           cp dist/win/contrib/* appdir/Cryptomator

+ 0 - 49
.github/workflows/winget.yml

@@ -1,49 +0,0 @@
-name: Release to Winget
-
-on:
-  workflow_call:
-    inputs:
-      releaseTag:
-        required: true
-        type: string
-  workflow_dispatch:
-    inputs:
-      releaseTag:
-        description: 'Release tag name'
-        required: true
-        type: string
-
-jobs:
-  publish-winget:
-    name: Publish on winget repo
-    runs-on: windows-latest
-    steps:
-      - name: Get download url for release assets
-        id: get-release-assets
-        uses: actions/github-script@v6
-        with:
-          script: |
-            const query =`query($tag:String!) {
-              repository(owner:"cryptomator", name:"cryptomator"){
-                release(tagName: $tag) {
-                    releaseAssets(first:20) {
-                      nodes {
-                        name
-                        downloadUrl
-                      }
-                  }
-                }
-              }
-            }`;
-            const variables = {
-              tag: "${{ inputs.releaseTag }}"
-            }
-            return await github.graphql(query, variables)
-      - name: Submit package to Windows Package Manager Community Repository
-        id: submit-winget
-        run: |
-          iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
-          $releaseAssets = (ConvertFrom-Json '${{ steps.get-release-assets.outputs.result }}').repository.release.releaseAssets.nodes
-          $installerUrl = $releaseAssets | Where-Object -Property name -match '^Cryptomator-.*\.msi$' | Select -ExpandProperty downloadUrl -First 1
-          .\wingetcreate.exe update Cryptomator.Cryptomator -s -v "${{ inputs.releaseTag }}" -u "$installerUrl" -t ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
-        shell: pwsh

+ 0 - 1
README.md

@@ -21,7 +21,6 @@ Cryptomator is provided free of charge as an open-source project despite the hig
   <tbody>
     <tr>
       <td><a href="https://www.gee-whiz.de/"><img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="80"></a></td>
-      <td><a href="https://proxy-hub.com/"><img src="https://cryptomator.org/img/sponsors/proxyhub.svg" alt="Proxy-Hub" height="80"></a></td>
     </tr>
   </tbody>
 </table>

+ 1 - 0
dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml

@@ -66,6 +66,7 @@
 	</content_rating>
 
 	<releases>
+		<release date="2023-04-05" version="1.7.4"/>
 		<release date="2023-03-15" version="1.7.3"/>
 		<release date="2023-03-07" version="1.7.2"/>
 		<release date="2023-03-03" version="1.7.1"/>

+ 3 - 38
pom.xml

@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>org.cryptomator</groupId>
 	<artifactId>cryptomator</artifactId>
-	<version>1.7.3</version>
+	<version>1.7.4</version>
 	<name>Cryptomator Desktop App</name>
 
 	<organization>
@@ -33,12 +33,12 @@
 		<nonModularGroupIds>org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents,de.swiesend,org.purejava,com.github.hypfvieh</nonModularGroupIds>
 
 		<!-- cryptomator dependencies -->
-		<cryptomator.cryptofs.version>2.6.2</cryptomator.cryptofs.version>
+		<cryptomator.cryptofs.version>2.6.3</cryptomator.cryptofs.version>
 		<cryptomator.integrations.version>1.2.0</cryptomator.integrations.version>
 		<cryptomator.integrations.win.version>1.2.0</cryptomator.integrations.win.version>
 		<cryptomator.integrations.mac.version>1.2.0</cryptomator.integrations.mac.version>
 		<cryptomator.integrations.linux.version>1.2.0</cryptomator.integrations.linux.version>
-		<cryptomator.fuse.version>2.0.4</cryptomator.fuse.version>
+		<cryptomator.fuse.version>2.0.5</cryptomator.fuse.version>
 		<cryptomator.dokany.version>2.0.0</cryptomator.dokany.version>
 		<cryptomator.webdav.version>2.0.2</cryptomator.webdav.version>
 
@@ -317,41 +317,6 @@
 					</compilerArgs>
 				</configuration>
 			</plugin>
-			<plugin>
-				<groupId>org.codehaus.mojo</groupId>
-				<artifactId>exec-maven-plugin</artifactId>
-				<version>3.1.0</version>
-				<executions>
-					<execution>
-						<id>compile-light-theme</id>
-						<phase>compile</phase>
-						<goals>
-							<goal>java</goal>
-						</goals>
-						<configuration>
-							<mainClass>javafx.graphics/com.sun.javafx.css.parser.Css2Bin</mainClass>
-							<arguments>
-								<arg>${project.basedir}/src/main/resources/css/light_theme.css</arg>
-								<arg>${project.build.outputDirectory}/css/light_theme.bss</arg>
-							</arguments>
-						</configuration>
-					</execution>
-					<execution>
-						<id>compile-dark-theme</id>
-						<phase>compile</phase>
-						<goals>
-							<goal>java</goal>
-						</goals>
-						<configuration>
-							<mainClass>javafx.graphics/com.sun.javafx.css.parser.Css2Bin</mainClass>
-							<arguments>
-								<arg>${project.basedir}/src/main/resources/css/dark_theme.css</arg>
-								<arg>${project.build.outputDirectory}/css/dark_theme.bss</arg>
-							</arguments>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-jar-plugin</artifactId>

+ 12 - 0
src/main/java/org/cryptomator/common/ObservableUtil.java

@@ -2,7 +2,9 @@ package org.cryptomator.common;
 
 import javafx.beans.binding.Bindings;
 import javafx.beans.value.ObservableValue;
+import java.util.Objects;
 import java.util.function.Function;
+import java.util.function.Supplier;
 
 public class ObservableUtil {
 
@@ -15,4 +17,14 @@ public class ObservableUtil {
 			}
 		}, observable);
 	}
+
+	public static <T, U> ObservableValue<U> mapWithDefault(ObservableValue<T> observable, Function<? super T, ? extends U> mapper, Supplier<U> defaultValue) {
+		return Bindings.createObjectBinding(() -> {
+			if (observable.getValue() == null) {
+				return defaultValue.get();
+			} else {
+				return mapper.apply(observable.getValue());
+			}
+		}, observable);
+	}
 }

+ 40 - 19
src/main/java/org/cryptomator/common/mount/MountModule.java

@@ -2,50 +2,71 @@ package org.cryptomator.common.mount;
 
 import dagger.Module;
 import dagger.Provides;
+import org.cryptomator.common.ObservableUtil;
 import org.cryptomator.common.settings.Settings;
+import org.cryptomator.integrations.mount.Mount;
 import org.cryptomator.integrations.mount.MountService;
 
+import javax.inject.Named;
 import javax.inject.Singleton;
-import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ObservableValue;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
 
 @Module
 public class MountModule {
 
+	private static final AtomicReference<MountService> formerSelectedMountService = new AtomicReference<>(null);
+	private static final List<String> problematicFuseMountServices = List.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", "org.cryptomator.frontend.fuse.mount.FuseTMountProvider");
+
 	@Provides
 	@Singleton
 	static List<MountService> provideSupportedMountServices() {
 		return MountService.get().toList();
 	}
 
-	//currently not used, because macFUSE and FUSE-T cannot be used in the same JVM
-	/*
 	@Provides
 	@Singleton
-	static ObservableValue<ActualMountService> provideMountService(Settings settings, List<MountService> serviceImpls) {
-		var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
-		return ObservableUtil.mapWithDefault(settings.mountService(), //
-				desiredServiceImpl -> { //
-					var desiredService = serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(desiredServiceImpl)).findAny(); //
-					return new ActualMountService(desiredService.orElse(fallbackProvider), desiredService.isPresent()); //
-				}, //
-				new ActualMountService(fallbackProvider, true));
+	@Named("FUPFMS")
+	static AtomicReference<MountService> provideFirstUsedProblematicFuseMountService() {
+		return new AtomicReference<>(null);
 	}
-	 */
 
 	@Provides
 	@Singleton
-	static ActualMountService provideActualMountService(Settings settings, List<MountService> serviceImpls) {
+	static ObservableValue<ActualMountService> provideMountService(Settings settings, List<MountService> serviceImpls, @Named("FUPFMS") AtomicReference<MountService> fupfms) {
 		var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
-		var desiredService = serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(settings.mountService().getValue())).findFirst(); //
-		return new ActualMountService(desiredService.orElse(fallbackProvider), desiredService.isPresent()); //
+
+		var observableMountService = ObservableUtil.mapWithDefault(settings.mountService(), //
+				desiredServiceImpl -> { //
+					var serviceFromSettings = serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(desiredServiceImpl)).findAny(); //
+					var targetedService = serviceFromSettings.orElse(fallbackProvider);
+					return applyWorkaroundForProblematicFuse(targetedService, serviceFromSettings.isPresent(), fupfms);
+				}, //
+				() -> { //
+					return applyWorkaroundForProblematicFuse(fallbackProvider, true, fupfms);
+				});
+		return observableMountService;
 	}
 
-	@Provides
-	@Singleton
-	static ObservableValue<ActualMountService> provideMountService(ActualMountService service) {
-		return new SimpleObjectProperty<>(service);
+	//see https://github.com/cryptomator/cryptomator/issues/2786
+	private synchronized static ActualMountService applyWorkaroundForProblematicFuse(MountService targetedService, boolean isDesired, AtomicReference<MountService> firstUsedProblematicFuseMountService) {
+		//set the first used problematic fuse service if applicable
+		var targetIsProblematicFuse = isProblematicFuseService(targetedService);
+		if (targetIsProblematicFuse && firstUsedProblematicFuseMountService.get() == null) {
+			firstUsedProblematicFuseMountService.set(targetedService);
+		}
+
+		//do not use the targeted mount service and fallback to former one, if the service is problematic _and_ not the first problematic one used.
+		if (targetIsProblematicFuse && !firstUsedProblematicFuseMountService.get().equals(targetedService)) {
+			return new ActualMountService(formerSelectedMountService.get(), false);
+		} else {
+			formerSelectedMountService.set(targetedService);
+			return new ActualMountService(targetedService, isDesired);
+		}
 	}
 
+	public static boolean isProblematicFuseService(MountService service) {
+		return problematicFuseMountServices.contains(service.getClass().getName());
+	}
 }

+ 19 - 1
src/main/java/org/cryptomator/ui/preferences/VolumePreferencesController.java

@@ -2,12 +2,14 @@ package org.cryptomator.ui.preferences;
 
 import dagger.Lazy;
 import org.cryptomator.common.ObservableUtil;
+import org.cryptomator.common.mount.MountModule;
 import org.cryptomator.common.settings.Settings;
 import org.cryptomator.integrations.mount.MountCapability;
 import org.cryptomator.integrations.mount.MountService;
 import org.cryptomator.ui.common.FxController;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 import javafx.application.Application;
 import javafx.beans.binding.Bindings;
 import javafx.beans.binding.BooleanExpression;
@@ -19,6 +21,7 @@ import javafx.util.StringConverter;
 import java.util.List;
 import java.util.Optional;
 import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicReference;
 
 @PreferencesScoped
 public class VolumePreferencesController implements FxController {
@@ -33,6 +36,7 @@ public class VolumePreferencesController implements FxController {
 	private final ObservableValue<Boolean> mountToDriveLetterSupported;
 	private final ObservableValue<Boolean> mountFlagsSupported;
 	private final ObservableValue<Boolean> readonlySupported;
+	private final ObservableValue<Boolean> fuseRestartRequired;
 	private final Lazy<Application> application;
 	private final List<MountService> mountProviders;
 	public ChoiceBox<MountService> volumeTypeChoiceBox;
@@ -40,7 +44,7 @@ public class VolumePreferencesController implements FxController {
 	public Button loopbackPortApplyButton;
 
 	@Inject
-	VolumePreferencesController(Settings settings, Lazy<Application> application, List<MountService> mountProviders, ResourceBundle resourceBundle) {
+	VolumePreferencesController(Settings settings, Lazy<Application> application, List<MountService> mountProviders, @Named("FUPFMS") AtomicReference<MountService> firstUsedProblematicFuseMountService, ResourceBundle resourceBundle) {
 		this.settings = settings;
 		this.application = application;
 		this.mountProviders = mountProviders;
@@ -53,6 +57,12 @@ public class VolumePreferencesController implements FxController {
 		this.mountToDriveLetterSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_AS_DRIVE_LETTER));
 		this.mountFlagsSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_FLAGS));
 		this.readonlySupported = selectedMountService.map(s -> s.hasCapability(MountCapability.READ_ONLY));
+		this.fuseRestartRequired = selectedMountService.map(s -> {//
+			return firstUsedProblematicFuseMountService.get() != null //
+					&& MountModule.isProblematicFuseService(s) //
+					&& !firstUsedProblematicFuseMountService.get().equals(s);
+		});
+
 	}
 
 	public void initialize() {
@@ -129,6 +139,14 @@ public class VolumePreferencesController implements FxController {
 		return mountFlagsSupported.getValue();
 	}
 
+	public ObservableValue<Boolean> fuseRestartRequiredProperty() {
+		return fuseRestartRequired;
+	}
+
+	public boolean getFuseRestartRequired() {
+		return fuseRestartRequired.getValue();
+	}
+
 	/* Helpers */
 
 	private class MountServiceConverter extends StringConverter<MountService> {

+ 4 - 0
src/main/resources/css/dark_theme.css

@@ -116,6 +116,10 @@
 	-fx-font-size: 0.64em;
 }
 
+.label-red {
+	-fx-text-fill: RED_5;
+}
+
 .text-flow > * {
 	-fx-fill: TEXT_FILL;
 }

+ 4 - 0
src/main/resources/css/light_theme.css

@@ -116,6 +116,10 @@
 	-fx-font-size: 0.64em;
 }
 
+.label-red {
+	-fx-text-fill: RED_5;
+}
+
 .text-flow > * {
 	-fx-fill: TEXT_FILL;
 }

+ 3 - 1
src/main/resources/fxml/preferences_volume.fxml

@@ -8,9 +8,9 @@
 <?import javafx.scene.control.Hyperlink?>
 <?import javafx.scene.control.Label?>
 <?import javafx.scene.control.Separator?>
+<?import javafx.scene.control.Tooltip?>
 <?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.VBox?>
-<?import javafx.scene.control.Tooltip?>
 <VBox xmlns:fx="http://javafx.com/fxml"
 	  xmlns="http://javafx.com/javafx"
 	  fx:controller="org.cryptomator.ui.preferences.VolumePreferencesController"
@@ -32,6 +32,8 @@
 			</Hyperlink>
 		</HBox>
 
+		<Label styleClass="label-red" text="%preferences.volume.fuseRestartRequired" visible="${controller.fuseRestartRequired}" managed="${controller.fuseRestartRequired}"/>
+
 		<HBox spacing="12" alignment="CENTER_LEFT" visible="${controller.loopbackPortSupported}" managed="${controller.loopbackPortSupported}">
 			<Label text="%preferences.volume.tcp.port"/>
 			<NumericTextField fx:id="loopbackPortField"/>

+ 2 - 1
src/main/resources/i18n/strings.properties

@@ -275,9 +275,10 @@ preferences.interface.showMinimizeButton=Show minimize button
 preferences.interface.showTrayIcon=Show tray icon (requires restart)
 ## Volume
 preferences.volume=Virtual Drive
-preferences.volume.type=Volume Type (requires restart)
+preferences.volume.type=Volume Type
 preferences.volume.type.automatic=Automatic
 preferences.volume.docsTooltip=Open the documentation to learn more about the different volume types.
+preferences.volume.fuseRestartRequired=To apply the changes, Cryptomator needs to be restarted.
 preferences.volume.tcp.port=TCP Port
 preferences.volume.supportedFeatures=The chosen volume type supports the following features:
 preferences.volume.feature.mountAuto=Automatic mount point selection

+ 0 - 1
src/main/resources/i18n/strings_be.properties

@@ -270,7 +270,6 @@ preferences.interface.showMinimizeButton=Паказаць кнопку згор
 preferences.interface.showTrayIcon=Паказваць іконку на інфармацыйнай панэлі (спатрэбіцца перазапуск)
 ## Volume
 preferences.volume=Віртуальны дыск
-preferences.volume.type=Тып тому (спатрэбіцца перазапуск)
 preferences.volume.type.automatic=Аўтаматычна
 preferences.volume.docsTooltip=Адчыні дакумэнтацыю, каб даведацца больш пра розныя тыпы тому.
 preferences.volume.tcp.port=Порт TCP

+ 0 - 1
src/main/resources/i18n/strings_ca.properties

@@ -274,7 +274,6 @@ preferences.interface.showMinimizeButton=Mostra el botó 'minimitzar'
 preferences.interface.showTrayIcon=Mostra la icona en la barra (cal reiniciar)
 ## Volume
 preferences.volume=Unitat virtual
-preferences.volume.type=Tipus de volum (requereix reiniciar)
 preferences.volume.type.automatic=Automàtic
 preferences.volume.docsTooltip=Obre la documentació per aprendre més sobre els diferents tipus de volums.
 preferences.volume.tcp.port=Port TCP

+ 0 - 1
src/main/resources/i18n/strings_da.properties

@@ -272,7 +272,6 @@ preferences.interface.showMinimizeButton=Vis knap til minimering
 preferences.interface.showTrayIcon=Vis ikon i system-bakken (kræver genstart)
 ## Volume
 preferences.volume=Virtuelt drev
-preferences.volume.type=Drev type (kræver genstart)
 preferences.volume.type.automatic=Automatisk
 preferences.volume.tcp.port=TCP port
 preferences.volume.supportedFeatures=Den valgte type drev understøtter følgende funktioner:

+ 3 - 2
src/main/resources/i18n/strings_de.properties

@@ -155,7 +155,7 @@ hub.unauthorized.message=Zugriff verweigert
 hub.unauthorized.description=Dein Gerät wurde noch nicht für den Zugriff auf diesen Tresor autorisiert. Bitte den Tresorbesitzer, dein Gerät zu autorisieren.
 ### License Exceeded
 hub.invalidLicense.message=Hub-Lizenz ungültig
-hub.invalidLicense.description=Die Lizenz deiner Cryptomator-Hub-Instanz ist ungültig. Bitte informiere deinen Hub-Administrator, um die Lizenz zu aktualisieren oder zu erneuern.
+hub.invalidLicense.description=Die Lizenz deiner Cryptomator-Hub-Instanz ist ungültig. Bitte informiere deinen Hub-Administrator, um die Lizenz zu erweitern oder zu erneuern.
 
 # Lock
 ## Force
@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Schaltfläche zum Minimieren anzeigen
 preferences.interface.showTrayIcon=Symbol im Infobereich anzeigen (Neustart erforderlich)
 ## Volume
 preferences.volume=Virtuelles Laufwerk
-preferences.volume.type=Laufwerkstyp (Neustart erforderlich)
+preferences.volume.type=Laufwerkstyp
 preferences.volume.type.automatic=Automatisch
 preferences.volume.docsTooltip=Öffne die Dokumentation, um mehr über die verschiedenen Laufwerkstypen zu erfahren.
+preferences.volume.fuseRestartRequired=Um die Änderungen anzuwenden, muss Cryptomator neu gestartet werden.
 preferences.volume.tcp.port=TCP-Port
 preferences.volume.supportedFeatures=Der gewählte Laufwerkstyp unterstützt folgende Funktionen:
 preferences.volume.feature.mountAuto=Automatische Einhängepunkt Auswahl

+ 2 - 1
src/main/resources/i18n/strings_el.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Εμφάνιση κουμπιού ελ
 preferences.interface.showTrayIcon=Εμφάνιση εικονιδίου tray (απαιτεί επανεκκίνηση)
 ## Volume
 preferences.volume=Εικονικός δίσκος
-preferences.volume.type=Τύπος Τόμου (απαιτείται επανεκκίνηση)
+preferences.volume.type=Τύπος Τόμου
 preferences.volume.type.automatic=Αυτόματα
 preferences.volume.docsTooltip=Ανοίξτε τις οδηγίες για να μάθετε περισσότερα σχετικά με τους διαφορετικούς τύπους τόμων.
+preferences.volume.fuseRestartRequired=Για να εφαρμοστούν οι αλλαγές, πρέπει να γίνει επανεκκίνηση του Cryptomator.
 preferences.volume.tcp.port=Θύρα TCP
 preferences.volume.supportedFeatures=Ο επιλεγμένος τύπος τόμου υποστηρίζει τις ακόλουθες δυνατότητες:
 preferences.volume.feature.mountAuto=Αυτόματη επιλογή σημείου προσάρτησης

+ 2 - 1
src/main/resources/i18n/strings_es.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Mostrar botón minimizar
 preferences.interface.showTrayIcon=Mostrar ícono de bandeja (requiere reiniciar)
 ## Volume
 preferences.volume=Unidad virtual
-preferences.volume.type=Tipo de volumen (requiere reiniciar)
+preferences.volume.type=Tipo de volumen
 preferences.volume.type.automatic=Automático
 preferences.volume.docsTooltip=Abra la documentación para saber más sobre los diferentes tipos de volumen.
+preferences.volume.fuseRestartRequired=Para aplicar los cambios, Cryptomator necesita ser reiniciado.
 preferences.volume.tcp.port=Puerto TCP
 preferences.volume.supportedFeatures=El tipo de volumen elegido admite las siguientes funciones:
 preferences.volume.feature.mountAuto=Selección automática del punto de montaje

+ 2 - 1
src/main/resources/i18n/strings_fr.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Afficher le bouton Réduire
 preferences.interface.showTrayIcon=Montrer l'icône de service (redémarrage nécessaire)
 ## Volume
 preferences.volume=Disque virtuel
-preferences.volume.type=Type de volume (redémarrage requis)
+preferences.volume.type=Type de volume
 preferences.volume.type.automatic=Automatique
 preferences.volume.docsTooltip=Consultez la documentation pour en savoir plus sur les différents types de volumes.
+preferences.volume.fuseRestartRequired=Pour appliquer les modifications, Cryptomator doit être redémarré.
 preferences.volume.tcp.port=Port TCP
 preferences.volume.supportedFeatures=Le type de volume choisi prend en charge les fonctionnalités suivantes :
 preferences.volume.feature.mountAuto=Sélection automatique du point de montage

+ 0 - 1
src/main/resources/i18n/strings_he.properties

@@ -274,7 +274,6 @@ preferences.interface.showMinimizeButton=הצג כפתור מזעור
 preferences.interface.showTrayIcon=הצג צלמית בשורה מטה (דורש הפעלה מחדש)
 ## Volume
 preferences.volume=כונן וירטואלי
-preferences.volume.type=סוג volume (דורש הפעלה מחדש)
 preferences.volume.type.automatic=אוטומטי
 preferences.volume.docsTooltip=בכדי ללמוד עוד על סוגי volume ניתן לקרוא את הדוקומנטציה.
 preferences.volume.tcp.port=פורט TCP

+ 23 - 0
src/main/resources/i18n/strings_hu.properties

@@ -53,6 +53,9 @@ addvaultwizard.new.fileAlreadyExists=Már létezik fájl/könyvtár ezzel a trez
 addvaultwizard.new.locationDoesNotExist=A megadott elérési úton lévő könyvtár nem létezik, vagy nem érhető el
 addvaultwizard.new.locationIsNotWritable=Nincs írási hozzáférés a megadott elérési úthoz
 addvaultwizard.new.locationIsOk=Megfelelő hely a trezornak
+addvaultwizard.new.invalidName=Érvénytelen vault név
+addvaultwizard.new.validName=Érvényes vault név
+addvaultwizard.new.validCharacters.message=A vault neve a következő karaktereket tartalmazhatja:
 ### Password
 addvaultwizard.new.createVaultBtn=Új széf létrehozása
 addvaultwizard.new.generateRecoveryKeyChoice=Nem fog tudni hozzáférni az adataihoz a jelszó nélkül. Akar egy visszaállítási kulcsot arra az esetre, ha elveszíti a jelszavát?
@@ -79,12 +82,14 @@ addvault.new.readme.accessLocation.4=Bátran eltávolíthatja ezt a fájlt.
 addvaultwizard.existing.instruction=Válassza ki a "vault.cryptomatotor" fájlt a meglévő tárolóhoz. Ha csak egy "masterkey.cryptomatotor" nevű fájl létezik, válassza azt.
 addvaultwizard.existing.chooseBtn=Kiválaszt…
 addvaultwizard.existing.filePickerTitle=Trezor fájl kiválasztása
+addvaultwizard.existing.filePickerMimeDesc=Cryptomator széf
 ## Success
 addvaultwizard.success.nextStepsInstructions=Széf létrehozva "%s".\nA tartalom eléréséhez, vagy hozzáadásához fel kell oldania a széfet. Alternatív megoldásként később bármikor feloldhatja.
 addvaultwizard.success.unlockNow=Azonnali feloldás
 
 # Remove Vault
 removeVault.title=Széf eltávolitása
+removeVault.message=Vault eltávolitása?
 removeVault.description=Ez kizárolag a Cryptomator-ból távolitja el ezt a széfet. Később hozzáadhatja újra. A titkosított fájlokat nem törli a merevlemezről.
 removeVault.confirmBtn=Széf eltávolitása
 
@@ -95,6 +100,7 @@ changepassword.finalConfirmation=Megértettem, hogy nem fogok hozzáférni az ad
 
 # Forget Password
 forgetPassword.title=Jelszó elfelejtése
+forgetPassword.message=Elfelejtette az elmentett jelszót?
 forgetPassword.description=Eltávolítja a széf mentett jelszavát a rendszere kulcstartójából.
 forgetPassword.confirmBtn=Jelszó elfelejtése
 
@@ -107,18 +113,23 @@ unlock.unlockBtn=Feloldás
 unlock.chooseMasterkey.description=Nem található a tároló kulcsfájlja a várt helyen. Kérjük válassza ki a kulcsfájlt manuálisan.
 unlock.chooseMasterkey.filePickerTitle=Mesterkulcs fájl kiválasztása
 ## Success
+unlock.success.message=Sikeres feloldás
 unlock.success.description="%s" sikreresen feloldásra került! Mostmár hozzáférhet a virtuális trezorhoz.
 unlock.success.rememberChoice=Jegyezze meg a választást és ne mutassa többet
 unlock.success.revealBtn=Széf megjelenítése
 ## Failure
 ## Hub
+hub.noKeychain.openBtn=Beállítások megnyitása
 ### Waiting
 ### Receive Key
+hub.receive.message=Válasz feldolgozása…
 ### Register Device
+hub.register.nameLabel=Készülék neve
 hub.register.occupiedMsg=Ez a név már használatban van
 hub.register.registerBtn=Megerősítés
 ### Registration Success
 ### Registration Failed
+hub.registerFailed.message=Az eszköz elnevezése sikertelen volt
 ### Unauthorized
 ### License Exceeded
 
@@ -136,6 +147,7 @@ lock.fail.description=A "%s" tárolót nem lehetett zárolni. Győződjön meg a
 migration.title=Széf frissítése
 ## Start
 migration.start.header=Széf frissítése
+migration.start.remarkUndone=Ezt a módosítást nem lehet visszafordítani.
 migration.start.confirm=Elolvastam és megértettem a fenti információkat
 ## Run
 migration.run.enterPassword=Írja be a jelszót a következőhöz Enter the password for "%s"
@@ -184,8 +196,19 @@ health.check.detail.checkFinished=Az ellenőrzés sikeresen véget ért.
 health.check.detail.checkFinishedAndFound=Az ellenőrzés véget ért. Kérem ellenőrizze az eredményét.
 health.check.detail.checkFailed=Az ellenőrzés egy hiba miatt megszakadt.
 health.check.detail.checkCancelled=Az ellenőrzés meg lett szakítva.
+health.check.detail.listFilters.label=Szűrő
+health.check.detail.fixAllSpecificBtn=Az összes ilyen javítása
 health.check.exportBtn=Jelentés exportálása
 ## Result view
+health.result.severityFilter.all=Súlyosság - Összes
+health.result.severityFilter.good=Rendben
+health.result.severityFilter.info=Infó
+health.result.severityFilter.warn=Figyelmeztetés
+health.result.severityFilter.crit=Kritikus
+health.result.fixStateFilter.fixable=Javítható
+health.result.fixStateFilter.notFixable=Nem javítható
+health.result.fixStateFilter.fixing=Javítás alatt…
+health.result.fixStateFilter.fixed=Kijavított
 ## Fix Application
 health.fix.fixBtn=Javítás
 health.fix.successTip=Javítás sikeres

+ 7 - 1
src/main/resources/i18n/strings_it.properties

@@ -154,6 +154,8 @@ hub.registerFailed.description=Si è verificato un errore nel processo di nomina
 hub.unauthorized.message=Accesso negato
 hub.unauthorized.description=Il tuo dispositivo non è ancora stato autorizzato ad accedere a questa cassaforte. Chiedi al proprietario della cassaforte di autorizzarlo.
 ### License Exceeded
+hub.invalidLicense.message=Licenza Hub non valida
+hub.invalidLicense.description=La tua istanza Cryptomator Hub ha una licenza non valida. Si prega di informare un amministratore Hub per aggiornare o rinnovare la licenza.
 
 # Lock
 ## Force
@@ -272,8 +274,10 @@ preferences.interface.showMinimizeButton=Mostra il pulsante minimizza
 preferences.interface.showTrayIcon=Mostra l'icona della barra d'applicazioni (richiede il riavvio)
 ## Volume
 preferences.volume=Unità Virtuale
-preferences.volume.type=Tipo di volume (richiede riavvio)
+preferences.volume.type=Tipo di Volume
 preferences.volume.type.automatic=Automatico
+preferences.volume.docsTooltip=Aprire la documentazione per saperne di più sui diversi tipi di volume.
+preferences.volume.fuseRestartRequired=Per applicare le modifiche, Cryptomator deve essere riavviato.
 preferences.volume.tcp.port=Porta TCP
 preferences.volume.supportedFeatures=Il tipo di volume scelto supporta le seguenti caratteristiche:
 preferences.volume.feature.mountAuto=Selezione automatica del punto di montaggio
@@ -443,6 +447,8 @@ recoveryKey.display.StorageHints=Mantienilo da qualche parte molto sicuro, ad es
 recoveryKey.recover.title=Reimposta Password
 recoveryKey.recover.prompt=Inserisci la tua chiave di recupero per "%s":
 recoveryKey.recover.correctKey=Questa è una chiave di recupero valida
+recoveryKey.recover.wrongKey=Questa chiave di recupero appartiene ad una cassaforte diversa
+recoveryKey.recover.invalidKey=Questa chiave di recupero non é valida
 recoveryKey.printout.heading=Chiave di recupero Cryptomator\n"%s"\n
 ### Reset Password
 recoveryKey.recover.resetBtn=Reimposta

+ 19 - 11
src/main/resources/i18n/strings_ja.properties

@@ -125,8 +125,8 @@ unlock.success.revealBtn=ドライブを表示
 ## Failure
 unlock.error.customPath.message=カスタム パスに金庫をマウントできません
 unlock.error.customPath.description.notSupported=カスタム パスを使い続けたい場合、環境設定に移動してサポートしているボリューム タイプを選択してください。もしくは、金庫のオプションに移動してサポートされるマウント ポイントを選択してください。
-unlock.error.customPath.description.notExists=カスタム マウント パスが存在していません。ローカル ファイルシステムで作成するか、金庫のオプションで変更を加えてください。
-unlock.error.customPath.description.generic=この金庫のカスタム・マウント・パスを選択しましたが、その使用は次のメッセージで失敗しました: %s
+unlock.error.customPath.description.notExists=カスタム マウント パスが存在していません。ローカル ファイルシステムで作成するか、金庫のオプションで変更てください。
+unlock.error.customPath.description.generic=この金庫のカスタム マウント パスを選択しましたが、次のメッセージで失敗しました: %s
 ## Hub
 hub.noKeychain.message=デバイス キーにアクセスできません
 hub.noKeychain.description=ハブ金庫を解錠するには、キーチェーンが保護するデバイス キーが必要です。続行するには、"%s" を有効にし環境設定からキーチェーンを選択します。
@@ -154,8 +154,8 @@ hub.registerFailed.description=デバイス名登録中にエラーが発生し
 hub.unauthorized.message=アクセスが拒否されました
 hub.unauthorized.description=お使いのデバイスはまだこの金庫にアクセスする権限がありません。金庫のオーナーに権限を与えてもらってください。
 ### License Exceeded
-hub.invalidLicense.message=ハブライセンスが無効です
-hub.invalidLicense.description=Cryptomator ハブインスタンスに無効なライセンスがあります。ライセンスをアップグレードまたは更新するには、ハブ管理者に連絡してください。
+hub.invalidLicense.message=Hub のライセンスが無効です
+hub.invalidLicense.description=Cryptomator Hub インスタンスのライセンスが無効です。ライセンスをアップグレードまたは更新するには、Hub の管理者にご連絡ください。
 
 # Lock
 ## Force
@@ -171,10 +171,10 @@ lock.fail.description=金庫 "%s" を施錠できませんでした。保存さ
 migration.title=金庫をアップグレード
 ## Start
 migration.start.header=金庫をアップグレード
-migration.start.text=Cryptomatorのこの新しいバージョンであなたの金庫「%s」を開くには、金庫を新しい形式にアップグレードする必要があります。これを行う前に、次のことを知っておく必要があります:
+migration.start.text=この新しいバージョンの Cryptomator 内で金庫 "%s" を開くには、金庫を新しい形式にアップグレードする必要があります。この操作を行う前に、次のことにご注意ください:
 migration.start.remarkUndone=このアップグレードは取り消すことができません。
-migration.start.remarkVersions=古い Cryptomator では、アップグレードされた金庫を開くことができなくなります。
-migration.start.remarkCanRun=あなたが金庫にアクセスするすべてのデバイスは、Cryptomatorのこのバージョンを実行できることを確認する必要があります。
+migration.start.remarkVersions=古い Cryptomator では、アップグレードた金庫を開くことができなくなります。
+migration.start.remarkCanRun=金庫にアクセスするすべてのデバイスがこのバージョンの Cryptomator を実行できることを確認する必要があります。
 migration.start.remarkSynced=アップグレードする前に、このデバイスと他のデバイスで、金庫が完全に同期されていることを確認する必要があります。
 migration.start.confirm=上記の情報を理解しました。
 ## Run
@@ -274,14 +274,15 @@ preferences.interface.showMinimizeButton=最小化ボタンを表示
 preferences.interface.showTrayIcon=トレイアイコンを表示 (再起動が必要)
 ## Volume
 preferences.volume=仮想ドライブ
-preferences.volume.type=ボリューム タイプ (再起動が必要)
+preferences.volume.type=ボリュームの種類
 preferences.volume.type.automatic=自動
 preferences.volume.docsTooltip=異なるボリュームタイプの詳細については、ドキュメントを確認してください。
+preferences.volume.fuseRestartRequired=変更を適用するには、Cryptomator を再起動する必要があります。
 preferences.volume.tcp.port=TCP ポート
-preferences.volume.supportedFeatures=選択されたボリュームタイプは、以下の機能をサポートしています。
+preferences.volume.supportedFeatures=選択したボリューム形式は、次の機能をサポートしています:
 preferences.volume.feature.mountAuto=マウント先の自動選択
-preferences.volume.feature.mountToDir=カスタムディレクトリをマウント先に指定
-preferences.volume.feature.mountToDriveLetter=ドライブレターをマウント先に指定
+preferences.volume.feature.mountToDir=カスタム ディレクトリをマウント先に指定
+preferences.volume.feature.mountToDriveLetter=ドライブ レターをマウント先に指定
 preferences.volume.feature.mountFlags=カスタム マウント オプション
 preferences.volume.feature.readOnly=読み取り専用マウント
 ## Updates
@@ -306,21 +307,27 @@ stats.title=%s の統計情報
 stats.cacheHitRate=キャッシュ ヒット率
 ## Read
 stats.read.throughput.idle=読み取り: アイドル状態
+stats.read.throughput.kibs=読み取り: %.2f KiB/s
 stats.read.throughput.mibs=読み取り: %.2f MiB/s
 stats.read.total.data.none=データ読み取り: -
+stats.read.total.data.kib=データ読み取り: %.1f KiB
 stats.read.total.data.mib=データ読み取り: %.1f MiB
 stats.read.total.data.gib=データ読み取り: %.1f GiB
 stats.decr.total.data.none=復号済みデータ: -
+stats.decr.total.data.kib=復号済みデータ: %.1f KiB
 stats.decr.total.data.mib=復号済みデータ: %.1f MiB
 stats.decr.total.data.gib=復号済みデータ: %.1f GiB
 stats.read.accessCount=合計読み取り: %d
 ## Write
 stats.write.throughput.idle=書き込み: アイドル状態
+stats.write.throughput.kibs=書き込み: %.2f KiB/s
 stats.write.throughput.mibs=書き込み: %.2f MiB/s
 stats.write.total.data.none=書き込み済みデータ: -
+stats.write.total.data.kib=書き込み済みデータ: %.1f KiB
 stats.write.total.data.mib=書き込み済みデータ: %.1f MiB
 stats.write.total.data.gib=書き込み済みデータ: %.1f GiB
 stats.encr.total.data.none=暗号化済みデータ: -
+stats.encr.total.data.kib=暗号化済みデータ: %.1f KiB
 stats.encr.total.data.mib=暗号化済みデータ: %.1f MiB
 stats.encr.total.data.gib=暗号化済みデータ: %.1f GiB
 stats.write.accessCount=合計書き込み: %d
@@ -363,6 +370,7 @@ main.vaultDetail.lockBtn=施錠
 main.vaultDetail.bytesPerSecondRead=読み取り:
 main.vaultDetail.bytesPerSecondWritten=書き込み:
 main.vaultDetail.throughput.idle=アイドル
+main.vaultDetail.throughput.kbps=%.1f KiB/s
 main.vaultDetail.throughput.mbps=%.1f MiB/s
 main.vaultDetail.stats=金庫の統計情報
 main.vaultDetail.locateEncryptedFileBtn=暗号化されたファイルの場所

+ 0 - 1
src/main/resources/i18n/strings_nb.properties

@@ -274,7 +274,6 @@ preferences.interface.showMinimizeButton=Vis minimer-knapp
 preferences.interface.showTrayIcon=Vis verktøykasseikon (krever omstart)
 ## Volume
 preferences.volume=Virtuell enhet
-preferences.volume.type=Volumtype (krever omstart)
 preferences.volume.type.automatic=Automatisk
 preferences.volume.docsTooltip=Åpne dokumentasjonen for å lære mer om de forskjellige volumtypene.
 preferences.volume.tcp.port=TCP Port

+ 2 - 1
src/main/resources/i18n/strings_nl.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Knop minimaliseren weergeven
 preferences.interface.showTrayIcon=Pictogram in systeemvak weergeven (herstart vereist)
 ## Volume
 preferences.volume=Virtuele schijf
-preferences.volume.type=Type Volume (herstart vereist)
+preferences.volume.type=Type volume
 preferences.volume.type.automatic=Automatisch
 preferences.volume.docsTooltip=Open de documentatie om meer te weten te komen over de verschillende volume types.
+preferences.volume.fuseRestartRequired=Om de wijzigingen toe te passen, moet Cryptomator opnieuw worden gestart.
 preferences.volume.tcp.port=TCP-poort
 preferences.volume.supportedFeatures=Het gekozen volume type ondersteunt de volgende functies:
 preferences.volume.feature.mountAuto=Automatische koppelpunt selectie

+ 7 - 1
src/main/resources/i18n/strings_pl.properties

@@ -274,7 +274,6 @@ preferences.interface.showMinimizeButton=Pokaż przycisk minimalizacji
 preferences.interface.showTrayIcon=Pokaż ikonę zasobnika (wymaga restartu)
 ## Volume
 preferences.volume=Dysk wirtualny
-preferences.volume.type=Typ udziału (wymaga ponownego uruchomienia)
 preferences.volume.type.automatic=Automatyczny
 preferences.volume.docsTooltip=Sprawdź dokumentację, aby dowiedzieć się więcej o różnych typach udziałów.
 preferences.volume.tcp.port=Port TCP
@@ -306,21 +305,27 @@ stats.title=Statystyki dla %s
 stats.cacheHitRate=Trafność cache
 ## Read
 stats.read.throughput.idle=Odczyt: bezczynny
+stats.read.throughput.kibs=Odczyt: %.2f kiB/s
 stats.read.throughput.mibs=Odczyt: %.2f kiB/s
 stats.read.total.data.none=Dane odczytywane: -
+stats.read.total.data.kib=Odczyt danych: %.1f KiB
 stats.read.total.data.mib=Odczyt danych: %.1f kiB
 stats.read.total.data.gib=Odczyt danych: %.1f kiB
 stats.decr.total.data.none=Dane odszyfrowane: -
+stats.decr.total.data.kib=Dane odszyfrowane: %.1f KiB
 stats.decr.total.data.mib=Dane odszyfrowane: %.1f kiB
 stats.decr.total.data.gib=Dane odszyfrowane: %.1f kiB
 stats.read.accessCount=Całkowite odczyty: %d
 ## Write
 stats.write.throughput.idle=Zapis: bezczynny
+stats.write.throughput.kibs=Zapis: %.2f KiB/s
 stats.write.throughput.mibs=Zapis: %.2f kiB/s
 stats.write.total.data.none=Zapisane dane: -
+stats.write.total.data.kib=Zapis danych: %.1f KiB
 stats.write.total.data.mib=Zapisane dane: %.1f MiB
 stats.write.total.data.gib=Zapisane dane: %.1f kiB
 stats.encr.total.data.none=Dane odszyfrowane: -
+stats.encr.total.data.kib=Dane zaszyfrowane: %.1f KiB
 stats.encr.total.data.mib=Dane odszyfrowane: %.1f kiB
 stats.encr.total.data.gib=Dane odszyfrowane: %.1f kiB
 stats.write.accessCount=Całkowity zapis: %d
@@ -363,6 +368,7 @@ main.vaultDetail.lockBtn=Blokuj
 main.vaultDetail.bytesPerSecondRead=Odczyt:
 main.vaultDetail.bytesPerSecondWritten=Zapisz:
 main.vaultDetail.throughput.idle=bezczynny
+main.vaultDetail.throughput.kbps=%.1f KiB/s
 main.vaultDetail.throughput.mbps=%.1f MiB/s
 main.vaultDetail.stats=Statystyki sejfu
 main.vaultDetail.locateEncryptedFileBtn=Zlokalizuj zaszyfrowany plik

+ 80 - 1
src/main/resources/i18n/strings_pt.properties

@@ -217,6 +217,7 @@ health.check.detail.checkFinishedAndFound=A verificação concluiu. Por favor, r
 health.check.detail.listFilters.label=Filtro
 health.check.exportBtn=Exportar relatórios
 ## Result view
+health.result.severityFilter.all=Gravidade - Todos
 health.result.severityFilter.good=Ótimo
 health.result.severityFilter.info=Informações
 health.result.severityFilter.warn=Atenção
@@ -262,15 +263,35 @@ preferences.about=Sobre
 # Vault Statistics
 stats.title=Estatísticas de %s
 ## Read
+stats.decr.total.data.none=Dados desencriptados: -
+stats.decr.total.data.kib=Dados desencriptados: %.1f KiB
+stats.decr.total.data.mib=Dados desencriptados: %.1f MiB
+stats.decr.total.data.gib=Dados desencriptados: %.1f GiB
+stats.read.accessCount=Total de leituras: %d
 ## Write
+stats.write.throughput.idle=Escrever: em pausa
+stats.write.throughput.kibs=Escrever: %.2f KiB/s
+stats.write.throughput.mibs=Escrever: %.2f MiB/s
+stats.write.total.data.none=Dados gravados: -
+stats.write.total.data.kib=Dados gravados: %.1f KiB
+stats.write.total.data.mib=Dados gravados: %.1f MiB
+stats.write.total.data.gib=Dados gravados: %.1f GiB
+stats.encr.total.data.none=Dados encriptados: -
+stats.encr.total.data.kib=Dados encriptados: %.1f KiB
+stats.encr.total.data.mib=Dados encriptados: %.1f MiB
+stats.encr.total.data.gib=Dados encriptados: %.1f GiB
+stats.write.accessCount=Total de escritas: %d
 
 ## Accesses
+stats.access.current=Acesso: %d
+stats.access.total=Total de acessos: %d
 
 
 # Main Window
 main.closeBtn.tooltip=Fechar
 main.minimizeBtn.tooltip=Minimizar
 main.preferencesBtn.tooltip=Preferências
+main.debugModeEnabled.tooltip=Modo de depuração está ativado
 main.supporterCertificateMissing.tooltip=Por favor, considere doar
 ## Vault List
 main.vaultlist.emptyList.onboardingInstruction=Clique aqui para adicionar um cofre
@@ -278,10 +299,12 @@ main.vaultlist.contextMenu.remove=Remover…
 main.vaultlist.contextMenu.lock=Trancar
 main.vaultlist.contextMenu.unlock=Desbloquear…
 main.vaultlist.contextMenu.unlockNow=Destrancar agora
+main.vaultlist.contextMenu.vaultoptions=Mostrar opções do Cofre
 main.vaultlist.contextMenu.reveal=Revelar unidade
 main.vaultlist.addVaultBtn=Adicionar Cofre
 ## Vault Detail
 ### Welcome
+main.vaultDetail.welcomeOnboarding=Obrigado por escolher Cryptomator para proteger os seus ficheiros. Se precisar de alguma ajuda, veja os nossos guias introdutórios:
 ### Locked
 main.vaultDetail.lockedStatus=BLOQUEADO
 main.vaultDetail.unlockBtn=Desbloquear…
@@ -292,24 +315,38 @@ main.vaultDetail.passwordSavedInKeychain=Palavra-passe guardada
 main.vaultDetail.unlockedStatus=DESBLOQUEADO
 main.vaultDetail.accessLocation=O conteúdo do seu cofre está acessível aqui:
 main.vaultDetail.revealBtn=Revelar unidade
+main.vaultDetail.copyUri=Copiar endereço
 main.vaultDetail.lockBtn=Trancar
+main.vaultDetail.bytesPerSecondRead=Ler:
+main.vaultDetail.bytesPerSecondWritten=Escrever:
 main.vaultDetail.throughput.idle=inativo
+main.vaultDetail.throughput.kbps=%.1f KiB/s
 main.vaultDetail.throughput.mbps=%.1f MiB/s
+main.vaultDetail.stats=Estatísticas do Cofre
 main.vaultDetail.locateEncryptedFileBtn=Localizar Ficheiro Encriptado
 main.vaultDetail.locateEncryptedFileBtn.tooltip=Escolha um ficheiro do seu cofre para localizar a sua contraparte encriptada
 main.vaultDetail.encryptedPathsCopied=Caminhos copiados para a área de transferência!
 main.vaultDetail.filePickerTitle=Selecione o ficheiro no cofre
 ### Missing
 main.vaultDetail.missing.info=O Cryptomator não conseguiu encontrar um cofre neste diretório.
+main.vaultDetail.missing.recheck=Verificar novamente
+main.vaultDetail.missing.remove=Remover da Lista de Cofres…
+main.vaultDetail.missing.changeLocation=Mudar localização do Cofre…
 ### Needs Migration
 main.vaultDetail.migrateButton=Atualizar Cofre
 main.vaultDetail.migratePrompt=O cofre precisa de ser atualizado para um novo formato, antes que possa acessá-lo
 ### Error
+main.vaultDetail.error.info=Ocorreu um erro a carregar o cofre do disco.
+main.vaultDetail.error.reload=Recarregar
+main.vaultDetail.error.windowTitle=Erro a carregar o cofre
 
 # Wrong File Alert
 wrongFileAlert.title=Como criptografar arquivos
 wrongFileAlert.message=Você tentou criptografar esses arquivos?
+wrongFileAlert.description=Para isso, o Cryptomator fornece um volume no gestor de ficheiros do seu sistema.
+wrongFileAlert.instruction.0=Para encriptar ficheiros, siga estes passos:
 wrongFileAlert.instruction.1=1. Desbloqueie o seu cofre.
+wrongFileAlert.instruction.2=2. Clique em "Revelar" para abrir o volume no seu gestor de ficheiros.
 wrongFileAlert.instruction.3=3. Adicione ficheiros a este volume.
 wrongFileAlert.link=Para obter assistência, visite
 
@@ -317,34 +354,76 @@ wrongFileAlert.link=Para obter assistência, visite
 ## General
 vaultOptions.general=Geral
 vaultOptions.general.vaultName=Nome do Cofre
+vaultOptions.general.autoLock.lockAfterTimePart1=Bloquear quando inativo por
+vaultOptions.general.autoLock.lockAfterTimePart2=minutos
 vaultOptions.general.unlockAfterStartup=Destrancar o cofre ao iniciar o Cryptomator
 vaultOptions.general.actionAfterUnlock=Após destrancar com sucesso
+vaultOptions.general.actionAfterUnlock.ignore=Não fazer nada
 vaultOptions.general.actionAfterUnlock.reveal=Revelar unidade
 vaultOptions.general.actionAfterUnlock.ask=Perguntar
+vaultOptions.general.startHealthCheckBtn=Verificar Saúde
 
 ## Mount
+vaultOptions.mount=Montar
+vaultOptions.mount.info=Opções dependem do tipo de volume selecionado.
+vaultOptions.mount.linkToPreferences=Abrir preferências da Unidade Virtual
 vaultOptions.mount.readonly=Somente leitura
+vaultOptions.mount.winDriveLetterOccupied=ocupado
+vaultOptions.mount.mountPoint=Ponto de montagem
+vaultOptions.mount.mountPoint.auto=Escolher automaticamente um local adequado
+vaultOptions.mount.mountPoint.driveLetter=Use a letra da unidade atribuída
+vaultOptions.mount.mountPoint.custom=Usar diretório escolhido
 vaultOptions.mount.mountPoint.directoryPickerButton=Escolher…
+vaultOptions.mount.mountPoint.directoryPickerTitle=Escolher um diretório
 ## Master Key
 vaultOptions.masterkey=Senha
 vaultOptions.masterkey.changePasswordBtn=Alterar Senha
 vaultOptions.masterkey.forgetSavedPasswordBtn=Esqueça a senha salva
 vaultOptions.masterkey.recoveryKeyExplanation=Uma chave de recuperação é a única forma de restaurar o acesso a um cofre se perder a senha.
 vaultOptions.masterkey.showRecoveryKeyBtn=Exibir Chave de Recuperação
+vaultOptions.masterkey.recoverPasswordBtn=Redefinir palavra-passe
 
 
 # Recovery Key
 ## Display Recovery Key
+recoveryKey.display.title=Mostrar chave de recuperação
+recoveryKey.create.message=Palavra-passe necessária
+recoveryKey.create.description=Inserir a palavra passe de "%s" para mostrar a chave de recuperação.
+recoveryKey.display.description=Esta chave de recuperação pode ser usada para restaurar acesso a "%s":
+recoveryKey.display.StorageHints=Guarde-a num lugar muito seguro, por exemplo:\n • Armazená-la usando um gerenciador de senhas\n • Guarde-a numa ‘pen’ USB\n • Imprima-a em papel
 ## Reset Password
 ### Enter Recovery Key
+recoveryKey.recover.title=Redefinir palavra-passe
+recoveryKey.recover.prompt=Insira a chave de recuperação para "%s":
+recoveryKey.recover.correctKey=Esta chave de recuperação está certa
+recoveryKey.recover.wrongKey=Esta chave de recuperação pertence a um cofre diferente
+recoveryKey.recover.invalidKey=Esta chave de recupreação não está certa
+recoveryKey.printout.heading=A chave de recuperação do Cryptomator \n"%s"\n
 ### Reset Password
+recoveryKey.recover.resetBtn=Repor
 ### Recovery Key Password Reset Success
+recoveryKey.recover.resetSuccess.message=Palavra-passe redefinida com sucesso
+recoveryKey.recover.resetSuccess.description=Você pode desbloquear o seu cofre com a nova senha.
 
 # New Password
+newPassword.promptText=Inserir uma nova palavra-passe
+newPassword.reenterPassword=Confirme a nova palavra-passe
+newPassword.passwordsMatch=As palavras-passe são iguais!
+newPassword.passwordsDoNotMatch=As palavras-passe não são iguais
+passwordStrength.messageLabel.tooShort=Use pelo menos %d caracteres
+passwordStrength.messageLabel.0=Muito fraca
+passwordStrength.messageLabel.1=Fraca
+passwordStrength.messageLabel.2=Razoável
 passwordStrength.messageLabel.3=Forte
 passwordStrength.messageLabel.4=Muito forte
 
 # Quit
+quit.title=Sair da aplicação
+quit.message=Existem cofres desbloqueados
+quit.description=Por favor, confirme que deseja sair. O Cryptomator irá fechar graciosamente todos os cofres desbloqueados para evitar a perda de dados.
 quit.lockAndQuitBtn=Bloquear e Sair
 
-# Forced Quit
+# Forced Quit
+quit.forced.message=Alguns cofres não poderam ser fechados
+quit.forced.description=Bloquear os cofres foi impossibilitado por operações pendentes ou ficheiros abertos. Poderá forçar o bloqueio dos cofres restantes, sob a possibilidade da perda de dados não guardados.
+quit.forced.forceAndQuitBtn=Forçar e Sair

+ 0 - 1
src/main/resources/i18n/strings_pt_BR.properties

@@ -272,7 +272,6 @@ preferences.interface.showMinimizeButton=Mostrar botão minimizar
 preferences.interface.showTrayIcon=Mostrar ícone na barra do sistema (requer reinicialização)
 ## Volume
 preferences.volume=Volume Virtual
-preferences.volume.type=Tipo de Volume (requer reinicialização)
 preferences.volume.type.automatic=Automático
 preferences.volume.tcp.port=Porta TCP
 preferences.volume.supportedFeatures=O tipo de volume escolhido suporta os seguintes recursos:

+ 0 - 1
src/main/resources/i18n/strings_ro.properties

@@ -272,7 +272,6 @@ preferences.interface.showMinimizeButton=Arată butonul de minimizare
 preferences.interface.showTrayIcon=Arată tray icon (necesită repornire)
 ## Volume
 preferences.volume=Unitate virtuală
-preferences.volume.type=Tip unitate de stocare (necesită repornire)
 preferences.volume.type.automatic=Automat
 preferences.volume.docsTooltip=Deschideți documentația pentru a afla mai multe despre tipurile diferite de unități de stocare.
 preferences.volume.tcp.port=Portul TCP

+ 2 - 1
src/main/resources/i18n/strings_ru.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Показывать кнопку св
 preferences.interface.showTrayIcon=Показывать значок в панели задач (требуется перезапуск)
 ## Volume
 preferences.volume=Виртуальный диск
-preferences.volume.type=Тип тома (требуется перезапуск)
+preferences.volume.type=Тип тома
 preferences.volume.type.automatic=Автоматически
 preferences.volume.docsTooltip=Откройте документацию, чтобы узнать больше о различных типах томов.
+preferences.volume.fuseRestartRequired=Для применения изменений необходимо перезапустить Cryptomator.
 preferences.volume.tcp.port=Порт TCP
 preferences.volume.supportedFeatures=Выбранный тип тома поддерживает следующие функции:
 preferences.volume.feature.mountAuto=Выбор точки автомонтирования

+ 2 - 1
src/main/resources/i18n/strings_sk.properties

@@ -272,9 +272,10 @@ preferences.interface.showMinimizeButton=Ukáž minimalizačné tlačidlo
 preferences.interface.showTrayIcon=Ukázať ikonu na sytémovej lište (vyžaduje reštart)
 ## Volume
 preferences.volume=Virtuálny disk
-preferences.volume.type=Typ oddielu (vyžaduje reštart)
+preferences.volume.type=Typ obsahu
 preferences.volume.type.automatic=Automaticky
 preferences.volume.docsTooltip=Pre viac informácií ohľadne iných typov volume otvorte dokumentáciu.
+preferences.volume.fuseRestartRequired=Pre aplikovanie zmien je potrebné Cryptomator reštartovať.
 preferences.volume.tcp.port=TCP port
 preferences.volume.supportedFeatures=Zvolený typ oddielu podporuje nasledovné funkcie:
 preferences.volume.feature.mountAuto=Automatická voľba bodu pripojenia

+ 2 - 1
src/main/resources/i18n/strings_sv.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Visa minimera-knapp
 preferences.interface.showTrayIcon=Visa ikon i aktivitetsfältet (kräver omstart)
 ## Volume
 preferences.volume=Virtuell enhet
-preferences.volume.type=Volymtyp (kräver omstart)
+preferences.volume.type=Volymtyp
 preferences.volume.type.automatic=Automatiskt
 preferences.volume.docsTooltip=Öppna dokumentationen för att läsa mer om de olika volymtyperna.
+preferences.volume.fuseRestartRequired=Cryptomator måste startas om för att tillämpa ändringarna.
 preferences.volume.tcp.port=TCP-port
 preferences.volume.supportedFeatures=Den valda volymtypen stöder följande funktioner:
 preferences.volume.feature.mountAuto=Automatiskt val av monteringspunkt

+ 1 - 1
src/main/resources/i18n/strings_sw.properties

@@ -274,7 +274,6 @@ preferences.interface.showMinimizeButton=Onyesha kitufe cha kupunguza
 preferences.interface.showTrayIcon=Onyesha ikoni ya trei (inahitaji kuanzisha upya)
 ## Volume
 preferences.volume=Kiendeshi pepe
-preferences.volume.type=Aina ya Sauti (inahitaji kuanzishwa upya)
 preferences.volume.type.automatic=Otomatiki
 preferences.volume.docsTooltip=Fungua hati ili kujifunza zaidi kuhusu aina tofauti za sauti.
 preferences.volume.tcp.port=Bandari ya TCP
@@ -283,6 +282,7 @@ preferences.volume.feature.mountAuto=Uchaguzi wa sehemu ya kupachika otomatiki
 preferences.volume.feature.mountToDir=Saraka maalum kama sehemu ya kupachika
 preferences.volume.feature.mountToDriveLetter=Endesha barua kama sehemu ya kupachika
 preferences.volume.feature.mountFlags=Chaguzi maalum za kupachika
+preferences.volume.feature.readOnly=Mlima wa kusoma pekee
 ## Updates
 preferences.updates=Sasishi
 preferences.updates.currentVersion=Toleo la Sasa: %s

+ 2 - 1
src/main/resources/i18n/strings_tr.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Küçültme düğmesini göster
 preferences.interface.showTrayIcon=Sistem tepsisi simgesini göster (Yeniden başlatma gerekir)
 ## Volume
 preferences.volume=Sanal Sürücü
-preferences.volume.type=Birim Türü (yeniden başlatma gerektirir)
+preferences.volume.type=Birim Türü
 preferences.volume.type.automatic=Otomatik
 preferences.volume.docsTooltip=Farklı birim türleri hakkında daha fazla bilgi edinmek için belgeleri açın.
+preferences.volume.fuseRestartRequired=Değişikliklerin uygulanması için Cryptomator uygulamasının yeniden başlatılması gerekmektedir.
 preferences.volume.tcp.port=TCP Portu
 preferences.volume.supportedFeatures=Seçilen birim türü aşağıdaki özellikleri destekler:
 preferences.volume.feature.mountAuto=Otomatik bağlama noktası seçimi

+ 2 - 1
src/main/resources/i18n/strings_zh.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=显示最小化按钮
 preferences.interface.showTrayIcon=显示托盘图标(需重启)
 ## Volume
 preferences.volume=虚拟磁盘
-preferences.volume.type=卷类型(需重启)
+preferences.volume.type=卷类型
 preferences.volume.type.automatic=自动
 preferences.volume.docsTooltip=打开文档以了解有关不同卷类型的更多信息
+preferences.volume.fuseRestartRequired=Cryptomator 需要重新启动以应用更改
 preferences.volume.tcp.port=TCP 端口
 preferences.volume.supportedFeatures=选定的卷类型支持以下功能:
 preferences.volume.feature.mountAuto=自动选择挂载点

+ 2 - 1
src/main/resources/i18n/strings_zh_HK.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=顯示最小化按鈕
 preferences.interface.showTrayIcon=顯示系統工作列圖示 (需重新啟動)
 ## Volume
 preferences.volume=虛擬磁碟
-preferences.volume.type=磁區類別(須重啟)
+preferences.volume.type=磁區類
 preferences.volume.type.automatic=自動
 preferences.volume.docsTooltip=閱讀文檔以了解各加密空間類型。
+preferences.volume.fuseRestartRequired=需要重新啟動 Cryptomator 以應用更改。
 preferences.volume.tcp.port=TCP 埠
 preferences.volume.supportedFeatures=所選擇的磁區空間類別支援下列功能:
 preferences.volume.feature.mountAuto=自動選擇掛載路徑

+ 2 - 1
src/main/resources/i18n/strings_zh_TW.properties

@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=顯示最小化按鈕
 preferences.interface.showTrayIcon=顯示系統工作列圖示 (需要重新啟動)
 ## Volume
 preferences.volume=虛擬磁碟
-preferences.volume.type=磁區類別 (須重啟)
+preferences.volume.type=磁區類
 preferences.volume.type.automatic=自动
 preferences.volume.docsTooltip=打開文檔以了解有關不同磁區類型更多信息。
+preferences.volume.fuseRestartRequired=需要重新啟動 Cryptomator以套用變更。
 preferences.volume.tcp.port=TCP 埠
 preferences.volume.supportedFeatures=所選擇的磁區空間類別支援下列功能:
 preferences.volume.feature.mountAuto=自動選擇掛載路徑