diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml
index 1ba5822e3..0d175fbf9 100644
--- a/.github/workflows/mac-dmg.yml
+++ b/.github/workflows/mac-dmg.yml
@@ -14,17 +14,28 @@ env:
jobs:
build:
- name: Build Cryptomator.app
- runs-on: macos-11
+ name: Build Cryptomator.app for ${{ matrix.output-suffix }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: true
+ matrix:
+ include:
+ - os: macos-11
+ architecture: x64
+ output-suffix: x64
+ - os: [self-hosted, macOS, ARM64]
+ architecture: aarch64
+ output-suffix: arm64
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Java
- uses: actions/setup-java@v2
+ uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ env.JAVA_VERSION }}
+ architecture: ${{ matrix.architecture }}
cache: 'maven'
- id: versions
name: Apply version information
@@ -186,7 +197,7 @@ jobs:
--icon ".background" 128 758
--icon ".fseventsd" 320 758
--icon ".VolumeIcon.icns" 512 758
- Cryptomator-${VERSION_NO}.dmg dmg
+ Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
env:
VERSION_NO: ${{ steps.versions.outputs.semVerNum }}
- name: Notarize .dmg
@@ -198,7 +209,7 @@ jobs:
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
+ run: mv Cryptomator-*.dmg Cryptomator-${{ steps.versions.outputs.semVerStr }}-${{ matrix.output-suffix }}.dmg
- name: Create detached GPG signature with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
@@ -213,7 +224,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
- name: dmg
+ name: dmg-${{ matrix.output-suffix }}
path: Cryptomator-*.dmg
if-no-files-found: error
- name: Publish dmg on GitHub Releases
@@ -225,5 +236,3 @@ jobs:
files: |
Cryptomator-*.dmg
Cryptomator-*.asc
-
-
diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml
index 48e9e61ff..91d967bf7 100644
--- a/.github/workflows/win-exe.yml
+++ b/.github/workflows/win-exe.yml
@@ -204,7 +204,7 @@ jobs:
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
+ $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
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 18be437d6..18e7c76e0 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -14,10 +14,10 @@
-
-
+
+
-
+
@@ -26,18 +26,18 @@
-
-
-
-
+
+
+
+
-
-
+
+
-
+
diff --git a/README.md b/README.md
index bfc5db571..0b72e2856 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,12 @@ Cryptomator is provided free of charge as an open-source project despite the hig
+### Special Shoutout
+
+Continuous integration hosting for ARM64 builds is provided by [MacStadium](https://www.macstadium.com/opensource).
+
+
+
---
## Introduction
@@ -86,7 +92,7 @@ For more information on the security details visit [cryptomator.org](https://doc
```
mvn clean install
-# or mvn clean install -Pwindows
+# or mvn clean install -Pwin
# or mvn clean install -Pmac
# or mvn clean install -Plinux
```
diff --git a/pom.xml b/pom.xml
index 151d7de69..09f5229ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0org.cryptomatorcryptomator
- 1.6.14
+ 1.6.15Cryptomator Desktop App
@@ -27,8 +27,8 @@
com.github.serceman,com.github.jnr,org.ow2.asm,net.java.dev.jna,org.apache.jackrabbit,org.apache.httpcomponents,de.swiesend,org.purejava,com.github.hypfvieh
- 2.1.0-beta3
- 2.4.2
+ 2.1.0-rc1
+ 2.4.41.1.01.1.21.1.2
@@ -39,27 +39,27 @@
3.12.0
- 2.41
+ 2.442.231.1-jre
- 2.9.0
- 18.0.1
+ 2.9.1
+ 18.0.24.0.0
- 9.23
- 1.4.0
- 2.0.0
+ 9.25.4
+ 1.4.3
+ 2.0.30.5.11.7.0
- 5.8.1
- 4.4.0
+ 5.9.1
+ 4.8.02.223.0.0
- 7.1.0
- 0.8.7
+ 7.2.1
+ 0.8.8
@@ -128,6 +128,14 @@
logback-core${logback.version}
+
+
+ jakarta.mail
+ jakarta.mail-api
+ 2.1.0
+ compile
+ true
+ ch.qos.logbacklogback-classic
@@ -263,7 +271,7 @@
org.apache.maven.pluginsmaven-resources-plugin
- 3.2.0
+ 3.3.0org.apache.maven.plugins
@@ -273,7 +281,7 @@
org.apache.maven.pluginsmaven-surefire-plugin
- 3.0.0-M5
+ 3.0.0-M7org.codehaus.mojo
@@ -283,7 +291,7 @@
org.apache.maven.pluginsmaven-jar-plugin
- 3.2.2
+ 3.3.0org.jacoco
@@ -319,7 +327,7 @@
org.codehaus.mojoexec-maven-plugin
- 3.0.0
+ 3.1.0compile-light-theme
diff --git a/src/main/java/org/cryptomator/common/keychain/KeychainModule.java b/src/main/java/org/cryptomator/common/keychain/KeychainModule.java
index 63749b445..604dfb40d 100644
--- a/src/main/java/org/cryptomator/common/keychain/KeychainModule.java
+++ b/src/main/java/org/cryptomator/common/keychain/KeychainModule.java
@@ -23,11 +23,14 @@ public class KeychainModule {
@Singleton
static ObjectExpression provideKeychainAccessProvider(Settings settings, List providers) {
return Bindings.createObjectBinding(() -> {
+ if (!settings.useKeychain().get()) {
+ return null;
+ }
var selectedProviderClass = settings.keychainProvider().get();
var selectedProvider = providers.stream().filter(provider -> provider.getClass().getName().equals(selectedProviderClass)).findAny();
var fallbackProvider = providers.stream().findFirst().orElse(null);
return selectedProvider.orElse(fallbackProvider);
- }, settings.keychainProvider());
+ }, settings.keychainProvider(), settings.useKeychain());
}
}
diff --git a/src/main/java/org/cryptomator/common/mountpoint/CustomMountPointChooser.java b/src/main/java/org/cryptomator/common/mountpoint/CustomMountPointChooser.java
index 60d7a3dc9..295e922c1 100644
--- a/src/main/java/org/cryptomator/common/mountpoint/CustomMountPointChooser.java
+++ b/src/main/java/org/cryptomator/common/mountpoint/CustomMountPointChooser.java
@@ -1,7 +1,6 @@
package org.cryptomator.common.mountpoint;
import org.apache.commons.lang3.SystemUtils;
-import org.cryptomator.common.Environment;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.common.vaults.MountPointRequirement;
@@ -19,7 +18,6 @@ import java.nio.file.NoSuchFileException;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.nio.file.attribute.BasicFileAttributes;
import java.util.Optional;
class CustomMountPointChooser implements MountPointChooser {
@@ -118,6 +116,7 @@ class CustomMountPointChooser implements MountPointChooser {
if (caller.getMountPointRequirement() == MountPointRequirement.PARENT_NO_MOUNT_POINT) {
Path hideaway = getHideaway(mountPoint);
try {
+ waitForMountpointRestoration(mountPoint);
Files.move(hideaway, mountPoint);
if (SystemUtils.IS_OS_WINDOWS) {
Files.setAttribute(mountPoint, WIN_HIDDEN, false);
@@ -128,6 +127,24 @@ class CustomMountPointChooser implements MountPointChooser {
}
}
+ //on Windows removing the mountpoint takes some time, so we poll for at most 3 seconds
+ private void waitForMountpointRestoration(Path mountPoint) throws FileAlreadyExistsException {
+ int attempts = 0;
+ while (!Files.notExists(mountPoint, LinkOption.NOFOLLOW_LINKS)) {
+ attempts++;
+ if (attempts >= 10) {
+ throw new FileAlreadyExistsException("Timeout waiting for mountpoint cleanup for " + mountPoint + " .");
+ }
+
+ try {
+ Thread.sleep(300);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new FileAlreadyExistsException("Interrupted before mountpoint " + mountPoint + " was cleared");
+ }
+ }
+ }
+
private void checkIsDirectory(Path toCheck) throws InvalidMountPointException {
if (!Files.isDirectory(toCheck, LinkOption.NOFOLLOW_LINKS)) {
throw new InvalidMountPointException(new NotDirectoryException(toCheck.toString()));
diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java
index 7e383bc18..94debddc2 100644
--- a/src/main/java/org/cryptomator/common/settings/Settings.java
+++ b/src/main/java/org/cryptomator/common/settings/Settings.java
@@ -33,6 +33,7 @@ public class Settings {
public static final boolean DEFAULT_CHECK_FOR_UPDATES = false;
public static final boolean DEFAULT_START_HIDDEN = false;
public static final boolean DEFAULT_AUTO_CLOSE_VAULTS = false;
+ public static final boolean DEFAULT_USE_KEYCHAIN = true;
public static final int DEFAULT_PORT = 42427;
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final WebDavUrlScheme DEFAULT_GVFS_SCHEME = WebDavUrlScheme.DAV;
@@ -53,6 +54,7 @@ public class Settings {
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UPDATES);
private final BooleanProperty startHidden = new SimpleBooleanProperty(DEFAULT_START_HIDDEN);
private final BooleanProperty autoCloseVaults = new SimpleBooleanProperty(DEFAULT_AUTO_CLOSE_VAULTS);
+ private final BooleanProperty useKeychain = new SimpleBooleanProperty(DEFAULT_USE_KEYCHAIN);
private final IntegerProperty port = new SimpleIntegerProperty(DEFAULT_PORT);
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
private final ObjectProperty preferredGvfsScheme = new SimpleObjectProperty<>(DEFAULT_GVFS_SCHEME);
@@ -85,6 +87,7 @@ public class Settings {
checkForUpdates.addListener(this::somethingChanged);
startHidden.addListener(this::somethingChanged);
autoCloseVaults.addListener(this::somethingChanged);
+ useKeychain.addListener(this::somethingChanged);
port.addListener(this::somethingChanged);
numTrayNotifications.addListener(this::somethingChanged);
preferredGvfsScheme.addListener(this::somethingChanged);
@@ -140,6 +143,8 @@ public class Settings {
return autoCloseVaults;
}
+ public BooleanProperty useKeychain() { return useKeychain; }
+
public IntegerProperty port() {
return port;
}
diff --git a/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java b/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java
index ff62672bd..03682b60c 100644
--- a/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java
+++ b/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java
@@ -50,6 +50,7 @@ public class SettingsJsonAdapter extends TypeAdapter {
out.name("theme").value(value.theme().get().name());
out.name("uiOrientation").value(value.userInterfaceOrientation().get().name());
out.name("keychainProvider").value(value.keychainProvider().get());
+ out.name("useKeychain").value(value.useKeychain().get());
out.name("licenseKey").value(value.licenseKey().get());
out.name("showMinimizeButton").value(value.showMinimizeButton().get());
out.name("showTrayIcon").value(value.showTrayIcon().get());
@@ -92,6 +93,7 @@ public class SettingsJsonAdapter extends TypeAdapter {
case "theme" -> settings.theme().set(parseUiTheme(in.nextString()));
case "uiOrientation" -> settings.userInterfaceOrientation().set(parseUiOrientation(in.nextString()));
case "keychainProvider" -> settings.keychainProvider().set(in.nextString());
+ case "useKeychain" -> settings.useKeychain().set(in.nextBoolean());
case "licenseKey" -> settings.licenseKey().set(in.nextString());
case "showMinimizeButton" -> settings.showMinimizeButton().set(in.nextBoolean());
case "showTrayIcon" -> settings.showTrayIcon().set(in.nextBoolean());
diff --git a/src/main/java/org/cryptomator/launcher/SupportedLanguages.java b/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
index ffff48a8a..760fb1168 100644
--- a/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
+++ b/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
@@ -15,9 +15,9 @@ public class SupportedLanguages {
private static final Logger LOG = LoggerFactory.getLogger(SupportedLanguages.class);
// 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", "sw", "ta", "te", "th", "tr", "uk", "zh", "zh-HK", "zh-TW");
+ public static final List LANGUAGAE_TAGS = List.of("en", "ar", "be", "bn", "bs", "ca", "cs", "da", "de", "el", "es", "fil", "fa", "fr", "gl", "he", //
+ "hi", "hr", "hu", "id", "it", "ja", "ko", "lv", "mk", "nb", "nl", "nn", "no", "pa", "pl", "pt", "pt-BR", "ro", "ru", "si", "sk", "sr", "sr-Latn", "sv", "sw", //
+ "ta", "te", "th", "tr", "uk", "vi", "zh", "zh-HK", "zh-TW");
@Nullable
private final String preferredLanguage;
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultNameController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultNameController.java
index 3068874ec..2ca73e172 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultNameController.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultNameController.java
@@ -40,19 +40,15 @@ public class CreateNewVaultNameController implements FxController {
this.chooseLocationScene = chooseLocationScene;
this.vaultPath = vaultPath;
this.vaultName = vaultName;
- this.validVaultName = Bindings.createBooleanBinding(this::isValidVaultNameInternal, vaultName);
+ this.validVaultName = Bindings.createBooleanBinding(this::isValidVaultName, vaultName);
}
@FXML
public void initialize() {
- vaultName.bind(textField.textProperty());
+ vaultName.bindBidirectional(textField.textProperty());
vaultName.addListener(this::vaultNameChanged);
}
- private boolean isValidVaultNameInternal() {
- return vaultName.get() != null && VALID_NAME_PATTERN.matcher(vaultName.get().trim()).matches();
- }
-
private void vaultNameChanged(@SuppressWarnings("unused") Observable observable) {
if (isValidVaultName()) {
if (vaultPath.get() != null) {
@@ -70,6 +66,7 @@ public class CreateNewVaultNameController implements FxController {
@FXML
public void next() {
window.setScene(chooseLocationScene.get());
+ vaultName.set(vaultName.get().trim());
}
/* Getter/Setter */
@@ -79,7 +76,7 @@ public class CreateNewVaultNameController implements FxController {
}
public boolean isValidVaultName() {
- return validVaultName.get();
+ return vaultName.get() != null && VALID_NAME_PATTERN.matcher(vaultName.get().trim()).matches();
}
}
diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java
index 07dc1e215..44a09b988 100644
--- a/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java
+++ b/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java
@@ -56,7 +56,7 @@ public class ReceiveKeyController implements FxController {
this.vaultBaseUri = getVaultBaseUri(vault);
this.licenseExceededScene = licenseExceededScene;
this.window.addEventHandler(WindowEvent.WINDOW_HIDING, this::windowClosed);
- this.httpClient = HttpClient.newBuilder().executor(executor).build();
+ this.httpClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).executor(executor).build();
}
@FXML
diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java
index bd997d994..4cf2d9fa2 100644
--- a/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java
+++ b/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java
@@ -76,7 +76,7 @@ public class RegisterDeviceController implements FxController {
this.registerFailedScene = registerFailedScene;
this.jwt = JWT.decode(this.bearerToken);
this.window.addEventHandler(WindowEvent.WINDOW_HIDING, this::windowClosed);
- this.httpClient = HttpClient.newBuilder().executor(executor).build();
+ this.httpClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).executor(executor).build();
}
public void initialize() {
diff --git a/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java
index ace6dadca..d2381b869 100644
--- a/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java
+++ b/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java
@@ -34,6 +34,7 @@ public class GeneralPreferencesController implements FxController {
private final Environment environment;
private final List keychainAccessProviders;
private final FxApplicationWindows appWindows;
+ public CheckBox useKeychainCheckbox;
public ChoiceBox keychainBackendChoiceBox;
public CheckBox startHiddenCheckbox;
public CheckBox autoCloseVaultsCheckbox;
@@ -64,6 +65,8 @@ public class GeneralPreferencesController implements FxController {
keychainBackendChoiceBox.setValue(keychainSettingsConverter.fromString(settings.keychainProvider().get()));
keychainBackendChoiceBox.setConverter(new KeychainProviderDisplayNameConverter());
Bindings.bindBidirectional(settings.keychainProvider(), keychainBackendChoiceBox.valueProperty(), keychainSettingsConverter);
+ useKeychainCheckbox.selectedProperty().bindBidirectional(settings.useKeychain());
+ keychainBackendChoiceBox.disableProperty().bind(useKeychainCheckbox.selectedProperty().not());
}
public boolean isAutoStartSupported() {
diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java
index ea8599b51..ea7358770 100644
--- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java
+++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java
@@ -31,8 +31,8 @@ import java.util.ResourceBundle;
public class TrayMenuBuilder {
private static final Logger LOG = LoggerFactory.getLogger(TrayMenuBuilder.class);
- private static final String TRAY_ICON_MAC = "/img/tray_icon_mac.png";
- private static final String TRAY_ICON = "/img/tray_icon.png";
+ private static final String TRAY_ICON_MAC = "/img/tray_icon_mac@2x.png";
+ private static final String TRAY_ICON = "/img/window_icon_32.png";
private final ResourceBundle resourceBundle;
private final VaultService vaultService;
diff --git a/src/main/resources/css/dark_theme.css b/src/main/resources/css/dark_theme.css
index 32bddbbf1..86467bb1a 100644
--- a/src/main/resources/css/dark_theme.css
+++ b/src/main/resources/css/dark_theme.css
@@ -5,15 +5,15 @@
******************************************************************************/
@font-face {
- src: url('opensans-regular.ttf');
+ src: url('opensans_regular.ttf');
}
@font-face {
- src: url('opensans-semibold.ttf');
+ src: url('opensans_semibold.ttf');
}
@font-face {
- src: url('opensans-bold.ttf');
+ src: url('opensans_bold.ttf');
}
/*******************************************************************************
diff --git a/src/main/resources/css/light_theme.css b/src/main/resources/css/light_theme.css
index a6cd67af9..ddc872eb2 100644
--- a/src/main/resources/css/light_theme.css
+++ b/src/main/resources/css/light_theme.css
@@ -5,15 +5,15 @@
******************************************************************************/
@font-face {
- src: url('opensans-regular.ttf');
+ src: url('opensans_regular.ttf');
}
@font-face {
- src: url('opensans-semibold.ttf');
+ src: url('opensans_semibold.ttf');
}
@font-face {
- src: url('opensans-bold.ttf');
+ src: url('opensans_bold.ttf');
}
/*******************************************************************************
diff --git a/src/main/resources/css/opensans-bold.ttf b/src/main/resources/css/opensans_bold.ttf
similarity index 100%
rename from src/main/resources/css/opensans-bold.ttf
rename to src/main/resources/css/opensans_bold.ttf
diff --git a/src/main/resources/css/opensans-regular.ttf b/src/main/resources/css/opensans_regular.ttf
similarity index 100%
rename from src/main/resources/css/opensans-regular.ttf
rename to src/main/resources/css/opensans_regular.ttf
diff --git a/src/main/resources/css/opensans-semibold.ttf b/src/main/resources/css/opensans_semibold.ttf
similarity index 100%
rename from src/main/resources/css/opensans-semibold.ttf
rename to src/main/resources/css/opensans_semibold.ttf
diff --git a/src/main/resources/css/quicksand-bold.ttf b/src/main/resources/css/quicksand_bold.ttf
similarity index 100%
rename from src/main/resources/css/quicksand-bold.ttf
rename to src/main/resources/css/quicksand_bold.ttf
diff --git a/src/main/resources/fxml/addvault_new_name.fxml b/src/main/resources/fxml/addvault_new_name.fxml
index e7494e116..185f80ed4 100644
--- a/src/main/resources/fxml/addvault_new_name.fxml
+++ b/src/main/resources/fxml/addvault_new_name.fxml
@@ -71,7 +71,7 @@
-
+
diff --git a/src/main/resources/fxml/preferences_general.fxml b/src/main/resources/fxml/preferences_general.fxml
index c255e2a0f..7f7954fc8 100644
--- a/src/main/resources/fxml/preferences_general.fxml
+++ b/src/main/resources/fxml/preferences_general.fxml
@@ -4,7 +4,6 @@
-
@@ -27,7 +26,7 @@
-
+
diff --git a/src/main/resources/i18n/strings_de.properties b/src/main/resources/i18n/strings_de.properties
index 620e5cac5..c9b4a2c66 100644
--- a/src/main/resources/i18n/strings_de.properties
+++ b/src/main/resources/i18n/strings_de.properties
@@ -16,7 +16,7 @@ generic.button.print=Drucken
# Error
error.message=Ein Fehler ist aufgetreten
-error.description=Ups! Das hat sich Cryptomator anders vorgestellt. Du kannst Lösungen für diesen Fehler nachschlagen oder einen neuen Fehlerbericht einreichen.
+error.description=Cryptomator hat diesen Fehler nicht erwartet. Du kannst für ihn nach bestehenden Lösungen suchen oder – falls der Fehler noch nicht gemeldet wurde – einen Fehlerbericht einreichen.
error.hyperlink.lookup=Diesen Fehler nachschlagen
error.hyperlink.report=Diesen Fehler melden
error.technicalDetails=Details:
@@ -104,7 +104,7 @@ changepassword.finalConfirmation=Mir ist bewusst, dass ich bei Verlust meines Pa
# Forget Password
forgetPassword.title=Passwort vergessen
forgetPassword.message=Gespeichertes Passwort löschen?
-forgetPassword.description=Dies löscht das gespeicherte Passwort dieses Tresors aus dem Schlüsselbund deines Betriebssystems.
+forgetPassword.description=Dies löscht das gespeicherte Tresorpasswort aus dem Schlüsselbund deines Betriebssystems.
forgetPassword.confirmBtn=Passwort vergessen
# Unlock
@@ -198,7 +198,7 @@ health.intro.text=Die Integritätsprüfung ist eine Sammlung von Tests, um Probl
health.intro.remarkSync=Stelle sicher, dass alle Geräte vollständig synchronisiert sind. Dies löst die meisten Probleme.
health.intro.remarkFix=Nicht alle Probleme können behoben werden.
health.intro.remarkBackup=Wenn Daten beschädigt sind, kann nur ein Backup helfen.
-health.intro.affirmation=Ich habe die obenstehende Information gelesen und verstanden
+health.intro.affirmation=Ich habe die oben genannten Informationen gelesen und verstanden
## Start Failure
health.fail.header=Fehler beim Laden der Tresorkonfiguration
health.fail.ioError=Beim Lesezugriff auf die Konfigurationsdatei ist ein Fehler aufgetreten.
diff --git a/src/main/resources/i18n/strings_it.properties b/src/main/resources/i18n/strings_it.properties
index 5ba913d86..bfd643db1 100644
--- a/src/main/resources/i18n/strings_it.properties
+++ b/src/main/resources/i18n/strings_it.properties
@@ -53,6 +53,12 @@ addvaultwizard.new.fileAlreadyExists=Un file o una cartella con il nome della ca
addvaultwizard.new.locationDoesNotExist=Una cartella nel percorso specificato non esiste o non è accessibile
addvaultwizard.new.locationIsNotWritable=Nessun accesso in scrittura nel percorso specificato
addvaultwizard.new.locationIsOk=Posizione idonea per la tua cassaforte
+addvaultwizard.new.invalidName=Nome cassaforte non valido
+addvaultwizard.new.validName=Nome cassaforte valido
+addvaultwizard.new.validCharacters.message=Il nome della cassaforte può contenere i seguenti caratteri:
+addvaultwizard.new.validCharacters.chars=Caratteri della parola (e.g. a, ж or 수)
+addvaultwizard.new.validCharacters.numbers=Numeri
+addvaultwizard.new.validCharacters.dashes=Trattino (%s) o tratto basso (%s)
### Password
addvaultwizard.new.createVaultBtn=Crea Cassaforte
addvaultwizard.new.generateRecoveryKeyChoice=Non potrai accedere ai tuoi dati senza la tua password. Desideri una chiave di recupero nel caso dovessi perdere la password?
@@ -86,6 +92,7 @@ addvaultwizard.success.unlockNow=Sblocca Ora
# Remove Vault
removeVault.title=Rimuovi Cassaforte
+removeVault.message=Rimuovere cassaforte?
removeVault.description=Questo farà solo dimenticare questa cassaforte a Cryptomator. Puoi aggiungerla nuovamente in seguito. Nessun file crittografato sarà eliminato dal tuo disco rigido.
removeVault.confirmBtn=Rimuovi Cassaforte
@@ -96,6 +103,7 @@ changepassword.finalConfirmation=Capisco che non potrò accedere ai miei dati se
# Forget Password
forgetPassword.title=Dimentica la Password
+forgetPassword.message=Dimentica Password salvata?
forgetPassword.description=Questo eliminerà la password salvata di questa cassaforte dal portachiavi del tuo sistema.
forgetPassword.confirmBtn=Dimentica Password
@@ -105,10 +113,12 @@ unlock.passwordPrompt=Inserisci la password per "%s":
unlock.savePassword=Ricorda la Password
unlock.unlockBtn=Sblocca
## Select
+unlock.chooseMasterkey.message=File Masterkey non trovato
unlock.chooseMasterkey.description=Impossibile trovare il file Masterkey per questa cassaforte alla sua posizione prevista. Sei pregato di sceglierlo manualmente.
unlock.chooseMasterkey.filePickerTitle=Seleziona il File Masterkey
unlock.chooseMasterkey.filePickerMimeDesc=Chiave principale di Cryptomator
## Success
+unlock.success.message=Sbloccato con successo
unlock.success.description="%s" sbloccato correttamente! La tua cassaforte è ora accessibile tramite la sua unità virtuale.
unlock.success.rememberChoice=Ricorda la scelta, non mostrarmelo più
unlock.success.revealBtn=Rivela l'Unità
@@ -120,13 +130,30 @@ unlock.error.invalidMountPoint.existing=Il punto di montaggio "%s" esiste già o
unlock.error.invalidMountPoint.driveLetterOccupied=La lettera di unità "%s" è già in uso.
## Hub
### Waiting
+hub.auth.message=In attesa di autenticazione…
+hub.auth.description=Dovresti essere reindirizzato automaticamente alla pagina di login.
+hub.auth.loginLink=Non reindirizzato? Clicca qui per aprirlo.
### Receive Key
+hub.receive.message=Elaborazione della risposta…
+hub.receive.description=Cryptomator sta ricevendo ed elaborando la risposta da Hub. Attendere prego.
### Register Device
+hub.register.message=Nome del dispositivo richiesto
+hub.register.description=Questo sembra essere il primo accesso Hub da questo dispositivo. Per identificarlo per l'autorizzazione di accesso, è necessario nominare questo dispositivo.
+hub.register.nameLabel=Nome Del Dispositivo
+hub.register.occupiedMsg=Nome già in uso
hub.register.registerBtn=Conferma
### Registration Success
+hub.registerSuccess.message=Dispositivo nominato
+hub.registerSuccess.description=Per accedere al vault, il tuo dispositivo deve essere autorizzato dal proprietario del vault.
### Registration Failed
+hub.registerFailed.message=Assegnazione del nome al dispositivo fallita
+hub.registerFailed.description=Si è verificato un errore nel processo di nomina. Per maggiori dettagli, consultare il registro delle applicazioni.
### Unauthorized
+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.licenseExceeded.message=Licenza scaduta
+hub.licenseExceeded.description=Cryptomator Hub ha dato accesso a più utenti rispetto ai suoi permessi di licenza. Contatta il tuo amministratore Hub per aggiornare la licenza o un amministratore del vault per rimuovere gli utenti dalle cassaforte.
# Lock
@@ -202,6 +229,7 @@ preferences.title=Preferenze
## General
preferences.general=Generale
preferences.general.startHidden=Nascondi la finestra avviando Cryptomator
+preferences.general.autoCloseVaults=Blocca automaticamente le cassaforti aperte all'uscita dell'applicazione
preferences.general.debugLogging=Abilita la registrazione di debug
preferences.general.debugDirectory=Rivela i file di registro
preferences.general.autoStart=Avvia Cryptomator all'avvio del sistema
@@ -363,20 +391,27 @@ vaultOptions.masterkey.changePasswordBtn=Modifica password
vaultOptions.masterkey.forgetSavedPasswordBtn=Dimentica Password Salvata
vaultOptions.masterkey.recoveryKeyExplanation=Una chiave di recupero è il tuo unico mezzo per ripristinare l'accesso a una cassaforte se perdi la tua password.
vaultOptions.masterkey.showRecoveryKeyBtn=Visualizza la chiave di recupero
+vaultOptions.masterkey.recoverPasswordBtn=Reimposta Password
# Recovery Key
## Display Recovery Key
+recoveryKey.display.title=Mostra Chiave Di Recupero
+recoveryKey.create.message=Password richiesta
recoveryKey.create.description=Inserisci la password per visualizzare la chiave di recupero per "%s":
recoveryKey.display.description=La seguente chiave di recupero può essere utilizzata per ripristinare l'accesso a %s":
recoveryKey.display.StorageHints=Mantienilo da qualche parte molto sicuro, ad es.\n • Archivialo usando un gestore di password\n • Salvarlo su un'unità flash USB\n • Stamparlo su carta
## Reset Password
### Enter Recovery Key
+recoveryKey.recover.title=Reimposta Password
recoveryKey.recover.prompt=Inserisci la tua chiave di recupero per "%s":
recoveryKey.recover.validKey=Questa è una chiave di recupero valida
recoveryKey.printout.heading=Chiave di recupero Cryptomator\n"%s"\n
### Reset Password
+recoveryKey.recover.resetBtn=Reimposta
### Recovery Key Password Reset Success
+recoveryKey.recover.resetSuccess.message=Password reimpostata correttamente
+recoveryKey.recover.resetSuccess.description=Puoi sbloccare la tua cassaforte con la nuova password.
# New Password
newPassword.promptText=Inserisci una nuova password
@@ -391,6 +426,12 @@ passwordStrength.messageLabel.3=Forte
passwordStrength.messageLabel.4=Molto forte
# Quit
+quit.title=Esci Dall'Applicazione
+quit.message=Ci sono cassaforti sbloccate
+quit.description=Si prega di confermare che si desidera uscire. Cryptomator bloccherà gentilmente tutte le cassaforti sbloccate per prevenire la perdita di dati.
quit.lockAndQuitBtn=Blocca ed Esci
-# Forced Quit
\ No newline at end of file
+# Forced Quit
+quit.forced.message=Qualche cassaforte non può essere bloccata
+quit.forced.description=Il blocco delle cassaforte è stato bloccato da operazioni in attesa o da file aperti. È possibile forzare il blocco delle cassaforti rimanenti, tuttavia interrompere le operazioni I/O potrebbe causare la perdita di dati non salvati.
+quit.forced.forceAndQuitBtn=Forza e Esci
\ No newline at end of file
diff --git a/src/main/resources/i18n/strings_ja.properties b/src/main/resources/i18n/strings_ja.properties
index cea387bdf..2df2a5ae3 100644
--- a/src/main/resources/i18n/strings_ja.properties
+++ b/src/main/resources/i18n/strings_ja.properties
@@ -138,11 +138,22 @@ hub.receive.message=応答を処理中…
hub.receive.description=Cryptomator が Hub からの応答を受信、処理中です。しばらくお待ちください。
### Register Device
hub.register.message=デバイスの名前が必要です
+hub.register.description=このデバイスからハブにアクセスするのは初めてのようです。アクセス認証の際のデバイス識別のためにこのデバイスに名前を付ける必要があります。
+hub.register.nameLabel=デバイス名
+hub.register.occupiedMsg=この名前は既に使われています
hub.register.registerBtn=確認
### Registration Success
+hub.registerSuccess.message=デバイス名の登録に成功しました
+hub.registerSuccess.description=金庫にアクセスするためには,金庫のオーナーが端末を認証する必要があります。
### Registration Failed
+hub.registerFailed.message=デバイス名の登録に失敗しました
+hub.registerFailed.description=デバイス名登録中にエラーが発生しました。エラーの詳細についてはアプリケーションログを参照してください。
### Unauthorized
+hub.unauthorized.message=アクセスが拒否されました
+hub.unauthorized.description=お使いのデバイスはまだこの金庫にアクセスする権限がありません。金庫のオーナーに権限を与えてもらってください。
### License Exceeded
+hub.licenseExceeded.message=ライセンス数が不足しています
+hub.licenseExceeded.description=Cryptomator Hubがライセンスの許可よりも多くのユーザーにアクセス権を与えています。ハブ管理者にライセンスをアップグレードするよう連絡するか,金庫の管理者に金庫からユーザーを削除するよう連絡してください。
# Lock
diff --git a/src/main/resources/i18n/strings_nb.properties b/src/main/resources/i18n/strings_nb.properties
index 50fb6b226..f251e9265 100644
--- a/src/main/resources/i18n/strings_nb.properties
+++ b/src/main/resources/i18n/strings_nb.properties
@@ -53,6 +53,12 @@ addvaultwizard.new.fileAlreadyExists=En fil eller mappe med det hvelvnavnet finn
addvaultwizard.new.locationDoesNotExist=En mappe i den angitte stien finnes ikke eller kan ikke nås
addvaultwizard.new.locationIsNotWritable=Ingen skrivetilgang på den angitte stien
addvaultwizard.new.locationIsOk=Egnet sted for hvelvet ditt
+addvaultwizard.new.invalidName=Ugyldig hvelvnavn
+addvaultwizard.new.validName=Gyldig hvelvnavn
+addvaultwizard.new.validCharacters.message=Hvelvnavnet kan inneholde følgende tegn:
+addvaultwizard.new.validCharacters.chars=Ordtegn (eks. a, ж or 수)
+addvaultwizard.new.validCharacters.numbers=Tall
+addvaultwizard.new.validCharacters.dashes=Bindestrek (%s) eller understrek (%s)
### Password
addvaultwizard.new.createVaultBtn=Opprett hvelv
addvaultwizard.new.generateRecoveryKeyChoice=Du vil ikke kunne få tilgang til dataene dine uten passordet. Vil du ha en gjenopprettingsnøkkel i tilefelle du mister passordet ditt?
@@ -79,12 +85,14 @@ addvault.new.readme.accessLocation.4=Denne filen kan fjernes hvis ønskelig.
addvaultwizard.existing.instruction=Velg "vault.cryptomator"-filen til ditt eksisterende hvelv. Hvis det kun finnes en fil med navnet "masterkey.cryptomator", så velger du den i stedet.
addvaultwizard.existing.chooseBtn=Velg…
addvaultwizard.existing.filePickerTitle=Velg hvelvfil
+addvaultwizard.existing.filePickerMimeDesc=Cryptomator-hvelv
## Success
addvaultwizard.success.nextStepsInstructions=Lagt til hvelvet "%s".\nDu må låse opp dette hvelvet for å få tilgang til eller legge til innhold. Alternativt kan du låse det opp på et hvilket som helst senere tidspunkt.
addvaultwizard.success.unlockNow=Lås opp nå
# Remove Vault
removeVault.title=Fjern hvelvet
+removeVault.message=Fjerne hvelv?
removeVault.description=Dette vil kun få Cryptomator til å glemme dette hvelvet. Du kan legge til hvelvet senere igjen. Ingen krypterte filer blir slettet fra harddisken.
removeVault.confirmBtn=Fjern hvelvet
@@ -95,6 +103,7 @@ changepassword.finalConfirmation=Jeg forstår at jeg ikke vil kunne få tilgang
# Forget Password
forgetPassword.title=Glem passord
+forgetPassword.message=Glemt lagret passord?
forgetPassword.description=Dette vil slette det lagrede passordet til dette hvelvet fra systemnøkkelringen min.
forgetPassword.confirmBtn=Glem passord
@@ -104,9 +113,12 @@ unlock.passwordPrompt=Skriv inn passordet for "%s":
unlock.savePassword=Husk passord
unlock.unlockBtn=Lås opp
## Select
+unlock.chooseMasterkey.message=Hovednøkkel-fil ikke funnet
unlock.chooseMasterkey.description=Kunne ikke finne hovednøkkelfilen for dette hvelvet på forventet sted. Venligst velg nøkkelfilen manuelt.
unlock.chooseMasterkey.filePickerTitle=Velg hovednøkkelfil
+unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator Hovednøkkel
## Success
+unlock.success.message=Opplåsing vellykket
unlock.success.description=Vellykket opplåsing av "%s"! Hvelvet ditt er nå tilgjengelig via sin virtuelle stasjon.
unlock.success.rememberChoice=Husk valget - ikke vis dette igjen
unlock.success.revealBtn=Gjør enheten synlig
@@ -118,13 +130,30 @@ unlock.error.invalidMountPoint.existing=Monteringspunktet "%s" finnes enten alle
unlock.error.invalidMountPoint.driveLetterOccupied=Stasjonsbokstav "%s" er allerede i bruk.
## Hub
### Waiting
+hub.auth.message=Venter på autentisering…
+hub.auth.description=Du burde bli automatisk videresendt til innloggingssiden.
+hub.auth.loginLink=Ikke videresendt? Klikk her for å åpne den.
### Receive Key
+hub.receive.message=Prosesserer svar…
+hub.receive.description=Cryptomator mottar og behandler svaret fra Hub. Vennligst vent.
### Register Device
+hub.register.message=Enhetsnavn påkrevd
+hub.register.description=Dette ser ut til å være den første Hub-tilgangen fra denne enheten. For å kunne identifisere den for tilgangsautorisasjon, må du å navngi denne enheten.
+hub.register.nameLabel=Enhetsnavn
+hub.register.occupiedMsg=Navnet er allerede i bruk
hub.register.registerBtn=Bekreft
### Registration Success
+hub.registerSuccess.message=Enheten navngitt
+hub.registerSuccess.description=For å få tilgang til hvelvet, så må enheten din bli autorisert av hvelvets eier.
### Registration Failed
+hub.registerFailed.message=Enhetsnavngiving mislyktes
+hub.registerFailed.description=Under navngivingsprosessen oppsto det en feilmelding. For flere detaljer, studere applikasjonsloggen.
### Unauthorized
+hub.unauthorized.message=Ingen tilgang
+hub.unauthorized.description=Enheten din har ikke blitt autorisert til å få tilgang til dette hvelvet ennå. Spør hvelveieren om å tillate det.
### License Exceeded
+hub.licenseExceeded.message=Lisensen overskredet
+hub.licenseExceeded.description=Cryptomator Hub har gitt tilgang til flere brukere enn lisensen dens tillater. Vennligst kontakt Hub-administratoren din for å få oppgradert lisensen eller få en hvelv-administrator til å fjerne brukere fra hvelv.
# Lock
@@ -200,6 +229,7 @@ preferences.title=Innstillinger
## General
preferences.general=Generelt
preferences.general.startHidden=Skjul vinduet når du starter Cryptomator
+preferences.general.autoCloseVaults=Låse åpne hvelv automatisk ved avslutning av programmet
preferences.general.debugLogging=Aktiver loggføring av feilsøk
preferences.general.debugDirectory=Vis loggfiler
preferences.general.autoStart=Start Cryptomator ved systemstart
@@ -361,20 +391,27 @@ vaultOptions.masterkey.changePasswordBtn=Endre passord
vaultOptions.masterkey.forgetSavedPasswordBtn=Glem passord
vaultOptions.masterkey.recoveryKeyExplanation=En gjenopprettingsnøkkel er den eneste måten å gjenopprette tilgangen til et hvelv på hvis du mister passordet.
vaultOptions.masterkey.showRecoveryKeyBtn=Vis gjenopprettingsnøkkelen
+vaultOptions.masterkey.recoverPasswordBtn=Nullstill passord
# Recovery Key
## Display Recovery Key
+recoveryKey.display.title=Vis gjenopprettingsnøkkel
+recoveryKey.create.message=Passord påkrevd
recoveryKey.create.description=Skriv inn passordet ditt for å vise gjenopprettingsnøkkelen for "%s":
recoveryKey.display.description=Følgende gjenopprettingsnøkkel kan brukes til å gjenopprette tilgang til "%s":
recoveryKey.display.StorageHints=Oppbevar den et veldig sikkert sted, f.eks. ved å:\n • Lagre den ved hjelp av et passordhvelv\n • Lagre den på en USB-minnepenn\n • Skrive den ut på papir
## Reset Password
### Enter Recovery Key
+recoveryKey.recover.title=Nullstill passordet
recoveryKey.recover.prompt=Skriv inn gjenopprettingsnøkkelen for "%s":
recoveryKey.recover.validKey=Dette er en gyldig gjenopprettingsnøkkel
recoveryKey.printout.heading=Cryptomator-gjenopprettingsnøkkel\n"%s"\n
### Reset Password
+recoveryKey.recover.resetBtn=Nullstill
### Recovery Key Password Reset Success
+recoveryKey.recover.resetSuccess.message=Passordnullstillingen vellykket
+recoveryKey.recover.resetSuccess.description=Du kan låse opp hvelvet med det nye passordet.
# New Password
newPassword.promptText=Skriv inn et nytt passord
@@ -389,6 +426,12 @@ passwordStrength.messageLabel.3=Sterkt
passwordStrength.messageLabel.4=Veldig sterkt
# Quit
+quit.title=Avslutt programmet
+quit.message=Det finnes ulåste hvelv
+quit.description=Vennligst bekreft at du ønsker å avslutte. Cryptomator vil på grasiøst vis låse alle ulåste hvelv for å forebygge tap av data.
quit.lockAndQuitBtn=Lås og avslutt
-# Forced Quit
\ No newline at end of file
+# Forced Quit
+quit.forced.message=Noen hvelv kunne ikke låses
+quit.forced.description=Låsing av hvelvene ble blokkert av ventende operasjoner eller åpne filer. Du kan tvinge låsing av gjenværende hvelv, men forstyrring av I/O kan resultere i tap av ulagret data.
+quit.forced.forceAndQuitBtn=Tvinge og avslutte
\ No newline at end of file
diff --git a/src/main/resources/i18n/strings_pl.properties b/src/main/resources/i18n/strings_pl.properties
index f747ab970..fb1b4f39c 100644
--- a/src/main/resources/i18n/strings_pl.properties
+++ b/src/main/resources/i18n/strings_pl.properties
@@ -15,7 +15,7 @@ generic.button.next=Dalej
generic.button.print=Drukuj
# Error
-error.message=Błąd %s
+error.message=Wystąpił błąd
error.description=Cryptomator nie spodziewał się czegoś takiego. Możesz wyszukać istniejące rozwiązania dla tego błędu. Jeśli nie został on jeszcze zgłoszony, możesz sam to zrobić.
error.hyperlink.lookup=Wyszukaj ten błąd
error.hyperlink.report=Zgłoś ten błąd
@@ -152,6 +152,8 @@ hub.registerFailed.description=Wystąpił błąd podczas ustawiania nazwy. Aby u
hub.unauthorized.message=Brak dostępu
hub.unauthorized.description=Twoje urządzenie nie zostało jeszcze upoważnione do dostępu do tego sejfu. Poproś właściciela sejfu o autoryzację.
### License Exceeded
+hub.licenseExceeded.message=Przekroczono licencję
+hub.licenseExceeded.description=Cryptomator Hub dał dostęp większej ilości użytkowników, niż pozwala na to licencja. Proszę skontaktować się z administratorem Hub, aby ulepszyć licencję lub z administratorem sejfu, aby usunąć użytkowników z sejfu.
# Lock
diff --git a/src/main/resources/i18n/strings_uk.properties b/src/main/resources/i18n/strings_uk.properties
index 23cddd234..b54d4c28b 100644
--- a/src/main/resources/i18n/strings_uk.properties
+++ b/src/main/resources/i18n/strings_uk.properties
@@ -4,7 +4,7 @@
## Button
generic.button.apply=Застосувати
generic.button.back=Назад
-generic.button.cancel=Відмінити
+generic.button.cancel=Скасувати
generic.button.change=Змінити
generic.button.choose=Обрати…
generic.button.close=Закрити
@@ -12,23 +12,23 @@ generic.button.copy=Копіювати
generic.button.copied=Скопійовано!
generic.button.done=Готово
generic.button.next=Далі
-generic.button.print=Друкувати
+generic.button.print=Друк
# Error
-error.message=Помилка %s
-error.description=Ой! Cryptomator не очікував, що таке трапиться. Ви можете знайти існуючі рішення цієї помилки. Або, якщо про це ще не повідомили, то не соромтеся зробити це.
+error.message=Сталася помилка
+error.description=Cryptomator не очікував, що таке трапиться. Спробуйте пошукати рішення цієї помилки, що вже існують. Якщо про помилку ще не повідомили, то не соромтеся це зробити.
error.hyperlink.lookup=Дізнатися більше про цю помилку
error.hyperlink.report=Повідомити про помилку
-error.technicalDetails=Докладно:
+error.technicalDetails=Подробиці:
# Defaults
defaults.vault.vaultName=Сховище
# Tray Menu
traymenu.showMainWindow=Показати
-traymenu.showPreferencesWindow=Властивості
-traymenu.lockAllVaults=Заблокувати все
-traymenu.quitApplication=Вийти
+traymenu.showPreferencesWindow=Налаштування
+traymenu.lockAllVaults=Заблокувати всі
+traymenu.quitApplication=Вихід
traymenu.vault.unlock=Розблокувати
traymenu.vault.lock=Заблокувати
traymenu.vault.reveal=Показати
@@ -37,7 +37,7 @@ traymenu.vault.reveal=Показати
addvaultwizard.title=Додати сховище
## Welcome
addvaultwizard.welcome.newButton=Створити нове сховище
-addvaultwizard.welcome.existingButton=Відкрити існуюче сховище
+addvaultwizard.welcome.existingButton=Відкрити сховище
## New
### Name
addvaultwizard.new.nameInstruction=Оберіть назву для сховища
@@ -46,34 +46,48 @@ addvaultwizard.new.namePrompt=Назва сховища
addvaultwizard.new.locationInstruction=Де Cryptomator має зберігати зашифровані файли вашого сховища?
addvaultwizard.new.locationLabel=Розташування сховища
addvaultwizard.new.locationPrompt=…
-addvaultwizard.new.directoryPickerLabel=Власне розташування
+addvaultwizard.new.directoryPickerLabel=Інше розташування
addvaultwizard.new.directoryPickerButton=Обрати…
-addvaultwizard.new.directoryPickerTitle=Оберіть директорію
-addvaultwizard.new.fileAlreadyExists=Файл чи папка з іменем сховища вже існує
+addvaultwizard.new.directoryPickerTitle=Обрати каталог
+addvaultwizard.new.fileAlreadyExists=Файл чи каталог з іменем сховища вже існує
+addvaultwizard.new.locationDoesNotExist=За вказаною адресою каталог недоступний або не існує
+addvaultwizard.new.locationIsNotWritable=Вказана адреса доступна лише для читання
+addvaultwizard.new.locationIsOk=Це місце підходить для сховища
+addvaultwizard.new.invalidName=Недопустима назва сховища
+addvaultwizard.new.validName=Допустима назва сховища
+addvaultwizard.new.validCharacters.message=Назва сховища може містити наступні символи:
+addvaultwizard.new.validCharacters.chars=Літери (напр. a, ж or 수)
+addvaultwizard.new.validCharacters.numbers=Цифри
+addvaultwizard.new.validCharacters.dashes=Дефіс (%s) або підкреслення (%s)
### Password
addvaultwizard.new.createVaultBtn=Створити сховище
+addvaultwizard.new.generateRecoveryKeyChoice=Ви не зможете отримати доступ до своїх даних, якщо втратите пароль. Хочете створити ключ відновлення на випадок втрати паролю?
+addvaultwizard.new.generateRecoveryKeyChoice.yes=Так, будь ласка, береженого Бог береже
+addvaultwizard.new.generateRecoveryKeyChoice.no=Ні, дякую, я не втрачу свій пароль
### Information
+addvault.new.readme.storageLocation.fileName=ВАЖЛИВО.rtf
+addvault.new.readme.storageLocation.1=⚠️ ФАЙЛИ СХОВИЩА ⚠️
addvault.new.readme.storageLocation.2=Це місце для зберігання вашого сховища.
addvault.new.readme.storageLocation.3=НЕ
-addvault.new.readme.storageLocation.4=• міняйте будь-які файли в цьому каталозі або
-addvault.new.readme.storageLocation.5=• вставляйте будь-які файли для шифрування до цієї теки.
+addvault.new.readme.storageLocation.4=• змінювати будь-які файли в цьому каталозі, або
+addvault.new.readme.storageLocation.5=• додавати до цього каталогу будь-які файли для шифрування.
## Existing
addvaultwizard.existing.chooseBtn=Обрати…
## Success
addvaultwizard.success.unlockNow=Розблокувати
# Remove Vault
-removeVault.title=Видалити сховище
+removeVault.title=Видалити "%s"
removeVault.confirmBtn=Видалити сховище
# Change Password
changepassword.title=Змінити пароль
-changepassword.enterOldPassword=Поточний пароль для "%s"
+changepassword.enterOldPassword=Введіть поточний пароль для "%s"
changepassword.finalConfirmation=Я розумію, що не зможу отримати доступ до даних, якщо забуду свій пароль
# Forget Password
-forgetPassword.title=Не пам'ятаю пароль
-forgetPassword.confirmBtn=Не пам'ятаю пароль
+forgetPassword.title=Забути пароль
+forgetPassword.confirmBtn=Забути пароль
# Unlock
unlock.title=Розблокувати "%s"
diff --git a/src/main/resources/i18n/strings_vi.properties b/src/main/resources/i18n/strings_vi.properties
index 856b85463..88a3c427e 100644
--- a/src/main/resources/i18n/strings_vi.properties
+++ b/src/main/resources/i18n/strings_vi.properties
@@ -65,6 +65,8 @@ addvaultwizard.new.generateRecoveryKeyChoice=Bạn sẽ không thể truy cập
addvaultwizard.new.generateRecoveryKeyChoice.yes=Vâng làm ơn, cẩn tắc vô áy náy
addvaultwizard.new.generateRecoveryKeyChoice.no=Không cảm ơn, tôi sẽ không mất mật khẩu
### Information
+addvault.new.readme.storageLocation.fileName=QUAN_TRONG.rft
+addvault.new.readme.storageLocation.1=⚠️ VỀ CÁC TẬP TIN BÊN TRONG VAULT ⚠️
addvault.new.readme.storageLocation.2=Đây là vị trí truy cập vault của bạn.
addvault.new.readme.storageLocation.3=ĐỪNG
addvault.new.readme.storageLocation.4=• thay đổi bất kỳ tệp nào trong thư mục này hoặc
@@ -74,10 +76,14 @@ addvault.new.readme.storageLocation.7=1. Thêm vault này vào Cryptomator.
addvault.new.readme.storageLocation.8=2. Mở khóa vault trong Cryptomator.
addvault.new.readme.storageLocation.9=3. Mở vị trí truy cập bằng cách nhấp vào nút "Mở".
addvault.new.readme.storageLocation.10=Nếu cần trợ giúp, hãy truy cập tài liệu: %s
+addvault.new.readme.accessLocation.fileName=XIN_CHAO.rtf
+addvault.new.readme.accessLocation.1=🔐️ PHÂN VÙNG DỮ LIỆU ĐƯỢC MÃ HOÁ 🔐️
addvault.new.readme.accessLocation.2=Đây là vị trí truy cập vault của bạn.
addvault.new.readme.accessLocation.3=Bất kỳ tệp nào được thêm vào đây sẽ được mã hóa bởi Cryptomator. Bạn có thể làm việc trên nó như trên bất kỳ ổ đĩa/thư mục nào khác. Đây chỉ là chế độ xem nội dung được giải mã của nó, các tệp của bạn luôn được mã hóa trên ổ cứng của bạn.
+addvault.new.readme.accessLocation.4=Bạn hoàn toàn có thể xoá tập tin này.
## Existing
addvaultwizard.existing.chooseBtn=Chọn…
+addvaultwizard.existing.filePickerTitle=Chọn Tập Tin Vault
addvaultwizard.existing.filePickerMimeDesc=Cryptomator Vault
## Success
addvaultwizard.success.nextStepsInstructions=Vault "%s" đã được thêm.\nBạn cần mở khóa vault để truy cập hoặc thêm nội dung. Ngoài ra, bạn có thể mở khóa ở bất kì lúc nào sau đó.
@@ -85,6 +91,7 @@ addvaultwizard.success.unlockNow=Mở khóa bây giờ
# Remove Vault
removeVault.title=Xóa Vault
+removeVault.message=Xoá vault?
removeVault.description=Điều này sẽ chỉ làm cho Cryptomator quên đi vault này. Bạn có thể thêm lại sau. Không có tệp được mã hóa nào sẽ bị xóa khỏi ổ cứng của bạn.
removeVault.confirmBtn=Xóa Vault
@@ -113,6 +120,7 @@ unlock.success.revealBtn=Hiển thị Drive
## Failure
unlock.error.message=Không thể mở vault
### Invalid Mount Point
+unlock.error.invalidMountPoint.driveLetterOccupied=Ký tự cho Ổ cứng "%s" đã được sử dụng.
## Hub
### Waiting
hub.auth.message=Đang chờ xác thực…
@@ -173,6 +181,9 @@ health.fail.ioError=Đã xảy ra lỗi khi truy cập và đọc tệp config.
health.fail.moreInfo=Thêm thông tin
## Check Selection
## Detail view
+health.check.detail.checkScheduled=Việc kiểm tra đã được lên lịch.
+health.check.detail.checkFinished=Việc kiểm tra đã kết thúc thành công.
+health.check.detail.checkCancelled=Việc kiểm tra đã bị huỷ bỏ.
health.check.exportBtn=Xuất Báo Cáo
## Fix Application
health.fix.fixBtn=Sửa
@@ -194,6 +205,7 @@ preferences.interface=Giao diện
preferences.interface.theme.automatic=Tự động
preferences.interface.theme.dark=Tối
preferences.interface.theme.light=Sáng
+preferences.interface.unlockThemes=Mở khoá chủ đề nền tối
preferences.interface.language=Ngôn ngữ (yêu cầu khởi động lại)
preferences.interface.language.auto=Mặc định hệ thống
preferences.interface.interfaceOrientation=Định hướng giao diện
@@ -203,6 +215,8 @@ preferences.interface.showMinimizeButton=Hiện nút thu nhỏ
preferences.interface.showTrayIcon=Hiển thị biểu tượng khay (yêu cầu khởi động lại)
## Volume
preferences.volume=Ổ lưu trữ ảo
+preferences.volume.type=Kiểu Phân Vùng
+preferences.volume.webdav.port=Cổng của WebDAV
## Updates
preferences.updates=Cập nhật
preferences.updates.currentVersion=Phiên bản hiện tại: %s
@@ -211,6 +225,7 @@ preferences.updates.checkNowBtn=Kiểm tra ngay
preferences.updates.updateAvailable=Có bản cập nhật lên phiên bản %s.
## Contribution
preferences.contribute=Hỗ trợ chúng tôi
+preferences.contribute.registeredFor=Chứng nhận Người Hỗ Trợ được đăng ký cho %s
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -219,6 +234,11 @@ preferences.about=Giới thiệu
# Vault Statistics
stats.title=Thống kê về %s
## Read
+stats.read.throughput.mibs=Đọc: %.2f MiB/s
+stats.read.total.data.none=Dữ liệu đã đọc: -
+stats.read.total.data.kib=Dữ liệu đã đọc: %.1f kiB
+stats.read.total.data.mib=Dữ liệu đã đọc: %.1f MiB
+stats.read.total.data.gib=Dữ liệu đã đọc: %.1f GiB
## Write
# Main Window