diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferModel.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferModel.java index 5418145bb..121e73e9a 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferModel.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferModel.java @@ -2,6 +2,7 @@ package io.xpipe.app.browser.file; import io.xpipe.app.browser.BrowserFullSessionModel; import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.util.DesktopHelper; import io.xpipe.app.util.ShellTemp; import io.xpipe.app.util.ThreadHelper; @@ -18,6 +19,7 @@ import org.apache.commons.io.FileUtils; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.ArrayList; @@ -162,7 +164,7 @@ public class BrowserTransferModel { } var files = toMove.stream().map(item -> item.getLocalFile()).toList(); - var downloads = DesktopHelper.getDownloadsDirectory(); + var downloads = getDownloadsTargetDirectory(); Files.createDirectories(downloads); for (Path file : files) { if (!Files.exists(file)) { @@ -183,6 +185,22 @@ public class BrowserTransferModel { DesktopHelper.browseFileInDirectory(downloads.resolve(files.getFirst().getFileName())); } + private Path getDownloadsTargetDirectory() throws Exception { + var def = DesktopHelper.getDownloadsDirectory(); + var custom = AppPrefs.get().downloadsDirectory().getValue(); + if (custom == null || custom.isBlank()) { + return def; + } + + try { + var path = Path.of(custom); + if (Files.isDirectory(path)) { + return path; + } + } catch (InvalidPathException ignored) {} + return def; + } + @Value public static class Item { BrowserFileSystemTabModel openFileSystemModel; diff --git a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java index 3cd40ea8a..616f82acb 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java +++ b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java @@ -126,6 +126,8 @@ public class AppPrefs { new SimpleBooleanProperty(true), "openConnectionSearchWindowOnConnectionCreation", Boolean.class, false); final ObjectProperty storageDirectory = mapLocal(new SimpleObjectProperty<>(DEFAULT_STORAGE_DIR), "storageDirectory", Path.class, true); + final ObjectProperty downloadsDirectory = + mapLocal(new SimpleObjectProperty<>(), "downloadsDirectory", String.class, false); final BooleanProperty confirmAllDeletions = mapLocal(new SimpleBooleanProperty(false), "confirmAllDeletions", Boolean.class, false); final BooleanProperty developerMode = @@ -148,7 +150,7 @@ public class AppPrefs { mapLocal(new SimpleBooleanProperty(false), "requireDoubleClickForConnections", Boolean.class, false); final BooleanProperty enableTerminalDocking = - mapLocal(new SimpleBooleanProperty(true), "enableTerminalDocking", Boolean.class, true); + mapLocal(new SimpleBooleanProperty(true), "enableTerminalDocking", Boolean.class, false); public ObservableBooleanValue requireDoubleClickForConnections() { return requireDoubleClickForConnections; @@ -226,6 +228,7 @@ public class AppPrefs { new SshCategory(), new LocalShellCategory(), new LoggingCategory(), + new FileBrowserCategory(), new SecurityCategory(), new HttpApiCategory(), new WorkflowCategory(), @@ -473,6 +476,10 @@ public class AppPrefs { return storageDirectory; } + public ObservableValue downloadsDirectory() { + return downloadsDirectory; + } + public ObservableValue developerMode() { return System.getProperty(DEVELOPER_MODE_PROP) != null ? new SimpleBooleanProperty(Boolean.parseBoolean(System.getProperty(DEVELOPER_MODE_PROP))) diff --git a/app/src/main/java/io/xpipe/app/prefs/FileBrowserCategory.java b/app/src/main/java/io/xpipe/app/prefs/FileBrowserCategory.java new file mode 100644 index 000000000..2e72e084b --- /dev/null +++ b/app/src/main/java/io/xpipe/app/prefs/FileBrowserCategory.java @@ -0,0 +1,26 @@ +package io.xpipe.app.prefs; + +import io.xpipe.app.comp.Comp; +import io.xpipe.app.util.OptionsBuilder; + +public class FileBrowserCategory extends AppPrefsCategory { + + @Override + protected String getId() { + return "fileBrowser"; + } + + @Override + protected Comp create() { + var prefs = AppPrefs.get(); + return new OptionsBuilder() + .addTitle("fileBrowser") + .sub(new OptionsBuilder() + .pref(prefs.enableTerminalDocking) + .addToggle(prefs.enableTerminalDocking) + .pref(prefs.confirmAllDeletions).addToggle(prefs.confirmAllDeletions) + .pref(prefs.downloadsDirectory) + .addString(prefs.downloadsDirectory)) + .buildComp(); + } +} diff --git a/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java b/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java index 516b54352..bf5941a9f 100644 --- a/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java @@ -62,8 +62,6 @@ public class TerminalCategory extends AppPrefsCategory { .apply(struc -> struc.get().setPromptText("myterminal -e $CMD")) .hide(prefs.terminalType.isNotEqualTo(ExternalTerminalType.CUSTOM))) .addComp(terminalTest) - .pref(prefs.enableTerminalDocking) - .addToggle(prefs.enableTerminalDocking) .hide(new SimpleBooleanProperty(!TerminalView.isSupported())) .pref(prefs.clearTerminalOnInit) .addToggle(prefs.clearTerminalOnInit)) diff --git a/app/src/main/java/io/xpipe/app/prefs/WorkflowCategory.java b/app/src/main/java/io/xpipe/app/prefs/WorkflowCategory.java index 693410ec5..3b39f7652 100644 --- a/app/src/main/java/io/xpipe/app/prefs/WorkflowCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/WorkflowCategory.java @@ -24,8 +24,6 @@ public class WorkflowCategory extends AppPrefsCategory { .addToggle(prefs.openConnectionSearchWindowOnConnectionCreation) .pref(prefs.requireDoubleClickForConnections) .addToggle(prefs.requireDoubleClickForConnections)) - .addTitle("fileBrowser") - .sub(new OptionsBuilder().pref(prefs.confirmAllDeletions).addToggle(prefs.confirmAllDeletions)) .buildComp(); } } diff --git a/app/src/main/resources/io/xpipe/app/resources/img/logo/logo.png b/app/src/main/resources/io/xpipe/app/resources/img/logo/logo.png index 08841c929..304cccc41 100644 Binary files a/app/src/main/resources/io/xpipe/app/resources/img/logo/logo.png and b/app/src/main/resources/io/xpipe/app/resources/img/logo/logo.png differ diff --git a/app/src/main/resources/io/xpipe/app/resources/style/browser.css b/app/src/main/resources/io/xpipe/app/resources/style/browser.css index 8e72efe8c..4d1c2bf18 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/browser.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/browser.css @@ -309,10 +309,14 @@ -fx-background-color: -color-warning-subtle; } -.root.nord .browser .table-row-cell:selected, .root.nord .browser .table-row-cell:hover:selected { +.root:dark.nord .browser .table-row-cell:selected, .root:dark.nord .browser .table-row-cell:hover:selected { -fx-background-color: -color-success-7; } +.root:light.nord .browser .table-row-cell:selected, .root:light.nord .browser .table-row-cell:hover:selected { + -fx-background-color: -color-success-1; +} + .browser .table-row-cell:folder:drag-over { -fx-background-color: -color-success-muted; } 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 11a0e6238..468b7db60 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 @@ -38,6 +38,11 @@ -fx-border-color: transparent; } +.root.nord .store-header-bar .menu-button { + -fx-background-radius: 0; + -fx-border-radius: 0; +} + .root:light .store-header-bar .menu-button { -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%); } @@ -126,6 +131,11 @@ -fx-background-radius: 3px; -fx-background-color: -color-bg-default; -fx-border-color: -color-fg-default; - -fx-border-width: 0.05em; + -fx-border-width: 1; -fx-border-radius: 3px; } + +.root.nord .store-header-bar .filter-bar { + -fx-background-radius: 0; + -fx-border-radius: 0; +} diff --git a/app/src/main/resources/io/xpipe/app/resources/style/prefs.css b/app/src/main/resources/io/xpipe/app/resources/style/prefs.css index 5bd864d78..49660fb4a 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/prefs.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/prefs.css @@ -41,6 +41,11 @@ -fx-background-radius: 4; } +.root.nord .prefs .sidebar { + -fx-border-radius: 0; + -fx-background-radius: 0; +} + .prefs .sidebar .button { -fx-background-color: transparent; -fx-padding: 0.5em 1em 0.5em 1.0em; @@ -48,6 +53,10 @@ -fx-background-insets: 0, 1 4 1 4; } +.root.nord .prefs .sidebar .button { + -fx-background-radius: 0, 0, 0; +} + .prefs .sidebar .button:selected { -fx-background-color: transparent, -color-border-default, -color-bg-default; -fx-font-weight: BOLD; diff --git a/lang/app/strings/translations_da.properties b/lang/app/strings/translations_da.properties index 86872575f..a9464c348 100644 --- a/lang/app/strings/translations_da.properties +++ b/lang/app/strings/translations_da.properties @@ -553,3 +553,5 @@ unpinTab=Fjern fanebladet pinned=Fastgjort enableTerminalDocking=Aktiver terminal-docking enableTerminalDockingDescription=Med terminal-docking kan du docke terminalvinduer til XPipe-applikationsvinduet for at simulere en nogenlunde integreret terminal. Terminalvinduerne styres derefter af XPipe, så de altid passer ind i docken. +downloadsDirectory=Brugerdefineret download-mappe +downloadsDirectoryDescription=Den brugerdefinerede mappe, som downloadede filer skal placeres i, når man klikker på knappen Flyt til downloads. Som standard vil XPipe bruge din brugers download-bibliotek. diff --git a/lang/app/strings/translations_de.properties b/lang/app/strings/translations_de.properties index 3632fe815..f87e39a26 100644 --- a/lang/app/strings/translations_de.properties +++ b/lang/app/strings/translations_de.properties @@ -547,3 +547,5 @@ unpinTab=Registerkarte "Anheften pinned=Angepinnt enableTerminalDocking=St Finn We transmission enableTerminalDockingDescription=Mit Terminal Docking kannst du Terminalfenster an das XPipe-Anwendungsfenster andocken, um ein integriertes Terminal zu simulieren. Κ Finn continues theARotional'93 Veranstə Off extampİ Weṣς +downloadsDirectory=Benutzerdefiniertes Download-Verzeichnis +downloadsDirectoryDescription=Das benutzerdefinierte Verzeichnis, in das heruntergeladene Dateien verschoben werden sollen, wenn du auf die Schaltfläche In Downloads verschieben klickst. Standardmäßig verwendet XPipe dein Benutzer-Download-Verzeichnis. diff --git a/lang/app/strings/translations_en.properties b/lang/app/strings/translations_en.properties index 074576365..d3d3b3953 100644 --- a/lang/app/strings/translations_en.properties +++ b/lang/app/strings/translations_en.properties @@ -553,4 +553,5 @@ unpinTab=Unpin tab pinned=Pinned enableTerminalDocking=Enable terminal docking enableTerminalDockingDescription=With terminal docking you can dock terminal windows to the XPipe application window to simulate a somewhat integrated terminal. The terminal windows are then managed by XPipe to always fit into the dock. -history=History \ No newline at end of file +downloadsDirectory=Custom downloads directory +downloadsDirectoryDescription=The custom directory to put downloaded files into when clicking on the move to downloads button. By default, XPipe will use your user downloads directory. \ No newline at end of file diff --git a/lang/app/strings/translations_es.properties b/lang/app/strings/translations_es.properties index d1a68ec33..991a03684 100644 --- a/lang/app/strings/translations_es.properties +++ b/lang/app/strings/translations_es.properties @@ -534,3 +534,5 @@ unpinTab=Desanclar pestaña pinned=Fijado enableTerminalDocking=Activar el acoplamiento de terminales enableTerminalDockingDescription=Con el acoplamiento de terminales puedes acoplar ventanas de terminal a la ventana de la aplicación XPipe para simular un terminal algo integrado. Las ventanas de terminal son gestionadas por XPipe para que siempre quepan en el acoplamiento. +downloadsDirectory=Directorio de descargas personalizado +downloadsDirectoryDescription=El directorio personalizado en el que colocar los archivos descargados al pulsar el botón mover a descargas. Por defecto, XPipe utilizará tu directorio de descargas de usuario. diff --git a/lang/app/strings/translations_fr.properties b/lang/app/strings/translations_fr.properties index 1dd30c32a..daf805e97 100644 --- a/lang/app/strings/translations_fr.properties +++ b/lang/app/strings/translations_fr.properties @@ -534,3 +534,5 @@ unpinTab=Onglet Unpin pinned=Épinglé enableTerminalDocking=Activer l'ancrage du terminal enableTerminalDockingDescription=Avec l'ancrage de terminal, tu peux ancrer des fenêtres de terminal à la fenêtre de l'application XPipe pour simuler un terminal quelque peu intégré. Les fenêtres du terminal sont alors gérées par XPipe pour toujours tenir dans la station d'accueil. +downloadsDirectory=Répertoire de téléchargements personnalisé +downloadsDirectoryDescription=Le répertoire personnalisé dans lequel placer les fichiers téléchargés lorsqu'on clique sur le bouton déplacer vers les téléchargements. Par défaut, XPipe utilisera le répertoire des téléchargements de l'utilisateur. diff --git a/lang/app/strings/translations_it.properties b/lang/app/strings/translations_it.properties index 94d548344..d2a207807 100644 --- a/lang/app/strings/translations_it.properties +++ b/lang/app/strings/translations_it.properties @@ -534,3 +534,5 @@ unpinTab=Scheda Unpin pinned=Appuntato enableTerminalDocking=Abilita l'aggancio del terminale enableTerminalDockingDescription=Con il docking del terminale puoi agganciare le finestre del terminale alla finestra dell'applicazione XPipe per simulare un terminale integrato. Le finestre del terminale vengono gestite da XPipe in modo da essere sempre inserite nel dock. +downloadsDirectory=Directory di download personalizzata +downloadsDirectoryDescription=La directory personalizzata in cui inserire i file scaricati quando si fa clic sul pulsante sposta nei download. Per impostazione predefinita, XPipe utilizzerà la directory dei download dell'utente. diff --git a/lang/app/strings/translations_ja.properties b/lang/app/strings/translations_ja.properties index 569f8c6a7..44b4a26f4 100644 --- a/lang/app/strings/translations_ja.properties +++ b/lang/app/strings/translations_ja.properties @@ -534,3 +534,5 @@ unpinTab=アンピンタブ pinned=ピン留め enableTerminalDocking=端末のドッキングを有効にする enableTerminalDockingDescription=ターミナルドッキングを使えば、XPipeのアプリケーションウィンドウにターミナルウィンドウをドッキングさせることができる。ターミナルウィンドウはXPipeによって管理され、常にドックに収まる。 +downloadsDirectory=カスタムダウンロードディレクトリ +downloadsDirectoryDescription=ダウンロードに移動ボタンをクリックしたときに、ダウンロードしたファイルを置くカスタムディレクトリ。デフォルトでは、XPipeはユーザーダウンロードディレクトリを使用する。 diff --git a/lang/app/strings/translations_nl.properties b/lang/app/strings/translations_nl.properties index 96f20e43e..93761578b 100644 --- a/lang/app/strings/translations_nl.properties +++ b/lang/app/strings/translations_nl.properties @@ -534,3 +534,5 @@ unpinTab=Tabblad afspelden pinned=Gepend enableTerminalDocking=Terminal docking inschakelen enableTerminalDockingDescription=Met terminal docking kun je terminalvensters in het XPipe toepassingsvenster plaatsen om een enigszins geïntegreerde terminal te simuleren. De terminalvensters worden dan door XPipe beheerd zodat ze altijd in het dock passen. +downloadsDirectory=Aangepaste downloadmap +downloadsDirectoryDescription=De aangepaste map om gedownloade bestanden in te plaatsen als je op de knop Verplaats naar downloads klikt. Standaard gebruikt XPipe je gebruikersdownloadmap. diff --git a/lang/app/strings/translations_pt.properties b/lang/app/strings/translations_pt.properties index 99a55b4d9..4db664e67 100644 --- a/lang/app/strings/translations_pt.properties +++ b/lang/app/strings/translations_pt.properties @@ -534,3 +534,5 @@ unpinTab=Desfixar separador pinned=Fixado enableTerminalDocking=Ativar a ancoragem do terminal enableTerminalDockingDescription=Com o terminal docking podes acoplar janelas de terminal à janela da aplicação XPipe para simular um terminal integrado. As janelas de terminal são então geridas pelo XPipe para caberem sempre na doca. +downloadsDirectory=Diretório de transferências personalizado +downloadsDirectoryDescription=O diretório personalizado para colocar os arquivos baixados ao clicar no botão mover para downloads. Por defeito, o XPipe utiliza o diretório de downloads do utilizador. diff --git a/lang/app/strings/translations_ru.properties b/lang/app/strings/translations_ru.properties index c9e5a57fe..f264ad2ba 100644 --- a/lang/app/strings/translations_ru.properties +++ b/lang/app/strings/translations_ru.properties @@ -534,3 +534,5 @@ unpinTab=Вкладка Unpin pinned=Pinned enableTerminalDocking=Включить стыковку терминалов enableTerminalDockingDescription=С помощью терминальной докировки ты можешь пристыковать окна терминалов к окну приложения XPipe, чтобы имитировать некий интегрированный терминал. Окна терминала управляются XPipe, чтобы всегда помещаться в док. +downloadsDirectory=Пользовательский каталог загрузок +downloadsDirectoryDescription=Пользовательская директория, в которую будут помещаться скачанные файлы при нажатии на кнопку перемещения в загрузки. По умолчанию XPipe будет использовать твой пользовательский каталог загрузок. diff --git a/lang/app/strings/translations_tr.properties b/lang/app/strings/translations_tr.properties index ce423a8d9..a189ce0d6 100644 --- a/lang/app/strings/translations_tr.properties +++ b/lang/app/strings/translations_tr.properties @@ -535,3 +535,5 @@ unpinTab=Sabitleme sekmesini aç pinned=Sabitlendi enableTerminalDocking=Terminal yerleştirmeyi etkinleştir enableTerminalDockingDescription=Terminal kenetleme ile terminal pencerelerini XPipe uygulama penceresine kenetleyerek bir nevi entegre terminal simülasyonu yapabilirsiniz. Terminal pencereleri daha sonra XPipe tarafından her zaman yuvaya sığacak şekilde yönetilir. +downloadsDirectory=Özel indirme dizini +downloadsDirectoryDescription=İndirilen dosyaları indirilenlere taşı düğmesine tıklandığında yerleştirilecek özel dizin. Varsayılan olarak, XPipe kullanıcı indirme dizininizi kullanacaktır. diff --git a/lang/app/strings/translations_zh.properties b/lang/app/strings/translations_zh.properties index 5142aa9e5..7e0236aed 100644 --- a/lang/app/strings/translations_zh.properties +++ b/lang/app/strings/translations_zh.properties @@ -534,3 +534,5 @@ unpinTab=取消固定选项卡 pinned=钉入 enableTerminalDocking=启用终端对接 enableTerminalDockingDescription=使用终端停靠功能,您可以将终端窗口停靠在 XPipe 应用程序窗口上,以模拟集成终端。XPipe会对终端窗口进行管理,使其始终适合停靠。 +downloadsDirectory=自定义下载目录 +downloadsDirectoryDescription=单击 "移动到下载 "按钮时将下载文件放入的自定义目录。默认情况下,XPipe 将使用您的用户下载目录。