From aa53bfea4b388b8715a1f2fd496cc82bcac06cec Mon Sep 17 00:00:00 2001 From: crschnick Date: Mon, 27 Jan 2025 01:22:07 +0000 Subject: [PATCH] Fixes --- README.md | 2 +- .../java/io/xpipe/app/core/mode/BaseMode.java | 1 + .../io/xpipe/app/icon/SystemIconManager.java | 20 ++++++++++-- .../io/xpipe/app/icon/SystemIconSource.java | 18 ++++++++++- .../java/io/xpipe/app/prefs/AppPrefs.java | 3 +- .../io/xpipe/app/prefs/IconsCategory.java | 31 +++++++++++++++---- .../io/xpipe/app/storage/DataStorage.java | 4 +++ 7 files changed, 66 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 77e803309..1ef525db2 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ XPipe fully integrates with your tools such as your favourite text/code editors, It currently supports: - [SSH](https://www.ssh.com/academy/ssh/protocol) connections, config files, and tunnels -- [Docker](https://www.docker.com/), [Podman](https://podman.io/), LXD](https://linuxcontainers.org/lxd/introduction/), and [incus](https://linuxcontainers.org/incus/) container instances located on any host +- [Docker](https://www.docker.com/), [Podman](https://podman.io/), [LXD](https://linuxcontainers.org/lxd/introduction/), and [incus](https://linuxcontainers.org/incus/) container instances located on any host - [Proxmox PVE](https://www.proxmox.com/en/proxmox-virtual-environment/overview) virtual machines and containers - [Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/about/), [KVM/QEMU](https://linux-kvm.org/page/Main_Page), [VMware Player/Workstation/Fusion](https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion) virtual machines - [Kubernetes](https://kubernetes.io/) clusters, pods, and containers diff --git a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java index 4e66a5b4c..61a35c57a 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java @@ -134,6 +134,7 @@ public class BaseMode extends OperationMode { PlatformInit.init(true); AppImages.init(); imagesLoaded.countDown(); + storageLoaded.await(); SystemIconManager.init(); }, () -> { diff --git a/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java b/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java index 5b4020bee..baaccc3c0 100644 --- a/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java +++ b/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java @@ -4,6 +4,7 @@ import io.xpipe.app.core.AppProperties; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.resources.AppImages; +import io.xpipe.app.storage.DataStorage; import java.nio.file.Files; import java.nio.file.Path; @@ -16,6 +17,19 @@ public class SystemIconManager { private static final Map LOADED = new HashMap<>(); private static final Set ICONS = new HashSet<>(); + public static List getEffectiveSources() { + var prefs = AppPrefs.get().getIconSources().getValue(); + var all = new ArrayList(); + all.add(SystemIconSource.Directory.builder().path(DataStorage.get().getIconsDir()).id("custom").build()); + all.add(SystemIconSource.GitRepository.builder().remote("https://github.com/selfhst/icons").id("selfhst").build()); + for (var pref : prefs) { + if (!all.contains(pref)) { + all.add(pref); + } + } + return all; + } + public static Map getSources() { return LOADED; } @@ -38,7 +52,7 @@ public class SystemIconManager { Files.createDirectories(DIRECTORY); LOADED.clear(); - for (var source : AppPrefs.get().getIconSources().getValue()) { + for (var source : getEffectiveSources()) { LOADED.put(source,SystemIconSourceData.of(source)); } @@ -54,7 +68,7 @@ public class SystemIconManager { public static void reloadImages() { AppImages.remove(s -> s.startsWith("icons/")); try { - for (var source : AppPrefs.get().getIconSources().getValue()) { + for (var source : getEffectiveSources()) { AppImages.loadRasterImages(SystemIconCache.getDirectory(source), "icons/" + source.getId()); } } catch (Exception e) { @@ -64,7 +78,7 @@ public class SystemIconManager { public static synchronized void reload() throws Exception { Files.createDirectories(DIRECTORY); - for (var source : AppPrefs.get().getIconSources().getValue()) { + for (var source : getEffectiveSources()) { source.refresh(); } reloadSources(); diff --git a/app/src/main/java/io/xpipe/app/icon/SystemIconSource.java b/app/src/main/java/io/xpipe/app/icon/SystemIconSource.java index 6935d5855..0d8049087 100644 --- a/app/src/main/java/io/xpipe/app/icon/SystemIconSource.java +++ b/app/src/main/java/io/xpipe/app/icon/SystemIconSource.java @@ -7,6 +7,7 @@ import io.xpipe.app.ext.ProcessControlProvider; import io.xpipe.app.util.DesktopHelper; import io.xpipe.app.util.Hyperlinks; import io.xpipe.core.process.CommandBuilder; +import io.xpipe.core.store.FileNames; import lombok.Builder; import lombok.Value; import lombok.extern.jackson.Jacksonized; @@ -32,7 +33,9 @@ public interface SystemIconSource { String id; @Override - public void refresh() throws Exception {} + public void refresh() throws Exception { + Files.createDirectories(path); + } @Override public Path getPath() { @@ -44,6 +47,11 @@ public interface SystemIconSource { return "mdi2f-folder"; } + @Override + public String getDisplayName() { + return path.getFileName().toString(); + } + @Override public String getDescription() { return path.toString(); @@ -51,6 +59,7 @@ public interface SystemIconSource { @Override public void open() throws Exception { + Files.createDirectories(path); DesktopHelper.browsePathLocal(path); } } @@ -86,6 +95,11 @@ public interface SystemIconSource { return "mdi2g-git"; } + @Override + public String getDisplayName() { + return FileNames.getFileName(remote); + } + @Override public String getDescription() { return "Git repository " + remote; @@ -105,6 +119,8 @@ public interface SystemIconSource { String getIcon(); + String getDisplayName(); + String getDescription(); void open() throws Exception; 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 7b2d73bbe..5a56f642d 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java +++ b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java @@ -80,8 +80,7 @@ public class AppPrefs { final BooleanProperty clearTerminalOnInit = mapLocal(new SimpleBooleanProperty(true), "clearTerminalOnInit", Boolean.class, false); final Property> iconSources = map(Mapping.builder() - .property(new SimpleObjectProperty<>(new ArrayList<>(List.of( - SystemIconSource.GitRepository.builder().remote("https://github.com/selfhst/icons").id("selfhst").build())))) + .property(new SimpleObjectProperty<>(new ArrayList<>())) .key("iconSources") .valueType(TypeFactory.defaultInstance().constructType(new TypeReference>() {})) .build()); diff --git a/app/src/main/java/io/xpipe/app/prefs/IconsCategory.java b/app/src/main/java/io/xpipe/app/prefs/IconsCategory.java index cd5f26184..e4e0c615f 100644 --- a/app/src/main/java/io/xpipe/app/prefs/IconsCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/IconsCategory.java @@ -24,6 +24,7 @@ import javafx.scene.control.TextField; import org.kordamp.ikonli.javafx.FontIcon; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -49,9 +50,9 @@ public class IconsCategory extends AppPrefsCategory { private Comp createOverview() { var sources = FXCollections.observableArrayList(); AppPrefs.get().getIconSources().subscribe((newValue) -> { - sources.setAll(newValue); + sources.setAll(SystemIconManager.getEffectiveSources()); }); - var box = new ListBoxViewComp<>(sources, sources, s -> createSourceEntry(s), true); + var box = new ListBoxViewComp<>(sources, sources, s -> createSourceEntry(s, sources), true); var busy = new SimpleBooleanProperty(false); var refreshButton = new TileButtonComp("refreshSources", "refreshSourcesDescription", "mdi2r-refresh", e -> { @@ -81,7 +82,12 @@ public class IconsCategory extends AppPrefsCategory { } var source = SystemIconSource.GitRepository.builder().remote(remote.get()).id(UUID.randomUUID().toString()).build(); - sources.add(source); + if (!sources.contains(source)) { + sources.add(source); + var nl = new ArrayList<>(AppPrefs.get().getIconSources().getValue()); + nl.add(source); + AppPrefs.get().iconSources.setValue(nl); + } }); modal.show(); e.consume(); @@ -99,7 +105,12 @@ public class IconsCategory extends AppPrefsCategory { } var source = SystemIconSource.Directory.builder().path(Path.of(dir.get())).id(UUID.randomUUID().toString()).build(); - sources.add(source); + if (!sources.contains(source)) { + sources.add(source); + var nl = new ArrayList<>(AppPrefs.get().getIconSources().getValue()); + nl.add(source); + AppPrefs.get().iconSources.setValue(nl); + } }); modal.show(); e.consume(); @@ -111,17 +122,25 @@ public class IconsCategory extends AppPrefsCategory { return vbox; } - private Comp createSourceEntry(SystemIconSource source) { + private Comp createSourceEntry(SystemIconSource source, List sources) { var delete = new IconButtonComp(new LabelGraphic.IconGraphic("mdal-delete_outline"), () -> { if (!AppDialog.confirm("iconSourceDeletion")) { return; } + var nl = new ArrayList<>(AppPrefs.get().getIconSources().getValue()); + nl.remove(source); + AppPrefs.get().iconSources.setValue(nl); + sources.remove(source); }); var buttons = new HorizontalComp(List.of(delete)); buttons.spacing(5); + if (!AppPrefs.get().getIconSources().getValue().contains(source)) { + buttons.disable(new SimpleBooleanProperty(true)); + } + var tile = new TileButtonComp( - new SimpleStringProperty(source.getId()), + new SimpleStringProperty(AppPrefs.get().getIconSources().getValue().contains(source) ? source.getDisplayName() : source.getId()), new SimpleStringProperty(source.getDescription()), new SimpleObjectProperty<>(source.getIcon()), actionEvent -> { diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index 40f1cb4b7..55d7980de 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -252,6 +252,10 @@ public abstract class DataStorage { return dir.resolve("data"); } + public Path getIconsDir() { + return dir.resolve("icons"); + } + protected Path getCategoriesDir() { return dir.resolve("categories"); }