diff --git a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/WelcomeController.java b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/WelcomeController.java index 2646c1a36..95a65f6ac 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/WelcomeController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/WelcomeController.java @@ -42,4 +42,5 @@ public class WelcomeController implements FxController { public boolean isNoVaultPresent() { return noVaultPresent.get(); } + } diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockController.java b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockController.java index e08164167..7e887ced4 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockController.java @@ -1,5 +1,10 @@ package org.cryptomator.ui.unlock; +import javafx.animation.Animation; +import javafx.animation.Interpolator; +import javafx.animation.KeyFrame; +import javafx.animation.KeyValue; +import javafx.animation.Timeline; import javafx.beans.binding.Bindings; import javafx.beans.binding.BooleanBinding; import javafx.beans.binding.ObjectBinding; @@ -9,7 +14,11 @@ import javafx.beans.property.SimpleBooleanProperty; import javafx.fxml.FXML; import javafx.scene.control.CheckBox; import javafx.scene.control.ContentDisplay; +import javafx.scene.image.ImageView; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Translate; import javafx.stage.Stage; +import javafx.util.Duration; import org.cryptomator.common.vaults.Vault; import org.cryptomator.keychain.KeychainManager; import org.cryptomator.ui.common.FxController; @@ -42,8 +51,15 @@ public class UnlockController implements FxController { private final ObjectBinding unlockButtonContentDisplay; private final BooleanBinding userInteractionDisabled; private final BooleanProperty unlockButtonDisabled; + public NiceSecurePasswordField passwordField; public CheckBox savePasswordCheckbox; + public ImageView face; + public ImageView leftArm; + public ImageView rightArm; + public ImageView legs; + public ImageView body; + public Animation unlockAnimation; @Inject public UnlockController(@UnlockWindow Stage window, @UnlockWindow Vault vault, AtomicReference password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional savedPassword, UserInteractionLock passwordEntryLock, ForgetPasswordComponent.Builder forgetPassword, Optional keychain) { @@ -60,12 +76,51 @@ public class UnlockController implements FxController { this.unlockButtonDisabled = new SimpleBooleanProperty(); } + @FXML public void initialize() { savePasswordCheckbox.setSelected(savedPassword.isPresent()); if (password.get() != null) { passwordField.setPassword(password.get()); } unlockButtonDisabled.bind(userInteractionDisabled.or(passwordField.textProperty().isEmpty())); + + var leftArmTranslation = new Translate(24, 0); + var leftArmRotation = new Rotate(60, 16, 30, 0); + var leftArmRetracted = new KeyValue(leftArmTranslation.xProperty(), 24); + var leftArmExtended = new KeyValue(leftArmTranslation.xProperty(), 0.0); + var leftArmHorizontal = new KeyValue(leftArmRotation.angleProperty(), 60, Interpolator.EASE_OUT); + var leftArmHanging = new KeyValue(leftArmRotation.angleProperty(), 0); + leftArm.getTransforms().setAll(leftArmTranslation, leftArmRotation); + + var rightArmTranslation = new Translate(-24, 0); + var rightArmRotation = new Rotate(60, 48, 30, 0); + var rightArmRetracted = new KeyValue(rightArmTranslation.xProperty(), -24); + var rightArmExtended = new KeyValue(rightArmTranslation.xProperty(), 0.0); + var rightArmHorizontal = new KeyValue(rightArmRotation.angleProperty(), -60); + var rightArmHanging = new KeyValue(rightArmRotation.angleProperty(), 0, Interpolator.EASE_OUT); + rightArm.getTransforms().setAll(rightArmTranslation, rightArmRotation); + + var legsRetractedY = new KeyValue(legs.scaleYProperty(), 0); + var legsExtendedY = new KeyValue(legs.scaleYProperty(), 1, Interpolator.EASE_OUT); + var legsRetractedX = new KeyValue(legs.scaleXProperty(), 0); + var legsExtendedX = new KeyValue(legs.scaleXProperty(), 1, Interpolator.EASE_OUT); + legs.setScaleY(0); + legs.setScaleX(0); + + var faceHidden = new KeyValue(face.opacityProperty(), 0.0); + var faceVisible = new KeyValue(face.opacityProperty(), 1.0, Interpolator.LINEAR); + face.setOpacity(0); + + unlockAnimation = new Timeline( + new KeyFrame(Duration.ZERO, leftArmRetracted, leftArmHorizontal, rightArmRetracted, rightArmHorizontal, legsRetractedY, legsRetractedX, faceHidden), + new KeyFrame(Duration.millis(200), leftArmExtended, leftArmHorizontal, rightArmRetracted, rightArmHorizontal), + new KeyFrame(Duration.millis(400), leftArmExtended, leftArmHanging, rightArmExtended, rightArmHorizontal), + new KeyFrame(Duration.millis(600), leftArmExtended, leftArmHanging, rightArmExtended, rightArmHanging), + new KeyFrame(Duration.millis(800), legsExtendedY, legsExtendedX, faceHidden), + new KeyFrame(Duration.millis(1000), faceVisible) + ); + + passwordEntryLock.awaitingInteraction().addListener(observable -> stopUnlockAnimation()); } @FXML @@ -88,6 +143,23 @@ public class UnlockController implements FxController { Arrays.fill(oldPw, ' '); } passwordEntryLock.interacted(UnlockModule.PasswordEntry.PASSWORD_ENTERED); + startUnlockAnimation(); + } + + private void startUnlockAnimation() { + leftArm.setVisible(true); + rightArm.setVisible(true); + legs.setVisible(true); + face.setVisible(true); + unlockAnimation.playFromStart(); + } + + private void stopUnlockAnimation() { + unlockAnimation.stop(); + leftArm.setVisible(false); + rightArm.setVisible(false); + legs.setVisible(false); + face.setVisible(false); } /* Save Password */ diff --git a/main/ui/src/main/resources/fxml/addvault_welcome.fxml b/main/ui/src/main/resources/fxml/addvault_welcome.fxml index 78fef4647..1639beac4 100644 --- a/main/ui/src/main/resources/fxml/addvault_welcome.fxml +++ b/main/ui/src/main/resources/fxml/addvault_welcome.fxml @@ -21,7 +21,7 @@ - + diff --git a/main/ui/src/main/resources/fxml/preferences_about.fxml b/main/ui/src/main/resources/fxml/preferences_about.fxml index d388663e5..ba738f25e 100644 --- a/main/ui/src/main/resources/fxml/preferences_about.fxml +++ b/main/ui/src/main/resources/fxml/preferences_about.fxml @@ -18,7 +18,7 @@ - + diff --git a/main/ui/src/main/resources/fxml/unlock.fxml b/main/ui/src/main/resources/fxml/unlock.fxml index 099a04148..331eeade8 100644 --- a/main/ui/src/main/resources/fxml/unlock.fxml +++ b/main/ui/src/main/resources/fxml/unlock.fxml @@ -5,6 +5,10 @@ + + + + @@ -19,11 +23,34 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/main/ui/src/main/resources/fxml/vault_detail_welcome.fxml b/main/ui/src/main/resources/fxml/vault_detail_welcome.fxml index 50ba0c3c6..d9b6ca9fc 100644 --- a/main/ui/src/main/resources/fxml/vault_detail_welcome.fxml +++ b/main/ui/src/main/resources/fxml/vault_detail_welcome.fxml @@ -11,8 +11,8 @@ spacing="24"> + - diff --git a/main/ui/src/main/resources/img/bot/arm-l.png b/main/ui/src/main/resources/img/bot/arm-l.png new file mode 100644 index 000000000..ecaab44f1 Binary files /dev/null and b/main/ui/src/main/resources/img/bot/arm-l.png differ diff --git a/main/ui/src/main/resources/img/bot/arm-l@2x.png b/main/ui/src/main/resources/img/bot/arm-l@2x.png new file mode 100644 index 000000000..77f9cbf0f Binary files /dev/null and b/main/ui/src/main/resources/img/bot/arm-l@2x.png differ diff --git a/main/ui/src/main/resources/img/bot/arm-r.png b/main/ui/src/main/resources/img/bot/arm-r.png new file mode 100644 index 000000000..c30d8328f Binary files /dev/null and b/main/ui/src/main/resources/img/bot/arm-r.png differ diff --git a/main/ui/src/main/resources/img/bot/arm-r@2x.png b/main/ui/src/main/resources/img/bot/arm-r@2x.png new file mode 100644 index 000000000..cbcfdf03c Binary files /dev/null and b/main/ui/src/main/resources/img/bot/arm-r@2x.png differ diff --git a/main/ui/src/main/resources/img/bot/body.png b/main/ui/src/main/resources/img/bot/body.png new file mode 100644 index 000000000..a473413e6 Binary files /dev/null and b/main/ui/src/main/resources/img/bot/body.png differ diff --git a/main/ui/src/main/resources/img/bot/body@2x.png b/main/ui/src/main/resources/img/bot/body@2x.png new file mode 100644 index 000000000..bbf91b292 Binary files /dev/null and b/main/ui/src/main/resources/img/bot/body@2x.png differ diff --git a/main/ui/src/main/resources/img/bot.png b/main/ui/src/main/resources/img/bot/bot.png similarity index 100% rename from main/ui/src/main/resources/img/bot.png rename to main/ui/src/main/resources/img/bot/bot.png diff --git a/main/ui/src/main/resources/img/bot@2x.png b/main/ui/src/main/resources/img/bot/bot@2x.png similarity index 100% rename from main/ui/src/main/resources/img/bot@2x.png rename to main/ui/src/main/resources/img/bot/bot@2x.png diff --git a/main/ui/src/main/resources/img/bot/face.png b/main/ui/src/main/resources/img/bot/face.png new file mode 100644 index 000000000..d2aa5bb85 Binary files /dev/null and b/main/ui/src/main/resources/img/bot/face.png differ diff --git a/main/ui/src/main/resources/img/bot/face@2x.png b/main/ui/src/main/resources/img/bot/face@2x.png new file mode 100644 index 000000000..706fd4136 Binary files /dev/null and b/main/ui/src/main/resources/img/bot/face@2x.png differ diff --git a/main/ui/src/main/resources/img/bot/legs.png b/main/ui/src/main/resources/img/bot/legs.png new file mode 100644 index 000000000..e53152382 Binary files /dev/null and b/main/ui/src/main/resources/img/bot/legs.png differ diff --git a/main/ui/src/main/resources/img/bot/legs@2x.png b/main/ui/src/main/resources/img/bot/legs@2x.png new file mode 100644 index 000000000..a467939ec Binary files /dev/null and b/main/ui/src/main/resources/img/bot/legs@2x.png differ