diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 18834c0fc..aaf6b0928 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -14,22 +14,45 @@
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/cryptomator/ui/controls/NotificationBar.java b/src/main/java/org/cryptomator/ui/controls/NotificationBar.java
new file mode 100644
index 000000000..58061ec82
--- /dev/null
+++ b/src/main/java/org/cryptomator/ui/controls/NotificationBar.java
@@ -0,0 +1,102 @@
+package org.cryptomator.ui.controls;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.fxml.FXML;
+import javafx.geometry.Pos;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
+
+public class NotificationBar extends HBox {
+
+ @FXML
+ private Label notificationLabel;
+
+ private final BooleanProperty dismissable = new SimpleBooleanProperty();
+ private final BooleanProperty notify = new SimpleBooleanProperty();
+
+
+ public NotificationBar() {
+ setAlignment(Pos.CENTER);
+ setStyle("-fx-alignment: center;");
+
+ Region spacer = new Region();
+ spacer.setMinWidth(40);
+
+ Region leftRegion = new Region();
+ HBox.setHgrow(leftRegion, javafx.scene.layout.Priority.ALWAYS);
+
+ Region rightRegion = new Region();
+ HBox.setHgrow(rightRegion, javafx.scene.layout.Priority.ALWAYS);
+
+ VBox vbox = new VBox();
+ vbox.setAlignment(Pos.CENTER);
+ HBox.setHgrow(vbox, javafx.scene.layout.Priority.ALWAYS);
+
+ notificationLabel = new Label();
+ notificationLabel.getStyleClass().add("notification-label");
+ notificationLabel.setStyle("-fx-alignment: center;");
+ vbox.getChildren().add(notificationLabel);
+
+ Button closeButton = new Button("X");
+ closeButton.setMinWidth(40);
+ closeButton.setStyle("-fx-background-color: transparent; -fx-text-fill: white; -fx-font-weight: bold;");
+ closeButton.visibleProperty().bind(dismissable);
+
+ closeButton.setOnAction(_ -> {
+ visibleProperty().unbind();
+ managedProperty().unbind();
+ visibleProperty().set(false);
+ managedProperty().set(false);
+ });
+ closeButton.visibleProperty().bind(dismissable);
+
+ closeButton.setOnAction(_ -> {
+ visibleProperty().unbind();
+ managedProperty().unbind();
+ visibleProperty().set(false);
+ managedProperty().set(false);
+ });
+
+ getChildren().addAll(spacer, leftRegion, vbox, rightRegion, closeButton);
+
+ visibleProperty().bind(notifyProperty());
+ managedProperty().bind(notifyProperty());
+ }
+
+ public String getText() {
+ return notificationLabel.getText();
+ }
+
+ public void setText(String text) {
+ notificationLabel.setText(text);
+ }
+
+ public void setStyleClass(String styleClass) {
+ getStyleClass().add(styleClass);
+ }
+
+ public boolean isDismissable() {
+ return dismissable.get();
+ }
+
+ public void setDismissable(boolean value) {
+ dismissable.set(value);
+ }
+
+ public boolean getNotify() {
+ return notify.get();
+ }
+
+ public void setNotify(boolean value) {
+ notify.set(value);
+ }
+
+ public BooleanProperty notifyProperty() {
+ return notify;
+ }
+
+}
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java
index a09c3afba..999ff7882 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java
@@ -1,20 +1,26 @@
package org.cryptomator.ui.mainwindow;
-import org.apache.commons.lang3.SystemUtils;
-import org.cryptomator.common.settings.Settings;
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.common.vaults.VaultListManager;
-import org.cryptomator.ui.common.FxController;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
import javafx.beans.Observable;
+import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
+import org.apache.commons.lang3.SystemUtils;
+import org.cryptomator.common.LicenseHolder;
+import org.cryptomator.common.settings.Settings;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.common.vaults.VaultListManager;
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.fxapp.FxApplicationWindows;
+import org.cryptomator.ui.fxapp.UpdateChecker;
+import org.cryptomator.ui.preferences.SelectedPreferencesTab;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
@MainWindowScoped
public class MainWindowController implements FxController {
@@ -24,19 +30,34 @@ public class MainWindowController implements FxController {
private final Stage window;
private final ReadOnlyObjectProperty selectedVault;
private final Settings settings;
+ private final FxApplicationWindows appWindows;
+ private final BooleanBinding updateAvailable;
+ private final LicenseHolder licenseHolder;
- public StackPane root;
+ @FXML
+ private StackPane root;
@Inject
- public MainWindowController(@MainWindow Stage window, ObjectProperty selectedVault, Settings settings) {
+ public MainWindowController(@MainWindow Stage window, //
+ ObjectProperty selectedVault, //
+ Settings settings, //
+ FxApplicationWindows appWindows, //
+ UpdateChecker updateChecker, //
+ LicenseHolder licenseHolder) {
this.window = window;
this.selectedVault = selectedVault;
this.settings = settings;
+ this.appWindows = appWindows;
+ this.updateAvailable = updateChecker.updateAvailableProperty();
+ this.licenseHolder = licenseHolder;
+ updateChecker.automaticallyCheckForUpdatesIfEnabled();
+
}
@FXML
public void initialize() {
LOG.trace("init MainWindowController");
+
if (SystemUtils.IS_OS_WINDOWS) {
root.getStyleClass().add("os-windows");
}
@@ -48,17 +69,16 @@ public class MainWindowController implements FxController {
window.setX(settings.windowXPosition.get());
window.setY(settings.windowYPosition.get());
}
- window.widthProperty().addListener((_,_,_) -> savePositionalSettings());
- window.heightProperty().addListener((_,_,_) -> savePositionalSettings());
- window.xProperty().addListener((_,_,_) -> savePositionalSettings());
- window.yProperty().addListener((_,_,_) -> savePositionalSettings());
+ window.widthProperty().addListener((_, _, _) -> savePositionalSettings());
+ window.heightProperty().addListener((_, _, _) -> savePositionalSettings());
+ window.xProperty().addListener((_, _, _) -> savePositionalSettings());
+ window.yProperty().addListener((_, _, _) -> savePositionalSettings());
}
private boolean neverTouched() {
return (settings.windowHeight.get() == 0) && (settings.windowWidth.get() == 0) && (settings.windowXPosition.get() == 0) && (settings.windowYPosition.get() == 0);
}
- @FXML
public void savePositionalSettings() {
settings.windowWidth.setValue(window.getWidth());
settings.windowHeight.setValue(window.getHeight());
@@ -73,4 +93,43 @@ public class MainWindowController implements FxController {
}
}
+ @FXML
+ public void showGeneralPreferences() {
+ appWindows.showPreferencesWindow(SelectedPreferencesTab.GENERAL);
+ }
+
+ @FXML
+ public void showContributePreferences() {
+ appWindows.showPreferencesWindow(SelectedPreferencesTab.CONTRIBUTE);
+ }
+
+ @FXML
+ public void showUpdatePreferences() {
+ appWindows.showPreferencesWindow(SelectedPreferencesTab.UPDATES);
+ }
+
+ public ReadOnlyBooleanProperty debugModeEnabledProperty() {
+ return settings.debugMode;
+ }
+
+ public boolean getDebugModeEnabled() {
+ return debugModeEnabledProperty().get();
+ }
+
+ public BooleanBinding updateAvailableProperty() {
+ return updateAvailable;
+ }
+
+ public boolean getUpdateAvailable() {
+ return updateAvailable.get();
+ }
+
+ public BooleanBinding licenseValidProperty(){
+ return licenseHolder.validLicenseProperty();
+ }
+
+ public boolean getLicenseValid() {
+ return licenseHolder.isValidLicense();
+ }
+
}
diff --git a/src/main/resources/css/dark_theme.css b/src/main/resources/css/dark_theme.css
index 02f1ef028..72af57751 100644
--- a/src/main/resources/css/dark_theme.css
+++ b/src/main/resources/css/dark_theme.css
@@ -311,6 +311,35 @@
-fx-fill: transparent;
}
+/*******************************************************************************
+ * *
+ * NotificationBar *
+ * *
+ ******************************************************************************/
+
+.notification-label {
+ -fx-text-fill: white;
+ -fx-font-weight: bold;
+}
+
+.notification-debug {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: RED_5;
+}
+
+.notification-update {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: YELLOW_5;
+}
+
+.notification-support {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: PRIMARY;
+}
+
/*******************************************************************************
* *
* ScrollBar *
diff --git a/src/main/resources/css/light_theme.css b/src/main/resources/css/light_theme.css
index 5820bae7b..84df05b10 100644
--- a/src/main/resources/css/light_theme.css
+++ b/src/main/resources/css/light_theme.css
@@ -311,6 +311,35 @@
-fx-fill: transparent;
}
+/*******************************************************************************
+ * *
+ * NotificationBar *
+ * *
+ ******************************************************************************/
+
+.notification-label {
+ -fx-text-fill: white;
+ -fx-font-weight: bold;
+}
+
+.notification-debug {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: RED_5;
+}
+
+.notification-update {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: YELLOW_5;
+}
+
+.notification-support {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: PRIMARY;
+}
+
/*******************************************************************************
* *
* ScrollBar *
diff --git a/src/main/resources/fxml/main_window.fxml b/src/main/resources/fxml/main_window.fxml
index bb650848d..327e2c470 100644
--- a/src/main/resources/fxml/main_window.fxml
+++ b/src/main/resources/fxml/main_window.fxml
@@ -3,15 +3,31 @@
+
+
+
+
+
diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties
index 27ec3f16d..fb8a26f73 100644
--- a/src/main/resources/i18n/strings.properties
+++ b/src/main/resources/i18n/strings.properties
@@ -386,6 +386,9 @@ main.vaultlist.contextMenu.vaultoptions=Show Vault Options
main.vaultlist.contextMenu.reveal=Reveal Drive
main.vaultlist.addVaultBtn.menuItemNew=Create New Vault...
main.vaultlist.addVaultBtn.menuItemExisting=Open Existing Vault...
+##Notificaition
+main.notification.updateAvailable=Update is available.
+main.notification.support=Support Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Thanks for choosing Cryptomator to protect your files. If you need any assistance, check out our getting started guides: