From 4944a634fb9a3bd36e72abf04a30b38bcea52e4e Mon Sep 17 00:00:00 2001 From: Martin Beyer Date: Thu, 14 Apr 2022 15:47:41 +0200 Subject: [PATCH 01/84] Add counter for file access --- .../cryptomator/common/vaults/VaultStats.java | 23 +++++++++++++++++++ .../ui/stats/VaultStatisticsController.java | 23 +++++++++++++++++++ src/main/resources/fxml/stats.fxml | 17 ++++++++++++++ src/main/resources/i18n/strings.properties | 4 ++++ 4 files changed, 67 insertions(+) diff --git a/src/main/java/org/cryptomator/common/vaults/VaultStats.java b/src/main/java/org/cryptomator/common/vaults/VaultStats.java index ac0b8df38..f5733fcd2 100644 --- a/src/main/java/org/cryptomator/common/vaults/VaultStats.java +++ b/src/main/java/org/cryptomator/common/vaults/VaultStats.java @@ -34,13 +34,16 @@ public class VaultStats { private final LongProperty bytesPerSecondWritten = new SimpleLongProperty(); private final LongProperty bytesPerSecondEncrypted = new SimpleLongProperty(); private final LongProperty bytesPerSecondDecrypted = new SimpleLongProperty(); + private final LongProperty bytesPerSecondAccessed = new SimpleLongProperty(); private final DoubleProperty cacheHitRate = new SimpleDoubleProperty(); private final LongProperty totalBytesRead = new SimpleLongProperty(); private final LongProperty totalBytesWritten = new SimpleLongProperty(); private final LongProperty totalBytesEncrypted = new SimpleLongProperty(); private final LongProperty totalBytesDecrypted = new SimpleLongProperty(); + private final LongProperty totalBytesAccessed = new SimpleLongProperty(); private final LongProperty filesRead = new SimpleLongProperty(); private final LongProperty filesWritten = new SimpleLongProperty(); + private final LongProperty filesAccessed = new SimpleLongProperty(); private final ObjectProperty lastActivity = new SimpleObjectProperty<>(); @Inject @@ -75,13 +78,16 @@ public class VaultStats { cacheHitRate.set(stats.map(this::getCacheHitRate).orElse(0.0)); bytesPerSecondDecrypted.set(stats.map(CryptoFileSystemStats::pollBytesDecrypted).orElse(0L)); bytesPerSecondEncrypted.set(stats.map(CryptoFileSystemStats::pollBytesEncrypted).orElse(0L)); + bytesPerSecondAccessed.set(stats.map(CryptoFileSystemStats::pollBytesAccessed).orElse(0L)); totalBytesRead.set(stats.map(CryptoFileSystemStats::pollTotalBytesRead).orElse(0L)); totalBytesWritten.set(stats.map(CryptoFileSystemStats::pollTotalBytesWritten).orElse(0L)); totalBytesEncrypted.set(stats.map(CryptoFileSystemStats::pollTotalBytesEncrypted).orElse(0L)); totalBytesDecrypted.set(stats.map(CryptoFileSystemStats::pollTotalBytesDecrypted).orElse(0L)); + totalBytesAccessed.set(stats.map(CryptoFileSystemStats::pollTotalBytesAccessed).orElse(0L)); var oldAccessCount = filesRead.get() + filesWritten.get(); filesRead.set(stats.map(CryptoFileSystemStats::pollAmountOfAccessesRead).orElse(0L)); filesWritten.set(stats.map(CryptoFileSystemStats::pollAmountOfAccessesWritten).orElse(0L)); + filesAccessed.set(stats.map(CryptoFileSystemStats::pollAmountOfAccesses).orElse(0L)); var newAccessCount = filesRead.get() + filesWritten.get(); // check for any I/O activity @@ -158,6 +164,14 @@ public class VaultStats { return bytesPerSecondDecrypted.get(); } + public LongProperty bytesPerSecondAccessedProperty() { + return bytesPerSecondAccessed; + } + + public long getBytesPerSecondAccessed(){ + return bytesPerSecondAccessed.get(); + } + public DoubleProperty cacheHitRateProperty() { return cacheHitRate; } public double getCacheHitRate() { @@ -180,6 +194,10 @@ public class VaultStats { public long getTotalBytesDecrypted() { return totalBytesDecrypted.get();} + public LongProperty getTotalBytesAccessedProperty() {return totalBytesAccessed;} + + public long getTotalBytesAccessed() { return totalBytesAccessed.get();} + public LongProperty filesRead() { return filesRead;} public long getFilesRead() { return filesRead.get();} @@ -188,6 +206,11 @@ public class VaultStats { public long getFilesWritten() {return filesWritten.get();} + public LongProperty filesAccessed() { + return filesAccessed;} + + public long getFilesAccessed() {return filesAccessed.get();} + public ObjectProperty lastActivityProperty() { return lastActivity; } diff --git a/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java b/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java index 56729f1fe..ef4963168 100644 --- a/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java +++ b/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java @@ -9,8 +9,10 @@ import javax.inject.Inject; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; +import javafx.beans.binding.Bindings; import javafx.beans.binding.DoubleBinding; import javafx.beans.binding.LongBinding; +import javafx.beans.property.LongProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; @@ -21,6 +23,7 @@ import javafx.scene.chart.XYChart.Series; import javafx.stage.Stage; import javafx.util.Duration; import java.util.Arrays; +import java.util.concurrent.Callable; @VaultStatisticsScoped public class VaultStatisticsController implements FxController { @@ -42,10 +45,13 @@ public class VaultStatisticsController implements FxController { private final LongBinding totalBytesWritten; private final LongBinding totalBytesEncrypted; private final LongBinding totalBytesDecrypted; + private final LongBinding totalBytesAccessed; private final LongBinding filesRead; private final LongBinding filesWritten; + private final LongBinding filesAccessed; private final LongBinding bpsEncrypted; private final LongBinding bpsDecrypted; + private final LongBinding bpsAccessed; public AreaChart readChart; public AreaChart writeChart; @@ -69,10 +75,13 @@ public class VaultStatisticsController implements FxController { this.totalBytesWritten = WeakBindings.bindLong(stats.totalBytesWrittenProperty()); this.totalBytesDecrypted = WeakBindings.bindLong(stats.totalBytesDecryptedProperty()); this.totalBytesEncrypted = WeakBindings.bindLong(stats.totalBytesEncryptedProperty()); + this.totalBytesAccessed = WeakBindings.bindLong(stats.getTotalBytesAccessedProperty()); this.filesRead = WeakBindings.bindLong(stats.filesRead()); this.filesWritten = WeakBindings.bindLong(stats.filesWritten()); + this.filesAccessed = WeakBindings.bindLong(stats.filesAccessed()); this.bpsEncrypted = WeakBindings.bindLong(stats.bytesPerSecondEncryptedProperty()); this.bpsDecrypted = WeakBindings.bindLong(stats.bytesPerSecondDecryptedProperty()); + this.bpsAccessed = WeakBindings.bindLong(stats.bytesPerSecondAccessedProperty()); this.ioAnimation = new Timeline(); //TODO Research better timer ioAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(IO_SAMPLING_INTERVAL), new IoSamplingAnimationHandler(readData, writeData))); @@ -184,6 +193,10 @@ public class VaultStatisticsController implements FxController { public long getTotalBytesDecrypted() { return totalBytesDecrypted.get();} + public LongBinding getTotalBytesAccessedProperty() {return totalBytesAccessed;} + + public long getTotalBytesAccessed() { return totalBytesAccessed.get();} + public LongBinding bpsEncryptedProperty() { return bpsEncrypted; } @@ -200,6 +213,12 @@ public class VaultStatisticsController implements FxController { return bpsDecrypted.get(); } + public LongBinding bpsAccessedProperty() { + return bpsAccessed; + } + + public long getBpsAccessed(){ return bpsAccessed.get();} + public LongBinding filesReadProperty() { return filesRead;} public long getFilesRead() { return filesRead.get();} @@ -207,4 +226,8 @@ public class VaultStatisticsController implements FxController { public LongBinding filesWrittenProperty() {return filesWritten;} public long getFilesWritten() {return filesWritten.get();} + + public LongBinding filesAccessedProperty() {return filesAccessed;} + + public long getFilesAccessed() {return filesAccessed.get();} } diff --git a/src/main/resources/fxml/stats.fxml b/src/main/resources/fxml/stats.fxml index b17dc67f6..6d7cc8291 100644 --- a/src/main/resources/fxml/stats.fxml +++ b/src/main/resources/fxml/stats.fxml @@ -72,4 +72,21 @@ + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 0ea837435..dac3c021a 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -262,6 +262,10 @@ stats.encr.total.data.mib=Data encrypted: %.1f MiB stats.encr.total.data.gib=Data encrypted: %.1f GiB stats.write.accessCount=Total writes: %d +## Accesses +stats.access.accessCount=Total accessed: %d + + # Main Window main.closeBtn.tooltip=Close main.minimizeBtn.tooltip=Minimize From e3c609351fe69a091d66c7f33cfb661cd9e9f85d Mon Sep 17 00:00:00 2001 From: Martin Beyer Date: Thu, 5 May 2022 00:09:39 +0200 Subject: [PATCH 02/84] Add third stats graph, displaying general file(attribute) accesses --- pom.xml | 2 +- .../cryptomator/common/vaults/VaultStats.java | 26 +++++------ .../ui/stats/VaultStatisticsController.java | 45 ++++++++++++------- src/main/resources/fxml/stats.fxml | 9 ++-- src/main/resources/i18n/strings.properties | 3 +- 5 files changed, 47 insertions(+), 38 deletions(-) diff --git a/pom.xml b/pom.xml index c4290f374..7a74bf11b 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 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.4.1 + 2.5.0-SNAPSHOT 1.1.0 1.1.0 1.1.0 diff --git a/src/main/java/org/cryptomator/common/vaults/VaultStats.java b/src/main/java/org/cryptomator/common/vaults/VaultStats.java index f5733fcd2..43346b763 100644 --- a/src/main/java/org/cryptomator/common/vaults/VaultStats.java +++ b/src/main/java/org/cryptomator/common/vaults/VaultStats.java @@ -34,16 +34,15 @@ public class VaultStats { private final LongProperty bytesPerSecondWritten = new SimpleLongProperty(); private final LongProperty bytesPerSecondEncrypted = new SimpleLongProperty(); private final LongProperty bytesPerSecondDecrypted = new SimpleLongProperty(); - private final LongProperty bytesPerSecondAccessed = new SimpleLongProperty(); private final DoubleProperty cacheHitRate = new SimpleDoubleProperty(); private final LongProperty totalBytesRead = new SimpleLongProperty(); private final LongProperty totalBytesWritten = new SimpleLongProperty(); private final LongProperty totalBytesEncrypted = new SimpleLongProperty(); private final LongProperty totalBytesDecrypted = new SimpleLongProperty(); - private final LongProperty totalBytesAccessed = new SimpleLongProperty(); private final LongProperty filesRead = new SimpleLongProperty(); private final LongProperty filesWritten = new SimpleLongProperty(); private final LongProperty filesAccessed = new SimpleLongProperty(); + private final LongProperty totalFilesAccessed = new SimpleLongProperty(); private final ObjectProperty lastActivity = new SimpleObjectProperty<>(); @Inject @@ -78,16 +77,15 @@ public class VaultStats { cacheHitRate.set(stats.map(this::getCacheHitRate).orElse(0.0)); bytesPerSecondDecrypted.set(stats.map(CryptoFileSystemStats::pollBytesDecrypted).orElse(0L)); bytesPerSecondEncrypted.set(stats.map(CryptoFileSystemStats::pollBytesEncrypted).orElse(0L)); - bytesPerSecondAccessed.set(stats.map(CryptoFileSystemStats::pollBytesAccessed).orElse(0L)); totalBytesRead.set(stats.map(CryptoFileSystemStats::pollTotalBytesRead).orElse(0L)); totalBytesWritten.set(stats.map(CryptoFileSystemStats::pollTotalBytesWritten).orElse(0L)); totalBytesEncrypted.set(stats.map(CryptoFileSystemStats::pollTotalBytesEncrypted).orElse(0L)); totalBytesDecrypted.set(stats.map(CryptoFileSystemStats::pollTotalBytesDecrypted).orElse(0L)); - totalBytesAccessed.set(stats.map(CryptoFileSystemStats::pollTotalBytesAccessed).orElse(0L)); var oldAccessCount = filesRead.get() + filesWritten.get(); filesRead.set(stats.map(CryptoFileSystemStats::pollAmountOfAccessesRead).orElse(0L)); filesWritten.set(stats.map(CryptoFileSystemStats::pollAmountOfAccessesWritten).orElse(0L)); filesAccessed.set(stats.map(CryptoFileSystemStats::pollAmountOfAccesses).orElse(0L)); + totalFilesAccessed.set(stats.map(CryptoFileSystemStats::pollTotalAmountOfAccesses).orElse(0L)); var newAccessCount = filesRead.get() + filesWritten.get(); // check for any I/O activity @@ -164,14 +162,6 @@ public class VaultStats { return bytesPerSecondDecrypted.get(); } - public LongProperty bytesPerSecondAccessedProperty() { - return bytesPerSecondAccessed; - } - - public long getBytesPerSecondAccessed(){ - return bytesPerSecondAccessed.get(); - } - public DoubleProperty cacheHitRateProperty() { return cacheHitRate; } public double getCacheHitRate() { @@ -194,10 +184,6 @@ public class VaultStats { public long getTotalBytesDecrypted() { return totalBytesDecrypted.get();} - public LongProperty getTotalBytesAccessedProperty() {return totalBytesAccessed;} - - public long getTotalBytesAccessed() { return totalBytesAccessed.get();} - public LongProperty filesRead() { return filesRead;} public long getFilesRead() { return filesRead.get();} @@ -211,6 +197,14 @@ public class VaultStats { public long getFilesAccessed() {return filesAccessed.get();} + public LongProperty totalFilesAccessed(){ + return totalFilesAccessed; + } + + public long getTotalFilesAccessed(){ + return totalFilesAccessed.get(); + } + public ObjectProperty lastActivityProperty() { return lastActivity; } diff --git a/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java b/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java index ef4963168..dd294a457 100644 --- a/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java +++ b/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java @@ -35,6 +35,7 @@ public class VaultStatisticsController implements FxController { private final VaultStats stats; private final Series readData; private final Series writeData; + private final Series accessData; private final Timeline ioAnimation; private final LongBinding bpsRead; private final LongBinding bpsWritten; @@ -45,20 +46,22 @@ public class VaultStatisticsController implements FxController { private final LongBinding totalBytesWritten; private final LongBinding totalBytesEncrypted; private final LongBinding totalBytesDecrypted; - private final LongBinding totalBytesAccessed; private final LongBinding filesRead; private final LongBinding filesWritten; private final LongBinding filesAccessed; + private final LongBinding totalFilesAccessed; private final LongBinding bpsEncrypted; private final LongBinding bpsDecrypted; - private final LongBinding bpsAccessed; public AreaChart readChart; public AreaChart writeChart; + public AreaChart accessChart; public NumberAxis readChartXAxis; public NumberAxis readChartYAxis; public NumberAxis writeChartXAxis; public NumberAxis writeChartYAxis; + public NumberAxis accessChartXAxis; + public NumberAxis accessChartYAxis; @Inject public VaultStatisticsController(VaultStatisticsComponent component, @VaultStatisticsWindow Stage window, @VaultStatisticsWindow Vault vault) { @@ -66,6 +69,7 @@ public class VaultStatisticsController implements FxController { this.stats = vault.getStats(); this.readData = new Series<>(); this.writeData = new Series<>(); + this.accessData = new Series<>(); this.bpsRead = WeakBindings.bindLong(stats.bytesPerSecondReadProperty()); this.bpsWritten = WeakBindings.bindLong(stats.bytesPerSecondWrittenProperty()); this.cacheHitRate = WeakBindings.bindDouble(stats.cacheHitRateProperty()); @@ -75,16 +79,15 @@ public class VaultStatisticsController implements FxController { this.totalBytesWritten = WeakBindings.bindLong(stats.totalBytesWrittenProperty()); this.totalBytesDecrypted = WeakBindings.bindLong(stats.totalBytesDecryptedProperty()); this.totalBytesEncrypted = WeakBindings.bindLong(stats.totalBytesEncryptedProperty()); - this.totalBytesAccessed = WeakBindings.bindLong(stats.getTotalBytesAccessedProperty()); this.filesRead = WeakBindings.bindLong(stats.filesRead()); this.filesWritten = WeakBindings.bindLong(stats.filesWritten()); this.filesAccessed = WeakBindings.bindLong(stats.filesAccessed()); + this.totalFilesAccessed = WeakBindings.bindLong(stats.totalFilesAccessed()); this.bpsEncrypted = WeakBindings.bindLong(stats.bytesPerSecondEncryptedProperty()); this.bpsDecrypted = WeakBindings.bindLong(stats.bytesPerSecondDecryptedProperty()); - this.bpsAccessed = WeakBindings.bindLong(stats.bytesPerSecondAccessedProperty()); this.ioAnimation = new Timeline(); //TODO Research better timer - ioAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(IO_SAMPLING_INTERVAL), new IoSamplingAnimationHandler(readData, writeData))); + ioAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(IO_SAMPLING_INTERVAL), new IoSamplingAnimationHandler(readData, writeData, accessData))); ioAnimation.setCycleCount(Animation.INDEFINITE); ioAnimation.play(); @@ -98,6 +101,7 @@ public class VaultStatisticsController implements FxController { public void initialize() { readChart.getData().addAll(readData); writeChart.getData().addAll(writeData); + accessChart.getData().addAll(accessData); } private class IoSamplingAnimationHandler implements EventHandler { @@ -105,16 +109,21 @@ public class VaultStatisticsController implements FxController { private long step = IO_SAMPLING_STEPS; private final Series decryptedBytesRead; private final Series encryptedBytesWrite; + private final Series accessedFiles; private final long[] maxBuf = new long[IO_SAMPLING_STEPS]; + private final long[] maxAccessBuf = new long[IO_SAMPLING_STEPS]; - public IoSamplingAnimationHandler(Series readData, Series writeData) { + + public IoSamplingAnimationHandler(Series readData, Series writeData, Series accessData) { this.decryptedBytesRead = readData; this.encryptedBytesWrite = writeData; + this.accessedFiles = accessData; // initialize data once and change value of data points later: for (int i = 0; i < IO_SAMPLING_STEPS; i++) { decryptedBytesRead.getData().add(new Data<>(i, 0)); encryptedBytesWrite.getData().add(new Data<>(i, 0)); + accessedFiles.getData().add(new Data<>(i, 0)); } } @@ -123,17 +132,22 @@ public class VaultStatisticsController implements FxController { final long currentStep = step++; final long decBytes = stats.bytesPerSecondReadProperty().get(); final long encBytes = stats.bytesPerSecondWrittenProperty().get(); + final long accFiles = stats.filesAccessed().get(); maxBuf[(int) currentStep % IO_SAMPLING_STEPS] = Math.max(decBytes, encBytes); - long allTimeMax = Arrays.stream(maxBuf).max().orElse(0l); + long allTimeMax = Arrays.stream(maxBuf).max().orElse(0L); + maxAccessBuf[(int) currentStep % IO_SAMPLING_STEPS] = accFiles; + long allTimeMaxAccessedFiles = Arrays.stream(maxAccessBuf).max().orElse(0L); // remove oldest value: decryptedBytesRead.getData().remove(0); encryptedBytesWrite.getData().remove(0); + accessedFiles.getData().remove(0); // add latest value: decryptedBytesRead.getData().add(new Data<>(currentStep, decBytes)); encryptedBytesWrite.getData().add(new Data<>(currentStep, encBytes)); + accessedFiles.getData().add(new Data<>(currentStep, accFiles)); // adjust ranges: readChartXAxis.setLowerBound(currentStep - IO_SAMPLING_STEPS * 1.0); @@ -142,6 +156,9 @@ public class VaultStatisticsController implements FxController { writeChartXAxis.setLowerBound(currentStep - IO_SAMPLING_STEPS * 1.0); writeChartXAxis.setUpperBound(currentStep); writeChartYAxis.setUpperBound(allTimeMax); + accessChartXAxis.setLowerBound(currentStep - IO_SAMPLING_STEPS * 1.0); + accessChartXAxis.setUpperBound(currentStep); + accessChartYAxis.setUpperBound(allTimeMaxAccessedFiles); } } @@ -193,10 +210,6 @@ public class VaultStatisticsController implements FxController { public long getTotalBytesDecrypted() { return totalBytesDecrypted.get();} - public LongBinding getTotalBytesAccessedProperty() {return totalBytesAccessed;} - - public long getTotalBytesAccessed() { return totalBytesAccessed.get();} - public LongBinding bpsEncryptedProperty() { return bpsEncrypted; } @@ -213,12 +226,6 @@ public class VaultStatisticsController implements FxController { return bpsDecrypted.get(); } - public LongBinding bpsAccessedProperty() { - return bpsAccessed; - } - - public long getBpsAccessed(){ return bpsAccessed.get();} - public LongBinding filesReadProperty() { return filesRead;} public long getFilesRead() { return filesRead.get();} @@ -230,4 +237,8 @@ public class VaultStatisticsController implements FxController { public LongBinding filesAccessedProperty() {return filesAccessed;} public long getFilesAccessed() {return filesAccessed.get();} + + public LongBinding totalFilesAccessedProperty() {return totalFilesAccessed;} + + public long getTotalFilesAccessed() {return totalFilesAccessed.get();} } diff --git a/src/main/resources/fxml/stats.fxml b/src/main/resources/fxml/stats.fxml index 6d7cc8291..458eeedf8 100644 --- a/src/main/resources/fxml/stats.fxml +++ b/src/main/resources/fxml/stats.fxml @@ -74,19 +74,22 @@ - + - + - + + + + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 80f1449bf..41baf4efe 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -263,7 +263,8 @@ stats.encr.total.data.gib=Data encrypted: %.1f GiB stats.write.accessCount=Total writes: %d ## Accesses -stats.access.accessCount=Total accessed: %d +stats.access.totalAccessCount=Total accessed: %d +stats.access.accessCount=Currently accessed: %d # Main Window From e5e606f3aef11ece17bb5c0b756f99ee9bcf2c4a Mon Sep 17 00:00:00 2001 From: Edward Chow Date: Sun, 16 Oct 2022 17:33:44 +1100 Subject: [PATCH 03/84] refresh vault list on tray icon click (#2383) --- .../ui/traymenu/TrayMenuBuilder.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java index ea7358770..eed41e318 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java @@ -3,6 +3,7 @@ package org.cryptomator.ui.traymenu; import com.google.common.base.Preconditions; import org.apache.commons.lang3.SystemUtils; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.integrations.tray.ActionItem; import org.cryptomator.integrations.tray.SeparatorItem; import org.cryptomator.integrations.tray.SubMenuItem; @@ -20,6 +21,10 @@ import javax.inject.Inject; import javafx.application.Platform; import javafx.beans.Observable; import javafx.collections.ObservableList; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.io.IOException; import java.io.UncheckedIOException; import java.util.ArrayList; @@ -63,6 +68,36 @@ public class TrayMenuBuilder { try (var image = getClass().getResourceAsStream(SystemUtils.IS_OS_MAC_OSX ? TRAY_ICON_MAC : TRAY_ICON)) { trayMenu.showTrayIcon(image.readAllBytes(), this::showMainWindow, "Cryptomator"); + SystemTray tray = SystemTray.getSystemTray(); + TrayIcon trayIcon = tray.getTrayIcons()[0]; + trayIcon.addMouseListener(new MouseListener() { + @Override + public void mouseClicked(MouseEvent e) { + for (Vault vault : vaults) { + VaultListManager.redetermineVaultState(vault); + } + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + + } + }); rebuildMenu(); initialized = true; } catch (IOException e) { From f852ae039237727e9398f301b85e5c65ac683cf9 Mon Sep 17 00:00:00 2001 From: Edward Chow Date: Sun, 16 Oct 2022 22:26:30 +1100 Subject: [PATCH 04/84] remove AWT code and relocate to TrayMenuController --- pom.xml | 2 +- .../ui/traymenu/AwtTrayMenuController.java | 15 ++++++++++ .../ui/traymenu/TrayMenuBuilder.java | 29 ++----------------- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/pom.xml b/pom.xml index 20a4ffab2..c56af2617 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 2.1.0-rc1 2.4.4 - 1.1.0 + 1.1.1 1.1.2 1.1.2 1.1.0 diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java index 79f1dd628..2d0699064 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -19,6 +19,8 @@ import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.List; @CheckAvailability @@ -58,6 +60,19 @@ public class AwtTrayMenuController implements TrayMenuController { addChildren(menu, items); } + + @Override + public void onBeforeShow(Runnable listener) { + SystemTray systemTray = SystemTray.getSystemTray(); + TrayIcon trayIcon = systemTray.getTrayIcons()[0]; + trayIcon.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + listener.run(); + } + }); + } + private void addChildren(Menu menu, List items) { for (var item : items) { // TODO: use Pattern Matching for switch, once available diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java index eed41e318..83dca0370 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java @@ -70,32 +70,9 @@ public class TrayMenuBuilder { trayMenu.showTrayIcon(image.readAllBytes(), this::showMainWindow, "Cryptomator"); SystemTray tray = SystemTray.getSystemTray(); TrayIcon trayIcon = tray.getTrayIcons()[0]; - trayIcon.addMouseListener(new MouseListener() { - @Override - public void mouseClicked(MouseEvent e) { - for (Vault vault : vaults) { - VaultListManager.redetermineVaultState(vault); - } - } - - @Override - public void mousePressed(MouseEvent e) { - - } - - @Override - public void mouseReleased(MouseEvent e) { - - } - - @Override - public void mouseEntered(MouseEvent e) { - - } - - @Override - public void mouseExited(MouseEvent e) { - + trayMenu.onBeforeShow(() -> { + for (Vault vault : vaults) { + VaultListManager.redetermineVaultState(vault); } }); rebuildMenu(); From 445be3b668ca29368e6f8a71e9c5fbb63c91ad2b Mon Sep 17 00:00:00 2001 From: Edward Chow Date: Sun, 16 Oct 2022 22:36:25 +1100 Subject: [PATCH 05/84] remove straggling lines of awt code --- src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java index 83dca0370..358e76ed4 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java @@ -68,8 +68,6 @@ public class TrayMenuBuilder { try (var image = getClass().getResourceAsStream(SystemUtils.IS_OS_MAC_OSX ? TRAY_ICON_MAC : TRAY_ICON)) { trayMenu.showTrayIcon(image.readAllBytes(), this::showMainWindow, "Cryptomator"); - SystemTray tray = SystemTray.getSystemTray(); - TrayIcon trayIcon = tray.getTrayIcons()[0]; trayMenu.onBeforeShow(() -> { for (Vault vault : vaults) { VaultListManager.redetermineVaultState(vault); From dc310c009f5a820f50acba2b922347f4091e6b30 Mon Sep 17 00:00:00 2001 From: Edward Chow Date: Tue, 1 Nov 2022 22:14:29 +1100 Subject: [PATCH 06/84] rename to onBeforeOpenMenu and init local reference in showTrayIcon() --- pom.xml | 2 +- .../ui/traymenu/AwtTrayMenuController.java | 24 +++++++++++-------- .../ui/traymenu/TrayMenuBuilder.java | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index c56af2617..fa598e5d9 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 2.1.0-rc1 2.4.4 - 1.1.1 + 1.2.0 1.1.2 1.1.2 1.1.0 diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java index 2d0699064..e8fbc570e 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -30,6 +30,7 @@ public class AwtTrayMenuController implements TrayMenuController { private static final Logger LOG = LoggerFactory.getLogger(AwtTrayMenuController.class); private final PopupMenu menu = new PopupMenu(); + private TrayIcon trayIcon; @CheckAvailability public static boolean isAvailable() { @@ -39,7 +40,7 @@ public class AwtTrayMenuController implements TrayMenuController { @Override public void showTrayIcon(byte[] rawImageData, Runnable defaultAction, String tooltip) throws TrayMenuException { var image = Toolkit.getDefaultToolkit().createImage(rawImageData); - var trayIcon = new TrayIcon(image, tooltip, menu); + trayIcon = new TrayIcon(image, tooltip, menu); trayIcon.setImageAutoSize(true); if (SystemUtils.IS_OS_WINDOWS) { @@ -62,15 +63,18 @@ public class AwtTrayMenuController implements TrayMenuController { @Override - public void onBeforeShow(Runnable listener) { - SystemTray systemTray = SystemTray.getSystemTray(); - TrayIcon trayIcon = systemTray.getTrayIcons()[0]; - trayIcon.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - listener.run(); - } - }); + public void onBeforeOpenMenu(Runnable listener) { + try { + this.trayIcon.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + listener.run(); + } + }); + } catch (Exception e) { + throw new IllegalStateException("Tray icon not found.", e); + } + } private void addChildren(Menu menu, List items) { diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java index 358e76ed4..fc7c344fd 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java @@ -68,7 +68,7 @@ public class TrayMenuBuilder { try (var image = getClass().getResourceAsStream(SystemUtils.IS_OS_MAC_OSX ? TRAY_ICON_MAC : TRAY_ICON)) { trayMenu.showTrayIcon(image.readAllBytes(), this::showMainWindow, "Cryptomator"); - trayMenu.onBeforeShow(() -> { + trayMenu.onBeforeOpenMenu(() -> { for (Vault vault : vaults) { VaultListManager.redetermineVaultState(vault); } From 6caf132cfb1fdef4759505aba38dd4c50b25fe58 Mon Sep 17 00:00:00 2001 From: Tobias Hagemann Date: Thu, 10 Nov 2022 18:18:34 +0100 Subject: [PATCH 07/84] fixes #2512 --- .../ChooseExistingVaultController.java | 82 +++++++++++++++++-- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java index 432007c99..50cbb73e0 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java @@ -2,10 +2,15 @@ package org.cryptomator.ui.addvaultwizard; import dagger.Lazy; import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.common.LicenseHolder; import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.UiTheme; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultListManager; +import org.cryptomator.integrations.uiappearance.Theme; +import org.cryptomator.integrations.uiappearance.UiAppearanceException; +import org.cryptomator.integrations.uiappearance.UiAppearanceListener; +import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; @@ -15,6 +20,8 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.Scene; import javafx.scene.image.Image; @@ -23,6 +30,7 @@ import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.util.Optional; import java.util.ResourceBundle; import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB; @@ -41,11 +49,14 @@ public class ChooseExistingVaultController implements FxController { private final VaultListManager vaultListManager; private final ResourceBundle resourceBundle; private final Settings settings; + private final Optional appearanceProvider; + private final LicenseHolder licenseHolder; + private final UiAppearanceListener systemInterfaceThemeListener = this::systemInterfaceThemeChanged; - private Image screenshot; + private final ObjectProperty screenshot = new SimpleObjectProperty<>(); @Inject - ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, Settings settings) { + ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, Settings settings, Optional appearanceProvider, LicenseHolder licenseHolder) { this.window = window; this.welcomeScene = welcomeScene; this.successScene = successScene; @@ -55,17 +66,73 @@ public class ChooseExistingVaultController implements FxController { this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; this.settings = settings; + this.appearanceProvider = appearanceProvider; + this.licenseHolder = licenseHolder; } @FXML public void initialize() { if (SystemUtils.IS_OS_MAC) { - this.screenshot = new Image(getClass().getResource("/img/select-masterkey-mac"+(UiTheme.LIGHT == settings.theme().get()? "":"-dark")+".png").toString()); + settings.theme().addListener(this::appThemeChanged); + setSelectedMacScreenshot(settings.theme().get()); } else { - this.screenshot = new Image(getClass().getResource("/img/select-masterkey-win.png").toString()); + this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-win.png").toString())); } } + private void appThemeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") UiTheme oldValue, UiTheme newValue) { + if (appearanceProvider.isPresent() && oldValue == UiTheme.AUTOMATIC && newValue != UiTheme.AUTOMATIC) { + try { + appearanceProvider.get().removeListener(systemInterfaceThemeListener); + } catch (UiAppearanceException e) { + LOG.error("Failed to disable automatic theme switching."); + } + } + setSelectedMacScreenshot(newValue); + } + + private void setSelectedMacScreenshot(UiTheme desiredTheme) { + UiTheme theme = licenseHolder.isValidLicense() ? desiredTheme : UiTheme.LIGHT; + switch (theme) { + case LIGHT -> setLightMacScreenshot(); + case DARK -> setDarkMacScreenshot(); + case AUTOMATIC -> { + appearanceProvider.ifPresent(provider -> { + try { + provider.addListener(systemInterfaceThemeListener); + } catch (UiAppearanceException e) { + LOG.error("Failed to enable automatic theme switching."); + } + }); + setSystemMacScreenshot(); + } + } + } + + private void systemInterfaceThemeChanged(Theme theme) { + switch (theme) { + case LIGHT -> setLightMacScreenshot(); + case DARK -> setDarkMacScreenshot(); + } + } + + private void setSystemMacScreenshot() { + if (appearanceProvider.isPresent()) { + systemInterfaceThemeChanged(appearanceProvider.get().getSystemTheme()); + } else { + LOG.warn("No UiAppearanceProvider present, assuming LIGHT theme..."); + setLightMacScreenshot(); + } + } + + private void setLightMacScreenshot() { + this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac.png").toString())); + } + + private void setDarkMacScreenshot() { + this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac-dark.png").toString())); + } + @FXML public void back() { window.setScene(welcomeScene.get()); @@ -92,8 +159,13 @@ public class ChooseExistingVaultController implements FxController { /* Getter */ - public Image getScreenshot() { + public ObjectProperty screenshotProperty() { return screenshot; } + public Image getScreenshot() { + return screenshot.get(); + } + + } From dda7255d8e2f303c05660fd844aab488dff8e994 Mon Sep 17 00:00:00 2001 From: Tobias Hagemann Date: Thu, 10 Nov 2022 18:36:14 +0100 Subject: [PATCH 08/84] deduplicated code --- .../ChooseExistingVaultController.java | 75 +++---------------- .../ui/fxapp/FxApplicationStyle.java | 11 ++- 2 files changed, 21 insertions(+), 65 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java index 50cbb73e0..0a0dc3d2e 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java @@ -2,18 +2,13 @@ package org.cryptomator.ui.addvaultwizard; import dagger.Lazy; import org.apache.commons.lang3.SystemUtils; -import org.cryptomator.common.LicenseHolder; -import org.cryptomator.common.settings.Settings; -import org.cryptomator.common.settings.UiTheme; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.integrations.uiappearance.Theme; -import org.cryptomator.integrations.uiappearance.UiAppearanceException; -import org.cryptomator.integrations.uiappearance.UiAppearanceListener; -import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; +import org.cryptomator.ui.fxapp.FxApplicationStyle; import org.cryptomator.ui.fxapp.FxApplicationWindows; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +25,6 @@ import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.nio.file.Path; -import java.util.Optional; import java.util.ResourceBundle; import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB; @@ -48,15 +42,12 @@ public class ChooseExistingVaultController implements FxController { private final ObjectProperty vault; private final VaultListManager vaultListManager; private final ResourceBundle resourceBundle; - private final Settings settings; - private final Optional appearanceProvider; - private final LicenseHolder licenseHolder; - private final UiAppearanceListener systemInterfaceThemeListener = this::systemInterfaceThemeChanged; + private final FxApplicationStyle applicationStyle; private final ObjectProperty screenshot = new SimpleObjectProperty<>(); @Inject - ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, Settings settings, Optional appearanceProvider, LicenseHolder licenseHolder) { + ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, FxApplicationStyle applicationStyle) { this.window = window; this.welcomeScene = welcomeScene; this.successScene = successScene; @@ -65,74 +56,30 @@ public class ChooseExistingVaultController implements FxController { this.vault = vault; this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; - this.settings = settings; - this.appearanceProvider = appearanceProvider; - this.licenseHolder = licenseHolder; + this.applicationStyle = applicationStyle; } @FXML public void initialize() { if (SystemUtils.IS_OS_MAC) { - settings.theme().addListener(this::appThemeChanged); - setSelectedMacScreenshot(settings.theme().get()); + applicationStyle.appliedThemeProperty().addListener(this::appliedThemeChanged); + setMacScreenshot(applicationStyle.appliedThemeProperty().get()); } else { this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-win.png").toString())); } } - private void appThemeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") UiTheme oldValue, UiTheme newValue) { - if (appearanceProvider.isPresent() && oldValue == UiTheme.AUTOMATIC && newValue != UiTheme.AUTOMATIC) { - try { - appearanceProvider.get().removeListener(systemInterfaceThemeListener); - } catch (UiAppearanceException e) { - LOG.error("Failed to disable automatic theme switching."); - } - } - setSelectedMacScreenshot(newValue); + private void appliedThemeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") Theme oldValue, Theme newValue) { + setMacScreenshot(newValue); } - private void setSelectedMacScreenshot(UiTheme desiredTheme) { - UiTheme theme = licenseHolder.isValidLicense() ? desiredTheme : UiTheme.LIGHT; + private void setMacScreenshot(Theme theme) { switch (theme) { - case LIGHT -> setLightMacScreenshot(); - case DARK -> setDarkMacScreenshot(); - case AUTOMATIC -> { - appearanceProvider.ifPresent(provider -> { - try { - provider.addListener(systemInterfaceThemeListener); - } catch (UiAppearanceException e) { - LOG.error("Failed to enable automatic theme switching."); - } - }); - setSystemMacScreenshot(); - } + case LIGHT -> this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac.png").toString())); + case DARK -> this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac-dark.png").toString())); } } - private void systemInterfaceThemeChanged(Theme theme) { - switch (theme) { - case LIGHT -> setLightMacScreenshot(); - case DARK -> setDarkMacScreenshot(); - } - } - - private void setSystemMacScreenshot() { - if (appearanceProvider.isPresent()) { - systemInterfaceThemeChanged(appearanceProvider.get().getSystemTheme()); - } else { - LOG.warn("No UiAppearanceProvider present, assuming LIGHT theme..."); - setLightMacScreenshot(); - } - } - - private void setLightMacScreenshot() { - this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac.png").toString())); - } - - private void setDarkMacScreenshot() { - this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac-dark.png").toString())); - } - @FXML public void back() { window.setScene(welcomeScene.get()); diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationStyle.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationStyle.java index 711da7948..b6681f728 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationStyle.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationStyle.java @@ -12,6 +12,8 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.application.Application; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import java.util.Optional; @@ -24,9 +26,10 @@ public class FxApplicationStyle { private final Optional appearanceProvider; private final LicenseHolder licenseHolder; private final UiAppearanceListener systemInterfaceThemeListener = this::systemInterfaceThemeChanged; + private final ObjectProperty appliedTheme = new SimpleObjectProperty<>(Theme.LIGHT); @Inject - public FxApplicationStyle(Settings settings, Optional appearanceProvider, LicenseHolder licenseHolder){ + public FxApplicationStyle(Settings settings, Optional appearanceProvider, LicenseHolder licenseHolder) { this.settings = settings; this.appearanceProvider = appearanceProvider; this.licenseHolder = licenseHolder; @@ -91,6 +94,7 @@ public class FxApplicationStyle { } else { Application.setUserAgentStylesheet(stylesheet.toString()); appearanceProvider.ifPresent(provider -> provider.adjustToTheme(Theme.LIGHT)); + appliedTheme.set(Theme.LIGHT); } } @@ -103,6 +107,11 @@ public class FxApplicationStyle { } else { Application.setUserAgentStylesheet(stylesheet.toString()); appearanceProvider.ifPresent(provider -> provider.adjustToTheme(Theme.DARK)); + appliedTheme.set(Theme.DARK); } } + + public ObjectProperty appliedThemeProperty() { + return appliedTheme; + } } From 1486826883ade9eb34dc324af163e4c9717b64d5 Mon Sep 17 00:00:00 2001 From: Edward Chow Date: Sat, 12 Nov 2022 22:19:22 +1100 Subject: [PATCH 09/84] remove unused imports --- .../java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java index fc7c344fd..e96446143 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java @@ -21,10 +21,6 @@ import javax.inject.Inject; import javafx.application.Platform; import javafx.beans.Observable; import javafx.collections.ObservableList; -import java.awt.SystemTray; -import java.awt.TrayIcon; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.io.IOException; import java.io.UncheckedIOException; import java.util.ArrayList; From 1414ab4681fd9f2725da0a0beb6667cf5a741b88 Mon Sep 17 00:00:00 2001 From: Edward Chow Date: Sat, 12 Nov 2022 22:26:08 +1100 Subject: [PATCH 10/84] use preconditions instead of try...catch --- .../ui/traymenu/AwtTrayMenuController.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java index e8fbc570e..4b6a96bca 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -1,5 +1,6 @@ package org.cryptomator.ui.traymenu; +import dagger.internal.Preconditions; import org.apache.commons.lang3.SystemUtils; import org.cryptomator.integrations.common.CheckAvailability; import org.cryptomator.integrations.common.Priority; @@ -64,17 +65,13 @@ public class AwtTrayMenuController implements TrayMenuController { @Override public void onBeforeOpenMenu(Runnable listener) { - try { - this.trayIcon.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - listener.run(); - } - }); - } catch (Exception e) { - throw new IllegalStateException("Tray icon not found.", e); - } - + Preconditions.checkNotNull(this.trayIcon); + this.trayIcon.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + listener.run(); + } + }); } private void addChildren(Menu menu, List items) { From d8ed9f854ad94f41fe536d1582e96d7508e22dd4 Mon Sep 17 00:00:00 2001 From: Edward Chow Date: Sun, 13 Nov 2022 11:42:41 +1100 Subject: [PATCH 11/84] update pom.xml for integrations-api 1.2.0-beta1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fa598e5d9..39ede10a8 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 2.1.0-rc1 2.4.4 - 1.2.0 + 1.2.0-beta1 1.1.2 1.1.2 1.1.0 From 759c21e5cf44f00ded62d563bd15ec2a4ef6979b Mon Sep 17 00:00:00 2001 From: Edward Chow Date: Sun, 13 Nov 2022 11:43:05 +1100 Subject: [PATCH 12/84] fix preconditions import --- .../java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java index 4b6a96bca..c82cea239 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -1,6 +1,6 @@ package org.cryptomator.ui.traymenu; -import dagger.internal.Preconditions; +import com.google.common.base.Preconditions; import org.apache.commons.lang3.SystemUtils; import org.cryptomator.integrations.common.CheckAvailability; import org.cryptomator.integrations.common.Priority; From 37f89fd2352485905d076e523ed3db94f344be6a Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 18 Nov 2022 10:46:22 +0100 Subject: [PATCH 13/84] Move release precondition checks to own workflow (#2535) --- .github/workflows/build.yml | 35 ----------------------- .github/workflows/release-check.yml | 43 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/release-check.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 94c9ab037..d94048ee9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,44 +13,9 @@ defaults: shell: bash jobs: - release-check-precondition: - name: Validate pushed commit to release/hotfix branch or pushed tag - runs-on: ubuntu-latest - if: "(startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/hotfix/') || startsWith(github.ref, 'refs/heads/release/')) - && !(contains(github.event.head_commit.message, '[ci skip]') || contains(github.event.head_commit.message, '[skip ci]'))" - steps: - - uses: actions/checkout@v2 - - id: validate-pom-version - name: Validate POM version - run: | - if [[ $GITHUB_REF =~ refs/heads/(hotfix|release)/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR=${GITHUB_REF##*/} - elif [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR=${GITHUB_REF##*/} - else - echo "Failed to parse version" - exit 1 - fi - - if [[ ${SEM_VER_STR} == `mvn help:evaluate -Dexpression=project.version -q -DforceStdout` ]]; then - echo "::set-output name=semVerStr::${SEM_VER_STR}" - else - echo "Version not set in POM" - exit 1 - fi - - name: Validate release in org.cryptomator.Cryptomator.metainfo.xml file - run: | - if ! grep -q "" dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml; then - echo "Release not set in dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml" - exit 1 - fi test: name: Compile and Test - needs: release-check-precondition runs-on: ubuntu-latest - if: "always() - && (needs.release-check-precondition.result=='success' || needs.release-check-precondition.result=='skipped') - && !(contains(github.event.head_commit.message, '[ci skip]') || contains(github.event.head_commit.message, '[skip ci]'))" steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 diff --git a/.github/workflows/release-check.yml b/.github/workflows/release-check.yml new file mode 100644 index 000000000..e2f116130 --- /dev/null +++ b/.github/workflows/release-check.yml @@ -0,0 +1,43 @@ +name: Release Check + +on: + push: + branches: + - 'release/**' + - 'hotfix/**' + +env: + JAVA_VERSION: 19 + +defaults: + run: + shell: bash + +jobs: + release-check-precondition: + name: Validate commits pushed to release/hotfix branch to fulfill release requirements + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - id: validate-pom-version + name: Validate POM version + run: | + if [[ $GITHUB_REF =~ refs/heads/(hotfix|release)/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then + SEM_VER_STR=${GITHUB_REF##*/} + else + echo "Failed to parse version" + exit 1 + fi + + if [[ ${SEM_VER_STR} == `mvn help:evaluate -Dexpression=project.version -q -DforceStdout` ]]; then + echo "::set-output name=semVerStr::${SEM_VER_STR}" + else + echo "Version not set in POM" + exit 1 + fi + - name: Validate release in org.cryptomator.Cryptomator.metainfo.xml file + run: | + if ! grep -q "" dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml; then + echo "Release not set in dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml" + exit 1 + fi \ No newline at end of file From 14d0d95f23a80d37ec2b0318fa5ac742d5dcb23c Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 18 Nov 2022 11:20:51 +0100 Subject: [PATCH 14/84] add variable to skip legacy check in installer --- dist/win/resources/main.wxs | 20 ++++++++++---------- dist/win/resources/overrides.wxi | 4 ++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/dist/win/resources/main.wxs b/dist/win/resources/main.wxs index b8703a14d..659a89979 100644 --- a/dist/win/resources/main.wxs +++ b/dist/win/resources/main.wxs @@ -65,16 +65,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/dist/win/resources/overrides.wxi b/dist/win/resources/overrides.wxi index 60133a35b..3d63573cc 100644 --- a/dist/win/resources/overrides.wxi +++ b/dist/win/resources/overrides.wxi @@ -36,4 +36,8 @@ Default value is `yes`. + + From 38062f9a8d58b3db9257cafed9bbec7256ab2562 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 18 Nov 2022 11:32:39 +0100 Subject: [PATCH 15/84] Move Cryptomator installer defaults to actual installer file --- dist/win/resources/main.wxs | 7 ++++++- dist/win/resources/overrides.wxi | 21 ++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/dist/win/resources/main.wxs b/dist/win/resources/main.wxs index 659a89979..d6247bf05 100644 --- a/dist/win/resources/main.wxs +++ b/dist/win/resources/main.wxs @@ -23,6 +23,11 @@ + + + + + - + diff --git a/dist/win/resources/overrides.wxi b/dist/win/resources/overrides.wxi index 3d63573cc..c4c946868 100644 --- a/dist/win/resources/overrides.wxi +++ b/dist/win/resources/overrides.wxi @@ -1,7 +1,7 @@ - - - - + - +Non-opening ProgID settings: +- IconFileEncryptedData +Full file name of icon file used for encrypted data files. Default is "Cryptomator-Vault.ico" - From 043184cf530088425b9c5032da61966c0598ad7d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 18 Nov 2022 12:36:10 +0100 Subject: [PATCH 16/84] set loopback device alias during build instead of hardcode --- .github/workflows/win-exe.yml | 12 ++++++++++++ dist/win/build.ps1 | 9 +++++++++ dist/win/contrib/patchWebDAV.bat | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 46e1dbed1..dd2bdb8a2 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -22,6 +22,8 @@ jobs: build-msi: name: Build .msi Installer runs-on: windows-latest + env: + LOOPBACK_ALIAS: 'cryptomator-vault' steps: - uses: actions/checkout@v3 with: @@ -105,6 +107,16 @@ jobs: - name: Patch Application Directory run: | cp dist/win/contrib/* appdir/Cryptomator + - name: Set LOOPBACK_ALIAS in patchWebDAV.bat + shell: pwsh + run: | + $patchScript = "appdir\Cryptomator\patchWebDAV.bat" + try { + (Get-Content $patchScript ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"${{ evn.LOOPBACK_ALIAS}}`"" | Set-Content $patchScript + } catch { + Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat" + exit 1 + } - name: Fix permissions run: attrib -r appdir/Cryptomator/Cryptomator.exe shell: pwsh diff --git a/dist/win/build.ps1 b/dist/win/build.ps1 index 50cdbd011..940384f64 100644 --- a/dist/win/build.ps1 +++ b/dist/win/build.ps1 @@ -105,6 +105,15 @@ if ($clean -and (Test-Path -Path $appPath)) { # patch app dir Copy-Item "contrib\*" -Destination "$AppName" attrib -r "$AppName\$AppName.exe" +# patch batch script to set hostfile +$webDAVPatcher = "$AppName\patchWebDAV.bat" +$alias = 'cryptomator-vault' +try { + (Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$alias`"" | Set-Content $webDAVPatcher +} catch { + Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat" + exit 1 +} # create .msi $Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources" diff --git a/dist/win/contrib/patchWebDAV.bat b/dist/win/contrib/patchWebDAV.bat index 1726147d2..aad226881 100644 --- a/dist/win/contrib/patchWebDAV.bat +++ b/dist/win/contrib/patchWebDAV.bat @@ -1,6 +1,6 @@ @echo off :: Default values for Cryptomator builds -SET LOOPBACK_ALIAS="cryptomator-vault" +::REPLACE ME cd %~dp0 powershell -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -Command .\patchWebDAV.ps1^ From 5729e2885d73819942d7a97aeca789ea3b0205a2 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 18 Nov 2022 12:41:29 +0100 Subject: [PATCH 17/84] fix typo [ci skip] --- .github/workflows/win-exe.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index dd2bdb8a2..f1a2b3515 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -112,7 +112,7 @@ jobs: run: | $patchScript = "appdir\Cryptomator\patchWebDAV.bat" try { - (Get-Content $patchScript ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"${{ evn.LOOPBACK_ALIAS}}`"" | Set-Content $patchScript + (Get-Content $patchScript ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"${{ env.LOOPBACK_ALIAS}}`"" | Set-Content $patchScript } catch { Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat" exit 1 From 13debaafbe52e93cc996555f322344d6af55c0ad Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 18 Nov 2022 13:34:38 +0100 Subject: [PATCH 18/84] set loopback alias in Cryptomator app during build time --- .github/workflows/win-exe.yml | 1 + dist/win/build.ps1 | 5 ++-- .../org/cryptomator/common/Environment.java | 17 ++++++------- .../common/vaults/WebDavVolume.java | 24 ++++++++++--------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index f1a2b3515..244cbfc36 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -98,6 +98,7 @@ jobs: --java-options "-Dcryptomator.p12Path=\"~/AppData/Roaming/Cryptomator/key.p12\"" --java-options "-Dcryptomator.ipcSocketPath=\"~/AppData/Roaming/Cryptomator/ipc.socket\"" --java-options "-Dcryptomator.mountPointsDir=\"~/Cryptomator\"" + --java-options "-Dcryptomator.loopbackAlias=\"${{ env.LOOPBACK_ALIAS }}\"" --java-options "-Dcryptomator.showTrayIcon=true" --java-options "-Dcryptomator.buildNumber=\"msi-${{ steps.versions.outputs.revNum }}\"" --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\"" diff --git a/dist/win/build.ps1 b/dist/win/build.ps1 index 940384f64..565194e7d 100644 --- a/dist/win/build.ps1 +++ b/dist/win/build.ps1 @@ -35,6 +35,7 @@ Write-Output "`$buildDir=$buildDir" Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME" $copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor" +$loopbackAlias = 'cryptomator-vault' # compile &mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin @@ -85,6 +86,7 @@ if ($clean -and (Test-Path -Path $appPath)) { --java-options "-Dcryptomator.ipcSocketPath=`"~/AppData/Roaming/$AppName/ipc.socket`"" ` --java-options "-Dcryptomator.p12Path=`"~/AppData/Roaming/$AppName/key.p12`"" ` --java-options "-Dcryptomator.mountPointsDir=`"~/$AppName`"" ` + --java-options "-Dcryptomator.loopbackAlias=`"$loopbackAlias`"" ` --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" ` --java-options "-Dcryptomator.integrationsWin.keychainPaths=`"~/AppData/Roaming/$AppName/keychain.json`"" ` --java-options "-Dcryptomator.showTrayIcon=true" ` @@ -107,9 +109,8 @@ Copy-Item "contrib\*" -Destination "$AppName" attrib -r "$AppName\$AppName.exe" # patch batch script to set hostfile $webDAVPatcher = "$AppName\patchWebDAV.bat" -$alias = 'cryptomator-vault' try { - (Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$alias`"" | Set-Content $webDAVPatcher + (Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$loopbackAlias`"" | Set-Content $webDAVPatcher } catch { Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat" exit 1 diff --git a/src/main/java/org/cryptomator/common/Environment.java b/src/main/java/org/cryptomator/common/Environment.java index 261750ad1..383261119 100644 --- a/src/main/java/org/cryptomator/common/Environment.java +++ b/src/main/java/org/cryptomator/common/Environment.java @@ -26,6 +26,7 @@ public class Environment { private static final String KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.keychainPaths"; private static final String P12_PATH_PROP_NAME = "cryptomator.p12Path"; private static final String LOG_DIR_PROP_NAME = "cryptomator.logDir"; + private static final String LOOPBACK_ALIAS_PROP_NAME = "cryptomator.loopbackAlias"; private static final String MOUNTPOINT_DIR_PROP_NAME = "cryptomator.mountPointsDir"; private static final String MIN_PW_LENGTH_PROP_NAME = "cryptomator.minPwLength"; private static final String APP_VERSION_PROP_NAME = "cryptomator.appVersion"; @@ -45,6 +46,7 @@ public class Environment { logCryptomatorSystemProperty(IPC_SOCKET_PATH_PROP_NAME); logCryptomatorSystemProperty(KEYCHAIN_PATHS_PROP_NAME); logCryptomatorSystemProperty(LOG_DIR_PROP_NAME); + logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME); logCryptomatorSystemProperty(PLUGIN_DIR_PROP_NAME); logCryptomatorSystemProperty(MOUNTPOINT_DIR_PROP_NAME); logCryptomatorSystemProperty(MIN_PW_LENGTH_PROP_NAME); @@ -90,6 +92,10 @@ public class Environment { return getPath(LOG_DIR_PROP_NAME).map(this::replaceHomeDir); } + public Optional getLoopbackAlias() { + return Optional.ofNullable(System.getProperty(LOOPBACK_ALIAS_PROP_NAME)); + } + public Optional getPluginDir() { return getPath(PLUGIN_DIR_PROP_NAME).map(this::replaceHomeDir); } @@ -112,22 +118,13 @@ public class Environment { } public int getMinPwLength() { - return getInt(MIN_PW_LENGTH_PROP_NAME, DEFAULT_MIN_PW_LENGTH); + return Integer.getInteger(MIN_PW_LENGTH_PROP_NAME, DEFAULT_MIN_PW_LENGTH); } public boolean showTrayIcon() { return Boolean.getBoolean(TRAY_ICON_PROP_NAME); } - private int getInt(String propertyName, int defaultValue) { - String value = System.getProperty(propertyName); - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { // includes "null" values - return defaultValue; - } - } - private Optional getPath(String propertyName) { String value = System.getProperty(propertyName); return Optional.ofNullable(value).map(Paths::get); diff --git a/src/main/java/org/cryptomator/common/vaults/WebDavVolume.java b/src/main/java/org/cryptomator/common/vaults/WebDavVolume.java index 3ac1820d4..af7ca10f2 100644 --- a/src/main/java/org/cryptomator/common/vaults/WebDavVolume.java +++ b/src/main/java/org/cryptomator/common/vaults/WebDavVolume.java @@ -2,6 +2,7 @@ package org.cryptomator.common.vaults; import com.google.common.base.CharMatcher; +import org.cryptomator.common.Environment; import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.settings.VolumeImpl; @@ -22,12 +23,11 @@ import java.util.function.Supplier; public class WebDavVolume implements Volume { - private static final String LOCALHOST_ALIAS = "cryptomator-vault"; - private final Provider serverProvider; private final VaultSettings vaultSettings; private final Settings settings; private final WindowsDriveLetters windowsDriveLetters; + private final Environment environment; private WebDavServer server; private WebDavServletController servlet; @@ -35,11 +35,12 @@ public class WebDavVolume implements Volume { private Consumer onExitAction; @Inject - public WebDavVolume(Provider serverProvider, VaultSettings vaultSettings, Settings settings, WindowsDriveLetters windowsDriveLetters) { + public WebDavVolume(Provider serverProvider, VaultSettings vaultSettings, Settings settings, WindowsDriveLetters windowsDriveLetters, Environment environment) { this.serverProvider = serverProvider; this.vaultSettings = vaultSettings; this.settings = settings; this.windowsDriveLetters = windowsDriveLetters; + this.environment = environment; } @Override @@ -129,16 +130,17 @@ public class WebDavVolume implements Volume { } private String getLocalhostAliasOrNull() { - try { - InetAddress alias = InetAddress.getByName(LOCALHOST_ALIAS); - if (alias.getHostAddress().equals("127.0.0.1")) { - return LOCALHOST_ALIAS; - } else { - return null; + return environment.getLoopbackAlias().map(alias -> { + try { + var address = InetAddress.getByName(alias); + if (address.getHostAddress().equals("127.0.0.1")) { + return alias; + } + } catch (UnknownHostException e) { + //no-op } - } catch (UnknownHostException e) { return null; - } + }).orElse(null); } private void cleanup() { From 65e26971ff3f2c2cec323daaa16e5c5bf6d57a85 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 21 Nov 2022 13:12:32 +0100 Subject: [PATCH 19/84] make loopback alias depend on appName --- dist/win/build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/win/build.ps1 b/dist/win/build.ps1 index 565194e7d..d80904182 100644 --- a/dist/win/build.ps1 +++ b/dist/win/build.ps1 @@ -35,7 +35,7 @@ Write-Output "`$buildDir=$buildDir" Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME" $copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor" -$loopbackAlias = 'cryptomator-vault' +$loopbackAlias = "$AppName-vault" # compile &mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin From 79952418f45dd0d5d636f56553cdace1f170efa2 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 21 Nov 2022 13:26:14 +0100 Subject: [PATCH 20/84] only use lower characters in loopback alias --- dist/win/build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/win/build.ps1 b/dist/win/build.ps1 index d80904182..2769e790f 100644 --- a/dist/win/build.ps1 +++ b/dist/win/build.ps1 @@ -35,7 +35,7 @@ Write-Output "`$buildDir=$buildDir" Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME" $copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor" -$loopbackAlias = "$AppName-vault" +$loopbackAlias = $AppName.toLower() + "-vault" # compile &mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin From 1b0eb34734dc190bc0b2e9454c1c0cfc86b82a93 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 21 Nov 2022 13:46:12 +0100 Subject: [PATCH 21/84] set loopback alias via parameter in ps1 script --- dist/win/build.bat | 4 +++- dist/win/build.ps1 | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dist/win/build.bat b/dist/win/build.bat index c97ebbb35..997d94328 100644 --- a/dist/win/build.bat +++ b/dist/win/build.bat @@ -9,8 +9,9 @@ SET ABOUT_URL="https://cryptomator.org" SET UPDATE_URL="https://cryptomator.org/downloads/" SET HELP_URL="https://cryptomator.org/contact/" SET MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator" +SET LOOPBACK_ALIAS="cryptomator-vault" -powershell -NoLogo -NoExit -ExecutionPolicy Unrestricted -Command .\build.ps1^ +powershell -NoLogo -ExecutionPolicy Unrestricted -Command .\build.ps1^ -AppName %APPNAME%^ -MainJarGlob "%MAIN_JAR_GLOB%"^ -ModuleAndMainClass "%MODULE_AND_MAIN_CLASS%"^ @@ -20,4 +21,5 @@ powershell -NoLogo -NoExit -ExecutionPolicy Unrestricted -Command .\build.ps1^ -AboutUrl "%ABOUT_URL%"^ -HelpUrl "%HELP_URL%"^ -UpdateUrl "%UPDATE_URL%"^ + -LoopbackAlias "%LOOPBACK_ALIAS%"^ -Clean 1 \ No newline at end of file diff --git a/dist/win/build.ps1 b/dist/win/build.ps1 index 2769e790f..1e316d5f2 100644 --- a/dist/win/build.ps1 +++ b/dist/win/build.ps1 @@ -8,6 +8,7 @@ Param( [Parameter(Mandatory, HelpMessage="Please provide a help url")][string] $HelpUrl, [Parameter(Mandatory, HelpMessage="Please provide an update url")][string] $UpdateUrl, [Parameter(Mandatory, HelpMessage="Please provide an about url")][string] $AboutUrl, + [Parameter(Mandatory, HelpMessage="Please provide an alias for localhost")][string] $LoopbackAlias, [bool] $clean ) @@ -35,7 +36,6 @@ Write-Output "`$buildDir=$buildDir" Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME" $copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor" -$loopbackAlias = $AppName.toLower() + "-vault" # compile &mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin @@ -86,7 +86,7 @@ if ($clean -and (Test-Path -Path $appPath)) { --java-options "-Dcryptomator.ipcSocketPath=`"~/AppData/Roaming/$AppName/ipc.socket`"" ` --java-options "-Dcryptomator.p12Path=`"~/AppData/Roaming/$AppName/key.p12`"" ` --java-options "-Dcryptomator.mountPointsDir=`"~/$AppName`"" ` - --java-options "-Dcryptomator.loopbackAlias=`"$loopbackAlias`"" ` + --java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" ` --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" ` --java-options "-Dcryptomator.integrationsWin.keychainPaths=`"~/AppData/Roaming/$AppName/keychain.json`"" ` --java-options "-Dcryptomator.showTrayIcon=true" ` @@ -110,7 +110,7 @@ attrib -r "$AppName\$AppName.exe" # patch batch script to set hostfile $webDAVPatcher = "$AppName\patchWebDAV.bat" try { - (Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$loopbackAlias`"" | Set-Content $webDAVPatcher + (Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$LoopbackAlias`"" | Set-Content $webDAVPatcher } catch { Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat" exit 1 From 83af5e796fe5c757c7dfc65e2600dd4711b87bdf Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 21 Nov 2022 22:10:06 +0100 Subject: [PATCH 22/84] publish only production versions to winget --- .github/workflows/win-exe.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 244cbfc36..332e1e725 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -24,6 +24,11 @@ jobs: runs-on: windows-latest env: LOOPBACK_ALIAS: 'cryptomator-vault' + outputs: + semVerNum: ${{ steps.versions.outputs.semVerNum }} + semVerStr: ${{ steps.versions.outputs.semVerStr }} + revNum: ${{ steps.versions.outputs.revNum }} + isProductionVersion: ${{ steps.versions.outputs.isProductionVersion}} steps: - uses: actions/checkout@v3 with: @@ -34,7 +39,7 @@ jobs: distribution: ${{ env.JAVA_DIST }} java-version: ${{ env.JAVA_VERSION }} cache: ${{ env.JAVA_CACHE }} - - id: versions + - id: versions name: Apply version information run: | if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then @@ -48,9 +53,14 @@ jobs: fi SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'` REVCOUNT=`git rev-list --count HEAD` + PRODUCTION_READY_VERSION="false" + if [[ $SEM_VER_STR =~ [0-9]+\.[0-9].[0-9]+ ]]; then + PRODUCTION_READY_VERSION="true" + fi echo "::set-output name=semVerStr::${SEM_VER_STR}" echo "::set-output name=semVerNum::${SEM_VER_NUM}" echo "::set-output name=revNum::${REVCOUNT}" + echo "::set-output name=isProductionVersion::${PRODUCTION_READY_VERSION}" - name: Validate Version uses: skymatic/semver-validation-action@v1 with: @@ -199,17 +209,14 @@ jobs: files: | *.msi *.asc - outputs: - semVerNum: ${{ steps.versions.outputs.semVerNum }} - semVerStr: ${{ steps.versions.outputs.semVerStr }} - revNum: ${{ steps.versions.outputs.revNum }} call-winget-flow: needs: [build-msi] - if: github.event.action == 'published' + if: github.event.action == 'published' && needs.build-msi.outputs.isProductionVersion uses: ./.github/workflows/winget.yml with: releaseTag: ${{ github.event.release.tag_name }} + secrets: inherit build-exe: From 3223ea2e5dfb7fbf4385e1c32ab940e200053c67 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 22 Nov 2022 11:18:05 +0100 Subject: [PATCH 23/84] Refactor version parsing and validation to reusable workflow --- .github/workflows/get-version-info.yml | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .github/workflows/get-version-info.yml diff --git a/.github/workflows/get-version-info.yml b/.github/workflows/get-version-info.yml new file mode 100644 index 000000000..1aa97b60a --- /dev/null +++ b/.github/workflows/get-version-info.yml @@ -0,0 +1,62 @@ +name: Parse and Validate a version string or tag + +on: + workflow_call: + inputs: + version: + description: "A specific version to use" + required: false + type: string + outputs: + semVerStr: + description: "The full version string." + value: ${{ jobs.determine-version.outputs.semVerStr}} + semVerNum: + description: "The numerical part of the version string" + value: ${{ jobs.determine-version.outputs.semVerNum}} + revNum: + description: "The revision number" + value: ${{ jobs.determine-version.outputs.revNum}} + +env: + JAVA_VERSION: 19 + JAVA_DIST: 'temurin' + JAVA_CACHE: 'maven' + +jobs: + determine-version: + name: 'Determines the version following semver' + runs-on: ubuntu-latest + outputs: + semVerNum: ${{ steps.versions.outputs.semVerNum }} + semVerStr: ${{ steps.versions.outputs.semVerStr }} + revNum: ${{ steps.versions.outputs.revNum }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: ${{ env.JAVA_DIST }} + java-version: ${{ env.JAVA_VERSION }} + cache: ${{ env.JAVA_CACHE }} + - id: versions + name: Get version information # TODO: is Github ref inherited when called from super workflow? + run: | + if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then + SEM_VER_STR=${GITHUB_REF##*/} + elif [[ "${{ inputs.version }}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then + SEM_VER_STR="${{ github.event.inputs.version }}" + else + SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` + fi + SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'` + REVCOUNT=`git rev-list --count HEAD` + echo "::set-output name=semVerStr::${SEM_VER_STR}" + echo "::set-output name=semVerNum::${SEM_VER_NUM}" + echo "::set-output name=revNum::${REVCOUNT}" + - name: Validate Version + uses: skymatic/semver-validation-action@v1 + with: + version: ${{ steps.versions.outputs.semVerStr }} \ No newline at end of file From 9ca8072ab6335e50852d32339823ece07f5cf83b Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 22 Nov 2022 14:45:49 +0100 Subject: [PATCH 24/84] Rename workflow and add type output --- .../{get-version-info.yml => get-version.yml} | 15 +++++++++++++++ 1 file changed, 15 insertions(+) rename .github/workflows/{get-version-info.yml => get-version.yml} (76%) diff --git a/.github/workflows/get-version-info.yml b/.github/workflows/get-version.yml similarity index 76% rename from .github/workflows/get-version-info.yml rename to .github/workflows/get-version.yml index 1aa97b60a..e4f49bf74 100644 --- a/.github/workflows/get-version-info.yml +++ b/.github/workflows/get-version.yml @@ -17,6 +17,9 @@ on: revNum: description: "The revision number" value: ${{ jobs.determine-version.outputs.revNum}} + versionType: + description: "Type of the version. Values are [stable, alpha, beta, rc, unknown]" + value: ${{ jobs.determine-version.outputs.type }} env: JAVA_VERSION: 19 @@ -31,6 +34,7 @@ jobs: semVerNum: ${{ steps.versions.outputs.semVerNum }} semVerStr: ${{ steps.versions.outputs.semVerStr }} revNum: ${{ steps.versions.outputs.revNum }} + type: ${{ steps.versions.outputs.type}} steps: - uses: actions/checkout@v3 with: @@ -53,9 +57,20 @@ jobs: fi SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'` REVCOUNT=`git rev-list --count HEAD` + TYPE="unknown" + if [[ $SEM_VER_STR =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then + TYPE="stable" + elif [[ $SEM_VER_STR =~ [0-9]+\.[0-9]+\.[0-9]+-alpha[1-9] ]]; then + TYPE="alpha" + elif [[ $SEM_VER_STR =~ [0-9]+\.[0-9]+\.[0-9]+-beta[1-9] ]]; then + TYPE="beta" + elif [[ $SEM_VER_STR =~ [0-9]+\.[0-9]+\.[0-9]+-rc[1-9] ]]; then + TYPE="rc" + fi echo "::set-output name=semVerStr::${SEM_VER_STR}" echo "::set-output name=semVerNum::${SEM_VER_NUM}" echo "::set-output name=revNum::${REVCOUNT}" + echo "::set-output name=type::${TYPE}" - name: Validate Version uses: skymatic/semver-validation-action@v1 with: From 083d0cfbc486f78c7e9c7312672c913cb3e9eb48 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 22 Nov 2022 14:51:12 +0100 Subject: [PATCH 25/84] migrate windows build to use get-version workflow --- .github/workflows/win-exe.yml | 61 +++++++++++------------------------ 1 file changed, 18 insertions(+), 43 deletions(-) diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 332e1e725..3fdea0c43 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -19,52 +19,27 @@ defaults: shell: bash jobs: + get-version: + uses: ./.github/workflows/get-version.yml + with: + version: ${{ github.event.inputs.version }} + build-msi: name: Build .msi Installer runs-on: windows-latest + needs: [get-version] env: LOOPBACK_ALIAS: 'cryptomator-vault' - outputs: - semVerNum: ${{ steps.versions.outputs.semVerNum }} - semVerStr: ${{ steps.versions.outputs.semVerStr }} - revNum: ${{ steps.versions.outputs.revNum }} - isProductionVersion: ${{ steps.versions.outputs.isProductionVersion}} steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Setup Java uses: actions/setup-java@v3 with: distribution: ${{ env.JAVA_DIST }} java-version: ${{ env.JAVA_VERSION }} cache: ${{ env.JAVA_CACHE }} - - id: versions - name: Apply version information - run: | - if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR=${GITHUB_REF##*/} - mvn versions:set -DnewVersion=${SEM_VER_STR} - elif [[ "${{ github.event.inputs.version }}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR="${{ github.event.inputs.version }}" - mvn versions:set -DnewVersion=${SEM_VER_STR} - else - SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` - fi - SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'` - REVCOUNT=`git rev-list --count HEAD` - PRODUCTION_READY_VERSION="false" - if [[ $SEM_VER_STR =~ [0-9]+\.[0-9].[0-9]+ ]]; then - PRODUCTION_READY_VERSION="true" - fi - echo "::set-output name=semVerStr::${SEM_VER_STR}" - echo "::set-output name=semVerNum::${SEM_VER_NUM}" - echo "::set-output name=revNum::${REVCOUNT}" - echo "::set-output name=isProductionVersion::${PRODUCTION_READY_VERSION}" - - name: Validate Version - uses: skymatic/semver-validation-action@v1 - with: - version: ${{ steps.versions.outputs.semVerStr }} + - name: Set version + run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} - name: Run maven run: mvn -B clean package -Pdependency-check,win -DskipTests - name: Patch target dir @@ -97,10 +72,10 @@ jobs: --name Cryptomator --vendor "Skymatic GmbH" --copyright "(C) 2016 - 2022 Skymatic GmbH" - --app-version "${{ steps.versions.outputs.semVerNum }}.${{ steps.versions.outputs.revNum }}" + --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}" --java-options "-Xss5m" --java-options "-Xmx256m" - --java-options "-Dcryptomator.appVersion=\"${{ steps.versions.outputs.semVerStr }}\"" + --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\"" --java-options "-Dfile.encoding=\"utf-8\"" --java-options "-Dcryptomator.logDir=\"~/AppData/Roaming/Cryptomator\"" --java-options "-Dcryptomator.pluginDir=\"~/AppData/Roaming/Cryptomator/Plugins\"" @@ -110,7 +85,7 @@ jobs: --java-options "-Dcryptomator.mountPointsDir=\"~/Cryptomator\"" --java-options "-Dcryptomator.loopbackAlias=\"${{ env.LOOPBACK_ALIAS }}\"" --java-options "-Dcryptomator.showTrayIcon=true" - --java-options "-Dcryptomator.buildNumber=\"msi-${{ steps.versions.outputs.revNum }}\"" + --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\"" --resource-dir dist/win/resources @@ -163,7 +138,7 @@ jobs: --name Cryptomator --vendor "Skymatic GmbH" --copyright "(C) 2016 - 2022 Skymatic GmbH" - --app-version "${{ steps.versions.outputs.semVerNum }}" + --app-version "${{ needs.get-version.outputs.semVerNum }}" --win-menu --win-dir-chooser --win-shortcut-prompt @@ -184,7 +159,7 @@ jobs: timestampUrl: 'http://timestamp.digicert.com' folder: installer - name: Add possible alpha/beta tags to installer name - run: mv installer/Cryptomator-*.msi Cryptomator-${{ steps.versions.outputs.semVerStr }}-x64.msi + run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.msi - name: Create detached GPG signature with key 615D449FE6E6A235 run: | echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import @@ -211,8 +186,8 @@ jobs: *.asc call-winget-flow: - needs: [build-msi] - if: github.event.action == 'published' && needs.build-msi.outputs.isProductionVersion + needs: [get-version, build-msi] + if: github.event.action == 'published' && needs.get-version.outputs.type == 'stable' uses: ./.github/workflows/winget.yml with: releaseTag: ${{ github.event.release.tag_name }} @@ -222,7 +197,7 @@ jobs: build-exe: name: Build .exe installer runs-on: windows-latest - needs: [build-msi] + needs: [version, build-msi] steps: - uses: actions/checkout@v3 - name: Download .msi @@ -258,7 +233,7 @@ jobs: "${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs -ext WixBalExtension -out dist/win/bundle/ - -dBundleVersion="${{ needs.build-msi.outputs.semVerNum }}.${{ needs.build-msi.outputs.revNum }}" + -dBundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}" -dBundleVendor="Skymatic GmbH" -dBundleCopyright="(C) 2016 - 2022 Skymatic GmbH" -dAboutUrl="https://cryptomator.org" @@ -298,7 +273,7 @@ jobs: timestampUrl: 'http://timestamp.digicert.com' folder: installer - name: Add possible alpha/beta tags to installer name - run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.build-msi.outputs.semVerStr }}-x64.exe + run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.exe - name: Create detached GPG signature with key 615D449FE6E6A235 run: | echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import From faf39c2507eb20813f892040c742fcd8ef458a9c Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 22 Nov 2022 15:01:47 +0100 Subject: [PATCH 26/84] fix wrong name --- .github/workflows/win-exe.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 3fdea0c43..055d5d194 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -197,7 +197,7 @@ jobs: build-exe: name: Build .exe installer runs-on: windows-latest - needs: [version, build-msi] + needs: [get-version, build-msi] steps: - uses: actions/checkout@v3 - name: Download .msi From 6983d9d72dfed2174fa54eb761fe88805ad02232 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 24 Nov 2022 10:12:59 +0100 Subject: [PATCH 27/84] Remove cryptolib dependency, bump cryptofs --- pom.xml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 725e3d7c2..221261a27 100644 --- a/pom.xml +++ b/pom.xml @@ -27,8 +27,7 @@ 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-rc1 - 2.4.5 + 2.5.0 1.1.0 1.1.2 1.1.2 @@ -64,11 +63,6 @@ - - org.cryptomator - cryptolib - ${cryptomator.cryptolib.version} - org.cryptomator cryptofs From d896fe21b58927b7efe8b58f18f5852319cb014f Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 24 Nov 2022 10:13:37 +0100 Subject: [PATCH 28/84] adapt result fixing to new api --- .../java/org/cryptomator/ui/health/CheckExecutor.java | 2 +- src/main/java/org/cryptomator/ui/health/Result.java | 8 ++++++-- .../java/org/cryptomator/ui/health/ResultFixApplier.java | 5 +++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/health/CheckExecutor.java b/src/main/java/org/cryptomator/ui/health/CheckExecutor.java index a9ee9a17f..c347f38cb 100644 --- a/src/main/java/org/cryptomator/ui/health/CheckExecutor.java +++ b/src/main/java/org/cryptomator/ui/health/CheckExecutor.java @@ -70,7 +70,7 @@ public class CheckExecutor { try (var masterkeyClone = masterkey.copy(); // var cryptor = CryptorProvider.forScheme(vaultConfig.getCipherCombo()).provide(masterkeyClone, csprng)) { c.getHealthCheck().check(vaultPath, vaultConfig, masterkeyClone, cryptor, diagnosis -> { - Platform.runLater(() -> c.getResults().add(Result.create(diagnosis))); + Platform.runLater(() -> c.getResults().add(Result.create(diagnosis, vaultPath, vaultConfig, masterkeyClone, cryptor))); highestResultSeverity = Comparators.max(highestResultSeverity, diagnosis.getSeverity()); }); } diff --git a/src/main/java/org/cryptomator/ui/health/Result.java b/src/main/java/org/cryptomator/ui/health/Result.java index 8327a1130..d8a18b890 100644 --- a/src/main/java/org/cryptomator/ui/health/Result.java +++ b/src/main/java/org/cryptomator/ui/health/Result.java @@ -1,10 +1,14 @@ package org.cryptomator.ui.health; +import org.cryptomator.cryptofs.VaultConfig; import org.cryptomator.cryptofs.health.api.DiagnosticResult; +import org.cryptomator.cryptolib.api.Cryptor; +import org.cryptomator.cryptolib.api.Masterkey; import javafx.beans.Observable; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; +import java.nio.file.Path; record Result(DiagnosticResult diagnosis, ObjectProperty fixState) { @@ -16,8 +20,8 @@ record Result(DiagnosticResult diagnosis, ObjectProperty fixState) { FIX_FAILED } - public static Result create(DiagnosticResult diagnosis) { - FixState initialState = diagnosis.getSeverity() == DiagnosticResult.Severity.WARN ? FixState.FIXABLE : FixState.NOT_FIXABLE; + public static Result create(DiagnosticResult diagnosis, Path vaultPath, VaultConfig config, Masterkey masterkey, Cryptor cryptor) { + FixState initialState = diagnosis.getFix(vaultPath, config, masterkey, cryptor).isPresent()? FixState.FIXABLE : FixState.NOT_FIXABLE; return new Result(diagnosis, new SimpleObjectProperty<>(initialState)); } diff --git a/src/main/java/org/cryptomator/ui/health/ResultFixApplier.java b/src/main/java/org/cryptomator/ui/health/ResultFixApplier.java index 3dc91e33b..4a71730a0 100644 --- a/src/main/java/org/cryptomator/ui/health/ResultFixApplier.java +++ b/src/main/java/org/cryptomator/ui/health/ResultFixApplier.java @@ -49,10 +49,11 @@ class ResultFixApplier { } public void fix(DiagnosticResult diagnosis) { - Preconditions.checkArgument(diagnosis.getSeverity() == DiagnosticResult.Severity.WARN, "Unfixable result"); try (var masterkeyClone = masterkey.copy(); // var cryptor = CryptorProvider.forScheme(vaultConfig.getCipherCombo()).provide(masterkeyClone, csprng)) { - diagnosis.fix(vaultPath, vaultConfig, masterkeyClone, cryptor); + diagnosis.getFix(vaultPath, vaultConfig, masterkeyClone, cryptor) + .orElseThrow(() -> new IllegalStateException("No fix for diagnosis "+diagnosis.getClass().getName() +" implemented.")) + .apply(); } catch (Exception e) { throw new FixFailedException(e); } From 74e3c284412d836742b209b1d5bccc3ea76a454b Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 25 Nov 2022 16:54:21 +0100 Subject: [PATCH 29/84] bump cryptofs --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 221261a27..911d0e2e1 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 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.5.0 + 2.5.1 1.1.0 1.1.2 1.1.2 From 4dc1d59305ae972e9f708c5f88c441460e78bb0b Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 25 Nov 2022 17:17:55 +0100 Subject: [PATCH 30/84] Implement fix all button --- .../ui/health/CheckDetailController.java | 38 ++++++++++++++-- .../ui/health/ResultFixApplier.java | 24 ++++++++--- .../ui/health/ResultListCellController.java | 31 ++++++------- .../resources/fxml/health_check_details.fxml | 43 ++++++++++++------- src/main/resources/i18n/strings.properties | 1 + 5 files changed, 95 insertions(+), 42 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java index c467a5328..83cb4ea7d 100644 --- a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java +++ b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java @@ -8,8 +8,12 @@ import org.cryptomator.ui.common.FxController; import javax.inject.Inject; import javafx.beans.binding.Binding; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanBinding; import javafx.beans.binding.BooleanExpression; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.fxml.FXML; @@ -35,30 +39,42 @@ public class CheckDetailController implements FxController { private final Binding countOfCritSeverity; private final Binding warnOrCritsExist; private final ResultListCellFactory resultListCellFactory; + private final ResultFixApplier resultFixApplier; + + private final BooleanProperty fixAllInfoResultsExecuted; + private final BooleanBinding fixAllInfoResultsPossible; public ListView resultsListView; private Subscription resultSubscription; @Inject - public CheckDetailController(ObjectProperty selectedTask, ResultListCellFactory resultListCellFactory) { + public CheckDetailController(ObjectProperty selectedTask, ResultListCellFactory resultListCellFactory, ResultFixApplier resultFixApplier) { this.resultListCellFactory = resultListCellFactory; + this.resultFixApplier = resultFixApplier; this.results = EasyBind.wrapList(FXCollections.observableArrayList()); this.check = selectedTask; this.checkState = selectedTask.flatMap(Check::stateProperty); this.checkName = selectedTask.map(Check::getName).orElse(""); this.checkRunning = BooleanExpression.booleanExpression(checkState.map(Check.CheckState.RUNNING::equals).orElse(false)); this.checkScheduled = BooleanExpression.booleanExpression(checkState.map(Check.CheckState.SCHEDULED::equals).orElse(false)); - this.checkSkipped =BooleanExpression.booleanExpression(checkState.map(Check.CheckState.SKIPPED::equals).orElse(false)); + this.checkSkipped = BooleanExpression.booleanExpression(checkState.map(Check.CheckState.SKIPPED::equals).orElse(false)); this.checkSucceeded = BooleanExpression.booleanExpression(checkState.map(Check.CheckState.SUCCEEDED::equals).orElse(false)); this.checkFailed = BooleanExpression.booleanExpression(checkState.map(Check.CheckState.ERROR::equals).orElse(false)); this.checkCancelled = BooleanExpression.booleanExpression(checkState.map(Check.CheckState.CANCELLED::equals).orElse(false)); this.checkFinished = checkSucceeded.or(checkFailed).or(checkCancelled); this.countOfWarnSeverity = results.reduce(countSeverity(DiagnosticResult.Severity.WARN)); this.countOfCritSeverity = results.reduce(countSeverity(DiagnosticResult.Severity.CRITICAL)); - this.warnOrCritsExist = EasyBind.combine(checkSucceeded, countOfWarnSeverity, countOfCritSeverity, (suceeded, warns, crits) -> suceeded && (warns.longValue() > 0 || crits.longValue() > 0) ); + this.warnOrCritsExist = EasyBind.combine(checkSucceeded, countOfWarnSeverity, countOfCritSeverity, (suceeded, warns, crits) -> suceeded && (warns.longValue() > 0 || crits.longValue() > 0)); + this.fixAllInfoResultsExecuted = new SimpleBooleanProperty(false); + this.fixAllInfoResultsPossible = Bindings.createBooleanBinding(() -> results.stream().anyMatch(this::isFixableInfoResult), results) // + .and(fixAllInfoResultsExecuted.not()); selectedTask.addListener(this::selectedTaskChanged); } + private boolean isFixableInfoResult(Result r) { + return r.diagnosis().getSeverity() == DiagnosticResult.Severity.INFO && r.getState() == Result.FixState.FIXABLE; + } + private void selectedTaskChanged(ObservableValue observable, Check oldValue, Check newValue) { if (resultSubscription != null) { resultSubscription.unsubscribe(); @@ -78,6 +94,13 @@ public class CheckDetailController implements FxController { resultsListView.setCellFactory(resultListCellFactory); } + @FXML + public void fixAllInfoResults() { + fixAllInfoResultsExecuted.setValue(true); + results.stream().filter(this::isFixableInfoResult).forEach(resultFixApplier::fix); + } + + /* Getter/Setter */ public String getCheckName() { @@ -175,4 +198,13 @@ public class CheckDetailController implements FxController { public Check getCheck() { return check.get(); } + + public ObservableValue fixAllInfoResultsPossibleProperty() { + return fixAllInfoResultsPossible; + } + + public boolean getFixAllInfoResultsPossible() { + return fixAllInfoResultsPossible.getValue(); + } + } diff --git a/src/main/java/org/cryptomator/ui/health/ResultFixApplier.java b/src/main/java/org/cryptomator/ui/health/ResultFixApplier.java index 4a71730a0..2654da221 100644 --- a/src/main/java/org/cryptomator/ui/health/ResultFixApplier.java +++ b/src/main/java/org/cryptomator/ui/health/ResultFixApplier.java @@ -23,6 +23,8 @@ import java.util.concurrent.atomic.AtomicReference; @HealthCheckScoped class ResultFixApplier { + private static final Logger LOG = LoggerFactory.getLogger(ResultFixApplier.class); + private final Path vaultPath; private final SecureRandom csprng; private final Masterkey masterkey; @@ -40,19 +42,26 @@ class ResultFixApplier { public CompletionStage fix(Result result) { Preconditions.checkArgument(result.getState() == Result.FixState.FIXABLE); - result.setState(Result.FixState.FIXING); - return CompletableFuture.runAsync(() -> fix(result.diagnosis()), sequentialExecutor) + return CompletableFuture.runAsync(() -> result.setState(Result.FixState.FIXING), Platform::runLater) // + .thenRunAsync(() -> fix(result.diagnosis()), sequentialExecutor) // .whenCompleteAsync((unused, throwable) -> { - var fixed = throwable == null ? Result.FixState.FIXED : Result.FixState.FIX_FAILED; - result.setState(fixed); + final Result.FixState s; + if (throwable == null) { + LOG.debug("Fix for {} applied successful.", result.diagnosis().getClass().getName()); + s = Result.FixState.FIXED; + } else { + LOG.error("Failed to apply fix for {}", result.diagnosis().getClass().getName(), throwable); + s = Result.FixState.FIX_FAILED; + } + result.setState(s); }, Platform::runLater); } - public void fix(DiagnosticResult diagnosis) { + private void fix(DiagnosticResult diagnosis) { try (var masterkeyClone = masterkey.copy(); // var cryptor = CryptorProvider.forScheme(vaultConfig.getCipherCombo()).provide(masterkeyClone, csprng)) { - diagnosis.getFix(vaultPath, vaultConfig, masterkeyClone, cryptor) - .orElseThrow(() -> new IllegalStateException("No fix for diagnosis "+diagnosis.getClass().getName() +" implemented.")) + diagnosis.getFix(vaultPath, vaultConfig, masterkeyClone, cryptor) // + .orElseThrow(() -> new IllegalStateException("No fix for diagnosis " + diagnosis.getClass().getName() + " implemented.")) // .apply(); } catch (Exception e) { throw new FixFailedException(e); @@ -60,6 +69,7 @@ class ResultFixApplier { } public static class FixFailedException extends CompletionException { + private FixFailedException(Throwable cause) { super(cause); } diff --git a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java index d655d0058..03c225d57 100644 --- a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java +++ b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java @@ -12,7 +12,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; -import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.binding.BooleanBinding; import javafx.beans.binding.ObjectBinding; @@ -49,8 +48,8 @@ public class ResultListCellController implements FxController { private final BooleanBinding fixFailed; private final BooleanBinding fixRunningOrDone; private final List subscriptions; - private final Tooltip fixSuccess; - private final Tooltip fixFail; + private final Tooltip fixSuccessTip; + private final Tooltip fixFailTip; private AutoAnimator fixRunningRotator; @@ -73,10 +72,10 @@ public class ResultListCellController implements FxController { this.fixFailed = Bindings.createBooleanBinding(this::isFixFailed, fixState); this.fixRunningOrDone = fixing.or(fixed).or(fixFailed); this.subscriptions = new ArrayList<>(); - this.fixSuccess = new Tooltip(resourceBundle.getString("health.fix.successTip")); - this.fixFail = new Tooltip(resourceBundle.getString("health.fix.failTip")); - fixSuccess.setShowDelay(Duration.millis(100)); - fixFail.setShowDelay(Duration.millis(100)); + this.fixSuccessTip = new Tooltip(resourceBundle.getString("health.fix.successTip")); + this.fixFailTip = new Tooltip(resourceBundle.getString("health.fix.failTip")); + fixSuccessTip.setShowDelay(Duration.millis(100)); + fixFailTip.setShowDelay(Duration.millis(100)); } @FXML @@ -93,22 +92,20 @@ public class ResultListCellController implements FxController { .onCondition(fixing) // .afterStop(() -> fixView.setRotate(0)) // .build(); + fixState.addListener(((observable, oldValue, newValue) -> { + if (newValue == Result.FixState.FIXED) { + Tooltip.install(fixView, fixSuccessTip); + } else if (newValue == Result.FixState.FIX_FAILED) { + Tooltip.install(fixView, fixFailTip); + } + })); } @FXML public void fix() { Result r = result.get(); if (r != null) { - fixApplier.fix(r).whenCompleteAsync(this::fixFinished, Platform::runLater); - } - } - - private void fixFinished(Void unused, Throwable exception) { - if (exception != null) { - LOG.error("Failed to apply fix", exception); - Tooltip.install(fixView, fixFail); - } else { - Tooltip.install(fixView, fixSuccess); + fixApplier.fix(r); } } diff --git a/src/main/resources/fxml/health_check_details.fxml b/src/main/resources/fxml/health_check_details.fxml index 6dd7d224e..d4564a852 100644 --- a/src/main/resources/fxml/health_check_details.fxml +++ b/src/main/resources/fxml/health_check_details.fxml @@ -5,25 +5,38 @@ + + + - + spacing="12"> + + + + + + - \ No newline at end of file diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 460b56476..d3ae3a0e4 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinished=The check finished successfully. health.check.detail.checkFinishedAndFound=The check finished running. Please review the results. health.check.detail.checkFailed=The check exited due to an error. health.check.detail.checkCancelled=The check was cancelled. +health.check.detail.fixAllSpecificBtn=Fix all of type health.check.exportBtn=Export Report ## Fix Application health.fix.fixBtn=Fix From 23d9521724ec57408198546abd0f56319896de93 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 25 Nov 2022 17:29:36 +0100 Subject: [PATCH 31/84] Remove resolved TODO (see https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_call) --- .github/workflows/get-version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/get-version.yml b/.github/workflows/get-version.yml index e4f49bf74..7ccb1b9a3 100644 --- a/.github/workflows/get-version.yml +++ b/.github/workflows/get-version.yml @@ -46,7 +46,7 @@ jobs: java-version: ${{ env.JAVA_VERSION }} cache: ${{ env.JAVA_CACHE }} - id: versions - name: Get version information # TODO: is Github ref inherited when called from super workflow? + name: Get version information run: | if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then SEM_VER_STR=${GITHUB_REF##*/} From 34986f59193c666e3da08d087936bedcb419f79e Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 25 Nov 2022 17:46:24 +0100 Subject: [PATCH 32/84] migrate other build worfklows to use get-version.yml --- .github/workflows/appimage.yml | 43 +++++++++++--------------------- .github/workflows/debian.yml | 32 +++++++----------------- .github/workflows/mac-dmg.yml | 45 ++++++++++++---------------------- 3 files changed, 38 insertions(+), 82 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 0bd519d39..26d455b8f 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -13,40 +13,25 @@ env: JAVA_VERSION: 19 jobs: + get-version: + uses: ./.github/workflows/get-version.yml + with: + version: ${{ github.event.inputs.version }} + build: name: Build AppImage runs-on: ubuntu-latest + needs: [get-version] steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Setup Java uses: actions/setup-java@v3 with: distribution: 'zulu' java-version: ${{ env.JAVA_VERSION }} cache: 'maven' - - id: versions - name: Apply version information - run: | - if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR=${GITHUB_REF##*/} - mvn versions:set -DnewVersion=${SEM_VER_STR} - elif [[ "${{ github.event.inputs.version }}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR="${{ github.event.inputs.version }}" - mvn versions:set -DnewVersion=${SEM_VER_STR} - else - SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` - fi - SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'` - REVCOUNT=`git rev-list --count HEAD` - echo "::set-output name=semVerStr::${SEM_VER_STR}" - echo "::set-output name=semVerNum::${SEM_VER_NUM}" - echo "::set-output name=revNum::${REVCOUNT}" - - name: Validate Version - uses: skymatic/semver-validation-action@v1 - with: - version: ${{ steps.versions.outputs.semVerStr }} + - name: Set version + run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} - name: Run maven run: mvn -B clean package -Pdependency-check,linux -DskipTests - name: Patch target dir @@ -69,8 +54,8 @@ jobs: - name: Prepare additional launcher run: envsubst '${SEMVER_STR} ${REVISION_NUM}' < dist/linux/launcher-gtk2.properties > launcher-gtk2.properties env: - SEMVER_STR: ${{ steps.versions.outputs.semVerStr }} - REVISION_NUM: ${{ steps.versions.outputs.revNum }} + SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }} + REVISION_NUM: ${{ needs.get-version.outputs.revNum }} - name: Run jpackage run: > ${JAVA_HOME}/bin/jpackage @@ -84,10 +69,10 @@ jobs: --name Cryptomator --vendor "Skymatic GmbH" --copyright "(C) 2016 - 2022 Skymatic GmbH" - --app-version "${{ steps.versions.outputs.semVerNum }}.${{ steps.versions.outputs.revNum }}" + --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}" --java-options "-Xss5m" --java-options "-Xmx256m" - --java-options "-Dcryptomator.appVersion=\"${{ steps.versions.outputs.semVerStr }}\"" + --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\"" --java-options "-Dfile.encoding=\"utf-8\"" --java-options "-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\"" --java-options "-Dcryptomator.pluginDir=\"~/.local/share/Cryptomator/plugins\"" @@ -96,7 +81,7 @@ jobs: --java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\"" --java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\"" --java-options "-Dcryptomator.showTrayIcon=false" - --java-options "-Dcryptomator.buildNumber=\"appimage-${{ steps.versions.outputs.revNum }}\"" + --java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.get-version.outputs.revNum }}\"" --add-launcher Cryptomator-gtk2=launcher-gtk2.properties --resource-dir dist/linux/resources - name: Patch Cryptomator.AppDir @@ -134,7 +119,7 @@ jobs: GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} - name: Build AppImage run: > - ./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ steps.versions.outputs.semVerStr }}-x86_64.AppImage + ./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.get-version.outputs.semVerStr }}-x86_64.AppImage -u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-x86_64.AppImage.zsync' --sign --sign-key=615D449FE6E6A235 --sign-args="--batch --pinentry-mode loopback" - name: Create detached GPG signatures diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 500587444..5fe3b7195 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -23,8 +23,6 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Install build tools run: | sudo add-apt-repository ppa:coffeelibs/openjdk @@ -36,24 +34,12 @@ jobs: distribution: 'zulu' java-version: ${{ env.JAVA_VERSION }} cache: 'maven' - - id: versions - name: Apply version information - run: | - if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR=${GITHUB_REF##*/} - mvn versions:set -DnewVersion=${SEM_VER_STR} - elif [[ "${{ github.event.inputs.version }}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR="${{ github.event.inputs.version }}" - mvn versions:set -DnewVersion=${SEM_VER_STR} - else - SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` - fi - SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'` - REVCOUNT=`git rev-list --count HEAD` - echo "::set-output name=semVerStr::${SEM_VER_STR}" - echo "::set-output name=semVerNum::${SEM_VER_NUM}" - echo "::set-output name=revNum::${REVCOUNT}" - echo "::set-output name=ppaVerStr::${SEM_VER_STR/-/\~}-${REVCOUNT}" + - id: versions + name: Create PPA version string + run: echo "::set-output name=ppaVerStr::${SEM_VER_STR/-/\~}-${REVCOUNT}" + env: + SEM_VER_STR: ${{ needs.get-version.outputs.semVerStr }} + REVCOUNT: ${{ needs.get-version.outputs.revNum }} - name: Validate Version uses: skymatic/semver-validation-action@v1 with: @@ -77,9 +63,9 @@ jobs: find . -name "*.jar" >> pkgdir/debian/source/include-binaries mv pkgdir cryptomator_${{ steps.versions.outputs.ppaVerStr }} env: - SEMVER_STR: ${{ steps.versions.outputs.semVerStr }} - VERSION_NUM: ${{ steps.versions.outputs.semVerNum }} - REVISION_NUM: ${{ steps.versions.outputs.revNum }} + SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }} + VERSION_NUM: ${{ needs.get-version.outputs.semVerNum }} + REVISION_NUM: ${{ needs.get-version.outputs.revNum }} PPA_VERSION: ${{ steps.versions.outputs.ppaVerStr }}-0ppa1 - name: Prepare GPG-Agent for signing with key 615D449FE6E6A235 run: | diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index b51430ee0..446760deb 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -13,9 +13,15 @@ env: JAVA_VERSION: 19 jobs: + get-version: + uses: ./.github/workflows/get-version.yml + with: + version: ${{ github.event.inputs.version }} + build: name: Build Cryptomator.app for ${{ matrix.output-suffix }} runs-on: ${{ matrix.os }} + needs: [get-version] strategy: fail-fast: false matrix: @@ -30,8 +36,6 @@ jobs: xcode-path: '/Applications/Xcode_13.2.1.app' steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Setup Java uses: actions/setup-java@v3 with: @@ -39,27 +43,8 @@ jobs: java-version: ${{ env.JAVA_VERSION }} architecture: ${{ matrix.architecture }} cache: 'maven' - - id: versions - name: Apply version information - run: | - if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR=${GITHUB_REF##*/} - mvn versions:set -DnewVersion=${SEM_VER_STR} - elif [[ "${{ github.event.inputs.version }}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then - SEM_VER_STR="${{ github.event.inputs.version }}" - mvn versions:set -DnewVersion=${SEM_VER_STR} - else - SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` - fi - SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'` - REVCOUNT=`git rev-list --count HEAD` - echo "::set-output name=semVerStr::${SEM_VER_STR}" - echo "::set-output name=semVerNum::${SEM_VER_NUM}" - echo "::set-output name=revNum::${REVCOUNT}" - - name: Validate Version - uses: skymatic/semver-validation-action@v1 - with: - version: ${{ steps.versions.outputs.semVerStr }} + - name: Set version + run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} - name: Run maven run: mvn -B clean package -Pdependency-check,mac -DskipTests - name: Patch target dir @@ -92,13 +77,13 @@ jobs: --name Cryptomator --vendor "Skymatic GmbH" --copyright "(C) 2016 - 2022 Skymatic GmbH" - --app-version "${{ steps.versions.outputs.semVerNum }}" + --app-version "${{ needs.get-version.outputs.semVerNum }} --java-options "-Xss5m" --java-options "-Xmx256m" --java-options "-Dfile.encoding=\"utf-8\"" --java-options "-Dapple.awt.enableTemplateImages=true" --java-options "-Dsun.java2d.metal=true" - --java-options "-Dcryptomator.appVersion=\"${{ steps.versions.outputs.semVerStr }}\"" + --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\"" --java-options "-Dcryptomator.logDir=\"~/Library/Logs/Cryptomator\"" --java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/Cryptomator/Plugins\"" --java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\"" @@ -106,7 +91,7 @@ jobs: --java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\"" --java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\"" --java-options "-Dcryptomator.showTrayIcon=true" - --java-options "-Dcryptomator.buildNumber=\"dmg-${{ steps.versions.outputs.revNum }}\"" + --java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.get-version.outputs.revNum }}\"" --mac-package-identifier org.cryptomator --resource-dir dist/mac/resources - name: Patch Cryptomator.app @@ -116,8 +101,8 @@ jobs: sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist env: - VERSION_NO: ${{ steps.versions.outputs.semVerNum }} - REVISION_NO: ${{ steps.versions.outputs.revNum }} + VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} + REVISION_NO: ${{ needs.get-version.outputs.revNum }} - name: Generate license for dmg run: > mvn -B license:add-third-party @@ -201,7 +186,7 @@ jobs: --icon ".VolumeIcon.icns" 512 758 Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg env: - VERSION_NO: ${{ steps.versions.outputs.semVerNum }} + VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} - name: Notarize .dmg if: startsWith(github.ref, 'refs/tags/') uses: cocoalibs/xcode-notarization-action@v1 @@ -212,7 +197,7 @@ jobs: team-id: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }} xcode-path: ${{ matrix.xcode-path }} - name: Add possible alpha/beta tags to installer name - run: mv Cryptomator-*.dmg Cryptomator-${{ steps.versions.outputs.semVerStr }}-${{ matrix.output-suffix }}.dmg + run: mv Cryptomator-*.dmg Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.output-suffix }}.dmg - name: Create detached GPG signature with key 615D449FE6E6A235 run: | echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import From 9984b2af9b84ad9de3449336e67202c38a2fda4a Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 25 Nov 2022 17:56:24 +0100 Subject: [PATCH 33/84] Fix errors --- .github/workflows/debian.yml | 12 +++++++----- .github/workflows/mac-dmg.yml | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 5fe3b7195..646c8e814 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -18,9 +18,15 @@ env: JAVA_VERSION: 19 jobs: + get-version: + uses: ./.github/workflows/get-version.yml + with: + version: ${{ github.event.inputs.version }} + build: name: Build Debian Package runs-on: ubuntu-20.04 + needs: [get-version] steps: - uses: actions/checkout@v3 - name: Install build tools @@ -40,10 +46,6 @@ jobs: env: SEM_VER_STR: ${{ needs.get-version.outputs.semVerStr }} REVCOUNT: ${{ needs.get-version.outputs.revNum }} - - name: Validate Version - uses: skymatic/semver-validation-action@v1 - with: - version: ${{ steps.versions.outputs.semVerStr }} - name: Run maven run: mvn -B clean package -Pdependency-check,linux -DskipTests - name: Create orig.tar.gz with common/ libs/ mods/ @@ -61,7 +63,7 @@ jobs: envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM}' < dist/linux/debian/rules > pkgdir/debian/rules envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog find . -name "*.jar" >> pkgdir/debian/source/include-binaries - mv pkgdir cryptomator_${{ steps.versions.outputs.ppaVerStr }} + mv pkgdir cryptomator_${PPA_VERSION} env: SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }} VERSION_NUM: ${{ needs.get-version.outputs.semVerNum }} diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index 446760deb..d52441a0e 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -77,7 +77,7 @@ jobs: --name Cryptomator --vendor "Skymatic GmbH" --copyright "(C) 2016 - 2022 Skymatic GmbH" - --app-version "${{ needs.get-version.outputs.semVerNum }} + --app-version "${{ needs.get-version.outputs.semVerNum }}" --java-options "-Xss5m" --java-options "-Xmx256m" --java-options "-Dfile.encoding=\"utf-8\"" From edaa2b7391118e8b8d841728c6794c9fac29aeaf Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 25 Nov 2022 18:07:07 +0100 Subject: [PATCH 34/84] Revert partially 9984b2af9b84ad9de3449336e67202c38a2fda4a --- .github/workflows/debian.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 646c8e814..2e3188039 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -63,7 +63,7 @@ jobs: envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM}' < dist/linux/debian/rules > pkgdir/debian/rules envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog find . -name "*.jar" >> pkgdir/debian/source/include-binaries - mv pkgdir cryptomator_${PPA_VERSION} + mv pkgdir cryptomator_${{ steps.versions.outputs.ppaVerStr }} env: SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }} VERSION_NUM: ${{ needs.get-version.outputs.semVerNum }} From 11aea06ecfcec00f2887aa05a420c508e1bac394 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 28 Nov 2022 13:36:15 +0100 Subject: [PATCH 35/84] replace deprecated set-output command in ci --- .github/workflows/debian.yml | 2 +- .github/workflows/dl-stats.yml | 2 +- .github/workflows/get-version.yml | 8 ++++---- .github/workflows/release-check.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 2e3188039..a194d4ad1 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -42,7 +42,7 @@ jobs: cache: 'maven' - id: versions name: Create PPA version string - run: echo "::set-output name=ppaVerStr::${SEM_VER_STR/-/\~}-${REVCOUNT}" + run: echo "ppaVerStr=${SEM_VER_STR/-/\~}-${REVCOUNT}" >> $GITHUB_OUTPUT env: SEM_VER_STR: ${{ needs.get-version.outputs.semVerStr }} REVCOUNT: ${{ needs.get-version.outputs.revNum }} diff --git a/.github/workflows/dl-stats.yml b/.github/workflows/dl-stats.yml index 0d9ca5dd7..dc87a2bbd 100644 --- a/.github/workflows/dl-stats.yml +++ b/.github/workflows/dl-stats.yml @@ -48,7 +48,7 @@ jobs: jq -c 'select(.filename|endswith(".dmg")) | select(.filename|endswith("-arm64.dmg")|not) | {name: "github.releases.downloads", tags: ["file=dmg", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json RESULT=$(jq -s -c "." output.json) - echo "::set-output name=result::${RESULT}" + echo "result=${RESULT}" >> $GITHUB_OUTPUT env: INTERVAL: 900 JSON_DATA: ${{ steps.get-stats.outputs.result }} diff --git a/.github/workflows/get-version.yml b/.github/workflows/get-version.yml index 7ccb1b9a3..1791a48f5 100644 --- a/.github/workflows/get-version.yml +++ b/.github/workflows/get-version.yml @@ -67,10 +67,10 @@ jobs: elif [[ $SEM_VER_STR =~ [0-9]+\.[0-9]+\.[0-9]+-rc[1-9] ]]; then TYPE="rc" fi - echo "::set-output name=semVerStr::${SEM_VER_STR}" - echo "::set-output name=semVerNum::${SEM_VER_NUM}" - echo "::set-output name=revNum::${REVCOUNT}" - echo "::set-output name=type::${TYPE}" + echo "semVerStr=${SEM_VER_STR}" >> $GITHUB_OUTPUT + echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT + echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT + echo "type=${TYPE}" >> $GITHUB_OUTPUT - name: Validate Version uses: skymatic/semver-validation-action@v1 with: diff --git a/.github/workflows/release-check.yml b/.github/workflows/release-check.yml index e2f116130..7309cb852 100644 --- a/.github/workflows/release-check.yml +++ b/.github/workflows/release-check.yml @@ -30,7 +30,7 @@ jobs: fi if [[ ${SEM_VER_STR} == `mvn help:evaluate -Dexpression=project.version -q -DforceStdout` ]]; then - echo "::set-output name=semVerStr::${SEM_VER_STR}" + echo "semVerStr=${SEM_VER_STR}" >> $GITHUB_OUTPUT else echo "Version not set in POM" exit 1 From db63a82d76b2b2272657b8ac2efb39f64f6313be Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 28 Nov 2022 13:46:02 +0100 Subject: [PATCH 36/84] bump version of skymatic actions --- .github/workflows/get-version.yml | 2 +- .github/workflows/win-exe.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/get-version.yml b/.github/workflows/get-version.yml index 1791a48f5..e6131b835 100644 --- a/.github/workflows/get-version.yml +++ b/.github/workflows/get-version.yml @@ -72,6 +72,6 @@ jobs: echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT echo "type=${TYPE}" >> $GITHUB_OUTPUT - name: Validate Version - uses: skymatic/semver-validation-action@v1 + uses: skymatic/semver-validation-action@v2 with: version: ${{ steps.versions.outputs.semVerStr }} \ No newline at end of file diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 055d5d194..0725c0329 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -107,7 +107,7 @@ jobs: run: attrib -r appdir/Cryptomator/Cryptomator.exe shell: pwsh - name: Codesign - uses: skymatic/code-sign-action@v1 + uses: skymatic/code-sign-action@v2 with: certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} password: ${{ secrets.WIN_CODESIGN_P12_PW }} @@ -150,7 +150,7 @@ jobs: env: JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs - name: Codesign MSI - uses: skymatic/code-sign-action@v1 + uses: skymatic/code-sign-action@v2 with: certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} password: ${{ secrets.WIN_CODESIGN_P12_PW }} @@ -250,7 +250,7 @@ jobs: -ib installer/unsigned/Cryptomator-Installer.exe -o tmp/engine.exe - name: Codesign burn engine - uses: skymatic/code-sign-action@v1 + uses: skymatic/code-sign-action@v2 with: certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} password: ${{ secrets.WIN_CODESIGN_P12_PW }} @@ -264,7 +264,7 @@ jobs: -ab tmp/engine.exe installer/unsigned/Cryptomator-Installer.exe -o installer/Cryptomator-Installer.exe - name: Codesign EXE - uses: skymatic/code-sign-action@v1 + uses: skymatic/code-sign-action@v2 with: certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} password: ${{ secrets.WIN_CODESIGN_P12_PW }} From 96de2556a986dc65092a8dd6103e3d6f444598b9 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 28 Nov 2022 15:00:16 +0100 Subject: [PATCH 37/84] apply correct style class on check icon --- src/main/java/org/cryptomator/ui/health/CheckStateIconView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/ui/health/CheckStateIconView.java b/src/main/java/org/cryptomator/ui/health/CheckStateIconView.java index 4f1a35f7a..ffb6771ea 100644 --- a/src/main/java/org/cryptomator/ui/health/CheckStateIconView.java +++ b/src/main/java/org/cryptomator/ui/health/CheckStateIconView.java @@ -31,7 +31,7 @@ public class CheckStateIconView extends FontAwesome5IconView { this.severity = EasyBind.wrapNullable(check).mapObservable(Check::highestResultSeverityProperty).asOrdinary(); this.glyph.bind(Bindings.createObjectBinding(this::glyphForState, state, severity)); this.subscriptions = List.of( // - EasyBind.includeWhen(getStyleClass(), "glyph-icon-muted", Bindings.equal(state, Check.CheckState.SKIPPED).or(Bindings.equal(state, Check.CheckState.CANCELLED))), // + EasyBind.includeWhen(getStyleClass(), "glyph-icon-muted", Bindings.equal(state, Check.CheckState.SKIPPED).or(Bindings.equal(state, Check.CheckState.CANCELLED)).or(Bindings.equal(severity, DiagnosticResult.Severity.INFO))), // EasyBind.includeWhen(getStyleClass(), "glyph-icon-primary", Bindings.equal(severity, DiagnosticResult.Severity.GOOD)), // EasyBind.includeWhen(getStyleClass(), "glyph-icon-orange", Bindings.equal(severity, DiagnosticResult.Severity.WARN).or(Bindings.equal(severity, DiagnosticResult.Severity.CRITICAL))), // EasyBind.includeWhen(getStyleClass(), "glyph-icon-red", Bindings.equal(state, Check.CheckState.ERROR)) // From 5f55530b4a5d8716b7ddeb47df71f1a224c5c9a8 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 29 Nov 2022 13:49:11 +0100 Subject: [PATCH 38/84] Add filters to results list --- .../ui/controls/FontAwesome5Icon.java | 1 + .../ui/health/CheckDetailController.java | 43 +++++++++++++++++-- .../resources/fxml/health_check_details.fxml | 18 +++++++- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java b/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java index 66eda7556..ea6ba00d3 100644 --- a/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java +++ b/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java @@ -27,6 +27,7 @@ public enum FontAwesome5Icon { FILE("\uF15B"), // FILE_IMPORT("\uF56F"), // FOLDER_OPEN("\uF07C"), // + FUNNEL("\uF0B0"), // HAND_HOLDING_HEART("\uF4BE"), // HEART("\uF004"), // HDD("\uF0A0"), // diff --git a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java index 83cb4ea7d..8f0454fd1 100644 --- a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java +++ b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java @@ -14,13 +14,25 @@ import javafx.beans.binding.BooleanExpression; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.fxml.FXML; +import javafx.scene.control.ChoiceBox; import javafx.scene.control.ListView; +import javafx.util.StringConverter; +import java.util.Arrays; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Stream; +import static org.cryptomator.cryptofs.health.api.DiagnosticResult.Severity; +import static org.cryptomator.ui.health.Result.FixState.FIXABLE; +import static org.cryptomator.ui.health.Result.FixState.FIXED; +import static org.cryptomator.ui.health.Result.FixState.FIXING; +import static org.cryptomator.ui.health.Result.FixState.FIX_FAILED; +import static org.cryptomator.ui.health.Result.FixState.NOT_FIXABLE; + @HealthCheckScoped public class CheckDetailController implements FxController { @@ -43,8 +55,11 @@ public class CheckDetailController implements FxController { private final BooleanProperty fixAllInfoResultsExecuted; private final BooleanBinding fixAllInfoResultsPossible; + private final ObjectProperty> resultsFilter; public ListView resultsListView; + public ChoiceBox severityChoiceBox; + public ChoiceBox fixStateChoiceBox; private Subscription resultSubscription; @Inject @@ -62,17 +77,18 @@ public class CheckDetailController implements FxController { this.checkFailed = BooleanExpression.booleanExpression(checkState.map(Check.CheckState.ERROR::equals).orElse(false)); this.checkCancelled = BooleanExpression.booleanExpression(checkState.map(Check.CheckState.CANCELLED::equals).orElse(false)); this.checkFinished = checkSucceeded.or(checkFailed).or(checkCancelled); - this.countOfWarnSeverity = results.reduce(countSeverity(DiagnosticResult.Severity.WARN)); - this.countOfCritSeverity = results.reduce(countSeverity(DiagnosticResult.Severity.CRITICAL)); + this.countOfWarnSeverity = results.reduce(countSeverity(Severity.WARN)); + this.countOfCritSeverity = results.reduce(countSeverity(Severity.CRITICAL)); this.warnOrCritsExist = EasyBind.combine(checkSucceeded, countOfWarnSeverity, countOfCritSeverity, (suceeded, warns, crits) -> suceeded && (warns.longValue() > 0 || crits.longValue() > 0)); this.fixAllInfoResultsExecuted = new SimpleBooleanProperty(false); this.fixAllInfoResultsPossible = Bindings.createBooleanBinding(() -> results.stream().anyMatch(this::isFixableInfoResult), results) // .and(fixAllInfoResultsExecuted.not()); + this.resultsFilter = new SimpleObjectProperty<>(r -> true); selectedTask.addListener(this::selectedTaskChanged); } private boolean isFixableInfoResult(Result r) { - return r.diagnosis().getSeverity() == DiagnosticResult.Severity.INFO && r.getState() == Result.FixState.FIXABLE; + return r.diagnosis().getSeverity() == Severity.INFO && r.getState() == FIXABLE; } private void selectedTaskChanged(ObservableValue observable, Check oldValue, Check newValue) { @@ -82,6 +98,8 @@ public class CheckDetailController implements FxController { if (newValue != null) { resultSubscription = EasyBind.bindContent(results, newValue.getResults()); } + severityChoiceBox.setValue(null); + fixStateChoiceBox.setValue(null); } private Function, Long> countSeverity(DiagnosticResult.Severity severity) { @@ -90,8 +108,25 @@ public class CheckDetailController implements FxController { @FXML public void initialize() { - resultsListView.setItems(results); + resultsListView.setItems(results.filtered(resultsFilter)); resultsListView.setCellFactory(resultListCellFactory); + + severityChoiceBox.getItems().add(null); + severityChoiceBox.getItems().addAll(Arrays.stream(DiagnosticResult.Severity.values()).toList()); + //severityFilter.setConverter(new SeverityStringifier()); + severityChoiceBox.setValue(null); + + fixStateChoiceBox.getItems().add(null); + fixStateChoiceBox.getItems().addAll(Arrays.stream(Result.FixState.values()).toList()); + fixStateChoiceBox.setValue(null); + + resultsFilter.bind(Bindings.createObjectBinding(() -> this::filterResults, severityChoiceBox.valueProperty(), fixStateChoiceBox.valueProperty())); + } + + private boolean filterResults(Result r) { + var desiredFixState = fixStateChoiceBox.getValue(); + var desiredSeverity = severityChoiceBox.getValue(); + return (desiredFixState == null || r.getState() == desiredFixState) && (desiredSeverity == null || r.diagnosis().getSeverity() == desiredSeverity); } @FXML diff --git a/src/main/resources/fxml/health_check_details.fxml b/src/main/resources/fxml/health_check_details.fxml index d4564a852..03b5a4dfa 100644 --- a/src/main/resources/fxml/health_check_details.fxml +++ b/src/main/resources/fxml/health_check_details.fxml @@ -8,6 +8,7 @@ + - - + + + + + + + \ No newline at end of file From 9cec45dc1f669fff1c357eec20dcaa6455ff1969 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 29 Nov 2022 14:18:43 +0100 Subject: [PATCH 39/84] Add context menu to copy single result info --- .../cryptomator/ui/health/CheckDetailController.java | 12 ++++++++++++ src/main/resources/fxml/health_check_details.fxml | 12 +++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java index 8f0454fd1..9ce582882 100644 --- a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java +++ b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java @@ -20,6 +20,8 @@ import javafx.collections.FXCollections; import javafx.fxml.FXML; import javafx.scene.control.ChoiceBox; import javafx.scene.control.ListView; +import javafx.scene.input.Clipboard; +import javafx.scene.input.ClipboardContent; import javafx.util.StringConverter; import java.util.Arrays; import java.util.function.Function; @@ -136,6 +138,16 @@ public class CheckDetailController implements FxController { } + @FXML + public void copyResultDetails() { + var result = resultsListView.getSelectionModel().getSelectedItem(); + if (result != null) { + ClipboardContent clipboardContent = new ClipboardContent(); + clipboardContent.putString(result.diagnosis().toString()); + Clipboard.getSystemClipboard().setContent(clipboardContent); + } + } + /* Getter/Setter */ public String getCheckName() { diff --git a/src/main/resources/fxml/health_check_details.fxml b/src/main/resources/fxml/health_check_details.fxml index 03b5a4dfa..41ccc4641 100644 --- a/src/main/resources/fxml/health_check_details.fxml +++ b/src/main/resources/fxml/health_check_details.fxml @@ -9,6 +9,8 @@ + + - + + + + + + + + + \ No newline at end of file From 2f9818aadec270b3ac0df9a5a1204e100e40226f Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 29 Nov 2022 17:07:43 +0100 Subject: [PATCH 40/84] use new JavaFX 19 API --- .../ChooseExistingVaultController.java | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java index 0a0dc3d2e..fe4ac3bd1 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java @@ -15,7 +15,6 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.Scene; @@ -25,6 +24,7 @@ import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.util.Objects; import java.util.ResourceBundle; import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB; @@ -42,9 +42,7 @@ public class ChooseExistingVaultController implements FxController { private final ObjectProperty vault; private final VaultListManager vaultListManager; private final ResourceBundle resourceBundle; - private final FxApplicationStyle applicationStyle; - - private final ObjectProperty screenshot = new SimpleObjectProperty<>(); + private final ObservableValue screenshot; @Inject ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, FxApplicationStyle applicationStyle) { @@ -56,28 +54,20 @@ public class ChooseExistingVaultController implements FxController { this.vault = vault; this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; - this.applicationStyle = applicationStyle; + this.screenshot = applicationStyle.appliedThemeProperty().map(this::selectScreenshot); } - @FXML - public void initialize() { + private Image selectScreenshot(Theme theme) { + String imageResourcePath; if (SystemUtils.IS_OS_MAC) { - applicationStyle.appliedThemeProperty().addListener(this::appliedThemeChanged); - setMacScreenshot(applicationStyle.appliedThemeProperty().get()); + imageResourcePath = switch (theme) { + case LIGHT -> "/img/select-masterkey-mac.png"; + case DARK -> "/img/select-masterkey-mac-dark.png"; + }; } else { - this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-win.png").toString())); - } - } - - private void appliedThemeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") Theme oldValue, Theme newValue) { - setMacScreenshot(newValue); - } - - private void setMacScreenshot(Theme theme) { - switch (theme) { - case LIGHT -> this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac.png").toString())); - case DARK -> this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac-dark.png").toString())); + imageResourcePath = "/img/select-masterkey-win.png"; } + return new Image((Objects.requireNonNull(getClass().getResource(imageResourcePath)).toString())); } @FXML @@ -106,12 +96,12 @@ public class ChooseExistingVaultController implements FxController { /* Getter */ - public ObjectProperty screenshotProperty() { + public ObservableValue screenshotProperty() { return screenshot; } public Image getScreenshot() { - return screenshot.get(); + return screenshot.getValue(); } From 99bc4dbdc5629afd2684cd7fe51c1364522815cb Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 25 Nov 2022 15:27:46 +0100 Subject: [PATCH 41/84] use openjfx jmods instead of jars --- .github/workflows/appimage.yml | 3 ++- .github/workflows/mac-dmg.yml | 3 ++- .github/workflows/win-exe.yml | 3 ++- pom.xml | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 26d455b8f..45ec85ef2 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -29,6 +29,7 @@ jobs: with: distribution: 'zulu' java-version: ${{ env.JAVA_VERSION }} + java-package: 'jdk+fx' cache: 'maven' - name: Set version run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} @@ -45,7 +46,7 @@ jobs: --verbose --output runtime --module-path "${JAVA_HOME}/jmods" - --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr + --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 diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index d52441a0e..94b38da96 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -41,6 +41,7 @@ jobs: with: distribution: 'zulu' java-version: ${{ env.JAVA_VERSION }} + java-package: 'jdk+fx' architecture: ${{ matrix.architecture }} cache: 'maven' - name: Set version @@ -58,7 +59,7 @@ jobs: --verbose --output runtime --module-path "${JAVA_HOME}/jmods" - --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr + --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 diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 0725c0329..dc5fc335f 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -37,6 +37,7 @@ jobs: with: distribution: ${{ env.JAVA_DIST }} java-version: ${{ env.JAVA_VERSION }} + java-package: 'jdk+fx' cache: ${{ env.JAVA_CACHE }} - name: Set version run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} @@ -53,7 +54,7 @@ jobs: --verbose --output runtime --module-path "${JAVA_HOME}/jmods" - --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr + --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 diff --git a/pom.xml b/pom.xml index 725e3d7c2..a8f620a32 100644 --- a/pom.xml +++ b/pom.xml @@ -371,6 +371,7 @@ org.apache.maven.plugins maven-dependency-plugin + copy-mods prepare-package @@ -380,7 +381,7 @@ runtime ${project.build.directory}/mods - ${nonModularGroupIds} + org.openjfx,${nonModularGroupIds} From abf944a1304d052eb5bfb25725f3f521b7916ee5 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 25 Nov 2022 15:57:04 +0100 Subject: [PATCH 42/84] add required openjfx jmods to debian source package --- .github/workflows/debian.yml | 13 ++++++++++++- dist/linux/debian/rules | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index a194d4ad1..e3f1c052d 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -16,6 +16,8 @@ on: env: JAVA_VERSION: 19 + OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/19/openjfx-19_linux-x64_bin-jmods.zip' + OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/19/openjfx-19_linux-aarch64_bin-jmods.zip' jobs: get-version: @@ -48,11 +50,20 @@ jobs: REVCOUNT: ${{ needs.get-version.outputs.revNum }} - name: Run maven run: mvn -B clean package -Pdependency-check,linux -DskipTests - - name: Create orig.tar.gz with common/ libs/ mods/ + - name: Download OpenJFX jmods + run: | + curl -L ${{ env.OPENJFX_JMODS_AMD64 }} -o openjfx-amd64.zip + mkdir -p jmods/amd64 + unzip -j openjfx-amd64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/amd64 + curl -L ${{ env.OPENJFX_JMODS_AARCH64 }} -o openjfx-aarch64.zip + mkdir -p jmods/aarch64 + unzip -j openjfx-aarch64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/aarch64 + - name: Create orig.tar.gz with common/ libs/ mods/ jmods/ run: | mkdir pkgdir cp -r target/libs pkgdir cp -r target/mods pkgdir + cp -r jmods pkgdir cp -r dist/linux/common/ pkgdir cp target/cryptomator-*.jar pkgdir/mods tar -cJf cryptomator_${{ steps.versions.outputs.ppaVerStr }}.orig.tar.xz -C pkgdir . diff --git a/dist/linux/debian/rules b/dist/linux/debian/rules index 04c256f60..37243040a 100755 --- a/dist/linux/debian/rules +++ b/dist/linux/debian/rules @@ -20,6 +20,7 @@ override_dh_auto_build: ln -s ../common/org.cryptomator.Cryptomator512.png resources/cryptomator.png $(JAVA_HOME)/bin/jlink \ --output runtime \ + --module-path "jmods:${JAVA_HOME}/jmods" \ --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr \ --strip-native-commands \ --no-header-files \ From a3fc68ab6fdb84f27d004be5d736d0a77b3a5c1d Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 25 Nov 2022 16:05:53 +0100 Subject: [PATCH 43/84] jlink javafx.* modules from arch-dependent jmod path --- dist/linux/debian/rules | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dist/linux/debian/rules b/dist/linux/debian/rules index 37243040a..08bac5f56 100755 --- a/dist/linux/debian/rules +++ b/dist/linux/debian/rules @@ -5,6 +5,12 @@ #export DH_VERBOSE=1 JAVA_HOME = /usr/lib/jvm/java-19-coffeelibs +DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) +ifeq ($(DEB_BUILD_ARCH),amd64) +JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods +else ifeq ($(DEB_BUILD_ARCH),arm64) +JMODS_PATH = jmods/aarch64:${JAVA_HOME}/jmods +endif %: dh $@ @@ -20,8 +26,8 @@ override_dh_auto_build: ln -s ../common/org.cryptomator.Cryptomator512.png resources/cryptomator.png $(JAVA_HOME)/bin/jlink \ --output runtime \ - --module-path "jmods:${JAVA_HOME}/jmods" \ - --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr \ + --module-path "${JMODS_PATH}" \ + --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 \ From ba7029968d32ece37d6dc9ad55eeb632707eb105 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Fri, 25 Nov 2022 16:20:40 +0100 Subject: [PATCH 44/84] try fixing `dpkg-shlibdeps: error: cannot find library libgtk-x11-2.0.so.0 ...` --- .github/workflows/debian.yml | 2 +- dist/linux/debian/control | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index e3f1c052d..e1c3ad2cc 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -35,7 +35,7 @@ jobs: run: | sudo add-apt-repository ppa:coffeelibs/openjdk sudo apt-get update - sudo apt-get install debhelper devscripts dput coffeelibs-jdk-19 + sudo apt-get install debhelper devscripts dput coffeelibs-jdk-19 libgtk2.0-0 - name: Setup Java uses: actions/setup-java@v3 with: diff --git a/dist/linux/debian/control b/dist/linux/debian/control index 77aba901c..0f0757321 100644 --- a/dist/linux/debian/control +++ b/dist/linux/debian/control @@ -2,7 +2,7 @@ Source: cryptomator Maintainer: Cryptobot Section: utils Priority: optional -Build-Depends: debhelper (>=10), coffeelibs-jdk-19 +Build-Depends: debhelper (>=10), coffeelibs-jdk-19, libgtk2.0-0 Standards-Version: 4.5.0 Homepage: https://cryptomator.org Vcs-Git: https://github.com/cryptomator/cryptomator.git From b98eb8c6566b665e1b8ed668694390f26c52b42c Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 30 Nov 2022 12:48:18 +0100 Subject: [PATCH 45/84] Using Zulu JDK, codesign addiitonal files on macOS --- .github/workflows/mac-dmg.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index d52441a0e..4f06953be 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -136,6 +136,10 @@ jobs: CODESIGN_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_CODESIGN_TMP_KEYCHAIN_PW }} - name: Codesign run: | + echo "Codesigning jdk files..." + find Cryptomator.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \; + find Cryptomator.app/Contents/runtime/Contents/Home/lib/ -name 'jspawnhelper' -exec codesign --force -o runtime -s ${CODESIGN_IDENTITY} {} \; + echo "Codesigning jar contents..." find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \; for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then From 65e1993b438d827ba97f6566a1b0628edfd163d1 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 30 Nov 2022 13:35:06 +0100 Subject: [PATCH 46/84] Add tooltip to result severity icon --- .../ui/health/ResultListCellController.java | 43 ++++++++++++++----- src/main/resources/i18n/strings.properties | 5 +++ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java index 03c225d57..7debc4207 100644 --- a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java +++ b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java @@ -48,10 +48,10 @@ public class ResultListCellController implements FxController { private final BooleanBinding fixFailed; private final BooleanBinding fixRunningOrDone; private final List subscriptions; - private final Tooltip fixSuccessTip; - private final Tooltip fixFailTip; - + private final Tooltip fixStateTip; + private final Tooltip severityTip; private AutoAnimator fixRunningRotator; + private final ResourceBundle resourceBundle; /* FXML */ public FontAwesome5IconView severityView; @@ -59,6 +59,7 @@ public class ResultListCellController implements FxController { @Inject public ResultListCellController(ResultFixApplier fixApplier, ResourceBundle resourceBundle) { + this.resourceBundle = resourceBundle; this.result = new SimpleObjectProperty<>(null); this.severity = result.map(Result::diagnosis).map(DiagnosticResult::getSeverity); this.description = result.map(Result::getDescription).orElse(""); @@ -72,10 +73,31 @@ public class ResultListCellController implements FxController { this.fixFailed = Bindings.createBooleanBinding(this::isFixFailed, fixState); this.fixRunningOrDone = fixing.or(fixed).or(fixFailed); this.subscriptions = new ArrayList<>(); - this.fixSuccessTip = new Tooltip(resourceBundle.getString("health.fix.successTip")); - this.fixFailTip = new Tooltip(resourceBundle.getString("health.fix.failTip")); - fixSuccessTip.setShowDelay(Duration.millis(100)); - fixFailTip.setShowDelay(Duration.millis(100)); + + this.fixStateTip = new Tooltip(); + fixStateTip.textProperty().bind(fixState.map(this::getFixStateDescription)); + fixStateTip.setShowDelay(Duration.millis(100)); + + this.severityTip = new Tooltip(); + severityTip.textProperty().bind(severity.map(this::getSeverityDescription)); + severityTip.setShowDelay(Duration.millis(150)); + } + + private String getFixStateDescription(Result.FixState fixState) { + return switch (fixState) { + case FIXED -> resourceBundle.getString("health.fix.successTip"); + case FIX_FAILED -> resourceBundle.getString("health.fix.failTip"); + default -> ""; + }; + } + + private String getSeverityDescription(DiagnosticResult.Severity severity) { + return resourceBundle.getString(switch (severity) { + case GOOD -> "health.result.severityTip.good"; + case INFO -> "health.result.severityTip.info"; + case WARN -> "health.result.severityTip.warn"; + case CRITICAL -> "health.result.severityTip.critical"; + }); } @FXML @@ -93,12 +115,11 @@ public class ResultListCellController implements FxController { .afterStop(() -> fixView.setRotate(0)) // .build(); fixState.addListener(((observable, oldValue, newValue) -> { - if (newValue == Result.FixState.FIXED) { - Tooltip.install(fixView, fixSuccessTip); - } else if (newValue == Result.FixState.FIX_FAILED) { - Tooltip.install(fixView, fixFailTip); + if (newValue == Result.FixState.FIXED || newValue == Result.FixState.FIX_FAILED) { + Tooltip.install(fixView, fixStateTip); } })); + Tooltip.install(severityView, severityTip); } @FXML diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index d3ae3a0e4..32ef07983 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -221,6 +221,11 @@ health.check.detail.checkFailed=The check exited due to an error. health.check.detail.checkCancelled=The check was cancelled. health.check.detail.fixAllSpecificBtn=Fix all of type health.check.exportBtn=Export Report +## Result view +health.result.severityTip.good=Vault structure intact. +health.result.severityTip.info=Vault structure intact, fix suggested. +health.result.severityTip.warn=Vault structure corrupted, fix highly advised. +health.result.severityTip.critical=Vault structure corrupted, data loss determined. ## Fix Application health.fix.fixBtn=Fix health.fix.successTip=Fix successful From 7bac78bc5d628b68a1d0d8724e659a7dff9a60d2 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 30 Nov 2022 13:48:08 +0100 Subject: [PATCH 47/84] Center Filters and let result list grow to bottom --- src/main/resources/fxml/health_check_details.fxml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/fxml/health_check_details.fxml b/src/main/resources/fxml/health_check_details.fxml index 41ccc4641..04bf1d63d 100644 --- a/src/main/resources/fxml/health_check_details.fxml +++ b/src/main/resources/fxml/health_check_details.fxml @@ -40,14 +40,14 @@ - - + + - + - diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 32ef07983..fc9134381 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -219,6 +219,9 @@ health.check.detail.checkFinished=The check finished successfully. health.check.detail.checkFinishedAndFound=The check finished running. Please review the results. health.check.detail.checkFailed=The check exited due to an error. health.check.detail.checkCancelled=The check was cancelled. +health.check.detail.listFilters.label=Filter +health.check.detail.listFilters.severity=Severity +health.check.detail.listFilters.fixState=Fix state health.check.detail.fixAllSpecificBtn=Fix all of type health.check.exportBtn=Export Report ## Result view From 792fe1eafee8913d522c99d55dfbbc73eb55da36 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 30 Nov 2022 16:23:44 +0100 Subject: [PATCH 49/84] use jfx19 API --- .../ui/health/ResultListCellController.java | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java index 7debc4207..64cac79d3 100644 --- a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java +++ b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java @@ -33,7 +33,6 @@ public class ResultListCellController implements FxController { private static final FontAwesome5Icon WARN_ICON = FontAwesome5Icon.EXCLAMATION_TRIANGLE; private static final FontAwesome5Icon CRIT_ICON = FontAwesome5Icon.TIMES; - private final Logger LOG = LoggerFactory.getLogger(ResultListCellController.class); private final ObjectProperty result; private final ObservableValue severity; @@ -41,12 +40,12 @@ public class ResultListCellController implements FxController { private final ResultFixApplier fixApplier; private final ObservableValue fixState; private final ObjectBinding severityGlyph; - private final ObjectBinding fixGlyph; private final BooleanBinding fixable; private final BooleanBinding fixing; private final BooleanBinding fixed; private final BooleanBinding fixFailed; private final BooleanBinding fixRunningOrDone; + private final ObservableValue fixGlyph; private final List subscriptions; private final Tooltip fixStateTip; private final Tooltip severityTip; @@ -66,12 +65,12 @@ public class ResultListCellController implements FxController { this.fixApplier = fixApplier; this.fixState = result.flatMap(Result::fixState); this.severityGlyph = Bindings.createObjectBinding(this::getSeverityGlyph, result); - this.fixGlyph = Bindings.createObjectBinding(this::getFixGlyph, fixState); this.fixable = Bindings.createBooleanBinding(this::isFixable, fixState); this.fixing = Bindings.createBooleanBinding(this::isFixing, fixState); this.fixed = Bindings.createBooleanBinding(this::isFixed, fixState); this.fixFailed = Bindings.createBooleanBinding(this::isFixFailed, fixState); this.fixRunningOrDone = fixing.or(fixed).or(fixFailed); + this.fixGlyph = fixState.map(this::getFixGlyph); this.subscriptions = new ArrayList<>(); this.fixStateTip = new Tooltip(); @@ -83,6 +82,15 @@ public class ResultListCellController implements FxController { severityTip.setShowDelay(Duration.millis(150)); } + public FontAwesome5Icon getFixGlyph(Result.FixState state) { + return switch (state) { + case FIXING -> FontAwesome5Icon.SPINNER; + case FIXED -> FontAwesome5Icon.CHECK; + case FIX_FAILED -> FontAwesome5Icon.TIMES; + default -> null; + }; + } + private String getFixStateDescription(Result.FixState fixState) { return switch (fixState) { case FIXED -> resourceBundle.getString("health.fix.successTip"); @@ -170,22 +178,10 @@ public class ResultListCellController implements FxController { }; } - public ObjectBinding fixGlyphProperty() { + public ObservableValue fixGlyphProperty() { return fixGlyph; } - public FontAwesome5Icon getFixGlyph() { - if (fixState.getValue() == null) { - return null; - } - return switch (fixState.getValue()) { - case NOT_FIXABLE, FIXABLE -> null; - case FIXING -> FontAwesome5Icon.SPINNER; - case FIXED -> FontAwesome5Icon.CHECK; - case FIX_FAILED -> FontAwesome5Icon.TIMES; - }; - } - public BooleanBinding fixableProperty() { return fixable; } From e097bea1f55eb12feeb01f7a8001f2bad72a0cbb Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 1 Dec 2022 13:28:36 +0100 Subject: [PATCH 50/84] adjust stats alignment --- src/main/resources/fxml/stats.fxml | 30 ++++++++++------------ src/main/resources/i18n/strings.properties | 2 +- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/main/resources/fxml/stats.fxml b/src/main/resources/fxml/stats.fxml index b50f36535..87baef251 100644 --- a/src/main/resources/fxml/stats.fxml +++ b/src/main/resources/fxml/stats.fxml @@ -13,6 +13,7 @@ + - - - - - - - - - - - + + + + + + + + + + @@ -86,10 +86,8 @@ - - - - + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 83c39cea6..cecceaad8 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -303,7 +303,7 @@ stats.write.accessCount=Total writes: %d ## Accesses stats.access.totalAccessCount=Total accessed: %d -stats.access.accessCount=Currently accessed: %d +stats.access.accessCount=Access: %d # Main Window From d5523f07bd098640dc365aaaddccb67e94c27539 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 1 Dec 2022 13:32:39 +0100 Subject: [PATCH 51/84] adjust translations and translation keys --- src/main/resources/fxml/stats.fxml | 4 ++-- src/main/resources/i18n/strings.properties | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/fxml/stats.fxml b/src/main/resources/fxml/stats.fxml index 87baef251..c1f8b2aec 100644 --- a/src/main/resources/fxml/stats.fxml +++ b/src/main/resources/fxml/stats.fxml @@ -74,7 +74,7 @@ - + @@ -86,7 +86,7 @@ - + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index cecceaad8..df33193a7 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -302,8 +302,8 @@ stats.encr.total.data.gib=Data encrypted: %.1f GiB stats.write.accessCount=Total writes: %d ## Accesses -stats.access.totalAccessCount=Total accessed: %d -stats.access.accessCount=Access: %d +stats.access.current=Access: %d +stats.access.total=Total accesses: %d # Main Window From 216abf224e3d56b178719444e998fd496b5cd06d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 1 Dec 2022 17:37:26 +0100 Subject: [PATCH 52/84] add severity and its list filter translatable --- .../ui/health/CheckDetailController.java | 40 ++++++++++++++++++- .../ui/health/ResultListCellController.java | 2 +- src/main/resources/i18n/strings.properties | 13 ++++-- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java index 9ce582882..7b6e9b85f 100644 --- a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java +++ b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java @@ -24,6 +24,7 @@ import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; import javafx.util.StringConverter; import java.util.Arrays; +import java.util.ResourceBundle; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Stream; @@ -54,6 +55,7 @@ public class CheckDetailController implements FxController { private final Binding warnOrCritsExist; private final ResultListCellFactory resultListCellFactory; private final ResultFixApplier resultFixApplier; + private final ResourceBundle resourceBundle; private final BooleanProperty fixAllInfoResultsExecuted; private final BooleanBinding fixAllInfoResultsPossible; @@ -65,9 +67,10 @@ public class CheckDetailController implements FxController { private Subscription resultSubscription; @Inject - public CheckDetailController(ObjectProperty selectedTask, ResultListCellFactory resultListCellFactory, ResultFixApplier resultFixApplier) { + public CheckDetailController(ObjectProperty selectedTask, ResultListCellFactory resultListCellFactory, ResultFixApplier resultFixApplier, ResourceBundle resourceBundle) { this.resultListCellFactory = resultListCellFactory; this.resultFixApplier = resultFixApplier; + this.resourceBundle = resourceBundle; this.results = EasyBind.wrapList(FXCollections.observableArrayList()); this.check = selectedTask; this.checkState = selectedTask.flatMap(Check::stateProperty); @@ -115,7 +118,7 @@ public class CheckDetailController implements FxController { severityChoiceBox.getItems().add(null); severityChoiceBox.getItems().addAll(Arrays.stream(DiagnosticResult.Severity.values()).toList()); - //severityFilter.setConverter(new SeverityStringifier()); + severityChoiceBox.setConverter(new SeverityStringifier()); severityChoiceBox.setValue(null); fixStateChoiceBox.getItems().add(null); @@ -148,6 +151,39 @@ public class CheckDetailController implements FxController { } } + /* -- Internal classes -- */ + + class SeverityStringifier extends StringConverter { + + @Override + public String toString(Severity object) { + if (object == null) { + return resourceBundle.getString("health.result.severityFilter.none"); + } + return switch (object) { + case GOOD -> resourceBundle.getString("health.result.severityFilter.good"); + case INFO -> resourceBundle.getString("health.result.severityFilter.info"); + case WARN -> resourceBundle.getString("health.result.severityFilter.warn"); + case CRITICAL -> resourceBundle.getString("health.result.severityFilter.crit"); + }; + } + + @Override + public Severity fromString(String string) { + if (resourceBundle.getString("health.result.severityFilter.good").equals(string)) { + return Severity.GOOD; + } else if (resourceBundle.getString("health.result.severityFilter.info").equals(string)) { + return Severity.INFO; + } else if (resourceBundle.getString("health.result.severityFilter.warn").equals(string)) { + return Severity.WARN; + } else if (resourceBundle.getString("health.result.severityFilter.crit").equals(string)) { + return Severity.CRITICAL; + } else { + return null; + } + } + } + /* Getter/Setter */ public String getCheckName() { diff --git a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java index 64cac79d3..35889ec26 100644 --- a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java +++ b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java @@ -104,7 +104,7 @@ public class ResultListCellController implements FxController { case GOOD -> "health.result.severityTip.good"; case INFO -> "health.result.severityTip.info"; case WARN -> "health.result.severityTip.warn"; - case CRITICAL -> "health.result.severityTip.critical"; + case CRITICAL -> "health.result.severityTip.crit"; }); } diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index fc9134381..95efdb2d3 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -225,10 +225,15 @@ health.check.detail.listFilters.fixState=Fix state health.check.detail.fixAllSpecificBtn=Fix all of type health.check.exportBtn=Export Report ## Result view -health.result.severityTip.good=Vault structure intact. -health.result.severityTip.info=Vault structure intact, fix suggested. -health.result.severityTip.warn=Vault structure corrupted, fix highly advised. -health.result.severityTip.critical=Vault structure corrupted, data loss determined. +health.result.severityFilter.none=Severity - All +health.result.severityFilter.good=Good +health.result.severityFilter.info=Info +health.result.severityFilter.warn=Warning +health.result.severityFilter.crit=Critical +health.result.severityTip.good=Severity: Good\nNormal vault structure. +health.result.severityTip.info=Severity: Info\nVault structure intact, fix suggested. +health.result.severityTip.warn=Severity: Warning\nVault structure corrupted, fix highly advised. +health.result.severityTip.crit=Severity: Critical\nVault structure corrupted, data loss determined. ## Fix Application health.fix.fixBtn=Fix health.fix.successTip=Fix successful From d9320910217f7e8ecc90d29b488791e33286956d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 1 Dec 2022 22:20:31 +0100 Subject: [PATCH 53/84] add translations for fixState filter --- .../ui/health/CheckDetailController.java | 38 ++++++++++++++++++- src/main/resources/i18n/strings.properties | 8 +++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java index 7b6e9b85f..04d96b271 100644 --- a/src/main/java/org/cryptomator/ui/health/CheckDetailController.java +++ b/src/main/java/org/cryptomator/ui/health/CheckDetailController.java @@ -123,6 +123,7 @@ public class CheckDetailController implements FxController { fixStateChoiceBox.getItems().add(null); fixStateChoiceBox.getItems().addAll(Arrays.stream(Result.FixState.values()).toList()); + fixStateChoiceBox.setConverter(new FixStateStringifier()); fixStateChoiceBox.setValue(null); resultsFilter.bind(Bindings.createObjectBinding(() -> this::filterResults, severityChoiceBox.valueProperty(), fixStateChoiceBox.valueProperty())); @@ -158,7 +159,7 @@ public class CheckDetailController implements FxController { @Override public String toString(Severity object) { if (object == null) { - return resourceBundle.getString("health.result.severityFilter.none"); + return resourceBundle.getString("health.result.severityFilter.all"); } return switch (object) { case GOOD -> resourceBundle.getString("health.result.severityFilter.good"); @@ -184,6 +185,40 @@ public class CheckDetailController implements FxController { } } + class FixStateStringifier extends StringConverter { + + @Override + public String toString(Result.FixState object) { + if (object == null) { + return resourceBundle.getString("health.result.fixStateFilter.all"); + } + return switch (object) { + case FIXABLE -> resourceBundle.getString("health.result.fixStateFilter.fixable"); + case NOT_FIXABLE -> resourceBundle.getString("health.result.fixStateFilter.notFixable"); + case FIXING -> resourceBundle.getString("health.result.fixStateFilter.fixing"); + case FIXED -> resourceBundle.getString("health.result.fixStateFilter.fixed"); + case FIX_FAILED -> resourceBundle.getString("health.result.fixStateFilter.fixFailed"); + }; + } + + @Override + public Result.FixState fromString(String string) { + if (resourceBundle.getString("health.result.fixStateFilter.fixable").equals(string)) { + return FIXABLE; + } else if (resourceBundle.getString("health.result.fixStateFilter.notFixable").equals(string)) { + return NOT_FIXABLE; + } else if (resourceBundle.getString("health.result.fixStateFilter.fixing").equals(string)) { + return FIXING; + } else if (resourceBundle.getString("health.result.fixStateFilter.fixed").equals(string)) { + return FIXED; + } else if (resourceBundle.getString("health.result.fixStateFilter.fixFailed").equals(string)) { + return FIX_FAILED; + } else { + return null; + } + } + } + /* Getter/Setter */ public String getCheckName() { @@ -289,5 +324,4 @@ public class CheckDetailController implements FxController { public boolean getFixAllInfoResultsPossible() { return fixAllInfoResultsPossible.getValue(); } - } diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 95efdb2d3..ea713f2d6 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -225,7 +225,7 @@ health.check.detail.listFilters.fixState=Fix state health.check.detail.fixAllSpecificBtn=Fix all of type health.check.exportBtn=Export Report ## Result view -health.result.severityFilter.none=Severity - All +health.result.severityFilter.all=Severity - All health.result.severityFilter.good=Good health.result.severityFilter.info=Info health.result.severityFilter.warn=Warning @@ -234,6 +234,12 @@ health.result.severityTip.good=Severity: Good\nNormal vault structure. health.result.severityTip.info=Severity: Info\nVault structure intact, fix suggested. health.result.severityTip.warn=Severity: Warning\nVault structure corrupted, fix highly advised. health.result.severityTip.crit=Severity: Critical\nVault structure corrupted, data loss determined. +health.result.fixStateFilter.all=Fix state - All +health.result.fixStateFilter.fixable=Fixable +health.result.fixStateFilter.notFixable=Not fixable +health.result.fixStateFilter.fixing=Fixing… +health.result.fixStateFilter.fixed=Fixed +health.result.fixStateFilter.fixFailed=Fix failed ## Fix Application health.fix.fixBtn=Fix health.fix.successTip=Fix successful From 0c1bbc5bfd3a8a49a1b9b46800cd1b76ea3a3d03 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 2 Dec 2022 10:52:49 +0100 Subject: [PATCH 54/84] remove labels and change alignment --- src/main/resources/fxml/health_check_details.fxml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/resources/fxml/health_check_details.fxml b/src/main/resources/fxml/health_check_details.fxml index 67f7c30c8..0d27e65f0 100644 --- a/src/main/resources/fxml/health_check_details.fxml +++ b/src/main/resources/fxml/health_check_details.fxml @@ -41,16 +41,14 @@ - + - From 3016d35c9b24a4e42da73b1a2968833ade0c7806 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 2 Dec 2022 11:22:50 +0100 Subject: [PATCH 55/84] closes #2488 --- pom.xml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 52cee0e48..dcafa2a5d 100644 --- a/pom.xml +++ b/pom.xml @@ -27,8 +27,7 @@ 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-rc1 - 2.4.5 + 2.5.1 1.2.0-beta1 1.1.2 1.1.2 @@ -64,11 +63,6 @@ - - org.cryptomator - cryptolib - ${cryptomator.cryptolib.version} - org.cryptomator cryptofs From 3641b34c2df2aea9f944e99a1978b5d98bd1450a Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 16:10:39 +0100 Subject: [PATCH 56/84] add guard to ensure pom defined jfx version matches the jdk bundled/jmod one --- .github/workflows/appimage.yml | 9 +++++++++ .github/workflows/debian.yml | 17 +++++++++++++++++ .github/workflows/mac-dmg.yml | 9 +++++++++ .github/workflows/win-exe.yml | 9 +++++++++ 4 files changed, 44 insertions(+) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 45ec85ef2..e0fc088bc 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -31,6 +31,15 @@ jobs: java-version: ${{ env.JAVA_VERSION }} java-package: 'jdk+fx' cache: 'maven' + - name: Ensure major jfx version in pom equals in jdk + shell: pwsh + 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 '.*=','' + if ($jfxPomVersion[0] -ne $jfxJdkVersion) { + Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + exit 1 + } - name: Set version run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} - name: Run maven diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index e1c3ad2cc..3d56822d4 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -51,13 +51,30 @@ jobs: - name: Run maven run: mvn -B clean package -Pdependency-check,linux -DskipTests - name: Download OpenJFX jmods + id: download-jmods run: | curl -L ${{ env.OPENJFX_JMODS_AMD64 }} -o openjfx-amd64.zip mkdir -p jmods/amd64 unzip -j openjfx-amd64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/amd64 + unzip -j jmods/amd64/javafx.base.jmod lib/javafx.properties -d jmods/amd64 curl -L ${{ env.OPENJFX_JMODS_AARCH64 }} -o openjfx-aarch64.zip mkdir -p jmods/aarch64 unzip -j openjfx-aarch64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/aarch64 + unzip -j jmods/aarch64/javafx.base.jmod lib/javafx.properties -d jmods/aarch64 + - name: Ensure major jfx version in pom and in jmods is the same + shell: pwsh + run: | + $jfxPomVersion = (&mvn help:evaluate -Dexpression=javafx.version -q -DforceStdout) -split "\." + $jfxJmodVersionAmd64 = (Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','' + $jfxJmodVersionAarch64 = (Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','' + if ($jfxJmodVersionAmd64 -ne $jfxJmodVersionAarch64 ) { + Out-Error "JavaFX Jmods for aarch64 and amd64 are different major versions" + exit 1 + } + if ($jfxPomVersion[0] -ne $jfxJmodVersionAmd64) { + Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version of Jmods(${jfxJmodVersion}) " + exit 1 + } - name: Create orig.tar.gz with common/ libs/ mods/ jmods/ run: | mkdir pkgdir diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index 94b38da96..e71f64084 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -44,6 +44,15 @@ jobs: java-package: 'jdk+fx' architecture: ${{ matrix.architecture }} cache: 'maven' + - name: Ensure major jfx version in pom equals in jdk + shell: pwsh + 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 '.*=','' + if ($jfxPomVersion[0] -ne $jfxJdkVersion) { + Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + exit 1 + } - name: Set version run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} - name: Run maven diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index dc5fc335f..3646b3e91 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -39,6 +39,15 @@ jobs: java-version: ${{ env.JAVA_VERSION }} java-package: 'jdk+fx' cache: ${{ env.JAVA_CACHE }} + - name: Ensure major jfx version in pom equals in jdk + shell: pwsh + 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 '.*=','' + if ($jfxPomVersion[0] -ne $jfxJdkVersion) { + Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + exit 1 + } - name: Set version run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} - name: Run maven From 169039903d0d5698e0699b432fe2ac8b19392d85 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 16:31:09 +0100 Subject: [PATCH 57/84] Use correct cmdlet --- .github/workflows/appimage.yml | 2 +- .github/workflows/debian.yml | 2 +- .github/workflows/mac-dmg.yml | 2 +- .github/workflows/win-exe.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index e0fc088bc..55f1f765e 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -37,7 +37,7 @@ jobs: $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 '.*=','' if ($jfxPomVersion[0] -ne $jfxJdkVersion) { - Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " exit 1 } - name: Set version diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 3d56822d4..fc066c9af 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -68,7 +68,7 @@ jobs: $jfxJmodVersionAmd64 = (Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','' $jfxJmodVersionAarch64 = (Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','' if ($jfxJmodVersionAmd64 -ne $jfxJmodVersionAarch64 ) { - Out-Error "JavaFX Jmods for aarch64 and amd64 are different major versions" + Write-Error "JavaFX Jmods for aarch64 and amd64 are different major versions" exit 1 } if ($jfxPomVersion[0] -ne $jfxJmodVersionAmd64) { diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index e71f64084..03083bb7c 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -50,7 +50,7 @@ jobs: $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 '.*=','' if ($jfxPomVersion[0] -ne $jfxJdkVersion) { - Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " exit 1 } - name: Set version diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 3646b3e91..978818136 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -45,7 +45,7 @@ jobs: $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 '.*=','' if ($jfxPomVersion[0] -ne $jfxJdkVersion) { - Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " exit 1 } - name: Set version From 497ddcfc9c07033e630e28c9e90060127020709f Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 16:37:48 +0100 Subject: [PATCH 58/84] shoulda used quotes --- .github/workflows/appimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 55f1f765e..957accb0d 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -34,7 +34,7 @@ jobs: - name: Ensure major jfx version in pom equals in jdk shell: pwsh run: | - $jfxPomVersion = (&mvn help:evaluate -Dexpression=javafx.version -q -DforceStdout) -split "\." + $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 '.*=','' if ($jfxPomVersion[0] -ne $jfxJdkVersion) { Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " From d6e14dab9a8be32353d43e49f801b1ddd162bb95 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 16:43:45 +0100 Subject: [PATCH 59/84] version defined in javafx.properties is also the complete version --- .github/workflows/appimage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 957accb0d..6bba24bbe 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -35,9 +35,9 @@ jobs: shell: pwsh 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 '.*=','' + $jfxJdkVersion = ((Get-Content -path "${env:JAVA_HOME}/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." if ($jfxPomVersion[0] -ne $jfxJdkVersion) { - Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK($($jfxJdkVersion[0])) " exit 1 } - name: Set version From b2b49f4d2f3fe8d519c687d3c424fd40e38c59ed Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 16:49:19 +0100 Subject: [PATCH 60/84] use correct pwsh syntax on all publish workflows --- .github/workflows/appimage.yml | 2 +- .github/workflows/debian.yml | 12 ++++++------ .github/workflows/mac-dmg.yml | 8 ++++---- .github/workflows/win-exe.yml | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 6bba24bbe..a3502145a 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -36,7 +36,7 @@ jobs: 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) { + 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])) " exit 1 } diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index fc066c9af..8eb75908b 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -64,15 +64,15 @@ jobs: - name: Ensure major jfx version in pom and in jmods is the same shell: pwsh run: | - $jfxPomVersion = (&mvn help:evaluate -Dexpression=javafx.version -q -DforceStdout) -split "\." - $jfxJmodVersionAmd64 = (Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','' - $jfxJmodVersionAarch64 = (Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','' - if ($jfxJmodVersionAmd64 -ne $jfxJmodVersionAarch64 ) { + $jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\." + $jfxJmodVersionAmd64 = ((Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." + $jfxJmodVersionAarch64 = ((Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." + if ($jfxJmodVersionAmd64[0] -ne $jfxJmodVersionAarch64[0] ) { Write-Error "JavaFX Jmods for aarch64 and amd64 are different major versions" exit 1 } - if ($jfxPomVersion[0] -ne $jfxJmodVersionAmd64) { - Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version of Jmods(${jfxJmodVersion}) " + if ($jfxPomVersion[0] -ne $jfxJmodVersionAmd64[0]) { + Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version of Jmods($($jfxJmodVersionAmd64[0])) " exit 1 } - name: Create orig.tar.gz with common/ libs/ mods/ jmods/ diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index 03083bb7c..ee27624c9 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -47,10 +47,10 @@ jobs: - name: Ensure major jfx version in pom equals in jdk shell: pwsh 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 '.*=','' - if ($jfxPomVersion[0] -ne $jfxJdkVersion) { - Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + $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])) " exit 1 } - name: Set version diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 978818136..1ccf7a560 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -42,10 +42,10 @@ jobs: - name: Ensure major jfx version in pom equals in jdk shell: pwsh 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 '.*=','' - if ($jfxPomVersion[0] -ne $jfxJdkVersion) { - Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK(${jfxJdkVersion}) " + $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])) " exit 1 } - name: Set version From 8086ec1c1045e7a800504a8b6f88558391e141a1 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 22:37:21 +0100 Subject: [PATCH 61/84] improve check on debian to not return non-zero code --- .github/workflows/debian.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 8eb75908b..a39fd346b 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -56,21 +56,23 @@ jobs: curl -L ${{ env.OPENJFX_JMODS_AMD64 }} -o openjfx-amd64.zip mkdir -p jmods/amd64 unzip -j openjfx-amd64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/amd64 - unzip -j jmods/amd64/javafx.base.jmod lib/javafx.properties -d jmods/amd64 curl -L ${{ env.OPENJFX_JMODS_AARCH64 }} -o openjfx-aarch64.zip mkdir -p jmods/aarch64 unzip -j openjfx-aarch64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/aarch64 - unzip -j jmods/aarch64/javafx.base.jmod lib/javafx.properties -d jmods/aarch64 - name: Ensure major jfx version in pom and in jmods is the same shell: pwsh run: | - $jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\." - $jfxJmodVersionAmd64 = ((Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." - $jfxJmodVersionAarch64 = ((Get-Content -Path "jmods/aarch64/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." + mkdir jfxBaseJmodAmd64 + jmod extract --dir jfxBaseJmodAmd64 jmods/amd64/javafx.base.jmod + $jfxJmodVersionAmd64 = ((Get-Content -Path "jfxBaseJmodAmd64/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." + mkdir jfxBaseJmodAarch64 + jmod extract --dir jfxBaseJmodAarch64 jmods/aarch64/javafx.base.jmod + $jfxJmodVersionAarch64 = ((Get-Content -Path "jfxBaseJmodAarch64/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." if ($jfxJmodVersionAmd64[0] -ne $jfxJmodVersionAarch64[0] ) { Write-Error "JavaFX Jmods for aarch64 and amd64 are different major versions" exit 1 } + $jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\." if ($jfxPomVersion[0] -ne $jfxJmodVersionAmd64[0]) { Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version of Jmods($($jfxJmodVersionAmd64[0])) " exit 1 From 83b198d49139baa390a69d72cfcac17d33a2ed50 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 22:38:37 +0100 Subject: [PATCH 62/84] only run jfx guard on one mac system --- .github/workflows/mac-dmg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index ee27624c9..7ce67c772 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -45,6 +45,7 @@ jobs: architecture: ${{ matrix.architecture }} cache: 'maven' - name: Ensure major jfx version in pom equals in jdk + if: ${{ matrix.architecture}} == 'x64' shell: pwsh run: | $jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\." From 00a3692dcf0410a1c8e61e3523d57874eb876863 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 22:59:42 +0100 Subject: [PATCH 63/84] final adjustments --- .github/workflows/debian.yml | 2 +- .github/workflows/mac-dmg.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index a39fd346b..8b6a3c956 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -74,7 +74,7 @@ jobs: } $jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\." if ($jfxPomVersion[0] -ne $jfxJmodVersionAmd64[0]) { - Out-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version of Jmods($($jfxJmodVersionAmd64[0])) " + Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version of Jmods($($jfxJmodVersionAmd64[0])) " exit 1 } - name: Create orig.tar.gz with common/ libs/ mods/ jmods/ diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index 7ce67c772..f2d128566 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -45,7 +45,7 @@ jobs: architecture: ${{ matrix.architecture }} cache: 'maven' - name: Ensure major jfx version in pom equals in jdk - if: ${{ matrix.architecture}} == 'x64' + if: ${{ !contains(matrix.os, 'self-hosted') }} shell: pwsh run: | $jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\." From 06922717c416c119d8419e6c07e8c23e8bbeafd5 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 5 Dec 2022 23:32:49 +0100 Subject: [PATCH 64/84] adjust spacing and window size to fit (english) labels --- src/main/resources/fxml/health_check_details.fxml | 3 +-- src/main/resources/fxml/health_check_list.fxml | 2 +- src/main/resources/fxml/health_start.fxml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/resources/fxml/health_check_details.fxml b/src/main/resources/fxml/health_check_details.fxml index 0d27e65f0..ac12a09c1 100644 --- a/src/main/resources/fxml/health_check_details.fxml +++ b/src/main/resources/fxml/health_check_details.fxml @@ -40,14 +40,13 @@ - + - diff --git a/src/main/resources/fxml/health_check_list.fxml b/src/main/resources/fxml/health_check_list.fxml index 1edb004df..3124e15c6 100644 --- a/src/main/resources/fxml/health_check_list.fxml +++ b/src/main/resources/fxml/health_check_list.fxml @@ -12,7 +12,7 @@ diff --git a/src/main/resources/fxml/health_start.fxml b/src/main/resources/fxml/health_start.fxml index 9edc65f50..cc65aaaaa 100644 --- a/src/main/resources/fxml/health_start.fxml +++ b/src/main/resources/fxml/health_start.fxml @@ -16,7 +16,7 @@ From 3cbe4aa7ebfca753ff5b80c50bf436c5d1efa2ec Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 6 Dec 2022 10:39:38 +0100 Subject: [PATCH 65/84] use functional style --- src/main/java/org/cryptomator/ui/health/Result.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/ui/health/Result.java b/src/main/java/org/cryptomator/ui/health/Result.java index d8a18b890..582e4f843 100644 --- a/src/main/java/org/cryptomator/ui/health/Result.java +++ b/src/main/java/org/cryptomator/ui/health/Result.java @@ -21,7 +21,7 @@ record Result(DiagnosticResult diagnosis, ObjectProperty fixState) { } public static Result create(DiagnosticResult diagnosis, Path vaultPath, VaultConfig config, Masterkey masterkey, Cryptor cryptor) { - FixState initialState = diagnosis.getFix(vaultPath, config, masterkey, cryptor).isPresent()? FixState.FIXABLE : FixState.NOT_FIXABLE; + FixState initialState = diagnosis.getFix(vaultPath, config, masterkey, cryptor).map( _f -> FixState.FIXABLE).orElse(FixState.NOT_FIXABLE); return new Result(diagnosis, new SimpleObjectProperty<>(initialState)); } From f9d28f20b31b7fbc1d61bc368d81f2519ae4281c Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 6 Dec 2022 10:59:18 +0100 Subject: [PATCH 66/84] Update README.md * update number of commits * remove "start" section --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0b72e2856..fc7d7df55 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator - File names get encrypted - Folder structure gets obfuscated - Use as many vaults in your Dropbox as you want, each having individual passwords -- Three thousand commits for the security of your data!! :tada: +- Four thousand commits for the security of your data!! :tada: ### Privacy @@ -85,7 +85,7 @@ For more information on the security details visit [cryptomator.org](https://doc ### Dependencies -* JDK 17 (e.g. temurin) +* JDK 19 (e.g. temurin) * Maven 3 ### Run Maven @@ -99,10 +99,6 @@ mvn clean install This will build all the jars and bundle them together with their OS-specific dependencies under `target`. This can now be used to build native packages. -### Start Cryptomator - -If you unzip the buildkit for your OS, you will find a launcher script with some basic settings. You might want to adjust these to your needs. To start Cryptomator, simply execute the launcher script from a terminal, e.g. `launcher-linux.sh`, if you're on a Linux system. - ## License This project is dual-licensed under the GPLv3 for FOSS projects as well as a commercial license for independent software vendors and resellers. If you want to modify this application under different conditions, feel free to contact our support team. From 512500aaeffdbed346f31e991c2e78367d1bb8c2 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 6 Dec 2022 11:03:29 +0100 Subject: [PATCH 67/84] bump cryptofs version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cd1fbb0fe..8b24ee97b 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 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.5.1 + 2.5.2 1.2.0-beta1 1.1.2 1.1.2 From 61027852e14890d1f7f9bce59f7e7c1c66d03ade Mon Sep 17 00:00:00 2001 From: Cryptobot Date: Tue, 6 Dec 2022 15:20:47 +0100 Subject: [PATCH 68/84] New Crowdin updates (#2474) New translations strings.properties Arabic; Belarusian; Bengali; Bosnian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Serbian (Cyrillic); Czech; Danish; Dutch; Filipino; French; Galician; German; Greek; Hebrew; Hindi; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Macedonian; Norwegian Bokmal; Norwegian Nynorsk; Persian; Polish; Portuguese; Portuguese, Brazilian; Punjabi; Romanian; Russian; Serbian (Latin) Sinhala; Slovak; Spanish; Swahili, Tanzania; Swedish; Tamil; Telugu; Thai; Turkish; Ukrainian; Vietnamese; [ci skip] --- src/main/resources/i18n/strings_ar.properties | 4 + src/main/resources/i18n/strings_be.properties | 174 +++++++++++++++++- src/main/resources/i18n/strings_bn.properties | 4 + src/main/resources/i18n/strings_bs.properties | 4 + src/main/resources/i18n/strings_ca.properties | 21 +++ src/main/resources/i18n/strings_cs.properties | 4 + src/main/resources/i18n/strings_da.properties | 4 + src/main/resources/i18n/strings_de.properties | 24 +++ src/main/resources/i18n/strings_el.properties | 4 + src/main/resources/i18n/strings_es.properties | 4 + src/main/resources/i18n/strings_fa.properties | 4 + .../resources/i18n/strings_fil.properties | 4 + src/main/resources/i18n/strings_fr.properties | 25 +++ src/main/resources/i18n/strings_gl.properties | 4 + src/main/resources/i18n/strings_he.properties | 4 + src/main/resources/i18n/strings_hi.properties | 25 +++ src/main/resources/i18n/strings_hr.properties | 4 + src/main/resources/i18n/strings_hu.properties | 4 + src/main/resources/i18n/strings_id.properties | 4 + src/main/resources/i18n/strings_it.properties | 4 + src/main/resources/i18n/strings_ja.properties | 4 + src/main/resources/i18n/strings_ko.properties | 4 + src/main/resources/i18n/strings_lv.properties | 4 + src/main/resources/i18n/strings_mk.properties | 4 + src/main/resources/i18n/strings_nb.properties | 6 +- src/main/resources/i18n/strings_nl.properties | 25 +++ src/main/resources/i18n/strings_nn.properties | 4 + src/main/resources/i18n/strings_pa.properties | 4 + src/main/resources/i18n/strings_pl.properties | 4 + src/main/resources/i18n/strings_pt.properties | 4 + .../resources/i18n/strings_pt_BR.properties | 6 + src/main/resources/i18n/strings_ro.properties | 107 ++++++++++- src/main/resources/i18n/strings_ru.properties | 4 + src/main/resources/i18n/strings_si.properties | 4 + src/main/resources/i18n/strings_sk.properties | 18 ++ src/main/resources/i18n/strings_sr.properties | 4 + .../resources/i18n/strings_sr_Latn.properties | 4 + src/main/resources/i18n/strings_sv.properties | 4 + src/main/resources/i18n/strings_sw.properties | 4 + src/main/resources/i18n/strings_ta.properties | 4 + src/main/resources/i18n/strings_te.properties | 4 + src/main/resources/i18n/strings_th.properties | 4 + src/main/resources/i18n/strings_tr.properties | 24 +++ src/main/resources/i18n/strings_uk.properties | 4 + src/main/resources/i18n/strings_vi.properties | 81 +++++++- src/main/resources/i18n/strings_zh.properties | 25 +++ .../resources/i18n/strings_zh_HK.properties | 72 +++++++- .../resources/i18n/strings_zh_TW.properties | 4 + 48 files changed, 743 insertions(+), 26 deletions(-) diff --git a/src/main/resources/i18n/strings_ar.properties b/src/main/resources/i18n/strings_ar.properties index d285db76d..0046e0afb 100644 --- a/src/main/resources/i18n/strings_ar.properties +++ b/src/main/resources/i18n/strings_ar.properties @@ -155,6 +155,7 @@ migration.impossible.moreInfo=لا يزال ممكناً فتح المخزن ب ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -200,6 +201,9 @@ stats.decr.total.data.none=تم فك تشفير البيانات:- ## Write stats.encr.total.data.none=البيانات المشفرة: - +## Accesses + + # Main Window main.closeBtn.tooltip=إغلاق main.minimizeBtn.tooltip=تصغير diff --git a/src/main/resources/i18n/strings_be.properties b/src/main/resources/i18n/strings_be.properties index f2a8d81a8..8b8c757c0 100644 --- a/src/main/resources/i18n/strings_be.properties +++ b/src/main/resources/i18n/strings_be.properties @@ -53,6 +53,12 @@ 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, ж або 수 +addvaultwizard.new.validCharacters.numbers=Лічбы +addvaultwizard.new.validCharacters.dashes=Злучок (%s) або падкрэслінік (%s) ### Password addvaultwizard.new.createVaultBtn=Стварыць скарбніцу addvaultwizard.new.generateRecoveryKeyChoice=Бяз гэтага пароля ты ня зможаш атрымаць доступ да сваіх даных. Ці хочаш ты мець ключ аднаўлення на выпадак, калі ты згубіш свой пароль? @@ -76,26 +82,30 @@ addvault.new.readme.accessLocation.2=Гэта месца дуступу да т addvault.new.readme.accessLocation.3=Любы дададзены сюды файл будзе зашыфраваны праз Cryptomator. Ты можаш працаваць тут як са звычайнаю тэчкаю альбо дыскам. Гэта толькі расшыфраваны агляд кантэнту, самі файлы заўжды захоўваюцца зашыфраванымі на тваім цвёрдым дыску. addvault.new.readme.accessLocation.4=Ты можаш выдаліць гэты файл. ## Existing +addvaultwizard.existing.instruction=Абяры файл "vault.cryptomator" у існуючай скарбніцы. Калі існуе толькі файл "masterkey.cryptomator", абяры яго. addvaultwizard.existing.chooseBtn=Абраць… addvaultwizard.existing.filePickerTitle=Абяры файл скарбніцы addvaultwizard.existing.filePickerMimeDesc=Скрабніца Cryptomator ## Success +addvaultwizard.success.nextStepsInstructions=Скарбніца "%s" дададзеная.\nТабе трэба разамкнуць гэтую скрабніцу, каб атрымаць доступ да зместу альбо дадаць яго. Таксама ты можаш разамкнуць яе ў любы іншы час. addvaultwizard.success.unlockNow=Разамкнуць зараз # Remove Vault removeVault.title=Выдаліць "%s" removeVault.message=Ці выдаліць скарбніцу? +removeVault.description=Гэта прывядзе толькі да таго, што Cryptomator забудзецца на гэтую скрынку. Ты зможаш дадаць яе пазней ізноў. Аніякія зашыфраваныя файлы з тайго жорсткага дыску не выдаляцьмуцца. removeVault.confirmBtn=Выдаліць скарбніцу # Change Password changepassword.title=Змяніць пароль changepassword.enterOldPassword=Увядзі бягучы пароль ад "%s" -changepassword.finalConfirmation=Я разумею, што калі забудуся на пароль, то згублю доступ да сваех даных +changepassword.finalConfirmation=Я разумею, што калі забудуся на пароль, то згублю доступ да маіх даных # Forget Password -forgetPassword.title=Забыўся на пароль -forgetPassword.message=Забыўся на захаваны пароль? -forgetPassword.confirmBtn=Забыўся на пароль +forgetPassword.title=Забыцца на пароль +forgetPassword.message=Ці забыцца на захаваны пароль? +forgetPassword.description=Гэта выдаліць захаваны пароль ад гэтай скарбніцы з твайго мэнэджара ключоў. +forgetPassword.confirmBtn=Забыцца на пароль # Unlock unlock.title=Разамкнуць "%s" @@ -104,45 +114,72 @@ unlock.savePassword=Захоўваць пароль unlock.unlockBtn=Адамкнуць ## Select unlock.chooseMasterkey.message=Файл майстра ключоў ня знойдзены +unlock.chooseMasterkey.description=Cryptomator ня змог знайсці файл masterkey у тваёй скарбніцы "%s". Калі ласка, абяры самастойна файл з ключом. unlock.chooseMasterkey.filePickerTitle=Абяры файл masterkey unlock.chooseMasterkey.filePickerMimeDesc=Майстар ключоў Cryptomator ## Success unlock.success.message=Паспяховае размыканне +unlock.success.description=Змест скарбніцы "%s" цяпер дасяжны праз ёйны мантажны пункт. unlock.success.rememberChoice=Запомні мой выбар і больш не пытай unlock.success.revealBtn=Паказаць дыск ## Failure unlock.error.message=Немагчыма разамкнуць скарбніцу ### Invalid Mount Point +unlock.error.invalidMountPoint.notExisting=Пункт мантажу "%s" не з'яўляецца пустой тэчкаю альбо ўвогуле не існуе. +unlock.error.invalidMountPoint.existing=Пункт мантажу "%s" ужо існуе альбо адсутнічае бацькоўская тэчка. +unlock.error.invalidMountPoint.driveLetterOccupied=Дыскавая літара "%s" ужо выкарыстоўваецца. ## Hub ### Waiting +hub.auth.message=Чаканне спраўджання… +hub.auth.description=Ты мусіш аўтаматычна перанакіравацца на старонку ўваходу. +hub.auth.loginLink=Не перанакіраваўся? Пстрыкні сюды, каб адчыніць старонку. ### Receive Key +hub.receive.message=Апрацоўка адказу… +hub.receive.description=Cryptomator атрымлівае ды апрацоўвае адказ ад Hub. Калі ласка, пачакай. ### Register Device +hub.register.message=Патрабуецца назва прылады +hub.register.description=Здаецца, што ты ў першы раз увайшла/-оў у Hub з гэтай прылады. Каб ідэнтыфікаваць яе для спраўджання доступу, табе трэба назваць гэтую прыладу. +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=Ліцэнзія пратэрмінаваная # Lock ## Force lock.forced.message=Замыканне не атрымалася +lock.forced.description=Замыканне скарбніцы "%s" было заблакаванае праз аперацыі ў апрацоўцы альбо праз адчыненыя файлы. Ты можаш прымусова замкнуць скарбніцу, але гэта можа прывесці да страты незахаваных даных. lock.forced.retryBtn=Паспрабаваць ізноў lock.forced.forceBtn=Замкнуць прымусова ## Failure lock.fail.message=Не атрымалася замкнуць скарбніцу +lock.fail.description=Скарбніцу "%s" не мажліва замкнуць. Упэўніся, што ты захаваў сваю незахаваную працу дзесьці ў іншым месцы, і што скночыліся ўсе важныя працэсы чытання-пісання. Для замыкання скарбніцы забі працэс Cryptomator. # Migration migration.title=Абнавіць скарбніцу ## Start +migration.start.prompt=Тваю скарбніцу "%s" неабходна абнавіць у новы фармат. Перад тым, як пачаць, запэўніся, што не адбываецца працэсу сінхранавання, які можа ўздзейнічаць на скарбніцу. migration.start.confirm=Так, мая скарбніца цалкам сінхранавана ## Run migration.run.enterPassword=Увядзіце пароль да "%s" migration.run.startMigrationBtn=Перамясціць скарбніцу migration.run.progressHint=Гэта можа заняць пэўны час… ## Success +migration.success.nextStepsInstructions=Міграцыя скарбніцы "%s" прайшла паспяхова.\nЦяпер ты можаш разамкнуць сваю скарбніцу. migration.success.unlockNow=Разамкнуць зараз ## Missing file system capabilities migration.error.missingFileSystemCapabilities.title=Файлавая сістэма не падтрымліваецца +migration.error.missingFileSystemCapabilities.description=Міграцыя не пачалася, бо твая скарбніца знаходзіцца ў непрыдатнай файлавай сістэме. migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=Файлавая сістэма не падтрымлівае доўгія назвы файлаў. migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=Файлавая сістэма не падтрымлівае доўгія сцежкі. migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Файлавая сістэма не дазваляе чытаць у ёй. @@ -152,6 +189,8 @@ migration.impossible.heading=Не мажліва перанесці скарбн # Health Check ## Start +health.title=Тэст на цэласнасць для "%s" +health.intro.header=Тэст на цэласнасць health.intro.remarkBackup=Калі даныя пашкоджаныя, дапаможа толькі рэзервовая копія. ## Start Failure health.fail.moreInfo=Падрабязней @@ -160,18 +199,43 @@ health.checkList.selectAllButton=Вылучыць усе элементы health.checkList.deselectAllButton=Адрабіць вылучэнне ўсіх элементаў health.check.runBatchBtn=Выканаць вылучаныя элементы ## Detail view +health.check.detail.checkCancelled=Праверка была скасавана. +health.check.exportBtn=Экспартаваць справаздачу +## Result view ## Fix Application +health.fix.fixBtn=Выправіць +health.fix.successTip=Паспяхова выпраўлена +health.fix.failTip=Няўдалае выпраўленне, глядзі пратакол з дэталямі # Preferences preferences.title=Налады ## General +preferences.general=Агульныя +preferences.general.startHidden=Хаваць акно пры запуску Cryptomator +preferences.general.autoCloseVaults=Замыкаць адчыненыя скарбніцы аўтаматычна пры выхадзе з праграмы +preferences.general.debugLogging=Уключыць пратакаляванне адладкі +preferences.general.debugDirectory=Паказаць файлы пратаколу +preferences.general.autoStart=Запускаць Cryptomator падчас запуску сістэмы +preferences.general.keychainBackend=Захоўваць паролі праз ## Interface +preferences.interface=Інтэрфэйс +preferences.interface.theme=Iнтэрфэйс +preferences.interface.theme.automatic=Аўтаматычна preferences.interface.theme.dark=Цёмная preferences.interface.theme.light=Светлая +preferences.interface.unlockThemes=Разблакаваць цёмную тэму preferences.interface.language=Мова (спатрэбуецца перазапуск) +preferences.interface.language.auto=Сістэма па змаўчанні +preferences.interface.interfaceOrientation=Арыентацыя інтэрфэйсу preferences.interface.interfaceOrientation.ltr=Злева ўправа preferences.interface.interfaceOrientation.rtl=Справа ўлева +preferences.interface.showMinimizeButton=Паказаць кнопку згортвання +preferences.interface.showTrayIcon=Паказваць іконку на інфармацыйнай панэлі (спатрэбіцца перазапуск) ## Volume +preferences.volume=Віртуальны дыск +preferences.volume.type=Тып тому +preferences.volume.webdav.port=Порт WebDAV +preferences.volume.webdav.scheme=Схема WebDAV ## Updates preferences.updates=Абнаўленні preferences.updates.currentVersion=Бягучая версія: %s @@ -180,20 +244,55 @@ preferences.updates.checkNowBtn=Праверыць зараз preferences.updates.updateAvailable=Даступна абнаўленне да версіі %s ## Contribution preferences.contribute=Падтрымай нас +preferences.contribute.getCertificate=Яшчэ ня маеш такога? Даведайся, як атрымаць. #<-- Add entries for donations and code/translation/documentation contribution --> ## About preferences.about=Пра нас # Vault Statistics +stats.title=Статыстыкі для %s ## Read +stats.read.throughput.idle=Чытанне: - +stats.read.throughput.kibs=Чытанне: %.2f КіБ/с +stats.read.throughput.mibs=Чытанне: %.2f МіБ/с +stats.read.total.data.none=Прачытана: - +stats.read.total.data.kib=Прачытана: %.1f КіБ +stats.read.total.data.mib=Прачытана: %.1f МіБ +stats.read.total.data.gib=Прачытана: %.1f ҐіБ +stats.decr.total.data.none=Расшыфравана: - +stats.decr.total.data.kib=Расшыфравана: %.1f КіБ +stats.decr.total.data.mib=Расшыфравана: %.1f МіБ +stats.decr.total.data.gib=Расшыфравана: %.1f ҐіБ +stats.read.accessCount=Агульная колькасць чытанняў: %d ## Write +stats.write.throughput.idle=Чытанне: - +stats.write.throughput.kibs=Пісанне: %.2f КіБ/с +stats.write.throughput.mibs=Пісанне: %.2f МіБ/с +stats.write.total.data.none=Напісана: - +stats.write.total.data.kib=Запісана: %.1f КіБ +stats.write.total.data.mib=Запісана: %.1f МіБ +stats.write.total.data.gib=Запісана: %.1f ҐіБ +stats.encr.total.data.none=Зашыфравана: - +stats.encr.total.data.kib=Зашыфравана: %.1f КіБ +stats.encr.total.data.mib=Зашыфравана: %.1f МіБ +stats.encr.total.data.gib=Зашыфравана: %.1f ҐіБ +stats.write.accessCount=Агульная колькасць запісаў: %d + +## Accesses + # Main Window main.closeBtn.tooltip=Зачыніць +main.minimizeBtn.tooltip=Згарнуць main.preferencesBtn.tooltip=Налады +main.debugModeEnabled.tooltip=Функццыя дыягназавання выключана +main.supporterCertificateMissing.tooltip=Калі ласка, падумай пра ахвяраванне ## Drag 'n' Drop +main.dropZone.dropVault=Дадаць гэтую скарбніцу +main.dropZone.unknownDragboardContent=Калі ты хочаш дадаць скарбніцу, перацягні яе ў гэтае акно ## Vault List +main.vaultlist.emptyList.onboardingInstruction=Пстрыкні тут, каб дадаць скарбніцу main.vaultlist.contextMenu.remove=Выдаліць… main.vaultlist.contextMenu.lock=Замкнуць main.vaultlist.contextMenu.unlock=Адамкнуць… @@ -207,37 +306,98 @@ main.vaultlist.addVaultBtn=Дадаць скарбніцу main.vaultDetail.lockedStatus=ЗАМКНЁНА main.vaultDetail.unlockBtn=Адамкнуць… main.vaultDetail.unlockNowBtn=Разамкнуць зараз +main.vaultDetail.optionsBtn=Параметры скарбніцы +main.vaultDetail.passwordSavedInKeychain=Пароль захаваны ### Unlocked main.vaultDetail.unlockedStatus=РАЗАМКНЁНА +main.vaultDetail.accessLocation=Змест тваёй скарбніцы даступны тут: main.vaultDetail.revealBtn=Паказаць дыск main.vaultDetail.lockBtn=Замкнуць +main.vaultDetail.bytesPerSecondRead=Чытанне: +main.vaultDetail.bytesPerSecondWritten=Пісанне: +main.vaultDetail.throughput.idle=бяздзейны +main.vaultDetail.throughput.kbps=%.1f КіБ/с +main.vaultDetail.throughput.mbps=%.1f МіБ/с +main.vaultDetail.stats=Статыстыка скарбніцы ### Missing +main.vaultDetail.missing.info=Cryptomator ня змог знайсці скарбніцу па гэтай сцежцы. +main.vaultDetail.missing.recheck=Пераправерыць +main.vaultDetail.missing.remove=Выдаліць са спісу скарбніц… +main.vaultDetail.missing.changeLocation=Змяніць месцазнаходжанне скарбніцы… ### Needs Migration main.vaultDetail.migrateButton=Абнавіць скарбніцу +main.vaultDetail.migratePrompt=Тваю скарбніцу трэба сканвертаваць у новы фармат, перад тым як ты зможаш атрымаць доступ да яе ### Error +main.vaultDetail.error.info=Адбылася памылка пры загрузцы скарбніцы з дыску. +main.vaultDetail.error.reload=Перазагрузіць +main.vaultDetail.error.windowTitle=Памылка загрузкі скарбніцы # Wrong File Alert +wrongFileAlert.title=Як зашыфраваць файлы +wrongFileAlert.message=Ці спрабаваў ты зашыфраваць гэтыя файлы? +wrongFileAlert.instruction.0=Каб зашыфраваць файлы, зрабі наступныя крокі: +wrongFileAlert.instruction.1=1. Разамкні свая скарбніцу. +wrongFileAlert.instruction.2=2. Пстрыкні па "Паказаць"; каб адчыніць том у тваім файлавым мэнэджары. +wrongFileAlert.instruction.3=3. Дадай свае файлы ў гэты том. +wrongFileAlert.link=Каб атрымаць больш інфармацыі, наведай # Vault Options ## General +vaultOptions.general=Агульныя vaultOptions.general.vaultName=Назва скарбніцы +vaultOptions.general.autoLock.lockAfterTimePart1=Замыкаць пры бяздзейнасці праз +vaultOptions.general.autoLock.lockAfterTimePart2=хвілін(ы) +vaultOptions.general.unlockAfterStartup=Размыкаць скрабніцу пры запуску Cryptomator +vaultOptions.general.actionAfterUnlock=Пасля паспяховага размыкання +vaultOptions.general.actionAfterUnlock.ignore=Нічога не рабі vaultOptions.general.actionAfterUnlock.reveal=Паказаць дыск +vaultOptions.general.actionAfterUnlock.ask=Запытацца ## Mount +vaultOptions.mount=Мантажаванне +vaultOptions.mount.readonly=Толькі для чытання +vaultOptions.mount.customMountFlags=Карыстальніцкія опцыі мантажавання +vaultOptions.mount.winDriveLetterOccupied=занята +vaultOptions.mount.mountPoint=Пункт мантажавання +vaultOptions.mount.mountPoint.auto=Аўтаматычны выбар пасуючага месцазнаходжання +vaultOptions.mount.mountPoint.driveLetter=Назначыць літару для дыску +vaultOptions.mount.mountPoint.custom=Уласная сцежка vaultOptions.mount.mountPoint.directoryPickerButton=Абраць… +vaultOptions.mount.mountPoint.directoryPickerTitle=Абяры парожнюю тэчку ## Master Key +vaultOptions.masterkey=Пароль vaultOptions.masterkey.changePasswordBtn=Змяніць пароль +vaultOptions.masterkey.forgetSavedPasswordBtn=Забыцца на захаваны пароль +vaultOptions.masterkey.showRecoveryKeyBtn=Паказаць ключ аднаўлення +vaultOptions.masterkey.recoverPasswordBtn=Скінуць пароль # Recovery Key ## Display Recovery Key +recoveryKey.display.title=Паказаць пароль аднаўлення +recoveryKey.create.message=Патрабуецца пароль +recoveryKey.create.description=Увядзі пароль ад "%s" каб паказаць ягоны код аднаўлення. +recoveryKey.display.description=Наступны код аднаўлення можа быць выкарастаны для аднаўлення доступу да "%s": recoveryKey.display.StorageHints=Захоўвай іх у бяспечным месцы, напрыклад:\n • Выкарыстоўваючы мэнэджар пароляў\n • На USB-флэшцы\n • Раздрукаванымі на паперы ## Reset Password ### Enter Recovery Key +recoveryKey.recover.title=Скінуць пароль +recoveryKey.recover.prompt=Увядзі свой ключ аднаўлення для "%s": +recoveryKey.recover.validKey=Гэта валідны ключ аднаўлення +recoveryKey.printout.heading=Ключ аднаўлення Cryptomator\n"%s"\n ### Reset Password +recoveryKey.recover.resetBtn=Скінуць ### Recovery Key Password Reset Success +recoveryKey.recover.resetSuccess.message=Пароль паспяхова скінуты +recoveryKey.recover.resetSuccess.description=Ты можаш разамкнуць сваю скарбніцу з дапамогаю новага паролю. # New Password +newPassword.promptText=Увядзі новы пароль +newPassword.reenterPassword=Пацвердзі новы пароль +newPassword.passwordsMatch=Паролі супадаюць! +newPassword.passwordsDoNotMatch=Паролі не супадаюць +passwordStrength.messageLabel.tooShort=Выкарыстай ня менш за %d сімвалаў +passwordStrength.messageLabel.0=Вельмі слабы passwordStrength.messageLabel.1=Слабы passwordStrength.messageLabel.2=Нармалёвы passwordStrength.messageLabel.3=Моцны @@ -246,5 +406,9 @@ passwordStrength.messageLabel.4=Вельмі моцны # Quit quit.title=Пакінуць праграму quit.message=Існуюць разамкнёныя скарбніцы +quit.description=Калі ласка, пацвердзі, што ты збіраешся выйсці. Cryptomator замкне ўсе разомкнутыя скарбніцы, каб прадухіліць страту даных. +quit.lockAndQuitBtn=Замкнуць ды вайсці -# Forced Quit \ No newline at end of file +# Forced Quit +quit.forced.message=Некаторыя скарбніцы не магчыма замкнуць +quit.forced.forceAndQuitBtn=Прымусіць і выйсці \ No newline at end of file diff --git a/src/main/resources/i18n/strings_bn.properties b/src/main/resources/i18n/strings_bn.properties index d9fbab722..10b8d750b 100644 --- a/src/main/resources/i18n/strings_bn.properties +++ b/src/main/resources/i18n/strings_bn.properties @@ -108,6 +108,7 @@ lock.forced.retryBtn=পুনরায় চেষ্টা করুন ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -124,6 +125,9 @@ lock.forced.retryBtn=পুনরায় চেষ্টা করুন ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=বন্ধ করুন ## Drag 'n' Drop diff --git a/src/main/resources/i18n/strings_bs.properties b/src/main/resources/i18n/strings_bs.properties index 3cfc2a387..a314ca074 100644 --- a/src/main/resources/i18n/strings_bs.properties +++ b/src/main/resources/i18n/strings_bs.properties @@ -154,6 +154,7 @@ migration.impossible.moreInfo=Sef se i dalje može otvoriti sa starijom verzijom ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -215,6 +216,9 @@ stats.encr.total.data.mib=Otključano podataka: %.1f MiB stats.encr.total.data.gib=Otključano podataka: %.1f GiB stats.write.accessCount=Ukupno upisano: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Zatvori main.minimizeBtn.tooltip=Minimiziraj diff --git a/src/main/resources/i18n/strings_ca.properties b/src/main/resources/i18n/strings_ca.properties index 3e6f33a34..17abe35fe 100644 --- a/src/main/resources/i18n/strings_ca.properties +++ b/src/main/resources/i18n/strings_ca.properties @@ -210,7 +210,23 @@ health.check.detail.checkFinished=La prova ha finalitzat amb èxit. health.check.detail.checkFinishedAndFound=La comprovació ha finalitzat. Si us plau, comproveu-ne es resultat. health.check.detail.checkFailed=La comprovació ha acabat a causa d'un error. health.check.detail.checkCancelled=S'ha cancel·lat la prova. +health.check.detail.listFilters.label=Filtre +health.check.detail.listFilters.severity=Gravetat +health.check.detail.listFilters.fixState=Estat de la reparació +health.check.detail.fixAllSpecificBtn=Qualsevol reparació health.check.exportBtn=Exporta informe +## Result view +health.result.severityFilter.all=Gravetat - Totes +health.result.severityFilter.good=Bé +health.result.severityFilter.info=Info +health.result.severityFilter.warn=Avís +health.result.severityFilter.crit=Crític +health.result.fixStateFilter.all=Estat de reparació - Tot +health.result.fixStateFilter.fixable=Es pot arreglar +health.result.fixStateFilter.notFixable=No es pot arreglar +health.result.fixStateFilter.fixing=Reparant… +health.result.fixStateFilter.fixed=Solucionat +health.result.fixStateFilter.fixFailed=Reparació fallida ## Fix Application health.fix.fixBtn=Corregeix health.fix.successTip=S'ha corregit amb èxit @@ -292,6 +308,11 @@ stats.encr.total.data.mib=Dades xifrades: %.1f MiB stats.encr.total.data.gib=Dades xifrades: %.1f GiB stats.write.accessCount=Total escrits: %d +## Accesses +stats.access.current=Accés: %d +stats.access.total=Total d'accessos: %d + + # Main Window main.closeBtn.tooltip=Tanca main.minimizeBtn.tooltip=Minimitza diff --git a/src/main/resources/i18n/strings_cs.properties b/src/main/resources/i18n/strings_cs.properties index 16097e8d2..062a410e4 100644 --- a/src/main/resources/i18n/strings_cs.properties +++ b/src/main/resources/i18n/strings_cs.properties @@ -192,6 +192,7 @@ health.check.detail.checkFinishedAndFound=Kontrola byla dokončena. Zkontrolujte health.check.detail.checkFailed=Kontrola byla ukončena z důvodu chyby. health.check.detail.checkCancelled=Kontrola byla zrušena. health.check.exportBtn=Exportovat sestavu +## Result view ## Fix Application health.fix.fixBtn=Opravit health.fix.successTip=Oprava byla úspěšná @@ -272,6 +273,9 @@ stats.encr.total.data.mib=Zašifrováno: %.1f MiB stats.encr.total.data.gib=Zašifrováno: %.1f GiB stats.write.accessCount=Celkem zapsáno: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Zavřít main.minimizeBtn.tooltip=Minimalizovat diff --git a/src/main/resources/i18n/strings_da.properties b/src/main/resources/i18n/strings_da.properties index 408dcbd2a..27e8349de 100644 --- a/src/main/resources/i18n/strings_da.properties +++ b/src/main/resources/i18n/strings_da.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=Kontrolproceduren er kørt færdig. Ge health.check.detail.checkFailed=Kontrolproceduren blev afbrudt af en fejl. health.check.detail.checkCancelled=Kontrolproceduren blev annulleret. health.check.exportBtn=Eksportér rapport +## Result view ## Fix Application health.fix.fixBtn=Reparér health.fix.successTip=Repareret @@ -300,6 +301,9 @@ stats.encr.total.data.mib=Data krypteret: %.1f MiB stats.encr.total.data.gib=Data krypteret: %.1f GiB stats.write.accessCount=Totalt antal skrivninger: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Luk main.minimizeBtn.tooltip=Minimér diff --git a/src/main/resources/i18n/strings_de.properties b/src/main/resources/i18n/strings_de.properties index c9b4a2c66..9ffed28ba 100644 --- a/src/main/resources/i18n/strings_de.properties +++ b/src/main/resources/i18n/strings_de.properties @@ -218,7 +218,26 @@ health.check.detail.checkFinished=Die Prüfung wurde erfolgreich abgeschlossen. health.check.detail.checkFinishedAndFound=Die Prüfung wurde abgeschlossen. Bitte überprüfe die Ergebnisse. health.check.detail.checkFailed=Die Prüfung wurde wegen eines Fehlers abgebrochen. health.check.detail.checkCancelled=Die Prüfung wurde abgebrochen. +health.check.detail.listFilters.label=Filter +health.check.detail.listFilters.severity=Schweregrad +health.check.detail.listFilters.fixState=Fix Status +health.check.detail.fixAllSpecificBtn=Behebe alle mit Status health.check.exportBtn=Bericht exportieren +## Result view +health.result.severityFilter.all=Schweregrad - Alle +health.result.severityFilter.good=Gut +health.result.severityFilter.info=Info +health.result.severityFilter.warn=Warnung +health.result.severityFilter.crit=Kritisch +health.result.severityTip.good=Schweregrad: Gut\nNormale Tresorstruktur. +health.result.severityTip.info=Schweregrad: Info\nTresorstruktur intakt, Beheben empfohlen. +health.result.severityTip.warn=Schweregrad: Warnung\nTresorstruktur beschädigt, Beheben dringend empfohlen. +health.result.severityTip.crit=Schweregrad: Kritisch\nTresorstruktur beschädigt, Datenverlust möglich. +health.result.fixStateFilter.all=Fix-Status - Alle +health.result.fixStateFilter.fixable=Fixierbar +health.result.fixStateFilter.notFixable=Nicht behebbar +health.result.fixStateFilter.fixed=Behoben +health.result.fixStateFilter.fixFailed=Fix fehlgeschlagen ## Fix Application health.fix.fixBtn=Beheben health.fix.successTip=Fehlerbehebung erfolgreich @@ -300,6 +319,11 @@ stats.encr.total.data.mib=Verschlüsselt: %.1f MiB stats.encr.total.data.gib=Verschlüsselt: %.1f GiB stats.write.accessCount=Schreibzugriffe: %d +## Accesses +stats.access.current=Zugriffe: %d +stats.access.total=Gesamte Zugriffe: %d + + # Main Window main.closeBtn.tooltip=Schließen main.minimizeBtn.tooltip=Minimieren diff --git a/src/main/resources/i18n/strings_el.properties b/src/main/resources/i18n/strings_el.properties index 2dba9e476..403413001 100644 --- a/src/main/resources/i18n/strings_el.properties +++ b/src/main/resources/i18n/strings_el.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=Ο έλεγχος σταμάτησε health.check.detail.checkFailed=Ο έλεγχος τερματίστηκε λόγω σφάλματος. health.check.detail.checkCancelled=Ο έλεγχος ακυρώθηκε. health.check.exportBtn=Εξαγωγή Αναφοράς +## Result view ## Fix Application health.fix.fixBtn=Επιδιόρθωση health.fix.successTip=Επιτυχής επιδιόρθωση @@ -300,6 +301,9 @@ stats.encr.total.data.mib=Δεδομένα που κρυπτογραφήθηκα stats.encr.total.data.gib=Δεδομένα που κρυπτογραφήθηκαν: %.1f GiB stats.write.accessCount=Συνολικές εγγραφές: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Κλείσιμο main.minimizeBtn.tooltip=Ελαχιστοποίηση diff --git a/src/main/resources/i18n/strings_es.properties b/src/main/resources/i18n/strings_es.properties index 7abba0429..bf256c145 100644 --- a/src/main/resources/i18n/strings_es.properties +++ b/src/main/resources/i18n/strings_es.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=La comprobación terminó de ejecutars health.check.detail.checkFailed=La comprobación terminó debido a un error. health.check.detail.checkCancelled=La comprobación se canceló. health.check.exportBtn=Exportar informe +## Result view ## Fix Application health.fix.fixBtn=Reparar health.fix.successTip=Reparación exitosa @@ -300,6 +301,9 @@ stats.encr.total.data.mib=Datos cifrados: %.1f MiB stats.encr.total.data.gib=Datos cifrados: %.1f GiB stats.write.accessCount=Total de escrituras: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Cerrar main.minimizeBtn.tooltip=Minimizar diff --git a/src/main/resources/i18n/strings_fa.properties b/src/main/resources/i18n/strings_fa.properties index 1cda0ec25..d6f2fef95 100644 --- a/src/main/resources/i18n/strings_fa.properties +++ b/src/main/resources/i18n/strings_fa.properties @@ -69,6 +69,7 @@ unlock.unlockBtn=بازکردن قفل ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -85,6 +86,9 @@ unlock.unlockBtn=بازکردن قفل ## Read ## Write +## Accesses + + # Main Window main.supporterCertificateMissing.tooltip=لطفا کمک مالی در نظر بگیرند ## Drag 'n' Drop diff --git a/src/main/resources/i18n/strings_fil.properties b/src/main/resources/i18n/strings_fil.properties index 7ab485d66..f150277ff 100644 --- a/src/main/resources/i18n/strings_fil.properties +++ b/src/main/resources/i18n/strings_fil.properties @@ -94,6 +94,7 @@ lock.forced.retryBtn=Subukan muli ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -113,6 +114,9 @@ preferences.interface.theme.light=Light ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=Isara main.preferencesBtn.tooltip=Mga Kagustuhan diff --git a/src/main/resources/i18n/strings_fr.properties b/src/main/resources/i18n/strings_fr.properties index 553820895..325ac10ef 100644 --- a/src/main/resources/i18n/strings_fr.properties +++ b/src/main/resources/i18n/strings_fr.properties @@ -218,7 +218,27 @@ health.check.detail.checkFinished=La vérification s'est terminée avec succès. health.check.detail.checkFinishedAndFound=Le test est terminé. Veuillez vérifier les résultats. health.check.detail.checkFailed=La vérification s'est arrêtée en raison d'une erreur. health.check.detail.checkCancelled=Vérification annulée. +health.check.detail.listFilters.label=Filtre +health.check.detail.listFilters.severity=Gravité +health.check.detail.listFilters.fixState=Corriger l'état +health.check.detail.fixAllSpecificBtn=Corriger tout le type health.check.exportBtn=Exporter le rapport +## Result view +health.result.severityFilter.all=Gravité - Tous +health.result.severityFilter.good=Satisfaisant +health.result.severityFilter.info=Information +health.result.severityFilter.warn=Avertissement +health.result.severityFilter.crit=Critique +health.result.severityTip.good=Gravité : structure de coffre normale. +health.result.severityTip.info=Gravité : Info\nStructure du coffre intacte, correction suggérée. +health.result.severityTip.warn=Gravité : Avertissement\nLa structure du coffre est corrompue, correction fortement recommandée. +health.result.severityTip.crit=Gravité : Structure du coffre critique,\ncorruption et perte de données. +health.result.fixStateFilter.all=Réparer l'état - Tous +health.result.fixStateFilter.fixable=Réparable +health.result.fixStateFilter.notFixable=Pas réparable +health.result.fixStateFilter.fixing=Réparation en cours… +health.result.fixStateFilter.fixed=Réparé +health.result.fixStateFilter.fixFailed=Réparation a échouée ## Fix Application health.fix.fixBtn=Réparer health.fix.successTip=Réparation réussie @@ -300,6 +320,11 @@ stats.encr.total.data.mib=Données chiffrées: %.1f MiO stats.encr.total.data.gib=Données chiffrées: %.1f GiO stats.write.accessCount=Total des écritures: %d +## Accesses +stats.access.current=Accès : %d +stats.access.total=Total des accès: %d + + # Main Window main.closeBtn.tooltip=Fermer main.minimizeBtn.tooltip=Réduire diff --git a/src/main/resources/i18n/strings_gl.properties b/src/main/resources/i18n/strings_gl.properties index 1b9b0de1a..6dd911a70 100644 --- a/src/main/resources/i18n/strings_gl.properties +++ b/src/main/resources/i18n/strings_gl.properties @@ -69,6 +69,7 @@ lock.forced.retryBtn=Tentar de novo ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -85,6 +86,9 @@ lock.forced.retryBtn=Tentar de novo ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=Pechar ## Drag 'n' Drop diff --git a/src/main/resources/i18n/strings_he.properties b/src/main/resources/i18n/strings_he.properties index ef5e92fdc..bca38389f 100644 --- a/src/main/resources/i18n/strings_he.properties +++ b/src/main/resources/i18n/strings_he.properties @@ -176,6 +176,7 @@ health.check.detail.checkFinishedAndFound=הבדיקה הסתיימה. ניתן health.check.detail.checkFailed=הבדיקה נכשלה בשל שגיאה. health.check.detail.checkCancelled=הבדיקה בוטלה. health.check.exportBtn=יצוא דוחות +## Result view ## Fix Application health.fix.fixBtn=תיקון @@ -227,6 +228,9 @@ stats.read.throughput.mibs=קריאה: %.2f MiB/s stats.read.total.data.none=מידע שנקרא: - ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=סגור main.preferencesBtn.tooltip=העדפות diff --git a/src/main/resources/i18n/strings_hi.properties b/src/main/resources/i18n/strings_hi.properties index d52d27d3b..b1e3dd312 100644 --- a/src/main/resources/i18n/strings_hi.properties +++ b/src/main/resources/i18n/strings_hi.properties @@ -50,6 +50,13 @@ addvaultwizard.new.directoryPickerLabel=अपने पसंद की जग addvaultwizard.new.directoryPickerButton=चुनें… 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.numbers=नंबर ### Password addvaultwizard.new.createVaultBtn=वॉल्ट बनाएं addvaultwizard.new.generateRecoveryKeyChoice=आप अपने पासवर्ड के बिना अपने डेटा तक नहीं पहुंच पाएंगे। क्या आप उस वक़्त के लिए एक पुनर्प्राप्ति कुंजी चाहते हैं जब आप अपना पासवर्ड खो देते हैं? @@ -86,8 +93,12 @@ removeVault.confirmBtn=वॉल्ट हटाए # Change Password changepassword.title=पासवर्ड बदलें changepassword.enterOldPassword="%s" का वर्तमान पासवर्ड दर्ज करें +changepassword.finalConfirmation=मैं समझता/समझती हूं कि अगर मैं अपना पासवर्ड भूल जाता हूं, तो मैं अपना डेटा एक्सेस नहीं कर पाऊंगा # Forget Password +forgetPassword.title=पासवर्ड भूल गए +forgetPassword.message=पासवर्ड भूल गए? +forgetPassword.confirmBtn=पासवर्ड भूल गए # Unlock unlock.title=अनलॉक "%s" @@ -99,13 +110,17 @@ unlock.chooseMasterkey.description=क्रिप्टोमेटर "%s" क ## Success unlock.success.message=अनलॉक सफल हुआ unlock.success.rememberChoice=विकल्प याद रखें, दोबारा ना दिखाएं +unlock.success.revealBtn=फोल्डर खोलें ## Failure unlock.error.message=वॉल्ट को अनलॉक करना असफल हुआ ### Invalid Mount Point ## Hub ### Waiting ### Receive Key +hub.receive.message=अभी संसाधित किया जा रहा है ### Register Device +hub.register.nameLabel=डिवाइस का नाम +hub.register.occupiedMsg=नाम पहले से प्रयोग में है hub.register.registerBtn=पुष्टि करें ### Registration Success ### Registration Failed @@ -118,6 +133,7 @@ hub.register.registerBtn=पुष्टि करें lock.forced.message=लॉक करना विफल हुआ lock.forced.retryBtn=पुन: प्रयास करें ## Failure +lock.fail.message=लॉक करना विफल # Migration migration.title=वाउल्ट को अपग्रेड करें @@ -135,6 +151,7 @@ migration.success.unlockNow=अब अनलॉक करें ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -145,6 +162,8 @@ preferences.general.autoCloseVaults=एप्लीकेशन बंद कर preferences.general.autoStart=क्रिप्टोमेटर को सिस्टम स्टार्ट पे खोले ## Interface preferences.interface.theme.automatic=ऑटोमैटिक +preferences.interface.theme.dark=डार्क +preferences.interface.theme.light=लाइट preferences.interface.interfaceOrientation.ltr=बाएं से दाएं preferences.interface.interfaceOrientation.rtl=दाएं से बाएं ## Volume @@ -159,6 +178,9 @@ preferences.contribute=हमें सपोर्ट करें ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=बंद करें main.preferencesBtn.tooltip=प्राथमिकताएं @@ -171,6 +193,7 @@ main.vaultlist.contextMenu.lock=लॉक करें main.vaultlist.contextMenu.unlock=अनलॉक करें... main.vaultlist.contextMenu.unlockNow=अब अनलॉक करें main.vaultlist.contextMenu.vaultoptions=वॉल्ट के विकल्प दिखाए +main.vaultlist.contextMenu.reveal=फोल्डर खोलें main.vaultlist.addVaultBtn=वाउल्ट डालें ## Vault Detail ### Welcome @@ -181,6 +204,7 @@ main.vaultDetail.unlockNowBtn=अब अनलॉक करें main.vaultDetail.optionsBtn=वॉल्ट के विकल्प ### Unlocked main.vaultDetail.accessLocation=आपके वॉल्ट की चीजें यहाँ एक्सेस कर सकतें हैं: +main.vaultDetail.revealBtn=फोल्डर खोलें main.vaultDetail.lockBtn=लॉक करें main.vaultDetail.stats=वॉल्ट के आंकड़े ### Missing @@ -199,6 +223,7 @@ wrongFileAlert.link=और मदद के लिए, यह जाएं vaultOptions.general=सामान्य vaultOptions.general.vaultName=वॉल्ट का नाम vaultOptions.general.actionAfterUnlock.ignore=कुछ न करें +vaultOptions.general.actionAfterUnlock.reveal=फोल्डर खोलें ## Mount vaultOptions.mount=माउंट हो रहा है diff --git a/src/main/resources/i18n/strings_hr.properties b/src/main/resources/i18n/strings_hr.properties index 8352113b2..af671fc73 100644 --- a/src/main/resources/i18n/strings_hr.properties +++ b/src/main/resources/i18n/strings_hr.properties @@ -192,6 +192,7 @@ health.check.detail.checkFinishedAndFound=Provjera je završena. Molimo pregleda health.check.detail.checkFailed=Provjera je otkazana zbog pogreške. health.check.detail.checkCancelled=Provjera je otkazana. health.check.exportBtn=Izvoz izvješća +## Result view ## Fix Application health.fix.fixBtn=Popravi health.fix.successTip=Popravak uspješan @@ -272,6 +273,9 @@ stats.encr.total.data.mib=Podataka šifrirano: %.1f MiB stats.encr.total.data.gib=Podataka šifrirano: %.1f GiB stats.write.accessCount=Ukupno pisanja: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Zatvori main.minimizeBtn.tooltip=Smanji diff --git a/src/main/resources/i18n/strings_hu.properties b/src/main/resources/i18n/strings_hu.properties index 453ff4d3f..8f8d7839e 100644 --- a/src/main/resources/i18n/strings_hu.properties +++ b/src/main/resources/i18n/strings_hu.properties @@ -189,6 +189,7 @@ health.check.detail.checkFinishedAndFound=Az ellenőrzés véget ért. Kérem el 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.exportBtn=Jelentés exportálása +## Result view ## Fix Application health.fix.fixBtn=Javítás health.fix.successTip=Javítás sikeres @@ -269,6 +270,9 @@ stats.encr.total.data.mib=Titkosított adat: %.1f MiB stats.encr.total.data.gib=Titkosított adat: %.1f GiB stats.write.accessCount=Összes írás: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Bezárás main.minimizeBtn.tooltip=Minimalizálás diff --git a/src/main/resources/i18n/strings_id.properties b/src/main/resources/i18n/strings_id.properties index 88884792d..30d5e4281 100644 --- a/src/main/resources/i18n/strings_id.properties +++ b/src/main/resources/i18n/strings_id.properties @@ -192,6 +192,7 @@ health.check.detail.checkFinishedAndFound=Pemeriksaan selesai. Silahkan tinjau h health.check.detail.checkFailed=Pemeriksaan terhenti karena terjadi kesalahan. health.check.detail.checkCancelled=Pemeriksaan dibatalkan. health.check.exportBtn=Ekspor Laporan +## Result view ## Fix Application health.fix.fixBtn=Perbaiki health.fix.successTip=Perbaikan berhasil @@ -272,6 +273,9 @@ stats.encr.total.data.mib=Data terenkripsi: %.1f MiB stats.encr.total.data.gib=Data terenkripsi: %.1f GiB stats.write.accessCount=Total ditulis: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Tutup main.minimizeBtn.tooltip=Perkecil diff --git a/src/main/resources/i18n/strings_it.properties b/src/main/resources/i18n/strings_it.properties index bfd643db1..c619f9711 100644 --- a/src/main/resources/i18n/strings_it.properties +++ b/src/main/resources/i18n/strings_it.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=Il controllo è terminato. Sei pregato health.check.detail.checkFailed=Il controllo è terminato a causa di un errore. health.check.detail.checkCancelled=Il controllo è stato annullato. health.check.exportBtn=Esporta il Rapporto +## Result view ## Fix Application health.fix.fixBtn=Correggi health.fix.successTip=Correzione riuscita @@ -300,6 +301,9 @@ stats.encr.total.data.mib=Dati crittografati: %.1f MiB stats.encr.total.data.gib=Dati crittografati: %.1f GiB stats.write.accessCount=Scritture totali: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Chiudi main.minimizeBtn.tooltip=Minimizza diff --git a/src/main/resources/i18n/strings_ja.properties b/src/main/resources/i18n/strings_ja.properties index 2df2a5ae3..4be14cfd9 100644 --- a/src/main/resources/i18n/strings_ja.properties +++ b/src/main/resources/i18n/strings_ja.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=実行中のチェックが終了し health.check.detail.checkFailed=エラーが発生したためチェックを終了しました。 health.check.detail.checkCancelled=チェックがキャンセルされました。 health.check.exportBtn=結果をエクスポート +## Result view ## Fix Application health.fix.fixBtn=修正 health.fix.successTip=正常に修正されました @@ -300,6 +301,9 @@ stats.encr.total.data.mib=暗号化済みデータ: %.1f MiB stats.encr.total.data.gib=暗号化済みデータ: %.1f GiB stats.write.accessCount=合計書き込み: %d +## Accesses + + # Main Window main.closeBtn.tooltip=閉じる main.minimizeBtn.tooltip=最小化 diff --git a/src/main/resources/i18n/strings_ko.properties b/src/main/resources/i18n/strings_ko.properties index 337bbad28..08def22f4 100644 --- a/src/main/resources/i18n/strings_ko.properties +++ b/src/main/resources/i18n/strings_ko.properties @@ -182,6 +182,7 @@ health.check.detail.checkRunning=검사가 현재 실행중입니다... health.check.detail.checkSkipped=선택된 검사항목이 없습니다. health.check.detail.checkFinished=검사가 성공적으로 완료되었습니다. health.check.exportBtn=보고서 내보내기 +## Result view ## Fix Application health.fix.fixBtn=문제해결 health.fix.successTip=문제 해결이 성공적으로 완료되었습니다 @@ -262,6 +263,9 @@ stats.encr.total.data.mib=데이터 암호화: %.1f MiB stats.encr.total.data.gib=데이터 암호화: %.1f GiB stats.write.accessCount=총 쓰기 횟수: %d +## Accesses + + # Main Window main.closeBtn.tooltip=닫기 main.minimizeBtn.tooltip=최소화 diff --git a/src/main/resources/i18n/strings_lv.properties b/src/main/resources/i18n/strings_lv.properties index bc230d174..cb1097bb0 100644 --- a/src/main/resources/i18n/strings_lv.properties +++ b/src/main/resources/i18n/strings_lv.properties @@ -148,6 +148,7 @@ migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Nav atļaujas ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -181,6 +182,9 @@ preferences.about=Par lietotni ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=Aizvērt main.minimizeBtn.tooltip=Minimizēt diff --git a/src/main/resources/i18n/strings_mk.properties b/src/main/resources/i18n/strings_mk.properties index a2a8c9737..8ca04f1c7 100644 --- a/src/main/resources/i18n/strings_mk.properties +++ b/src/main/resources/i18n/strings_mk.properties @@ -57,6 +57,7 @@ hub.register.registerBtn=Потврди ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -73,6 +74,9 @@ hub.register.registerBtn=Потврди ## Read ## Write +## Accesses + + # Main Window ## Drag 'n' Drop ## Vault List diff --git a/src/main/resources/i18n/strings_nb.properties b/src/main/resources/i18n/strings_nb.properties index f251e9265..48c0b52f3 100644 --- a/src/main/resources/i18n/strings_nb.properties +++ b/src/main/resources/i18n/strings_nb.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=Helsesjekken er ferdig å kjøre. Venn health.check.detail.checkFailed=Helsesjekken avsluttet på grunn av en feil. health.check.detail.checkCancelled=Helsesjekken ble avbrutt. health.check.exportBtn=Eksporter rapport +## Result view ## Fix Application health.fix.fixBtn=Reparer health.fix.successTip=Vellykket reparering @@ -229,7 +230,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.autoCloseVaults=Låsen åpner 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 @@ -300,6 +301,9 @@ stats.encr.total.data.mib=Data kryptert: %.1f MiB stats.encr.total.data.gib=Data kryptert: %.1f GiB stats.write.accessCount=Skrivninger totalt: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Lukk main.minimizeBtn.tooltip=Minimer diff --git a/src/main/resources/i18n/strings_nl.properties b/src/main/resources/i18n/strings_nl.properties index 7f91e1257..31752272b 100644 --- a/src/main/resources/i18n/strings_nl.properties +++ b/src/main/resources/i18n/strings_nl.properties @@ -218,7 +218,27 @@ health.check.detail.checkFinished=De controle is succesvol beëindigd. health.check.detail.checkFinishedAndFound=De controle is beëindigd. Bekijk alstublieft de resultaten. health.check.detail.checkFailed=De controle is afgesloten door een fout. health.check.detail.checkCancelled=De controle werd geannuleerd. +health.check.detail.listFilters.label=Filter +health.check.detail.listFilters.severity=Ernst +health.check.detail.listFilters.fixState=Herstel staat +health.check.detail.fixAllSpecificBtn=Repareer alle soorten health.check.exportBtn=Exporteer rapport +## Result view +health.result.severityFilter.all=Ernst - Alles +health.result.severityFilter.good=Goed +health.result.severityFilter.info=Info +health.result.severityFilter.warn=Waarschuwing +health.result.severityFilter.crit=Kritiek +health.result.severityTip.good=Ernst: Goed\nNormale kluis structuur. +health.result.severityTip.info=Ernst: Info\nKluis structuur intact, oplossing voorgesteld,. +health.result.severityTip.warn=Ernst: Waarschuwing\nKluis structuur beschadigd, reparatie hoogst aanbevolen. +health.result.severityTip.crit=Ernst: Kritiek\nKluis structuur corrupt, data verlies bepaald. +health.result.fixStateFilter.all=Herstel status - Alles +health.result.fixStateFilter.fixable=Repareerbaar +health.result.fixStateFilter.notFixable=Niet repareerbaar +health.result.fixStateFilter.fixing=Repareren… +health.result.fixStateFilter.fixed=Gerepareerd +health.result.fixStateFilter.fixFailed=Reparatie mislukt ## Fix Application health.fix.fixBtn=Herstel health.fix.successTip=Hersteld @@ -300,6 +320,11 @@ stats.encr.total.data.mib=Gegevens versleuteld: %.1f MiB stats.encr.total.data.gib=Gegevens versleuteld: %.1f GiB stats.write.accessCount=Totaal geschreven: %d +## Accesses +stats.access.current=Toegang: %d +stats.access.total=Totaal aantal toegangen: %d + + # Main Window main.closeBtn.tooltip=Sluiten main.minimizeBtn.tooltip=Minimaliseer diff --git a/src/main/resources/i18n/strings_nn.properties b/src/main/resources/i18n/strings_nn.properties index 0473d9d1d..fd77503b6 100644 --- a/src/main/resources/i18n/strings_nn.properties +++ b/src/main/resources/i18n/strings_nn.properties @@ -139,6 +139,7 @@ migration.impossible.moreInfo=Kvelven kan framleis opnast viss du bruker ein eld ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -173,6 +174,9 @@ preferences.about=Om ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=Lukk main.minimizeBtn.tooltip=Minimer diff --git a/src/main/resources/i18n/strings_pa.properties b/src/main/resources/i18n/strings_pa.properties index 2a0038b47..96071db82 100644 --- a/src/main/resources/i18n/strings_pa.properties +++ b/src/main/resources/i18n/strings_pa.properties @@ -147,6 +147,7 @@ migration.impossible.moreInfo=ਵਾਲਟ ਨੂੰ ਅਜੇ ਵੀ ਪੁਰ ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -208,6 +209,9 @@ stats.encr.total.data.mib=ਡਾਟਾ ਇੰਕ੍ਰਿਪਟ ਕੀਤਾ: %. stats.encr.total.data.gib=ਡਾਟਾ ਇੰਕ੍ਰਿਪਟ ਕੀਤਾ: %.1f GiB stats.write.accessCount=ਕੁੱਲ ਲਿਖੇ: %d +## Accesses + + # Main Window main.closeBtn.tooltip=ਬੰਦ ਕਰੋ main.minimizeBtn.tooltip=ਘੱਟੋ-ਘੱਟ diff --git a/src/main/resources/i18n/strings_pl.properties b/src/main/resources/i18n/strings_pl.properties index fb1b4f39c..6100a696b 100644 --- a/src/main/resources/i18n/strings_pl.properties +++ b/src/main/resources/i18n/strings_pl.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=Test zakończony. Proszę sprawdzić w health.check.detail.checkFailed=Wystąpił błąd, test zakończony. health.check.detail.checkCancelled=Test został anulowany. health.check.exportBtn=Eksportuj raport +## Result view ## Fix Application health.fix.fixBtn=Napraw health.fix.successTip=Naprawa udana @@ -300,6 +301,9 @@ 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 +## Accesses + + # Main Window main.closeBtn.tooltip=Zamknij main.minimizeBtn.tooltip=Minimalizuj diff --git a/src/main/resources/i18n/strings_pt.properties b/src/main/resources/i18n/strings_pt.properties index ff3a94c30..6135ca49b 100644 --- a/src/main/resources/i18n/strings_pt.properties +++ b/src/main/resources/i18n/strings_pt.properties @@ -209,6 +209,7 @@ health.check.detail.checkRunning=A verificação está atualmente a decorrer… health.check.detail.checkSkipped=A verificação não foi selecionada para ser executada. health.check.detail.checkFinished=A verificação foi concluída com sucesso. health.check.detail.checkFinishedAndFound=A verificação concluiu. Por favor, reveja os resultados. +## Result view ## Fix Application health.fix.fixBtn=Corrigir @@ -247,6 +248,9 @@ stats.title=Estatísticas de %s ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=Fechar main.minimizeBtn.tooltip=Minimizar diff --git a/src/main/resources/i18n/strings_pt_BR.properties b/src/main/resources/i18n/strings_pt_BR.properties index 853f2c3ed..f9ce6cc74 100644 --- a/src/main/resources/i18n/strings_pt_BR.properties +++ b/src/main/resources/i18n/strings_pt_BR.properties @@ -218,7 +218,10 @@ health.check.detail.checkFinished=A verificação foi concluída com sucesso. health.check.detail.checkFinishedAndFound=A verificação terminou em execução. Por favor, reveja os resultados. health.check.detail.checkFailed=A verificação foi encerrada devido a um erro. health.check.detail.checkCancelled=A verificação foi cancelada. +health.check.detail.listFilters.label=Filtro +health.check.detail.listFilters.severity=Severidade health.check.exportBtn=Exportar Relatório +## Result view ## Fix Application health.fix.fixBtn=Corrigir health.fix.successTip=Consertado com sucesso @@ -300,6 +303,9 @@ stats.encr.total.data.mib=Dados criptografados: %.1f MiB stats.encr.total.data.gib=Dados criptografados: %.1f GiB stats.write.accessCount=Total gravado: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Fechar main.minimizeBtn.tooltip=Minimizar diff --git a/src/main/resources/i18n/strings_ro.properties b/src/main/resources/i18n/strings_ro.properties index dd72912bf..80a500344 100644 --- a/src/main/resources/i18n/strings_ro.properties +++ b/src/main/resources/i18n/strings_ro.properties @@ -16,6 +16,10 @@ generic.button.print=Tipărește # Error error.message=A apărut o eroare +error.description=Cryptomatorul nu se aștepta să se întâmple asta. Puteți căuta soluții existente pentru această eroare. În cazul in care nu s-a raportat încă, nu ezitați să faceți acest lucru. +error.hyperlink.lookup=Caută soluții pentru această eroare +error.hyperlink.report=Raportează această eroare +error.technicalDetails=Detalii: # Defaults defaults.vault.vaultName=Seif @@ -49,6 +53,12 @@ addvaultwizard.new.fileAlreadyExists=Există deja un fișier sau un dosar cu num addvaultwizard.new.locationDoesNotExist=Dosarul în calea specificată nu există sau nu poate fi accesat addvaultwizard.new.locationIsNotWritable=Nu există acces la scriere la calea specificată addvaultwizard.new.locationIsOk=Locația potrivită pentru seiful dumneavoastră +addvaultwizard.new.invalidName=Nume de seif invalid +addvaultwizard.new.validName=Nume de seif valid +addvaultwizard.new.validCharacters.message=Numele seifului poate conține următoarele caractere: +addvaultwizard.new.validCharacters.chars=Caractere (e.x. a, ж or 수) +addvaultwizard.new.validCharacters.numbers=Numere +addvaultwizard.new.validCharacters.dashes=Linii(%s) sau sub-linii(%s) ### Password addvaultwizard.new.createVaultBtn=Crează seif addvaultwizard.new.generateRecoveryKeyChoice=Nu veți putea accesa datele dvs. fără parolă. Doriți o cheie de recuperare pentru cazul în care vă pierdeți parola? @@ -67,18 +77,22 @@ addvault.new.readme.storageLocation.8=2. Deblocați seiful în Cryptomator. addvault.new.readme.storageLocation.9=3. Deschideți locația de acces făcând clic pe butonul "Reveal". addvault.new.readme.storageLocation.10=Dacă aveți nevoie de ajutor, vizitați documentația: %s addvault.new.readme.accessLocation.fileName=BINEATIVENIT.rtf -addvault.new.readme.accessLocation.1=🔐️ UNITATE CRIPTATĂ 🔐️ +addvault.new.readme.accessLocation.1=🔐️ VOLUM CRIPTAT 🔐️ addvault.new.readme.accessLocation.2=Aceasta este locația de acces a seifului dvs. addvault.new.readme.accessLocation.3=Orice fișier adăugat la acest volum va fi criptat de către Cryptomator. Puteți lucra la el ca pe orice altă unitate/folder. Aceasta este doar o vizualizare decriptată a conținutului său, fișierele sunt criptate tot timpul pe hard disk-ul tău. addvault.new.readme.accessLocation.4=Puteți să ștergeți acest fișier. ## Existing +addvaultwizard.existing.instruction=Alegeți fișierul "vault.cryptomator" al seifului dvs. existent. Dacă există doar un fișier numit "masterkey.cryptomator", alegeți-l pe acesta. addvaultwizard.existing.chooseBtn=Alege… +addvaultwizard.existing.filePickerTitle=Selectați fișierul seif +addvaultwizard.existing.filePickerMimeDesc=Seif Cryptomator ## Success addvaultwizard.success.nextStepsInstructions=Seiful "%s" a fost adăugat.\nTrebuie să deblocați acest seif pentru a accesa sau adăuga conținut. Alternativ, îl puteți debloca în orice moment ulterior. addvaultwizard.success.unlockNow=Deblochează acum # Remove Vault removeVault.title=Eliminați seiful +removeVault.message=Ștergeți seiful? removeVault.description=Acest lucru va face Cryptomator să uite de acest seif. Îl puteţi adăuga din nou mai târziu. Nici un fişier criptat nu va fi şters din hard disk-ul dvs. removeVault.confirmBtn=Eliminați seiful @@ -89,6 +103,7 @@ changepassword.finalConfirmation=Înțeleg că nu voi putea accesa datele mele d # Forget Password forgetPassword.title=Parolă uitată +forgetPassword.message=Ați uitat parola? forgetPassword.description=Această acțiune va șterge parola salvată a acestui seif din keychain-ul sistemului de operare. forgetPassword.confirmBtn=Parolă uitată @@ -98,32 +113,55 @@ unlock.passwordPrompt=Introduceți parola pentru "%s": unlock.savePassword=Memorează parola unlock.unlockBtn=Deblocați ## Select +unlock.chooseMasterkey.message=Fișierul cheii principale nu a fost găsit unlock.chooseMasterkey.description=Nu s-a putut găsi fișierul masterkey pentru acest seif la locația așteptată. Vă rugăm să alegeți manual fișierul cheie. unlock.chooseMasterkey.filePickerTitle=Selectaţi fişierul Masterkey +unlock.chooseMasterkey.filePickerMimeDesc=Cheia principală a Cryptomator-ului ## Success +unlock.success.message=Seiful a fost deblocat cu succes unlock.success.description=Deblocat "%s" cu succes! Seiful dvs. este acum accesibil prin unitatea sa virtuală. unlock.success.rememberChoice=Ține minte alegerea, nu mai arăta asta din nou -unlock.success.revealBtn=Dezvăluie unitatea +unlock.success.revealBtn=Dezvăluie partiția ## Failure -unlock.error.message=Imposibil de deblocat seiful +unlock.error.message=Seiful nu a fost putut deschis ### Invalid Mount Point unlock.error.invalidMountPoint.notExisting=Punctul de montare "%s" nu este un dosar, nu este gol sau nu există. unlock.error.invalidMountPoint.existing=Punctul de montare "%s" există deja sau dosarul părinte lipsește. +unlock.error.invalidMountPoint.driveLetterOccupied=Partiția cu litera "%s" este deja in folosința. ## Hub ### Waiting +hub.auth.message=Se așteaptă autentificarea… +hub.auth.description=Ar trebui să fiți redirecționat automat către pagina de autentificare. +hub.auth.loginLink=Nu ați fost redirecționat? Apăsați aici pentru a deschide pagina. ### Receive Key +hub.receive.message=Se procesează răspunsul… +hub.receive.description=In acest moment Criptomatorul primește și procesează răspunsul de la Hub. Vă rugăm să așteptați. ### Register Device +hub.register.message=Numele dispozitivului este necesar +hub.register.description=Se pare că este prima data când accesați Hub-ul de pe acest dispozitiv. Trebuie sa denumiți acest dispozitiv pentru autorizarea accesului. +hub.register.nameLabel=Numele dispozitivului +hub.register.occupiedMsg=Acest nume este deja utilizat hub.register.registerBtn=Confirmați ### Registration Success +hub.registerSuccess.message=Dispozitiv numit +hub.registerSuccess.description=Pentru a accesa acest seif, dispozitivul dvs. trebuie să fie autorizat de proprietarul seifului. ### Registration Failed +hub.registerFailed.message=Numirea dispozitivului a eșuat +hub.registerFailed.description=O eroare a fost întâmpinata în procesul de denumire. Pentru mai multe detalii, verificați jurnalul aplicației. ### Unauthorized +hub.unauthorized.message=Acces respins +hub.unauthorized.description=Dispozitivul dvs. nu a fost autorizat să acceseze acest seif. Solicitați proprietarului seifului să va autorizeze accesul. ### License Exceeded +hub.licenseExceeded.message=Numărul de licențe a fost depășit +hub.licenseExceeded.description=Cryptomator Hub a permis accesul la mai mulți utilizatori decât licența permite. Vă rugăm să contactați administratorul Hub-ului dumneavoastră pentru a actualiza licența sau un administrator de seif pentru a elimina utilizatorii din seifuri. # Lock ## Force +lock.forced.message=Blocarea a eșuat lock.forced.description=Blocarea "%s" a fost blocată de operațiile în așteptare sau de fișierele deschise. Puteți forța blocarea acestui seif, dar întreruperea I/O poate duce la pierderea datelor nesalvate. lock.forced.retryBtn=Încercați din nou +lock.forced.forceBtn=Blocare forțată ## Failure lock.fail.message=Blocarea seifului a eșuat. lock.fail.description=Seiful "%s" nu a putut fi blocat. Asigurați-vă că lucrările nesalvate sunt salvate altundeva și că operațiunile importante de citire/scriere sunt terminate. Pentru a închide seiful omoară procesul Cryptomator. @@ -131,7 +169,7 @@ lock.fail.description=Seiful "%s" nu a putut fi blocat. Asigurați-vă că lucr # Migration migration.title=Îmbunătățește seiful ## Start -migration.start.prompt=Seiful dvs. "%s" trebuie să fie actualizat la un format mai nou. Înainte de a continua, asigurați-vă că nu există sincronizare în așteptare care să afecteze acest seif. +migration.start.prompt=Seiful dvs. "%s" trebuie să fie actualizat la un format mai nou. Înainte de a continua, asigurați-vă că nu există sincronizări în așteptare care să afecteze acest seif. migration.start.confirm=Da, seiful meu este complet sincronizat ## Run migration.run.enterPassword=Introduceți parola pentru "%s" @@ -141,16 +179,16 @@ migration.run.progressHint=Acest lucru poate dura ceva timp… migration.success.nextStepsInstructions=Seiful "%s" a fost migrat cu succes.\nAcum puteți debloca seiful dvs. migration.success.unlockNow=Deblochează acum ## Missing file system capabilities -migration.error.missingFileSystemCapabilities.title=Tip de fișier nesuportat +migration.error.missingFileSystemCapabilities.title=Sistem de fișiere nesuportat migration.error.missingFileSystemCapabilities.description=Migrarea nu a fost pornită, deoarece seiful dvs. este localizat pe un sistem de fișiere necorespunzător. migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=Sistemul de fişiere nu acceptă nume de fişiere lungi. migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=Sistemul de fișiere nu suportă căi lungi. migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Sistemul de fișiere nu permite citirea. migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Sistemul de fişiere nu permite scrierea. ## Impossible -migration.impossible.heading=Imposibil de migrat seiful +migration.impossible.heading=Seiful nu a putut fi migrat migration.impossible.reason=Seiful nu poate fi migrat automat deoarece locația sa de stocare sau punctul de acces nu este compatibilă. -migration.impossible.moreInfo=Seiful poate fi deschis în continuare cu o versiune mai veche. Pentru instrucţiuni despre cum să migraţi manual un seif, vizitaţi +migration.impossible.moreInfo=Seiful poate fi deschis cu o versiune mai veche. Pentru instrucţiuni despre cum să migraţi manual un seif, vizitaţi # Health Check ## Start @@ -180,7 +218,27 @@ health.check.detail.checkFinished=Verificarea s-a terminat cu succes. health.check.detail.checkFinishedAndFound=Verificarea s-a terminat. Vă rugăm să examinați rezultatele. health.check.detail.checkFailed=Verificarea a ieșit din cauza unei erori. health.check.detail.checkCancelled=Verificarea a fost anulată. +health.check.detail.listFilters.label=Filtru +health.check.detail.listFilters.severity=Severitate +health.check.detail.listFilters.fixState=Repară starea +health.check.detail.fixAllSpecificBtn=Repară tot de tipul health.check.exportBtn=Exportare raport +## Result view +health.result.severityFilter.all=Severitate - Toate +health.result.severityFilter.good=Bună +health.result.severityFilter.info=Informații +health.result.severityFilter.warn=Atenție +health.result.severityFilter.crit=Critică +health.result.severityTip.good=Severitate: Bună\nStructura seifului este normală. +health.result.severityTip.info=Severitate: Info\nStructura de seif este intactă, reparația este sugerată. +health.result.severityTip.warn=Severitate: Avertisment\nStructura seifului este coruptă, repararea este recomandată. +health.result.severityTip.crit=Severitate: Critică\nStructura de seif este coruptă, pierderea de date a fost determinată. +health.result.fixStateFilter.all=Repară starea - Toate +health.result.fixStateFilter.fixable=Reparabil +health.result.fixStateFilter.notFixable=Nu este reparabil +health.result.fixStateFilter.fixing=In curs de reparare… +health.result.fixStateFilter.fixed=Reparat +health.result.fixStateFilter.fixFailed=Reparația a eșuat ## Fix Application health.fix.fixBtn=Repară health.fix.successTip=Remediere reușită @@ -191,13 +249,25 @@ preferences.title=Preferințe ## General preferences.general=Setări Generale preferences.general.startHidden=Ascunde fereastra la pornirea Cryptomator +preferences.general.autoCloseVaults=Încuie seifurile deschise la ieșirea din aplicație automat preferences.general.debugLogging=Activează jurnalul de depanare preferences.general.debugDirectory=Dezvăluie fişierele jurnal preferences.general.autoStart=Lansați Cryptomator la pornirea sistemului preferences.general.keychainBackend=Salvează parolele cu ## Interface +preferences.interface=Interfață +preferences.interface.theme=Aspect +preferences.interface.theme.automatic=Automat preferences.interface.theme.dark=Întunecat preferences.interface.theme.light=Luminos +preferences.interface.unlockThemes=Deblochează tema întunecată +preferences.interface.language=Limba (necesită repornirea programului) +preferences.interface.language.auto=Prestabilit din sistem +preferences.interface.interfaceOrientation=Orientarea interfeței +preferences.interface.interfaceOrientation.ltr=De la stânga la dreapta +preferences.interface.interfaceOrientation.rtl=De la dreapta la stânga +preferences.interface.showMinimizeButton=Arată butonul de minimizare +preferences.interface.showTrayIcon=Arată tray icon (necesită repornire) ## Volume preferences.volume=Unitate virtuală preferences.volume.type=Tip volum @@ -250,6 +320,11 @@ stats.encr.total.data.mib=Date criptate: %.1f MiB stats.encr.total.data.gib=Date criptate: %.1f GiB stats.write.accessCount=Total scrieri: %d +## Accesses +stats.access.current=Acces: %d +stats.access.total=Accesuri totale: %d + + # Main Window main.closeBtn.tooltip=Închide main.minimizeBtn.tooltip=Minimizează @@ -297,6 +372,9 @@ main.vaultDetail.missing.changeLocation=Schimbați locația seifului… main.vaultDetail.migrateButton=Îmbunătățește seiful main.vaultDetail.migratePrompt=Înainte de a-l putea accesa, seiful dumneavoastră trebuie actualizat la format nou ### Error +main.vaultDetail.error.info=A apărut o eroare la încărcarea seifului de pe disc. +main.vaultDetail.error.reload=Reîncărcare +main.vaultDetail.error.windowTitle=S-a produs o eroare la încărcarea datelor # Wrong File Alert wrongFileAlert.title=Cum să criptați fișierele @@ -338,20 +416,27 @@ vaultOptions.masterkey.changePasswordBtn=Schimbați parola vaultOptions.masterkey.forgetSavedPasswordBtn=Parolă salvată uitată vaultOptions.masterkey.recoveryKeyExplanation=O cheie de recuperare este singurul mijloc de a restabili accesul la un seif în caz că vă pierdeți parola. vaultOptions.masterkey.showRecoveryKeyBtn=Afișează cheia de recuperare +vaultOptions.masterkey.recoverPasswordBtn=Resetează Parola # Recovery Key ## Display Recovery Key +recoveryKey.display.title=Arată cheia de recuperare +recoveryKey.create.message=Trebuie să introduceți o parolă recoveryKey.create.description=Introduceți parola pentru a afișa cheia de recuperare pentru "%s: recoveryKey.display.description=Următoarea cheie de recuperare poate fi folosită pentru a restabili accesul la "%s": recoveryKey.display.StorageHints=Păstrați cheia de recuperare undeva foarte sigur, de ex.\n • Păstrați-o folosind un manager de parole\n • Salvați-o pe un flash USB stick\n • Imprimați-o pe hârtie ## Reset Password ### Enter Recovery Key +recoveryKey.recover.title=Resetează Parola recoveryKey.recover.prompt=Introduceți cheia de recuperare pentru "%s: recoveryKey.recover.validKey=Aceasta este o cheie de recuperare validă recoveryKey.printout.heading=Cheia de recuperare Cryptomator\n"%s"\n ### Reset Password +recoveryKey.recover.resetBtn=Resetează ### Recovery Key Password Reset Success +recoveryKey.recover.resetSuccess.message=Parola a fost resetată cu succes +recoveryKey.recover.resetSuccess.description=Puteți debloca seiful cu parola noua. # New Password newPassword.promptText=Introduceți o parolă nouă @@ -366,6 +451,12 @@ passwordStrength.messageLabel.3=Puternică passwordStrength.messageLabel.4=Foarte puternică # Quit +quit.title=Închide aplicația +quit.message=Există seifuri deblocate +quit.description=Vă rugăm să confirmați că doriți să ieșiți. Cryptomatorul va încuia toate seifurile deblocate pentru a preveni pierderea datelor. quit.lockAndQuitBtn=Blocați și ieșiți -# Forced Quit \ No newline at end of file +# Forced Quit +quit.forced.message=Unele seifuri nu au putut fi blocate +quit.forced.description=Încuierea seifurilor a fost blocata de operațiuni in curs sau de fișiere deschise. Puteți încuia forțat aceste seifuri dar prin întreruperea operațiunilor I/O poate rezulta în pierderea datelor nesalvate. +quit.forced.forceAndQuitBtn=Încuiați forțat și ieșiți \ No newline at end of file diff --git a/src/main/resources/i18n/strings_ru.properties b/src/main/resources/i18n/strings_ru.properties index a4f8cf979..14de6bd52 100644 --- a/src/main/resources/i18n/strings_ru.properties +++ b/src/main/resources/i18n/strings_ru.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=Проверка завершена. health.check.detail.checkFailed=Проверка прервана из-за ошибки. health.check.detail.checkCancelled=Проверка была отменена. health.check.exportBtn=Экспорт отчёта +## Result view ## Fix Application health.fix.fixBtn=Исправить health.fix.successTip=Исправлено @@ -300,6 +301,9 @@ stats.encr.total.data.mib=Зашифровано: %.1f МиБ stats.encr.total.data.gib=Зашифровано: %.1f ГиБ stats.write.accessCount=Всего записей: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Закрыть main.minimizeBtn.tooltip=Свернуть diff --git a/src/main/resources/i18n/strings_si.properties b/src/main/resources/i18n/strings_si.properties index 4c9ed156d..aeb596a70 100644 --- a/src/main/resources/i18n/strings_si.properties +++ b/src/main/resources/i18n/strings_si.properties @@ -72,6 +72,7 @@ unlock.unlockBtn=අගුළුහරින්න ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -88,6 +89,9 @@ unlock.unlockBtn=අගුළුහරින්න ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=වසන්න ## Drag 'n' Drop diff --git a/src/main/resources/i18n/strings_sk.properties b/src/main/resources/i18n/strings_sk.properties index bff6fc50b..b84f9b1f3 100644 --- a/src/main/resources/i18n/strings_sk.properties +++ b/src/main/resources/i18n/strings_sk.properties @@ -218,7 +218,20 @@ health.check.detail.checkFinished=Kontrola skončila úspešne. health.check.detail.checkFinishedAndFound=Kontrola skončila. Prosím pozrite si jej výsledky. health.check.detail.checkFailed=Kontrola skončila kôli chybe. health.check.detail.checkCancelled=Kontrola bola zrušená. +health.check.detail.listFilters.label=Filter +health.check.detail.listFilters.severity=Závažnosť +health.check.detail.listFilters.fixState=Stav opravy health.check.exportBtn=Exportovať správu +## Result view +health.result.severityFilter.good=Dobrý +health.result.severityFilter.info=Informácie +health.result.severityFilter.warn=Výstraha +health.result.severityFilter.crit=Kritický +health.result.fixStateFilter.fixable=Opraviteľné +health.result.fixStateFilter.notFixable=Neopraviteľné +health.result.fixStateFilter.fixing=Opravovanie… +health.result.fixStateFilter.fixed=Opravené +health.result.fixStateFilter.fixFailed=Oprava zlyhala ## Fix Application health.fix.fixBtn=Opraviť health.fix.successTip=Oprava úspešná @@ -300,6 +313,11 @@ stats.encr.total.data.mib=Odkódovaných dát: %.1f MiB stats.encr.total.data.gib=Odkódovaných dát: %.1f GiB stats.write.accessCount=Suma zápisov: %d +## Accesses +stats.access.current=Sprístupnené: %d +stats.access.total=Celkovo sprístupnené: %d + + # Main Window main.closeBtn.tooltip=Zavrieť main.minimizeBtn.tooltip=Minimalizovať diff --git a/src/main/resources/i18n/strings_sr.properties b/src/main/resources/i18n/strings_sr.properties index 89cb48dbc..219b7bdf3 100644 --- a/src/main/resources/i18n/strings_sr.properties +++ b/src/main/resources/i18n/strings_sr.properties @@ -152,6 +152,7 @@ migration.impossible.moreInfo=Sef se i dalje može otvoriti sa starijom verzijom ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -218,6 +219,9 @@ stats.encr.total.data.mib=Шифровано података: %.1f MiB stats.encr.total.data.gib=Шифровано података: %.1f GiB stats.write.accessCount=Укупно уписано: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Zatvori main.minimizeBtn.tooltip=Умањи diff --git a/src/main/resources/i18n/strings_sr_Latn.properties b/src/main/resources/i18n/strings_sr_Latn.properties index e0aae541f..f15b62251 100644 --- a/src/main/resources/i18n/strings_sr_Latn.properties +++ b/src/main/resources/i18n/strings_sr_Latn.properties @@ -141,6 +141,7 @@ migration.impossible.moreInfo=Sef se i dalje može otvoriti sa starijom verzijom ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -194,6 +195,9 @@ stats.decr.total.data.mib=Dešifrovano podataka: %.1f MiB stats.decr.total.data.gib=Dešifrovano podataka: %.1f GiB ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=Zatvori main.preferencesBtn.tooltip=Podešavanja diff --git a/src/main/resources/i18n/strings_sv.properties b/src/main/resources/i18n/strings_sv.properties index ce827c492..4975137ce 100644 --- a/src/main/resources/i18n/strings_sv.properties +++ b/src/main/resources/i18n/strings_sv.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=Kontrollen är slutförd. Vänligen gr health.check.detail.checkFailed=Kontrollen avslutades på grund av ett fel. health.check.detail.checkCancelled=Kontrollen avbröts. health.check.exportBtn=Exportera rapport +## Result view ## Fix Application health.fix.fixBtn=Åtgärda health.fix.successTip=Åtgärden lyckades @@ -300,6 +301,9 @@ stats.encr.total.data.mib=Data krypterad: %.1f MiB stats.encr.total.data.gib=Data krypterad: %.1f GiB stats.write.accessCount=Totalt skrivet: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Stäng main.minimizeBtn.tooltip=Minimera diff --git a/src/main/resources/i18n/strings_sw.properties b/src/main/resources/i18n/strings_sw.properties index ecdd7ca51..f685726f9 100644 --- a/src/main/resources/i18n/strings_sw.properties +++ b/src/main/resources/i18n/strings_sw.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=Ukaguzi ulimaliza kukimbia. Tafadhali health.check.detail.checkFailed=Ukaguzi ulitoka kwa sababu ya kosa. health.check.detail.checkCancelled=Ukaguzi ulikatishwa. health.check.exportBtn=Hamisha Ripoti +## Result view ## Fix Application health.fix.fixBtn=Kurekebisha health.fix.successTip=Rekebisha imefanikiwa @@ -300,6 +301,9 @@ stats.encr.total.data.mib=Data iliyosimbwa kwa njia fiche: %.1f MiB stats.encr.total.data.gib=Data iliyosimbwa kwa njia fiche: %.1f GiB stats.write.accessCount=Jumla ya maandishi anaandika: %d +## Accesses + + # Main Window main.closeBtn.tooltip=Futa main.minimizeBtn.tooltip=Kupunguza diff --git a/src/main/resources/i18n/strings_ta.properties b/src/main/resources/i18n/strings_ta.properties index b594e0df4..432200d1f 100644 --- a/src/main/resources/i18n/strings_ta.properties +++ b/src/main/resources/i18n/strings_ta.properties @@ -179,6 +179,7 @@ health.intro.affirmation=மேலே உள்ள தகவல்களைப health.fail.header=பெட்டகம் கட்டமைப்பை ஏற்றுவதில் பிழை ## Check Selection ## Detail view +## Result view ## Fix Application health.fix.fixBtn=சரிசெய் @@ -226,6 +227,9 @@ stats.encr.total.data.mib=குறியாக்கம் செய்யப stats.encr.total.data.gib=குறியாக்கம் செய்யப்பட்ட தரவு: %.1f GiB stats.write.accessCount=மொத்த எழுதப்பட்டது: %d +## Accesses + + # Main Window main.closeBtn.tooltip=மூடு main.minimizeBtn.tooltip=சிறிதாக்கு diff --git a/src/main/resources/i18n/strings_te.properties b/src/main/resources/i18n/strings_te.properties index 98bb54590..849ad66e9 100644 --- a/src/main/resources/i18n/strings_te.properties +++ b/src/main/resources/i18n/strings_te.properties @@ -57,6 +57,7 @@ lock.forced.retryBtn=మళ్ళీ చేయండి ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -75,6 +76,9 @@ preferences.interface.theme.light=కాంతి ## Read ## Write +## Accesses + + # Main Window ## Drag 'n' Drop ## Vault List diff --git a/src/main/resources/i18n/strings_th.properties b/src/main/resources/i18n/strings_th.properties index 62c8f2bd2..b2141453c 100644 --- a/src/main/resources/i18n/strings_th.properties +++ b/src/main/resources/i18n/strings_th.properties @@ -115,6 +115,7 @@ unlock.unlockBtn=ปลดล็อก ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -132,6 +133,9 @@ preferences.title=การตั้งค่า ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=ปิด main.preferencesBtn.tooltip=การตั้งค่า diff --git a/src/main/resources/i18n/strings_tr.properties b/src/main/resources/i18n/strings_tr.properties index e8dbab2a1..e1e583470 100644 --- a/src/main/resources/i18n/strings_tr.properties +++ b/src/main/resources/i18n/strings_tr.properties @@ -218,7 +218,26 @@ health.check.detail.checkFinished=Kontrol başarıyla tamamlandı. health.check.detail.checkFinishedAndFound=Kontrol işlemi tamamlandı. Lütfen sonuçları inceleyin. health.check.detail.checkFailed=Bir hata nedeniyle kontrolden çıkıldı. health.check.detail.checkCancelled=Kontrol iptal edildi. +health.check.detail.listFilters.label=Filtrele +health.check.detail.listFilters.severity=Önem Derecesi +health.check.detail.listFilters.fixState=Onarım durumu health.check.exportBtn=Raporu Dışa Aktar +## Result view +health.result.severityFilter.all=Önem derecesi - Hepsi +health.result.severityFilter.good=İyi +health.result.severityFilter.info=Bilgi +health.result.severityFilter.warn=Uyarı +health.result.severityFilter.crit=Kritik +health.result.severityTip.good=Önem derecesi: İyi\nKasa yapısı normal. +health.result.severityTip.info=Önem derecesi: Bilgi\nKasa yapısı hasarsız, onarım önerilir. +health.result.severityTip.warn=Önem derecesi: Uyarı\nKasa yapısı bozulmuş, onarım şiddetle tavsiye edilir. +health.result.severityTip.crit=Önem derecesi: Kritik\nKasa yapısı bozulmuş, veri kaybı tespit edildi. +health.result.fixStateFilter.all=Onarım durumu - Hepsi +health.result.fixStateFilter.fixable=Onarılabilir +health.result.fixStateFilter.notFixable=Onarılamaz +health.result.fixStateFilter.fixing=Onarılıyor… +health.result.fixStateFilter.fixed=Onarıldı +health.result.fixStateFilter.fixFailed=Onarım başarısız ## Fix Application health.fix.fixBtn=Düzelt health.fix.successTip=Düzeltme başarılı @@ -300,6 +319,11 @@ stats.encr.total.data.mib=Şifrelenen veri: %.1f MB stats.encr.total.data.gib=Şifrelenen veri: %.1f GB stats.write.accessCount=Toplam yazma: %d +## Accesses +stats.access.current=Erişim: %d +stats.access.total=Toplam erişim: %d + + # Main Window main.closeBtn.tooltip=Kapat main.minimizeBtn.tooltip=Simge Durumuna Küçült diff --git a/src/main/resources/i18n/strings_uk.properties b/src/main/resources/i18n/strings_uk.properties index b54d4c28b..1262c77e9 100644 --- a/src/main/resources/i18n/strings_uk.properties +++ b/src/main/resources/i18n/strings_uk.properties @@ -129,6 +129,7 @@ migration.success.unlockNow=Розблокувати ## Start Failure ## Check Selection ## Detail view +## Result view ## Fix Application # Preferences @@ -146,6 +147,9 @@ preferences.title=Властивості ## Read ## Write +## Accesses + + # Main Window main.closeBtn.tooltip=Закрити main.preferencesBtn.tooltip=Властивості diff --git a/src/main/resources/i18n/strings_vi.properties b/src/main/resources/i18n/strings_vi.properties index 88a3c427e..2e7557a9a 100644 --- a/src/main/resources/i18n/strings_vi.properties +++ b/src/main/resources/i18n/strings_vi.properties @@ -74,7 +74,7 @@ addvault.new.readme.storageLocation.5=• dán bất kỳ tệp nào để mã h addvault.new.readme.storageLocation.6=Nếu bạn muốn mã hóa tệp và xem nội dung của vault, hãy làm như sau: 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.9=3. Mở vị trí truy cập bằng cách nhấp vào nút "Hiện thị". 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Á 🔐️ @@ -112,14 +112,19 @@ unlock.passwordPrompt=Nhập mật khẩu cho "%s": unlock.savePassword=Nhớ mật khẩu unlock.unlockBtn=Mở khoá ## Select +unlock.chooseMasterkey.message=Không tìm thấy tệp Masterkey +unlock.chooseMasterkey.filePickerTitle=Chọn tệp Masterkey unlock.chooseMasterkey.filePickerMimeDesc=Khóa chính Cryptomator ## Success unlock.success.message=Mở khóa thành công +unlock.success.description=Nội dung trong vault "%s" đã có thể được truy xuất, thông qua đường dẫn gắn kết với nó. unlock.success.rememberChoice=Ghi nhớ lựa chọn, không hiện lại -unlock.success.revealBtn=Hiển thị Drive +unlock.success.revealBtn=Hiển thị Ổ đĩa ## Failure unlock.error.message=Không thể mở vault ### Invalid Mount Point +unlock.error.invalidMountPoint.notExisting=Đường dẫn gắn kết "%s" không phải là một thư mục, hoặc thư mục này không rỗng hoặc không tồn tại. +unlock.error.invalidMountPoint.existing=Đường dẫn liên kết "%s" đã tồn tại hoặc không tìm thấy thư mục cha. unlock.error.invalidMountPoint.driveLetterOccupied=Ký tự cho Ổ cứng "%s" đã được sử dụng. ## Hub ### Waiting @@ -135,8 +140,11 @@ hub.register.nameLabel=Tên thiết bị hub.register.occupiedMsg=Tên đã sử dụng hub.register.registerBtn=Xác nhận ### Registration Success +hub.registerSuccess.message=Thiết bị đã được đặt tên hub.registerSuccess.description=Để truy cập vault, thiết bị của bạn cần được chủ sở hữu cho phép. ### Registration Failed +hub.registerFailed.message=Đặt tên thiết bị thất bại +hub.registerFailed.description=Lỗi phát sinh trong quá trình đặt tên. Để biết thêm chi tiết, hãy nhìn vào nhật ký ứng dụng (application log). ### Unauthorized hub.unauthorized.message=Truy cập bị từ chối hub.unauthorized.description=Thiết bị của bạn chưa được phép truy cập vault này. Yêu cầu chủ sở hữu cấp phép. @@ -147,8 +155,10 @@ hub.unauthorized.description=Thiết bị của bạn chưa được phép truy ## Force lock.forced.message=Khóa thất bại lock.forced.retryBtn=Thử lại +lock.forced.forceBtn=Ép Khoá ## Failure lock.fail.message=Khóa vault thất bại. +lock.fail.description=Không thể khoá vault "%s". Hãy chắc rằng phần việc dang dở của bạn đã được lưu ở nơi khác, và các chỉ thị Đọc/Ghi quan trọng đã hoàn tất. Sau đó, bạn có thể tắt tiến trình (process) Cryptomator để khoá vault lại. # Migration migration.title=Nâng cấp Vault @@ -172,12 +182,17 @@ migration.impossible.heading=Không thể di chuyển vault # Health Check ## Start +health.title=Kiểm tra Ổn định cho "%s" +health.intro.header=Kiểm tra Ổn định +health.intro.text=Kiểm tra tính ổn định là tập hợp các kiểm tra nhằm phát hiện và có thể sửa chữa các vấn đề ở cấu trúc nội bộ trong Vault của bạn. Vui lòng chú ý là: health.intro.remarkSync=Đảm bảo tất cả các thiết bị được đồng bộ hóa hoàn toàn, điều này giải quyết hầu hết các vấn đề. health.intro.remarkFix=Không phải tất cả các vấn đề đều có thể được khắc phục. health.intro.remarkBackup=Nếu dữ liệu bị hỏng, chỉ có bản sao lưu mới có thể giúp được. health.intro.affirmation=Tôi đã đọc và hiểu thông tin trên ## Start Failure +health.fail.header=Lỗi khi tải cấu hình Vault health.fail.ioError=Đã xảy ra lỗi khi truy cập và đọc tệp config. +health.fail.parseError=Lỗi xuất hiện khi phân tích cú pháp trong cấu hình của vault. health.fail.moreInfo=Thêm thông tin ## Check Selection ## Detail view @@ -185,6 +200,7 @@ 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 +## Result view ## Fix Application health.fix.fixBtn=Sửa health.fix.successTip=Sửa thành công @@ -197,11 +213,12 @@ preferences.general=Chung preferences.general.startHidden=Ẩn cửa sổ khi khởi động Cryptomator preferences.general.autoCloseVaults=Tự động khóa các vault còn đang mở khi thoát ứng dụng preferences.general.debugLogging=Bật nhật kí gỡ lỗi -preferences.general.debugDirectory=Mở file log +preferences.general.debugDirectory=Mở tệp nhật ký preferences.general.autoStart=Khởi chạy Cryptomator khi khởi động hệ thống preferences.general.keychainBackend=Lưu mật khẩu với ## Interface preferences.interface=Giao diện +preferences.interface.theme=Cái nhìn và cảm nhận preferences.interface.theme.automatic=Tự động preferences.interface.theme.dark=Tối preferences.interface.theme.light=Sáng @@ -217,6 +234,7 @@ preferences.interface.showTrayIcon=Hiển thị biểu tượng khay (yêu cầu preferences.volume=Ổ lưu trữ ảo preferences.volume.type=Kiểu Phân Vùng preferences.volume.webdav.port=Cổng của WebDAV +preferences.volume.webdav.scheme=Lược đồ WebDAV ## Updates preferences.updates=Cập nhật preferences.updates.currentVersion=Phiên bản hiện tại: %s @@ -226,6 +244,9 @@ 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 +preferences.contribute.noCertificate=Hỗ trợ Cryptomator và lấy về cho bạn chứng nhận người hỗ trợ. Chứng nhận này giống như giấy phép sử dụng phần mềm, nhưng chỉ dành cho những con người tuyệt vời đang dùng phần mềm tự do. ;-) +preferences.contribute.getCertificate=Bạn chưa có? Tìm hiểu cách bạn có thể lấy được nó. +preferences.contribute.promptText=Vui lòng dán mã chứng nhận người hỗ trợ vào đây #<-- Add entries for donations and code/translation/documentation contribution --> ## About @@ -233,13 +254,36 @@ preferences.about=Giới thiệu # Vault Statistics stats.title=Thống kê về %s +stats.cacheHitRate=Tỷ lệ truy cập bộ nhớ cache ## Read +stats.read.throughput.idle=Đọc: không có +stats.read.throughput.kibs=Đọc: %.2f kiB/s 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 +stats.decr.total.data.none=Dữ liệu được giải mã: - +stats.decr.total.data.kib=Dữ liệu được giải mã: %.1f kiB +stats.decr.total.data.mib=Dữ liệu được giải mã: %.1f MiB +stats.decr.total.data.gib=Dữ liệu được giải mã: %.1f GiB +stats.read.accessCount=Tổng đọc: %d ## Write +stats.write.throughput.idle=Ghi: tạm ngưng +stats.write.throughput.kibs=Ghi: %.2f kiB/s +stats.write.throughput.mibs=Ghi: %.2f MiB/s +stats.write.total.data.none=Dữ liệu đã ghi: - +stats.write.total.data.kib=Dữ liệu đã ghi: %.1f kiB +stats.write.total.data.mib=Dữ liệu đã ghi: %.1f MiB +stats.write.total.data.gib=Dữ liệu đã ghi: %.1f GiB +stats.encr.total.data.none=Dữ liệu được mã hóa: - +stats.encr.total.data.kib=Dữ liệu được mã hóa: %.1f kiB +stats.encr.total.data.mib=Dữ liệu được mã hóa: %.1f MiB +stats.encr.total.data.gib=Dữ liệu được mã hóa: %.1f GiB +stats.write.accessCount=Tổng ghi: %d + +## Accesses + # Main Window main.closeBtn.tooltip=Đóng @@ -257,7 +301,7 @@ main.vaultlist.contextMenu.lock=Khoá main.vaultlist.contextMenu.unlock=Mở khoá… main.vaultlist.contextMenu.unlockNow=Mở khóa bây giờ main.vaultlist.contextMenu.vaultoptions=Hiện tùy chọn vault -main.vaultlist.contextMenu.reveal=Hiển thị Drive +main.vaultlist.contextMenu.reveal=Hiển thị Ổ đĩa main.vaultlist.addVaultBtn=Thêm Vault ## Vault Detail ### Welcome @@ -271,9 +315,13 @@ main.vaultDetail.passwordSavedInKeychain=Đã lưu mật khẩu ### Unlocked main.vaultDetail.unlockedStatus=ĐÃ MỞ KHÓA main.vaultDetail.accessLocation=Nội dung trong vault của bạn có thể truy cập ở đây: -main.vaultDetail.revealBtn=Hiển thị Drive +main.vaultDetail.revealBtn=Hiển thị Ổ đĩa main.vaultDetail.lockBtn=Khoá +main.vaultDetail.bytesPerSecondRead=Đọc: +main.vaultDetail.bytesPerSecondWritten=Ghi: main.vaultDetail.throughput.idle=chờ +main.vaultDetail.throughput.kbps=%.1f kiB/s +main.vaultDetail.throughput.mbps=%.1f MiB/s main.vaultDetail.stats=Thống kê Vault ### Missing main.vaultDetail.missing.info=Cryptomator không thể tìm thấy vault tại đường dẫn này. @@ -293,6 +341,8 @@ wrongFileAlert.title=Cách mã hóa tệp wrongFileAlert.message=Bạn đã cố gắng mã hóa các tệp này? wrongFileAlert.instruction.0=Để mã hóa tệp, hãy làm theo các bước sau: wrongFileAlert.instruction.1=1. Mở Vault của bạn. +wrongFileAlert.instruction.2=2. Bấm vào "Hiển thị" để mở ổ đĩa trên trình quản lý tệp. +wrongFileAlert.instruction.3=3. Thêm tệp của bạn vào ổ đĩa này. wrongFileAlert.link=Để được hỗ trợ thêm, hãy truy cập # Vault Options @@ -304,18 +354,23 @@ vaultOptions.general.autoLock.lockAfterTimePart2=phút vaultOptions.general.unlockAfterStartup=Mở khóa vault khi khởi động Cryptomator vaultOptions.general.actionAfterUnlock=Sau khi mở khóa thành công vaultOptions.general.actionAfterUnlock.ignore=Không làm gì -vaultOptions.general.actionAfterUnlock.reveal=Hiển thị Drive +vaultOptions.general.actionAfterUnlock.reveal=Hiển thị Ổ đĩa vaultOptions.general.actionAfterUnlock.ask=Hỏi +vaultOptions.general.startHealthCheckBtn=Bắt đầu Kiểm tra sức khỏe ## Mount vaultOptions.mount.readonly=Chỉ đọc -vaultOptions.mount.winDriveLetterOccupied=Sử dụng +vaultOptions.mount.winDriveLetterOccupied=đã bị chiếm +vaultOptions.mount.mountPoint=Đường dẫn gắn kết +vaultOptions.mount.mountPoint.auto=Tự động chọn một vị trí thích hợp +vaultOptions.mount.mountPoint.driveLetter=Sử dụng ký tự ổ đĩa được chỉ định vaultOptions.mount.mountPoint.custom=Tuỳ chỉnh đường dẫn vaultOptions.mount.mountPoint.directoryPickerButton=Chọn… vaultOptions.mount.mountPoint.directoryPickerTitle=Chọn đường dẫn trống ## Master Key vaultOptions.masterkey=Mật khẩu vaultOptions.masterkey.changePasswordBtn=Đổi mật khẩu +vaultOptions.masterkey.forgetSavedPasswordBtn=Quên mật khẩu đã lưu vaultOptions.masterkey.recoveryKeyExplanation=Khóa khôi phục là cách duy nhất để khôi phục quyền truy cập vào vault nếu bạn mất mật khẩu. vaultOptions.masterkey.showRecoveryKeyBtn=Hiện Khóa Khôi Phục vaultOptions.masterkey.recoverPasswordBtn=Đặt lại Mật khẩu @@ -323,10 +378,15 @@ vaultOptions.masterkey.recoverPasswordBtn=Đặt lại Mật khẩu # Recovery Key ## Display Recovery Key +recoveryKey.display.title=Hiển thị Khóa Khôi Phục +recoveryKey.create.message=Yêu cầu mật khẩu +recoveryKey.create.description=Nhập mật khẩu cho "%s" để hiện khóa khôi phục. +recoveryKey.display.description=Khóa khôi phục sau có thể được sử dụng để khôi phục quyền truy cập vào "%s": recoveryKey.display.StorageHints=Giữ ở một nơi rất an toàn, ví dụ:\n • Lưu trữ bằng trình quản lý mật khẩu\n • Lưu vào ổ đĩa flash USB\n • In ra giấy ## Reset Password ### Enter Recovery Key recoveryKey.recover.title=Đặt lại Mật khẩu +recoveryKey.recover.prompt=Nhập khóa khôi phục của bạn cho "%s": recoveryKey.recover.validKey=Đây là khóa khôi phục hợp lệ recoveryKey.printout.heading=Khóa Khôi phục Cryptomator\n"%s"\n ### Reset Password @@ -349,6 +409,11 @@ passwordStrength.messageLabel.4=Rất mạnh # Quit quit.title=Thoát ứng dụng +quit.message=Có vault chưa được khóa +quit.description=Vui lòng xác nhận rằng bạn muốn thoát. Cryptomator sẽ khóa tất cả các vault đã mở khóa để tránh mất dữ liệu. quit.lockAndQuitBtn=Khóa và Thoát -# Forced Quit \ No newline at end of file +# Forced Quit +quit.forced.message=Không thể khóa một số vault +quit.forced.description=Việc khoá vault đã bị chặn bởi các hoạt động đang chờ xử lý hoặc các tệp đang mở. Bạn có thể buộc khóa các vault còn lại, tuy nhiên việc làm gián đoạn đọc/ghi có thể dẫn đến mất dữ liệu chưa được lưu. +quit.forced.forceAndQuitBtn=Bắt buộc và Thoát \ No newline at end of file diff --git a/src/main/resources/i18n/strings_zh.properties b/src/main/resources/i18n/strings_zh.properties index ef2008900..d87659e20 100644 --- a/src/main/resources/i18n/strings_zh.properties +++ b/src/main/resources/i18n/strings_zh.properties @@ -218,7 +218,27 @@ health.check.detail.checkFinished=成功完成检查 health.check.detail.checkFinishedAndFound=检查运行完成,请查看结果 health.check.detail.checkFailed=检查由于出错而退出 health.check.detail.checkCancelled=检查已被取消 +health.check.detail.listFilters.label=筛选 +health.check.detail.listFilters.severity=严重性 +health.check.detail.listFilters.fixState=修复状态 +health.check.detail.fixAllSpecificBtn=修复所有类型 health.check.exportBtn=导出报告 +## Result view +health.result.severityFilter.all=严重性 - 全部 +health.result.severityFilter.good=良好 +health.result.severityFilter.info=信息 +health.result.severityFilter.warn=警告 +health.result.severityFilter.crit=危急 +health.result.severityTip.good=严重性:良好\n普通保险库结构 +health.result.severityTip.info=严重性:信息\n保险库结构完好无损,建议修复 +health.result.severityTip.warn=严重性:警告\n保险库结构损坏,强烈建议修复 +health.result.severityTip.crit=严重性:危急\n保险库结构损坏,已确定数据丢失 +health.result.fixStateFilter.all=修复状态 - 全部 +health.result.fixStateFilter.fixable=可修复 +health.result.fixStateFilter.notFixable=无法修复 +health.result.fixStateFilter.fixing=正在修复… +health.result.fixStateFilter.fixed=已修复 +health.result.fixStateFilter.fixFailed=修复失败 ## Fix Application health.fix.fixBtn=修复 health.fix.successTip=修复成功 @@ -300,6 +320,11 @@ stats.encr.total.data.mib=已加密数据:%.1f MiB stats.encr.total.data.gib=已加密数据:%.1f GiB stats.write.accessCount=写入总数:%d +## Accesses +stats.access.current=访问量:%d +stats.access.total=总访问量:%d + + # Main Window main.closeBtn.tooltip=关闭 main.minimizeBtn.tooltip=最小化 diff --git a/src/main/resources/i18n/strings_zh_HK.properties b/src/main/resources/i18n/strings_zh_HK.properties index e2bff681a..4b44241bd 100644 --- a/src/main/resources/i18n/strings_zh_HK.properties +++ b/src/main/resources/i18n/strings_zh_HK.properties @@ -15,7 +15,7 @@ generic.button.next=繼續 generic.button.print=列印 # Error -error.message=%s 錯誤 +error.message=發生錯誤 error.description=糟糕!Cryptomator 發生了預期外的錯誤。你可以嘗試查找這錯誤的現有解決方案,如果是新錯誤,請隨時向我們報告。 error.hyperlink.lookup=搜尋此錯誤 error.hyperlink.report=報告此錯誤 @@ -52,7 +52,13 @@ addvaultwizard.new.directoryPickerTitle=選取資料夾 addvaultwizard.new.fileAlreadyExists=已存在與加密庫同名的檔案或資料夾 addvaultwizard.new.locationDoesNotExist=指定的資料夾不存在或無法存取 addvaultwizard.new.locationIsNotWritable=沒有指定路徑的寫入權限 -addvaultwizard.new.locationIsOk=適合放置你的加密庫 +addvaultwizard.new.locationIsOk=可存放加密庫的的位置 +addvaultwizard.new.invalidName=無效的加密庫名稱 +addvaultwizard.new.validName=有效的加密庫名稱 +addvaultwizard.new.validCharacters.message=加密庫名稱可包含以下字元: +addvaultwizard.new.validCharacters.chars=單詞字符 (例如 a、ж 或 수) +addvaultwizard.new.validCharacters.numbers=數字 +addvaultwizard.new.validCharacters.dashes=連字符 (%s) 或下劃線 (%s) ### Password addvaultwizard.new.createVaultBtn=建立加密庫 addvaultwizard.new.generateRecoveryKeyChoice=若遺失密碼,你將無法存取資料。你是否希望建立一組在遺失密碼時可用作復原的金鑰? @@ -86,6 +92,7 @@ addvaultwizard.success.unlockNow=立即解鎖 # Remove Vault removeVault.title=移除加密庫 +removeVault.message=移除加密庫? removeVault.description=這只會讓 Cryptomator 忘記這個加密庫。你可以之後再重新加入。已加密的檔案將不會從硬碟中移除。 removeVault.confirmBtn=移除加密庫 @@ -96,6 +103,7 @@ changepassword.finalConfirmation=我明白如果忘記密碼將無法存取資 # Forget Password forgetPassword.title=忘記密碼 +forgetPassword.message=清除已儲存的密碼? forgetPassword.description=這將會從系統鑰匙圈中移除這個加密庫已存的密碼。 forgetPassword.confirmBtn=忘記密碼 @@ -105,10 +113,12 @@ unlock.passwordPrompt=輸入「%s」的密碼: unlock.savePassword=記住密碼 unlock.unlockBtn=解鎖 ## Select +unlock.chooseMasterkey.message=未找到Masterkey檔案 unlock.chooseMasterkey.description=無法在其預期位置找到此加密庫的主密鑰檔案。請手動選擇密鑰文件。 unlock.chooseMasterkey.filePickerTitle=選擇主金鑰檔案 unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator 主密鑰 ## Success +unlock.success.message=解鎖成功 unlock.success.description=成功解鎖「%s」!現在可以存取你的加密庫。 unlock.success.rememberChoice=記得這個決定,不要再顯示 unlock.success.revealBtn=展示磁碟 @@ -120,13 +130,30 @@ unlock.error.invalidMountPoint.existing=掛載點「%s」已經存在或其上 unlock.error.invalidMountPoint.driveLetterOccupied=磁碟代號「%s」已被使用。 ## Hub ### Waiting +hub.auth.message=等待認證中… +hub.auth.description=您將被自動傳送到登入頁面。 +hub.auth.loginLink=未被轉送?點擊這裡打開 ### Receive Key +hub.receive.message=處理著回應… +hub.receive.description=Cryptomator正在接收並處理來自Hub的回應。 請等待。 ### Register Device +hub.register.message=需要設備名稱 +hub.register.description=似乎為第一次透過 Hub 訪問此設備。您需要命名此設備,以便識別設備並授予讀取權限。 +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 的被授予授權的使用者的數量,多於許可證容許的使用者數量。 請聯絡 Cryptomator Hub 管理員升級授權,或聯絡加密庫管理員從加密庫移除使用者。 # Lock @@ -142,7 +169,7 @@ lock.fail.description=加密庫「%s」無法被鎖定。請確保未存檔的 # Migration migration.title=升級加密庫 ## Start -migration.start.prompt=加密庫「%s」需要升級成新的格式。在開始前請確保不會有檔案同步干擾更新過程。 +migration.start.prompt=加密庫「%s」需要更新成新的格式。更新前,請確保無檔案同步干擾更新。 migration.start.confirm=是的,我的加密庫已同步完成 ## Run migration.run.enterPassword=輸入「%s」的密碼 @@ -191,7 +218,25 @@ health.check.detail.checkFinished=檢查順利完成。 health.check.detail.checkFinishedAndFound=檢查結束,請查看結果。 health.check.detail.checkFailed=檢查發生錯誤並意外退出。 health.check.detail.checkCancelled=檢查被取消。 +health.check.detail.listFilters.severity=過濾精度 +health.check.detail.listFilters.fixState=鎖定/維持當前狀態 health.check.exportBtn=匯出報告 +## Result view +health.result.severityFilter.all=過濾精度 - 所有 +health.result.severityFilter.good=適當 +health.result.severityFilter.info=詳細 +health.result.severityFilter.warn=警報 +health.result.severityFilter.crit=危急 +health.result.severityTip.good=檢查結果:良好\n加密庫結構正常 +health.result.severityTip.info=程度:詳細\n加密庫結構無缺完整,建議維持/鎖定目前狀態 +health.result.severityTip.warn=程度:警報\n加密庫結構受損,強烈建議修復 +health.result.severityTip.crit=程度:危急\n加密庫結構受損,已確定有數據丟失或受損 +health.result.fixStateFilter.all=修復狀態 - 全部 +health.result.fixStateFilter.fixable=可以修復 +health.result.fixStateFilter.notFixable=無法修復 +health.result.fixStateFilter.fixing=修復中 +health.result.fixStateFilter.fixed=已修復 +health.result.fixStateFilter.fixFailed=修復失敗 ## Fix Application health.fix.fixBtn=修復 health.fix.successTip=修復成功 @@ -202,6 +247,7 @@ preferences.title=偏好設定 ## General preferences.general=一般 preferences.general.startHidden=啟動 Cryptomator 時隱藏視窗 +preferences.general.autoCloseVaults=關閉應用時,自動鎖定打開的加密庫 preferences.general.debugLogging=啟用除錯日誌 preferences.general.debugDirectory=展示日誌檔案 preferences.general.autoStart=系統啟動時同時啟動 Cryptomator @@ -272,6 +318,11 @@ stats.encr.total.data.mib=資料加密: %.1f MiB stats.encr.total.data.gib=資料加密: %.1f GiB stats.write.accessCount=總寫入: %d +## Accesses +stats.access.current=訪問紀錄:%d +stats.access.total=總存取數:%d + + # Main Window main.closeBtn.tooltip=關閉 main.minimizeBtn.tooltip=最小化 @@ -363,20 +414,27 @@ vaultOptions.masterkey.changePasswordBtn=更改密碼 vaultOptions.masterkey.forgetSavedPasswordBtn=清除已儲存密碼 vaultOptions.masterkey.recoveryKeyExplanation=在您遺失密碼時,僅能以復原金鑰恢復存取。 vaultOptions.masterkey.showRecoveryKeyBtn=顯示復原金鑰 +vaultOptions.masterkey.recoverPasswordBtn=重設密碼 # Recovery Key ## Display Recovery Key +recoveryKey.display.title=顯示恢復金鑰 +recoveryKey.create.message=需要密碼 recoveryKey.create.description=請輸入您的密碼以顯示「%s」的復原金鑰: recoveryKey.display.description=下方的復原金鑰可用來恢復「%s」的存取: recoveryKey.display.StorageHints=請把它保存在非常安全的地方,例如:\n • 使用密碼管理器保管\n • 存在 USB 隨身碟裡\n • 印在紙上 ## Reset Password ### Enter Recovery Key +recoveryKey.recover.title=重設密碼 recoveryKey.recover.prompt=輸入「%s」的復原金鑰: recoveryKey.recover.validKey=這是有效的復原金鑰 recoveryKey.printout.heading=Cryptomator 復原金鑰\n「%s」\n ### Reset Password +recoveryKey.recover.resetBtn=重設 ### Recovery Key Password Reset Success +recoveryKey.recover.resetSuccess.message=密碼重設成功 +recoveryKey.recover.resetSuccess.description=您現在可以用新密碼解鎖您的加密庫 # New Password newPassword.promptText=輸入新密碼 @@ -391,6 +449,12 @@ passwordStrength.messageLabel.3=強 passwordStrength.messageLabel.4=非常強 # Quit +quit.title=結束應用程式 +quit.message=有加密庫仍是解鎖的 +quit.description=請確定您要關閉程式,Cryptomator 將穩定有序地鎖定全部加密庫,防止數據丟失。 quit.lockAndQuitBtn=鎖定並離開 -# Forced Quit \ No newline at end of file +# Forced Quit +quit.forced.message=無法鎖定某些加密庫 +quit.forced.description=仍有未完成的操作或有開啟中的檔案以致無法鎖定。你可以強制鎖定這個加密庫,不過中斷讀寫可能會導致資料遺失或未被儲存。 +quit.forced.forceAndQuitBtn=強制退出程式 \ No newline at end of file diff --git a/src/main/resources/i18n/strings_zh_TW.properties b/src/main/resources/i18n/strings_zh_TW.properties index e519d868a..4bc3d0535 100644 --- a/src/main/resources/i18n/strings_zh_TW.properties +++ b/src/main/resources/i18n/strings_zh_TW.properties @@ -219,6 +219,7 @@ health.check.detail.checkFinishedAndFound=檢查結束。請查看結果。 health.check.detail.checkFailed=發生錯誤,檢查意外退出。 health.check.detail.checkCancelled=檢查被取消。 health.check.exportBtn=匯出報告 +## Result view ## Fix Application health.fix.fixBtn=修復 health.fix.successTip=修復成功 @@ -300,6 +301,9 @@ stats.encr.total.data.mib=資料加密:%.1f MiB stats.encr.total.data.gib=資料加密:%.1f GiB stats.write.accessCount=總寫入:%d +## Accesses + + # Main Window main.closeBtn.tooltip=關閉 main.minimizeBtn.tooltip=最小化 From 4bd99d2b667c50472c742df5d231ac7a01ec3a0d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 6 Dec 2022 15:24:52 +0100 Subject: [PATCH 69/84] preparing 1.6.16 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b24ee97b..2dabb39b6 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.cryptomator cryptomator - 1.7.0-SNAPSHOT + 1.6.16 Cryptomator Desktop App From d8b71db8e53f3f39ea6fb741b0d07936e9aec201 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 6 Dec 2022 15:27:17 +0100 Subject: [PATCH 70/84] bump metainfo.xml --- dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml index 453a5f9d0..9cb44d090 100644 --- a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml +++ b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml @@ -66,6 +66,7 @@ + From 1b9480293a513b946f4e5b860b6849d8716adb67 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 6 Dec 2022 15:43:25 +0100 Subject: [PATCH 71/84] Bump cryptofs --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b24ee97b..b140c3a83 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 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.5.2 + 2.5.3 1.2.0-beta1 1.1.2 1.1.2 From e188169916be218e02986753671aa8c224fd4591 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 6 Dec 2022 15:44:02 +0100 Subject: [PATCH 72/84] add missing javafx getter in resultListCell --- .../org/cryptomator/ui/health/ResultListCellController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java index 35889ec26..06bcd91b6 100644 --- a/src/main/java/org/cryptomator/ui/health/ResultListCellController.java +++ b/src/main/java/org/cryptomator/ui/health/ResultListCellController.java @@ -182,6 +182,10 @@ public class ResultListCellController implements FxController { return fixGlyph; } + public FontAwesome5Icon getFixGlyph() { + return fixGlyph.getValue(); + } + public BooleanBinding fixableProperty() { return fixable; } From 5665984a9be57fc004e3904103b3933c1bd273e0 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 6 Dec 2022 20:13:34 +0100 Subject: [PATCH 73/84] trigger Debian build and provide version info by hand --- .github/workflows/debian.yml | 64 +++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 8b6a3c956..7b94d57fb 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -1,18 +1,23 @@ name: Build Debian Package on: - release: - types: [published] workflow_dispatch: inputs: + ref: + description: 'GitHub Ref' + required: true + description: 'refs/tags/1.6.16' + semver: + description: 'SemVer String (e.g. 1.7.0-beta1)' + required: true + ppaver: + description: 'Full PPA Version String (e.g. 1.6.16+1.7.0~beta1-0ppa1)' + required: true dput: description: 'Upload to PPA' required: true default: false type: boolean - version: - description: 'Version' - required: false env: JAVA_VERSION: 19 @@ -20,17 +25,22 @@ env: OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/19/openjfx-19_linux-aarch64_bin-jmods.zip' jobs: - get-version: - uses: ./.github/workflows/get-version.yml - with: - version: ${{ github.event.inputs.version }} - build: name: Build Debian Package runs-on: ubuntu-20.04 - needs: [get-version] steps: - uses: actions/checkout@v3 + with: + ref: ${{ github.events.inputs.ref }} + - id: versions + name: Get version information + run: | + SEM_VER_STR="${{ github.events.inputs.semver }}" + SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'` + REVCOUNT=`git rev-list --count HEAD` + echo "semVerStr=${SEM_VER_STR}" >> $GITHUB_OUTPUT + echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT + echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT - name: Install build tools run: | sudo add-apt-repository ppa:coffeelibs/openjdk @@ -42,12 +52,6 @@ jobs: distribution: 'zulu' java-version: ${{ env.JAVA_VERSION }} cache: 'maven' - - id: versions - name: Create PPA version string - run: echo "ppaVerStr=${SEM_VER_STR/-/\~}-${REVCOUNT}" >> $GITHUB_OUTPUT - env: - SEM_VER_STR: ${{ needs.get-version.outputs.semVerStr }} - REVCOUNT: ${{ needs.get-version.outputs.revNum }} - name: Run maven run: mvn -B clean package -Pdependency-check,linux -DskipTests - name: Download OpenJFX jmods @@ -85,7 +89,7 @@ jobs: cp -r jmods pkgdir cp -r dist/linux/common/ pkgdir cp target/cryptomator-*.jar pkgdir/mods - tar -cJf cryptomator_${{ steps.versions.outputs.ppaVerStr }}.orig.tar.xz -C pkgdir . + tar -cJf cryptomator_${{ github.event.inputs.ppaver }}.orig.tar.xz -C pkgdir . - name: Patch and rename pkgdir run: | cp -r dist/linux/debian/ pkgdir @@ -93,12 +97,12 @@ jobs: envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM}' < dist/linux/debian/rules > pkgdir/debian/rules envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog find . -name "*.jar" >> pkgdir/debian/source/include-binaries - mv pkgdir cryptomator_${{ steps.versions.outputs.ppaVerStr }} + mv pkgdir cryptomator_${{ github.event.inputs.ppaver }} env: - SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }} - VERSION_NUM: ${{ needs.get-version.outputs.semVerNum }} - REVISION_NUM: ${{ needs.get-version.outputs.revNum }} - PPA_VERSION: ${{ steps.versions.outputs.ppaVerStr }}-0ppa1 + SEMVER_STR: ${{ steps.versions.outputs.semVerStr }} + VERSION_NUM: ${{ steps.versions.outputs.semVerNum }} + REVISION_NUM: ${{ steps.versions.outputs.revNum }} + PPA_VERSION: ${{ github.event.inputs.ppaver }} - name: Prepare GPG-Agent for signing with key 615D449FE6E6A235 run: | echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import @@ -113,7 +117,7 @@ jobs: env: DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback DEBSIGN_KEYID: 615D449FE6E6A235 - working-directory: cryptomator_${{ steps.versions.outputs.ppaVerStr }} + working-directory: cryptomator_${{ github.event.inputs.ppaver }} - name: Create detached GPG signatures run: | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb @@ -130,13 +134,21 @@ jobs: cryptomator_*_amd64.deb cryptomator_*.asc - name: Publish on PPA - if: startsWith(github.ref, 'refs/tags/') || inputs.dput + if: inputs.dput run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes + + # If ref is a tag, also upload to GitHub Releases: + - name: Determine tag name + if: startsWith(github.events.inputs.ref, 'refs/tags/') + run: | + REF=${{ github.events.inputs.ref }} + echo "TAG_NAME=${REF##*/}" >> $GITHUB_ENV - name: Publish Debian package on GitHub Releases - if: startsWith(github.ref, 'refs/tags/') + if: startsWith(github.events.inputs.ref, 'refs/tags/') uses: softprops/action-gh-release@v1 with: fail_on_unmatched_files: true + tag_name: ${{ github.env.TAG_NAME }} token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} files: | cryptomator_*_amd64.deb From d1971e3c2a40ff28451e8b3780fd2ef6647f12b2 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 6 Dec 2022 20:18:55 +0100 Subject: [PATCH 74/84] yml validation error --- .github/workflows/debian.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 7b94d57fb..a29a0ddd1 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -4,9 +4,8 @@ on: workflow_dispatch: inputs: ref: - description: 'GitHub Ref' + description: 'GitHub Ref (e.g. refs/tags/1.6.16)' required: true - description: 'refs/tags/1.6.16' semver: description: 'SemVer String (e.g. 1.7.0-beta1)' required: true @@ -64,7 +63,7 @@ jobs: mkdir -p jmods/aarch64 unzip -j openjfx-aarch64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/aarch64 - name: Ensure major jfx version in pom and in jmods is the same - shell: pwsh + shell: pwsh # TODO translate to bash run: | mkdir jfxBaseJmodAmd64 jmod extract --dir jfxBaseJmodAmd64 jmods/amd64/javafx.base.jmod From ba2a4955d0f8fea75e36df1aba2c30a5ac7ab951 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 6 Dec 2022 20:27:19 +0100 Subject: [PATCH 75/84] fix expected orig.tar.gz name --- .github/workflows/debian.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index a29a0ddd1..f465f4069 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -10,7 +10,7 @@ on: description: 'SemVer String (e.g. 1.7.0-beta1)' required: true ppaver: - description: 'Full PPA Version String (e.g. 1.6.16+1.7.0~beta1-0ppa1)' + description: 'Base PPA Version String (e.g. 1.6.16+1.7.0~beta1) without -0ppa1' required: true dput: description: 'Upload to PPA' @@ -101,7 +101,7 @@ jobs: SEMVER_STR: ${{ steps.versions.outputs.semVerStr }} VERSION_NUM: ${{ steps.versions.outputs.semVerNum }} REVISION_NUM: ${{ steps.versions.outputs.revNum }} - PPA_VERSION: ${{ github.event.inputs.ppaver }} + PPA_VERSION: ${{ github.event.inputs.ppaver }}-0ppa1 - name: Prepare GPG-Agent for signing with key 615D449FE6E6A235 run: | echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import From 2cc01be236e77ce1551061cb05cd4f1233defe8b Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 6 Dec 2022 20:44:51 +0100 Subject: [PATCH 76/84] simplify jmod compatibility check --- .github/workflows/debian.yml | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index f465f4069..4e925d7af 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -63,23 +63,26 @@ jobs: mkdir -p jmods/aarch64 unzip -j openjfx-aarch64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/aarch64 - name: Ensure major jfx version in pom and in jmods is the same - shell: pwsh # TODO translate to bash run: | - mkdir jfxBaseJmodAmd64 - jmod extract --dir jfxBaseJmodAmd64 jmods/amd64/javafx.base.jmod - $jfxJmodVersionAmd64 = ((Get-Content -Path "jfxBaseJmodAmd64/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." - mkdir jfxBaseJmodAarch64 - jmod extract --dir jfxBaseJmodAarch64 jmods/aarch64/javafx.base.jmod - $jfxJmodVersionAarch64 = ((Get-Content -Path "jfxBaseJmodAarch64/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." - if ($jfxJmodVersionAmd64[0] -ne $jfxJmodVersionAarch64[0] ) { - Write-Error "JavaFX Jmods for aarch64 and amd64 are different major versions" + JMOD_VERSION_AMD64=$(jmod describe ${JAVA_HOME}/jmods/amd64/javafx.base.jmod | head -1) + JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@} + JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*} + JMOD_VERSION_AARCH64=$(jmod describe ${JAVA_HOME}/jmods/aarch64/javafx.base.jmod | head -1) + JMOD_VERSION_AARCH64=${JMOD_VERSION_AARCH64#*@} + JMOD_VERSION_AARCH64=${JMOD_VERSION_AARCH64%%.*} + 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 - } - $jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\." - if ($jfxPomVersion[0] -ne $jfxJmodVersionAmd64[0]) { - Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version of Jmods($($jfxJmodVersionAmd64[0])) " + fi + + if [ $POM_JFX_VERSION -ne $JMOD_VERSION_AARCH64 ]; then + >&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != aarch64 jmod version (${JMOD_VERSION_AARCH64})" exit 1 - } + fi - name: Create orig.tar.gz with common/ libs/ mods/ jmods/ run: | mkdir pkgdir From db928ba034bfe19106212d93450bef3a94d2d34c Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 6 Dec 2022 20:49:09 +0100 Subject: [PATCH 77/84] try fixing debian build --- dist/linux/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/linux/debian/control b/dist/linux/debian/control index 0f0757321..e7860406a 100644 --- a/dist/linux/debian/control +++ b/dist/linux/debian/control @@ -2,7 +2,7 @@ Source: cryptomator Maintainer: Cryptobot Section: utils Priority: optional -Build-Depends: debhelper (>=10), coffeelibs-jdk-19, libgtk2.0-0 +Build-Depends: debhelper (>=10), coffeelibs-jdk-19, libgtk2.0-0, libgtk-3-0 Standards-Version: 4.5.0 Homepage: https://cryptomator.org Vcs-Git: https://github.com/cryptomator/cryptomator.git From 5ba137dda5daa6811c1ae988b8df6af3217550e7 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 7 Dec 2022 11:11:31 +0100 Subject: [PATCH 78/84] Add additional build dependencies to debian build --- dist/linux/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/linux/debian/control b/dist/linux/debian/control index e7860406a..c6dcfc5a5 100644 --- a/dist/linux/debian/control +++ b/dist/linux/debian/control @@ -2,7 +2,7 @@ Source: cryptomator Maintainer: Cryptobot Section: utils Priority: optional -Build-Depends: debhelper (>=10), coffeelibs-jdk-19, libgtk2.0-0, libgtk-3-0 +Build-Depends: debhelper (>=10), coffeelibs-jdk-19, libgtk2.0-0, libgtk-3-0, libXxf87vm, libgl2 Standards-Version: 4.5.0 Homepage: https://cryptomator.org Vcs-Git: https://github.com/cryptomator/cryptomator.git From 0e9b11564729bb21259bbd05879e138242d67d25 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 7 Dec 2022 11:43:59 +0100 Subject: [PATCH 79/84] debian build: use correct package names --- dist/linux/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/linux/debian/control b/dist/linux/debian/control index c6dcfc5a5..b17454f40 100644 --- a/dist/linux/debian/control +++ b/dist/linux/debian/control @@ -2,7 +2,7 @@ Source: cryptomator Maintainer: Cryptobot Section: utils Priority: optional -Build-Depends: debhelper (>=10), coffeelibs-jdk-19, libgtk2.0-0, libgtk-3-0, libXxf87vm, libgl2 +Build-Depends: debhelper (>=10), coffeelibs-jdk-19, libgtk2.0-0, libgtk-3-0, libxxf86vm1, libgl1 Standards-Version: 4.5.0 Homepage: https://cryptomator.org Vcs-Git: https://github.com/cryptomator/cryptomator.git From 0e7ec8eb3753e9d71e6638a224052e2c281e359d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 7 Dec 2022 12:24:42 +0100 Subject: [PATCH 80/84] bump replace deprecated syntax and dependencies in win-exe build --- .github/workflows/win-exe.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 1ccf7a560..36d727bd0 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -316,12 +316,12 @@ jobs: needs: [build-msi, build-exe] steps: - name: Download .msi - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: msi path: msi - name: Download .exe - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: exe path: exe @@ -331,7 +331,7 @@ jobs: cp msi/*.msi files cp exe/*.exe files - name: Upload to Kaspersky - uses: SamKirkland/FTP-Deploy-Action@4.3.0 + uses: SamKirkland/FTP-Deploy-Action@4.3.3 with: protocol: ftps server: allowlist.kaspersky-labs.com From ebcd0adf78b12dd9883a2bab20a3a8349c12ca2d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 7 Dec 2022 14:17:42 +0100 Subject: [PATCH 81/84] Update dependency-check plugin and exclude false positive --- pom.xml | 2 +- suppression.xml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b140c3a83..6f34af07f 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 23.0.0 - 7.2.1 + 7.4.0 0.8.8 diff --git a/suppression.xml b/suppression.xml index ccd1a1cdf..75373c5cd 100644 --- a/suppression.xml +++ b/suppression.xml @@ -35,13 +35,15 @@ CVE-2022-25366 + ^commons\-cli:commons\-cli:.*$ cpe:/a:apache:james - + cpe:/a:spirit-project:spirit + cpe:/a:apache:commons_net \ No newline at end of file From 0725a63b09922ec5dafd3ecd5c4953fedb023f25 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 7 Dec 2022 14:29:00 +0100 Subject: [PATCH 82/84] release winget manually --- .github/workflows/win-exe.yml | 21 ++++++++++++--------- .github/workflows/winget.yml | 7 +------ 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 36d727bd0..84055a328 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -195,15 +195,6 @@ jobs: *.msi *.asc - call-winget-flow: - needs: [get-version, build-msi] - if: github.event.action == 'published' && needs.get-version.outputs.type == 'stable' - uses: ./.github/workflows/winget.yml - with: - releaseTag: ${{ github.event.release.tag_name }} - secrets: inherit - - build-exe: name: Build .exe installer runs-on: windows-latest @@ -308,6 +299,18 @@ jobs: files: | Cryptomator-*.exe Cryptomator-*.asc + - name: Slack Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_USERNAME: 'Cryptobot' + SLACK_ICON: false + SLACK_ICON_EMOJI: ':bot:' + SLACK_CHANNEL: 'cryptomator-desktop' + SLACK_TITLE: "Windows build of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} finished." + SLACK_MESSAGE: "Ready to ." + SLACK_FOOTER: false + MSG_MINIMAL: true allowlist: name: Anti Virus Allowlisting diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index 7115a1785..6d1475ef7 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -1,11 +1,6 @@ name: Release to Winget on: - workflow_call: - inputs: - releaseTag: - required: true - type: string workflow_dispatch: inputs: releaseTag: @@ -18,7 +13,7 @@ jobs: name: Publish on winget repo runs-on: windows-latest steps: - - name: Get download url for msi artifacts + - name: Get download url for release assets id: get-release-assets uses: actions/github-script@v6 with: From c61087e69711e4c1444e211d33851c70c9121a71 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 7 Dec 2022 14:52:33 +0100 Subject: [PATCH 83/84] create and upload source signature after release publish --- .github/workflows/build.yml | 12 ------------ .github/workflows/post-publish.yml | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/post-publish.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d94048ee9..b31bfa08a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,15 +42,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - - name: Sign source tarball with key 615D449FE6E6A235 - if: startsWith(github.ref, 'refs/tags/') - run: | - git archive --prefix="cryptomator-${{ github.ref_name }}/" -o "cryptomator-${{ github.ref_name }}.tar.gz" ${{ github.ref }} - echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import - echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.tar.gz - env: - GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} - GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} - name: Draft a release if: startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v1 @@ -59,9 +50,6 @@ jobs: discussion_category_name: releases token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} generate_release_notes: true - files: | - cryptomator-*.tar.gz.asc - fail_on_unmatched_files: true body: |- :construction: Work in Progress diff --git a/.github/workflows/post-publish.yml b/.github/workflows/post-publish.yml new file mode 100644 index 000000000..4a70e8d42 --- /dev/null +++ b/.github/workflows/post-publish.yml @@ -0,0 +1,28 @@ +name: Post Release Publish Tasks + +on: + release: + types: [published] + +jobs: + get-version: + runs-on: ubuntu-latest + steps: + - name: Download source tarball + run: | + curl -L -H "Accept: application/vnd.github+json" ${{ github.event.release.tarball_url }} --output cryptomator-${{ github.event.release.tag_name }}.tar.gz + - name: Sign source tarball with key 615D449FE6E6A235 + if: startsWith(github.ref, 'refs/tags/') + run: | + echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import + echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.tar.gz + env: + GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} + - name: Publish asc on GitHub Releases + uses: softprops/action-gh-release@v1 + with: + fail_on_unmatched_files: true + token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} + files: | + cryptomator-*.tar.gz.asc From f9d588320c0abdeae5a4064482c293112997d617 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 7 Dec 2022 14:53:41 +0100 Subject: [PATCH 84/84] add slack notification to release PPA --- .github/workflows/post-publish.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/post-publish.yml b/.github/workflows/post-publish.yml index 4a70e8d42..bd3cc1c7e 100644 --- a/.github/workflows/post-publish.yml +++ b/.github/workflows/post-publish.yml @@ -26,3 +26,15 @@ jobs: token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} files: | cryptomator-*.tar.gz.asc + - name: Slack Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_USERNAME: 'Cryptobot' + SLACK_ICON: false + SLACK_ICON_EMOJI: ':bot:' + SLACK_CHANNEL: 'cryptomator-desktop' + SLACK_TITLE: "Release ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published." + SLACK_MESSAGE: "Ready to ." + SLACK_FOOTER: false + MSG_MINIMAL: true \ No newline at end of file