mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-22 04:31:27 +00:00
Merge branch 'develop' into feature/dialog-builder
This commit is contained in:
@@ -2,7 +2,8 @@ import ch.qos.logback.classic.spi.Configurator;
|
||||
import org.cryptomator.common.locationpresets.DropboxLinuxLocationPresetsProvider;
|
||||
import org.cryptomator.common.locationpresets.DropboxMacLocationPresetsProvider;
|
||||
import org.cryptomator.common.locationpresets.DropboxWindowsLocationPresetsProvider;
|
||||
import org.cryptomator.common.locationpresets.GoogleDriveLocationPresetsProvider;
|
||||
import org.cryptomator.common.locationpresets.GoogleDriveMacLocationPresetsProvider;
|
||||
import org.cryptomator.common.locationpresets.GoogleDriveWindowsLocationPresetsProvider;
|
||||
import org.cryptomator.common.locationpresets.ICloudMacLocationPresetsProvider;
|
||||
import org.cryptomator.common.locationpresets.ICloudWindowsLocationPresetsProvider;
|
||||
import org.cryptomator.common.locationpresets.LeitzcloudLocationPresetsProvider;
|
||||
@@ -48,6 +49,7 @@ open module org.cryptomator.desktop {
|
||||
|
||||
/* dagger bs */
|
||||
requires jakarta.inject;
|
||||
requires static javax.inject;
|
||||
requires java.compiler;
|
||||
|
||||
uses org.cryptomator.common.locationpresets.LocationPresetsProvider;
|
||||
@@ -56,7 +58,7 @@ open module org.cryptomator.desktop {
|
||||
provides Configurator with LogbackConfiguratorFactory;
|
||||
provides LocationPresetsProvider with //
|
||||
DropboxWindowsLocationPresetsProvider, DropboxMacLocationPresetsProvider, DropboxLinuxLocationPresetsProvider, //
|
||||
GoogleDriveLocationPresetsProvider, //
|
||||
GoogleDriveMacLocationPresetsProvider, GoogleDriveWindowsLocationPresetsProvider, //
|
||||
ICloudWindowsLocationPresetsProvider, ICloudMacLocationPresetsProvider, //
|
||||
LeitzcloudLocationPresetsProvider, //
|
||||
MegaLocationPresetsProvider, //
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
package org.cryptomator.common.locationpresets;
|
||||
|
||||
import org.cryptomator.integrations.common.CheckAvailability;
|
||||
import org.cryptomator.integrations.common.OperatingSystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
|
||||
|
||||
@OperatingSystem(MAC)
|
||||
@CheckAvailability
|
||||
public final class GoogleDriveMacLocationPresetsProvider implements LocationPresetsProvider {
|
||||
|
||||
private static final Path ROOT_LOCATION = LocationPresetsProvider.resolveLocation("~/Library/CloudStorage/").toAbsolutePath();
|
||||
private static final Predicate<String> PATTERN = Pattern.compile("^GoogleDrive-[^/]+$").asMatchPredicate();
|
||||
|
||||
private static final List<Path> FALLBACK_LOCATIONS = List.of( //
|
||||
LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), //
|
||||
LocationPresetsProvider.resolveLocation("~/Google Drive/My Drive"), //
|
||||
LocationPresetsProvider.resolveLocation("~/GoogleDrive"), //
|
||||
LocationPresetsProvider.resolveLocation("~/Google Drive") //
|
||||
);
|
||||
|
||||
@Override
|
||||
public Stream<LocationPreset> getLocations() {
|
||||
List<LocationPreset> cloudStorageDirLocations = getCloudStorageDirLocations();
|
||||
return cloudStorageDirLocations.isEmpty() ? getFallbackLocation().stream() : cloudStorageDirLocations.stream();
|
||||
|
||||
}
|
||||
|
||||
@CheckAvailability
|
||||
public static boolean isPresent() {
|
||||
return isRootLocationPresent() || FALLBACK_LOCATIONS.stream().anyMatch(Files::isDirectory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a root location directory is present that matches the specified pattern.
|
||||
* <p>
|
||||
* This method scans the {@code ROOT_LOCATION} directory for subdirectories and tests each one against a pre-defined pattern ({@code PATTERN}).
|
||||
*
|
||||
* @return {@code true} if a matching root location is present, otherwise {@code false}.
|
||||
*/
|
||||
public static boolean isRootLocationPresent() {
|
||||
try (var dirStream = Files.list(ROOT_LOCATION)) {
|
||||
return dirStream.anyMatch(path -> Files.isDirectory(path) && PATTERN.test(path.getFileName().toString()));
|
||||
} catch (IOException | UncheckedIOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Google Drive preset String.
|
||||
*
|
||||
* @param accountPath The path to the Google Drive account directory (e.g. {@code ~/Library/CloudStorage/GoogleDrive-username})
|
||||
* @return {@code String}. For example: "Google Drive - username"
|
||||
*/
|
||||
private String getDriveLocationString(Path accountPath) {
|
||||
String accountName = accountPath.getFileName().toString().replace("GoogleDrive-", "");
|
||||
return STR."Google Drive - \{accountName}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of cloud storage directory locations based on the {@code ROOT_LOCATION}.
|
||||
* <p>
|
||||
* This method lists all directories in the {@code ROOT_LOCATION}, filters them based on whether their names match
|
||||
* a predefined pattern ({@code PATTERN}), and then extracts presets using {@code getPresetsFromAccountPath(Path)}.
|
||||
* <p>
|
||||
*
|
||||
* @return a list of {@code LocationPreset} objects representing valid cloud storage directory locations.
|
||||
*/
|
||||
private List<LocationPreset> getCloudStorageDirLocations() {
|
||||
try (var dirStream = Files.list(ROOT_LOCATION)) {
|
||||
return dirStream.filter(path -> Files.isDirectory(path) && PATTERN.test(path.getFileName().toString()))
|
||||
.flatMap(this::getPresetsFromAccountPath)
|
||||
.toList();
|
||||
} catch (IOException | UncheckedIOException e) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a stream of {@code LocationPreset} objects from a given Google Drive account path.
|
||||
* <p>
|
||||
* This method lists all directories within the provided {@code accountPath} and filters them
|
||||
* to identify folders whose names match any of the translations defined in {@code MY_DRIVE_TRANSLATIONS}.
|
||||
*
|
||||
* @param accountPath the root path of the Google Drive account to scan.
|
||||
* @return a stream of {@code LocationPreset} objects representing matching directories.
|
||||
*/
|
||||
private Stream<LocationPreset> getPresetsFromAccountPath(Path accountPath) {
|
||||
try (var driveStream = Files.list(accountPath)) {
|
||||
return driveStream
|
||||
.filter(preset -> MY_DRIVE_TRANSLATIONS
|
||||
.contains(preset.getFileName().toString()))
|
||||
.map(drivePath -> new LocationPreset(
|
||||
getDriveLocationString(accountPath),
|
||||
drivePath
|
||||
)).toList().stream();
|
||||
} catch (IOException e) {
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing a fallback location preset for Google Drive.
|
||||
* <p>
|
||||
* This method iterates through the predefined fallback locations, checks if any of them is a directory,
|
||||
* and creates a {@code LocationPreset} object for the first matching directory found.
|
||||
*
|
||||
* @return a list containing a single fallback location preset if a valid directory is found, otherwise an empty list.
|
||||
* @deprecated This method is intended for legacy support and may be removed in future releases.
|
||||
*/
|
||||
@Deprecated
|
||||
private List<LocationPreset> getFallbackLocation() {
|
||||
return FALLBACK_LOCATIONS.stream()
|
||||
.filter(Files::isDirectory)
|
||||
.map(location -> new LocationPreset("Google Drive", location))
|
||||
.findFirst()
|
||||
.stream()
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of translations for "My Drive" in various languages.
|
||||
* <p>
|
||||
* This constant is used to identify different language-specific labels for "My Drive" in Google Drive.
|
||||
* <p>
|
||||
* The translations were originally extracted from the Chromium project’s Chrome OS translation files.
|
||||
* <p>
|
||||
* Source: `ui/chromeos/translations` directory in the Chromium repository.
|
||||
*/
|
||||
private static final Set<String> MY_DRIVE_TRANSLATIONS = Set.of("My Drive", "የእኔ Drive", "ملفاتي", "মোৰ ড্ৰাইভ", "Diskim", "Мой Дыск", "Моят диск", "আমার ড্রাইভ", "Moj disk", "La meva unitat", "Můj disk", "Mit drev", "Meine Ablage", "Το Drive μου", "Mi unidad", "Minu ketas", "Nire unitatea", "Aking Drive", "Oma Drive", "Mon disque", "Mon Drive", "A miña unidade", "મારી ડ્રાઇવ", "मेरी ड्राइव", "Saját meghajtó", "Իմ դրայվը", "Drive Saya", "Drifið mitt", "I miei file", "האחסון שלי", "マイドライブ", "ჩემი Drive", "Менің Drive дискім", "ដ្រាយរបស់ខ្ញុំ", "ನನ್ನ ಡ್ರೈವ್", "내 드라이브", "Менин Drive'ым", "Mano Diskas", "Mans disks", "Мојот Drive", "എന്റെ ഡ്രൈവ്", "Миний Драйв", "माझा ड्राइव्ह", "मेरो ड्राइभ", "Mijn Drive", "Min disk", "ମୋ ଡ୍ରାଇଭ୍", "Mój dysk", "Meu Drive", "O meu disco", "Contul meu Drive", "Мой диск", "මගේ Drive", "Môj disk", "Disku im", "Мој диск", "Min enhet", "Hifadhi Yangu", "எனது இயக்ககம்", "నా డ్రైవ్", "ไดรฟ์ของฉัน", "Drive'ım", "Мій диск", "میری ڈرائیو", "Drive của tôi", "我的云端硬盘", "我的雲端硬碟", "IDrayivu yami");
|
||||
}
|
||||
@@ -9,13 +9,11 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
|
||||
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
|
||||
|
||||
@OperatingSystem(WINDOWS)
|
||||
@OperatingSystem(MAC)
|
||||
@CheckAvailability
|
||||
public final class GoogleDriveLocationPresetsProvider implements LocationPresetsProvider {
|
||||
public final class GoogleDriveWindowsLocationPresetsProvider implements LocationPresetsProvider {
|
||||
|
||||
private static final List<Path> LOCATIONS = Arrays.asList( //
|
||||
LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), //
|
||||
@@ -37,5 +35,4 @@ public final class GoogleDriveLocationPresetsProvider implements LocationPresets
|
||||
.findFirst() //
|
||||
.stream();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,7 +32,6 @@ public class Settings {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Settings.class);
|
||||
|
||||
static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false;
|
||||
static final boolean DEFAULT_CHECK_FOR_UPDATES = false;
|
||||
static final boolean DEFAULT_START_HIDDEN = false;
|
||||
static final boolean DEFAULT_AUTO_CLOSE_VAULTS = false;
|
||||
@@ -50,11 +49,9 @@ public class Settings {
|
||||
SystemUtils.IS_OS_LINUX ? "org.cryptomator.linux.quickaccess.NautilusBookmarks" : null;
|
||||
|
||||
static final String DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT.name();
|
||||
static final boolean DEFAULT_SHOW_MINIMIZE_BUTTON = false;
|
||||
public static final Instant DEFAULT_TIMESTAMP = Instant.parse("2000-01-01T00:00:00Z");
|
||||
|
||||
public final ObservableList<VaultSettings> directories;
|
||||
public final BooleanProperty askedForUpdateCheck;
|
||||
public final BooleanProperty checkForUpdates;
|
||||
public final BooleanProperty startHidden;
|
||||
public final BooleanProperty autoCloseVaults;
|
||||
public final BooleanProperty useKeychain;
|
||||
@@ -75,6 +72,8 @@ public class Settings {
|
||||
public final IntegerProperty windowHeight;
|
||||
public final StringProperty language;
|
||||
public final StringProperty mountService;
|
||||
public final BooleanProperty checkForUpdates;
|
||||
public final ObjectProperty<Instant> lastUpdateCheckReminder;
|
||||
public final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
|
||||
|
||||
private Consumer<Settings> saveCmd;
|
||||
@@ -92,8 +91,6 @@ public class Settings {
|
||||
*/
|
||||
Settings(SettingsJson json) {
|
||||
this.directories = FXCollections.observableArrayList(VaultSettings::observables);
|
||||
this.askedForUpdateCheck = new SimpleBooleanProperty(this, "askedForUpdateCheck", json.askedForUpdateCheck);
|
||||
this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
|
||||
this.startHidden = new SimpleBooleanProperty(this, "startHidden", json.startHidden);
|
||||
this.autoCloseVaults = new SimpleBooleanProperty(this, "autoCloseVaults", json.autoCloseVaults);
|
||||
this.useKeychain = new SimpleBooleanProperty(this, "useKeychain", json.useKeychain);
|
||||
@@ -114,6 +111,8 @@ public class Settings {
|
||||
this.language = new SimpleStringProperty(this, "language", json.language);
|
||||
this.mountService = new SimpleStringProperty(this, "mountService", json.mountService);
|
||||
this.quickAccessService = new SimpleStringProperty(this, "quickAccessService", json.quickAccessService);
|
||||
this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
|
||||
this.lastUpdateCheckReminder = new SimpleObjectProperty<>(this, "lastUpdateCheckReminder", json.lastReminderForUpdateCheck);
|
||||
this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck);
|
||||
|
||||
this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList());
|
||||
@@ -121,8 +120,6 @@ public class Settings {
|
||||
migrateLegacySettings(json);
|
||||
|
||||
directories.addListener(this::somethingChanged);
|
||||
askedForUpdateCheck.addListener(this::somethingChanged);
|
||||
checkForUpdates.addListener(this::somethingChanged);
|
||||
startHidden.addListener(this::somethingChanged);
|
||||
autoCloseVaults.addListener(this::somethingChanged);
|
||||
useKeychain.addListener(this::somethingChanged);
|
||||
@@ -143,6 +140,8 @@ public class Settings {
|
||||
language.addListener(this::somethingChanged);
|
||||
mountService.addListener(this::somethingChanged);
|
||||
quickAccessService.addListener(this::somethingChanged);
|
||||
checkForUpdates.addListener(this::somethingChanged);
|
||||
lastUpdateCheckReminder.addListener(this::somethingChanged);
|
||||
lastSuccessfulUpdateCheck.addListener(this::somethingChanged);
|
||||
}
|
||||
|
||||
@@ -177,8 +176,6 @@ public class Settings {
|
||||
SettingsJson serialized() {
|
||||
var json = new SettingsJson();
|
||||
json.directories = directories.stream().map(VaultSettings::serialized).toList();
|
||||
json.askedForUpdateCheck = askedForUpdateCheck.get();
|
||||
json.checkForUpdatesEnabled = checkForUpdates.get();
|
||||
json.startHidden = startHidden.get();
|
||||
json.autoCloseVaults = autoCloseVaults.get();
|
||||
json.useKeychain = useKeychain.get();
|
||||
@@ -199,6 +196,8 @@ public class Settings {
|
||||
json.language = language.get();
|
||||
json.mountService = mountService.get();
|
||||
json.quickAccessService = quickAccessService.get();
|
||||
json.checkForUpdatesEnabled = checkForUpdates.get();
|
||||
json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get();
|
||||
json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get();
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -18,15 +18,9 @@ class SettingsJson {
|
||||
@JsonProperty("writtenByVersion")
|
||||
String writtenByVersion;
|
||||
|
||||
@JsonProperty("askedForUpdateCheck")
|
||||
boolean askedForUpdateCheck = Settings.DEFAULT_ASKED_FOR_UPDATE_CHECK;
|
||||
|
||||
@JsonProperty("autoCloseVaults")
|
||||
boolean autoCloseVaults = Settings.DEFAULT_AUTO_CLOSE_VAULTS;
|
||||
|
||||
@JsonProperty("checkForUpdatesEnabled")
|
||||
boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES;
|
||||
|
||||
@JsonProperty("debugMode")
|
||||
boolean debugMode = Settings.DEFAULT_DEBUG_MODE;
|
||||
|
||||
@@ -82,6 +76,13 @@ class SettingsJson {
|
||||
@JsonProperty(value = "preferredVolumeImpl", access = JsonProperty.Access.WRITE_ONLY) // WRITE_ONLY means value is "written" into the java object during deserialization. Upvote this: https://github.com/FasterXML/jackson-annotations/issues/233
|
||||
String preferredVolumeImpl;
|
||||
|
||||
@JsonProperty("checkForUpdatesEnabled")
|
||||
boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES;
|
||||
|
||||
@JsonProperty("lastReminderForUpdateCheck")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
|
||||
Instant lastReminderForUpdateCheck = Settings.DEFAULT_TIMESTAMP;
|
||||
|
||||
@JsonProperty("lastSuccessfulUpdateCheck")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
|
||||
Instant lastSuccessfulUpdateCheck = Settings.DEFAULT_TIMESTAMP;
|
||||
|
||||
@@ -11,6 +11,8 @@ import org.slf4j.LoggerFactory;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javafx.application.Platform;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@FxApplicationScoped
|
||||
@@ -72,8 +74,12 @@ public class FxApplication {
|
||||
return null;
|
||||
});
|
||||
|
||||
if (!environment.disableUpdateCheck()) {
|
||||
appWindows.checkAndShowUpdateReminderWindow();
|
||||
var time14DaysAgo = Instant.now().minus(Duration.ofDays(14));
|
||||
if (!environment.disableUpdateCheck() //
|
||||
&& !settings.checkForUpdates.getValue() //
|
||||
&& settings.lastSuccessfulUpdateCheck.get().isBefore(time14DaysAgo) //
|
||||
&& settings.lastUpdateCheckReminder.get().isBefore(time14DaysAgo)) {
|
||||
appWindows.showUpdateReminderWindow();
|
||||
}
|
||||
|
||||
migrateAndInformDokanyRemoval();
|
||||
|
||||
@@ -49,7 +49,7 @@ public class FxApplicationWindows {
|
||||
private final Lazy<PreferencesComponent> preferencesWindow;
|
||||
private final QuitComponent.Builder quitWindowBuilder;
|
||||
private final UnlockComponent.Factory unlockWorkflowFactory;
|
||||
private final UpdateReminderComponent.Factory updateReminderWindowBuilder;
|
||||
private final UpdateReminderComponent.Factory updateReminderWindowFactory;
|
||||
private final LockComponent.Factory lockWorkflowFactory;
|
||||
private final ErrorComponent.Factory errorWindowFactory;
|
||||
private final ExecutorService executor;
|
||||
@@ -65,7 +65,7 @@ public class FxApplicationWindows {
|
||||
Lazy<PreferencesComponent> preferencesWindow, //
|
||||
QuitComponent.Builder quitWindowBuilder, //
|
||||
UnlockComponent.Factory unlockWorkflowFactory, //
|
||||
UpdateReminderComponent.Factory updateReminderWindowBuilder, //
|
||||
UpdateReminderComponent.Factory updateReminderWindowFactory, //
|
||||
LockComponent.Factory lockWorkflowFactory, //
|
||||
ErrorComponent.Factory errorWindowFactory, //
|
||||
VaultOptionsComponent.Factory vaultOptionsWindow, //
|
||||
@@ -78,7 +78,7 @@ public class FxApplicationWindows {
|
||||
this.preferencesWindow = preferencesWindow;
|
||||
this.quitWindowBuilder = quitWindowBuilder;
|
||||
this.unlockWorkflowFactory = unlockWorkflowFactory;
|
||||
this.updateReminderWindowBuilder = updateReminderWindowBuilder;
|
||||
this.updateReminderWindowFactory = updateReminderWindowFactory;
|
||||
this.lockWorkflowFactory = lockWorkflowFactory;
|
||||
this.errorWindowFactory = errorWindowFactory;
|
||||
this.executor = executor;
|
||||
@@ -143,8 +143,8 @@ public class FxApplicationWindows {
|
||||
CompletableFuture.runAsync(() -> quitWindowBuilder.build().showQuitWindow(response,forced), Platform::runLater);
|
||||
}
|
||||
|
||||
public void checkAndShowUpdateReminderWindow() {
|
||||
CompletableFuture.runAsync(() -> updateReminderWindowBuilder.create().checkAndShowUpdateReminderWindow(), Platform::runLater);
|
||||
public void showUpdateReminderWindow() {
|
||||
CompletableFuture.runAsync(() -> updateReminderWindowFactory.create().showUpdateReminderWindow(), Platform::runLater);
|
||||
}
|
||||
|
||||
public void showDokanySupportEndWindow() {
|
||||
|
||||
@@ -2,14 +2,11 @@ package org.cryptomator.ui.updatereminder;
|
||||
|
||||
import dagger.Lazy;
|
||||
import dagger.Subcomponent;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
@UpdateReminderScoped
|
||||
@Subcomponent(modules = {UpdateReminderModule.class})
|
||||
@@ -21,16 +18,11 @@ public interface UpdateReminderComponent {
|
||||
@FxmlScene(FxmlFile.UPDATE_REMINDER)
|
||||
Lazy<Scene> updateReminderScene();
|
||||
|
||||
Settings settings();
|
||||
|
||||
default void checkAndShowUpdateReminderWindow() {
|
||||
var now = Instant.now();
|
||||
if (!settings().checkForUpdates.getValue() && settings().lastSuccessfulUpdateCheck.get().isBefore(now.minus(Duration.ofDays(14)))) {
|
||||
Stage stage = window();
|
||||
stage.setScene(updateReminderScene().get());
|
||||
stage.sizeToScene();
|
||||
stage.show();
|
||||
}
|
||||
default void showUpdateReminderWindow() {
|
||||
Stage stage = window();
|
||||
stage.setScene(updateReminderScene().get());
|
||||
stage.sizeToScene();
|
||||
stage.show();
|
||||
}
|
||||
|
||||
@Subcomponent.Factory
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.cryptomator.ui.fxapp.UpdateChecker;
|
||||
import javax.inject.Inject;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.stage.Stage;
|
||||
import java.time.Instant;
|
||||
|
||||
@UpdateReminderScoped
|
||||
public class UpdateReminderController implements FxController {
|
||||
@@ -23,6 +24,11 @@ public class UpdateReminderController implements FxController {
|
||||
this.updateChecker = updateChecker;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
settings.lastUpdateCheckReminder.set(Instant.now());
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void cancel() {
|
||||
window.close();
|
||||
|
||||
Reference in New Issue
Block a user