From 72bda5ae63b79c14fd19c314d6bb4326a4d6a05f Mon Sep 17 00:00:00 2001 From: crschnick Date: Thu, 4 Apr 2024 09:08:59 +0000 Subject: [PATCH] More display fixes --- .../app/browser/BrowserGreetingComp.java | 7 ++-- .../app/comp/store/StoreCategoryWrapper.java | 38 +++++++++++++++---- .../xpipe/app/comp/store/StoreEntryComp.java | 3 +- .../comp/store/StoreEntryListStatusComp.java | 3 +- .../xpipe/app/comp/store/StoreViewState.java | 2 +- .../io/xpipe/app/core/AppLayoutModel.java | 19 +++------- .../app/fxcomps/impl/StoreCategoryComp.java | 2 +- .../xpipe/app/prefs/AppearanceCategory.java | 21 +++++++++- .../xpipe/app/resources/style/header-bars.css | 16 ++++---- .../io/xpipe/app/resources/style/style.css | 12 +----- lang/app/strings/translations_de.properties | 9 +++-- lang/app/strings/translations_en.properties | 11 +++++- 12 files changed, 90 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserGreetingComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserGreetingComp.java index 2041ce02f..3fe6ba9fe 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserGreetingComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserGreetingComp.java @@ -2,6 +2,7 @@ package io.xpipe.app.browser; import atlantafx.base.theme.Styles; import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppLayoutModel; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.util.PlatformThread; @@ -30,11 +31,11 @@ public class BrowserGreetingComp extends SimpleComp { var hour = ldt.getHour(); String text; if (hour > 18 || hour < 5) { - text = "Good evening"; + text = AppI18n.get("goodEvening"); } else if (hour < 12) { - text = "Good morning"; + text = AppI18n.get("goodMorning"); } else { - text = "Good afternoon"; + text = AppI18n.get("goodAfternoon"); } return text; } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java index d09c643bc..9d48725a0 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java @@ -1,5 +1,6 @@ package io.xpipe.app.comp.store; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; @@ -80,6 +81,10 @@ public class StoreCategoryWrapper { private void setupListeners() { name.addListener((c, o, n) -> { + if (n.equals(translatedName(category.getName()))) { + return; + } + category.setName(n); }); @@ -91,6 +96,10 @@ public class StoreCategoryWrapper { update(); }); + AppPrefs.get().language().addListener((observable, oldValue, newValue) -> { + update(); + }); + sortMode.addListener((observable, oldValue, newValue) -> { category.setSortMode(newValue); }); @@ -112,8 +121,9 @@ public class StoreCategoryWrapper { public void update() { // Avoid reupdating name when changed from the name property! - if (!category.getName().equals(name.getValue())) { - name.setValue(category.getName()); + var catName = translatedName(category.getName()); + if (!catName.equals(name.getValue())) { + name.setValue(catName); } lastAccess.setValue(category.getLastAccess().minus(Duration.ofMillis(500))); @@ -140,18 +150,30 @@ public class StoreCategoryWrapper { }); } - public String getName() { - return name.getValue(); + private String translatedName(String original) { + if (original.equals("All connections")) { + return AppI18n.get("allConnections"); + } + if (original.equals("All scripts")) { + return AppI18n.get("allScripts"); + } + if (original.equals("Predefined")) { + return AppI18n.get("predefined"); + } + if (original.equals("Custom")) { + return AppI18n.get("custom"); + } + if (original.equals("Default")) { + return AppI18n.get("default"); + } + + return original; } public Property nameProperty() { return name; } - public Instant getLastAccess() { - return lastAccess.getValue(); - } - public Property lastAccessProperty() { return lastAccess; } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java index b93d23326..e9348cd68 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java @@ -368,7 +368,8 @@ public abstract class StoreEntryComp extends SimpleComp { StoreViewState.get() .getSortedCategories(wrapper.getCategory().getValue().getRoot()) .forEach(storeCategoryWrapper -> { - MenuItem m = new MenuItem(storeCategoryWrapper.getName()); + MenuItem m = new MenuItem(); + m.textProperty().bind(storeCategoryWrapper.nameProperty()); m.setOnAction(event -> { wrapper.moveTo(storeCategoryWrapper.getCategory()); event.consume(); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java index e799a442e..d2412f1bd 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java @@ -126,7 +126,8 @@ public class StoreEntryListStatusComp extends SimpleComp { } private Region createButtons() { - var menu = new MenuButton(AppI18n.get("addConnections"), new FontIcon("mdi2p-plus-thick")); + var menu = new MenuButton(null, new FontIcon("mdi2p-plus-thick")); + menu.textProperty().bind(AppI18n.observable("addConnections")); menu.setAlignment(Pos.CENTER); menu.setTextAlignment(TextAlignment.CENTER); AppFont.medium(menu); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java b/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java index cc5b80337..f08b2e4ad 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java @@ -270,7 +270,7 @@ public class StoreViewState { return parent; } - return o1.getName().compareToIgnoreCase(o2.getName()); + return o1.nameProperty().getValue().compareToIgnoreCase(o2.nameProperty().getValue()); } }; return ListBindingsHelper.filteredContentBinding( diff --git a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java index 91f17b93b..b15f8dda2 100644 --- a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java +++ b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java @@ -2,7 +2,6 @@ package io.xpipe.app.core; import io.xpipe.app.browser.BrowserComp; import io.xpipe.app.browser.BrowserModel; -import io.xpipe.app.comp.DeveloperTabComp; import io.xpipe.app.comp.store.StoreLayoutComp; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.prefs.AppPrefsComp; @@ -74,19 +73,11 @@ public class AppLayoutModel { var l = new ArrayList<>(List.of( new Entry(AppI18n.observable("browser"), "mdi2f-file-cabinet", new BrowserComp(BrowserModel.DEFAULT)), new Entry(AppI18n.observable("connections"), "mdi2c-connection", new StoreLayoutComp()), - new Entry(AppI18n.observable("settings"), "mdsmz-miscellaneous_services", new AppPrefsComp()))); - // new SideMenuBarComp.Entry(AppI18n.observable("help"), "mdi2b-book-open-variant", new - // StorageLayoutComp()), - // new SideMenuBarComp.Entry(AppI18n.observable("account"), "mdi2a-account", new StorageLayoutComp()) - if (AppProperties.get().isDeveloperMode() && !AppProperties.get().isImage()) { - l.add(new Entry(AppI18n.observable("developer"), "mdi2b-book-open-variant", new DeveloperTabComp())); - } - - l.add(new Entry( - AppI18n.observable("explorePlans"), - "mdi2p-professional-hexagon", - LicenseProvider.get().overviewPage())); - + new Entry(AppI18n.observable("settings"), "mdsmz-miscellaneous_services", new AppPrefsComp()), + new Entry( + AppI18n.observable("explorePlans"), + "mdi2p-professional-hexagon", + LicenseProvider.get().overviewPage()))); return l; } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java index f493d02cb..6620ec31c 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java @@ -106,7 +106,7 @@ public class StoreCategoryComp extends SimpleComp { var l = category.getChildren() .sorted(Comparator.comparing( - storeCategoryWrapper -> storeCategoryWrapper.getName().toLowerCase(Locale.ROOT))); + storeCategoryWrapper -> storeCategoryWrapper.nameProperty().getValue().toLowerCase(Locale.ROOT))); var children = new ListBoxViewComp<>(l, l, storeCategoryWrapper -> new StoreCategoryComp(storeCategoryWrapper)); var emptyBinding = Bindings.isEmpty(category.getChildren()); diff --git a/app/src/main/java/io/xpipe/app/prefs/AppearanceCategory.java b/app/src/main/java/io/xpipe/app/prefs/AppearanceCategory.java index 896a448ca..6cc2880a8 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AppearanceCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/AppearanceCategory.java @@ -2,14 +2,21 @@ package io.xpipe.app.prefs; import atlantafx.base.controls.ProgressSliderSkin; import atlantafx.base.theme.Styles; +import io.xpipe.app.comp.base.ButtonComp; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppTheme; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.impl.ChoiceComp; +import io.xpipe.app.fxcomps.impl.HorizontalComp; import io.xpipe.app.fxcomps.impl.IntFieldComp; +import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.OptionsBuilder; +import javafx.geometry.Pos; import javafx.scene.control.Slider; +import org.kordamp.ikonli.javafx.FontIcon; import java.util.Arrays; +import java.util.List; public class AppearanceCategory extends AppPrefsCategory { @@ -18,6 +25,18 @@ public class AppearanceCategory extends AppPrefsCategory { return "appearance"; } + private Comp languageChoice() { + var prefs = AppPrefs.get(); + var c = ChoiceComp.ofTranslatable(prefs.language, Arrays.asList(SupportedLocale.values()), false); + var visit = new ButtonComp(AppI18n.observable("translate"), new FontIcon("mdi2w-web"), () -> { + Hyperlinks.open(Hyperlinks.TRANSLATE); + }); + return new HorizontalComp(List.of(c, visit)).apply(struc -> { + struc.get().setAlignment(Pos.CENTER_LEFT); + struc.get().setSpacing(10); + }); + } + @Override protected Comp create() { var prefs = AppPrefs.get(); @@ -26,7 +45,7 @@ public class AppearanceCategory extends AppPrefsCategory { .sub(new OptionsBuilder() .nameAndDescription("language") .addComp( - ChoiceComp.ofTranslatable(prefs.language, Arrays.asList(SupportedLocale.values()), false), + languageChoice(), prefs.language) .nameAndDescription("theme") .addComp( diff --git a/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css b/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css index 796d4b334..a40eb5d41 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css @@ -43,11 +43,6 @@ -fx-background-color: linear-gradient(from 100% 0% to 0% 100%, rgb(12, 11, 11) 40%, rgb(32, 32, 40) 50%, rgb(35, 29, 29) 100%); } -.store-header-bar .menu-button:hover, .root:key-navigation .store-header-bar .menu-button:focused { - -fx-background-color: -color-bg-default; - -fx-border-color: -color-fg-default; -} - .store-header-bar .menu-button > * { -fx-text-fill: -color-bg-default; } @@ -61,15 +56,20 @@ -fx-border-width: 4; } -.store-header-bar .menu-button:hover > *, .root:key-navigation .store-header-bar .menu-button:focused > * { +.root .store-header-bar .menu-button:hover, .root:key-navigation .store-header-bar .menu-button:focused { + -fx-background-color: -color-bg-default; + -fx-border-color: -color-fg-default; +} + +.root .store-header-bar .menu-button:hover > *, .root:key-navigation .store-header-bar .menu-button:focused > * { -fx-text-fill: -color-fg-default; } -.store-header-bar .menu-button:hover > * > .ikonli-font-icon, .root:key-navigation .store-header-bar .menu-button:focused > * > .ikonli-font-icon { +.root .store-header-bar .menu-button:hover > * > .ikonli-font-icon, .root:key-navigation .store-header-bar .menu-button:focused > * > .ikonli-font-icon { -fx-icon-color: -color-fg-default; } -.store-header-bar .menu-button:hover .arrow, .root:key-navigation .store-header-bar .menu-button:focused .arrow { +.root .store-header-bar .menu-button:hover .arrow, .root:key-navigation .store-header-bar .menu-button:focused .arrow { -fx-border-color: -color-fg-default; -fx-border-width: 4; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/style.css b/app/src/main/resources/io/xpipe/app/resources/style/style.css index 9961de269..c170ce6a9 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/style.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/style.css @@ -2,19 +2,11 @@ -fx-background-color: transparent; } -.root:pretty:dark.background { - -fx-background-color: linear-gradient(from 100% 0% to 0% 100%, derive(-color-bg-default, 5%) 40%, derive(-color-bg-default, 2%) 50%, derive(-color-bg-default, 5%) 100%); -} - -.root:performance:dark.background { +.root:dark.background { -fx-background-color: derive(-color-bg-default, 5%); } -.root:pretty:light.background { - -fx-background-color: linear-gradient(from 100% 0% to 0% 100%, derive(-color-bg-default, -9%) 40%, derive(-color-bg-default, 1%) 50%, derive(-color-bg-default, -9%) 100%); -} - -.root:performance:light.background { +.root:light.background { -fx-background-color: derive(-color-bg-default, -9%); } diff --git a/lang/app/strings/translations_de.properties b/lang/app/strings/translations_de.properties index f50fa23fb..c4dd730fa 100644 --- a/lang/app/strings/translations_de.properties +++ b/lang/app/strings/translations_de.properties @@ -176,7 +176,8 @@ connections=Verbindungen settings=Einstellungen explorePlans=Lizenz help=Hilfe -about=Über +#custom +about=Informationen developer=Entwickler browseFileTitle=Datei durchsuchen browse=Durchsuchen @@ -200,7 +201,8 @@ checkForUpdates=Nach Updates suchen checkForUpdatesDescription=Ein Update herunterladen, wenn es eins gibt lastChecked=Zuletzt geprüft version=Version -build=Version erstellen +#custom +build=Build runtimeVersion=Laufzeitversion virtualMachine=Virtuelle Maschine updateReady=Update installieren @@ -276,7 +278,8 @@ useSystemFont=Systemschriftart verwenden openDataDir=Verzeichnis der Tresordaten openDataDirButton=Datenverzeichnis öffnen openDataDirDescription=Wenn du zusätzliche Dateien, wie z.B. SSH-Schlüssel, systemübergreifend mit deinem Git-Repository synchronisieren möchtest, kannst du sie in das Verzeichnis Speicherdaten legen. Bei allen Dateien, die dort referenziert werden, werden die Dateipfade auf allen synchronisierten Systemen automatisch angepasst. -updates=Aktualisiert +#custom +updates=Updates passwordKey=Passwortschlüssel selectAll=Alles auswählen command=Befehl diff --git a/lang/app/strings/translations_en.properties b/lang/app/strings/translations_en.properties index 94d08f250..1f0f78733 100644 --- a/lang/app/strings/translations_en.properties +++ b/lang/app/strings/translations_en.properties @@ -271,7 +271,7 @@ confirmGitShareTitle=Confirm git sharing confirmGitShareHeader=This will copy the file into your git vault and commit your changes. Do you want to continue? gitShareFileTooltip=Add file to the git vault data directory so that it is automatically synced.\n\nThis action can only be used when the git vault is enabled in the settings. performanceMode=Performance mode -performanceModeDescription=Disables all visual effects that are not required to improve the application performance. +performanceModeDescription=Disables all visual effects that are not required in order to improve the application performance. dontAcceptNewHostKeys=Don't accept new SSH host keys automatically dontAcceptNewHostKeysDescription=XPipe will automatically accept host keys by default from systems where your SSH client has no known host key already saved. If any known host key has changed however, it will refuse to connect unless you accept the new one.\n\nDisabling this behavior allows you to check all host keys, even if there is no conflict initially. uiScale=UI Scale @@ -326,7 +326,7 @@ runOnStartup=Run on startup closeBehaviour=Close behaviour closeBehaviourDescription=Controls how XPipe should proceed upon closing its main window. language=Language -languageDescription=The display language to use.\n\nNote that these use automatic translations as a base and are adapted via contributions. +languageDescription=The display language to use.\n\nNote that these use automatic translations as a base and are manually fixed and improved by contributors. You can also help the translation effort by submitting translation fixes on GitHub. #context: display theme lightTheme=Light Theme #context: display theme @@ -414,3 +414,10 @@ disableTerminalRemotePasswordPreparation=Disable terminal remote password prepar disableTerminalRemotePasswordPreparationDescription=In situations where a remote shell connection that goes through multiple intermediate systems should be established in the terminal, there might be a requirement to prepare any required passwords on one of the intermediate systems to allow for an automatic filling of any prompts.\n\nIf you don't want the passwords to ever be transferred to any intermediate system, you can disable this behavior. Any required intermediate password will then be queried in the terminal itself when opened. more=More translate=Translate +allConnections=All connections +allScripts=All scripts +predefined=Predefined +default=Default +goodMorning=Good morning +goodAfternoon=Good afternoon +goodNight=Good night