diff --git a/app/build.gradle b/app/build.gradle index d571d4342..535a042d9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,7 +66,7 @@ dependencies { exclude group: "com.fasterxml.jackson.dataformat", module: "jackson-dataformat-yaml" } - api "com.github.weisj:jsvg:2.0.1-SNAPSHOT" + api "com.github.weisj:jsvg:1.7.2" api 'io.xpipe:vernacular:1.16' api 'org.bouncycastle:bcprov-jdk18on:1.81' api 'info.picocli:picocli:4.7.7' diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreIconChoiceComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreIconChoiceComp.java index cde2dee8b..96052e137 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreIconChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreIconChoiceComp.java @@ -60,7 +60,7 @@ public class StoreIconChoiceComp extends SimpleComp { } private void initTable(TableView> table) { - if (SystemIconCache.isBuilt()) { + if (!SystemIconManager.isCacheOutdated()) { for (int i = 0; i < columns; i++) { var col = new TableColumn, SystemIcon>("col" + i); final int colIndex = i; @@ -107,6 +107,11 @@ public class StoreIconChoiceComp extends SimpleComp { } private void updateData(TableView> table, String filterString) { + if (SystemIconManager.isCacheOutdated()) { + table.getItems().clear(); + return; + } + var available = icons.stream() .filter(systemIcon -> AppImages.hasNormalImage( "icons/" + systemIcon.getSource().getId() + "/" + systemIcon.getId() + "-40.png")) diff --git a/app/src/main/java/io/xpipe/app/icon/SystemIconCache.java b/app/src/main/java/io/xpipe/app/icon/SystemIconCache.java index 8420d719a..bd657c42e 100644 --- a/app/src/main/java/io/xpipe/app/icon/SystemIconCache.java +++ b/app/src/main/java/io/xpipe/app/icon/SystemIconCache.java @@ -1,5 +1,7 @@ package io.xpipe.app.icon; +import com.github.weisj.jsvg.SVGRenderingHints; +import com.github.weisj.jsvg.attributes.ViewBox; import io.xpipe.app.core.AppProperties; import io.xpipe.app.issue.ErrorEventFactory; import io.xpipe.app.issue.TrackEvent; @@ -7,8 +9,6 @@ import io.xpipe.app.prefs.AppPrefs; import com.github.weisj.jsvg.SVGDocument; import com.github.weisj.jsvg.parser.SVGLoader; -import com.github.weisj.jsvg.renderer.SVGRenderingHints; -import com.github.weisj.jsvg.view.ViewBox; import lombok.Getter; import org.apache.commons.io.FileUtils; @@ -27,27 +27,25 @@ public class SystemIconCache { private static final Path DIRECTORY = AppProperties.get().getDataDir().resolve("cache").resolve("icons").resolve("raster"); private static final int[] sizes = new int[] {16, 24, 40, 80}; - private static final int VERSION = 2; - - @Getter - private static boolean built = false; + public static final int VERSION = 2; public static Path getDirectory(SystemIconSource source) { var target = DIRECTORY.resolve(source.getId()); return target; } - public static void refreshBuilt() throws IOException { - if (!Files.exists(DIRECTORY)) { - return; - } - - try (var stream = Files.walk(DIRECTORY)) { - built = stream.anyMatch(path -> Files.isRegularFile(path)); + public static int getCacheSourceHash() { + try { + var hashFile = DIRECTORY.resolve("sourcehash"); + var hash = Files.exists(hashFile) ? Files.readString(hashFile).strip() : null; + return hash != null ? Integer.parseInt(hash) : 0; + } catch (Exception e) { + ErrorEventFactory.fromThrowable(e).handle(); + return 0; } } - public static void rebuildCache(Map all) { + public static void rebuildCache(Map all, int sourceHash) { try { var versionFile = DIRECTORY.resolve("version"); var version = @@ -61,6 +59,9 @@ public class SystemIconCache { Files.writeString(versionFile, String.valueOf(VERSION)); } + var hashFile = DIRECTORY.resolve("sourcehash"); + Files.writeString(hashFile, String.valueOf(sourceHash)); + for (var e : all.entrySet()) { var target = DIRECTORY.resolve(e.getKey().getId()); Files.createDirectories(target); 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 c23ee7c68..0ccd16d4e 100644 --- a/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java +++ b/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java @@ -19,6 +19,12 @@ public class SystemIconManager { private static final Map LOADED = new HashMap<>(); private static final Set ICONS = new HashSet<>(); + private static int cacheSourceHash; + private static int sourceHash; + + public static boolean isCacheOutdated() { + return cacheSourceHash == 0 || sourceHash != cacheSourceHash; + } public static List getAllSources() { var prefs = AppPrefs.get().getIconSources().getValue(); @@ -82,10 +88,32 @@ public class SystemIconManager { } } + private static synchronized int calculateSourceHash(Map all) { + var total = 0; + var set = false; + for (var e : all.entrySet()) { + for (SystemIconSourceFile icon : e.getValue().getIcons()) { + total += icon.getFile().toString().hashCode(); + set = true; + } + } + + if (set) { + total += AppPrefs.get().preferMonochromeIcons().get() ? 1 : 0; + total += SystemIconCache.VERSION; + } + + return total != 0 ? total : set ? -1 : 0; + } + public static void init() throws Exception { + cacheSourceHash = SystemIconCache.getCacheSourceHash(); reloadSources(); - SystemIconCache.refreshBuilt(); + sourceHash = calculateSourceHash(LOADED); reloadImages(); + AppPrefs.get().preferMonochromeIcons().addListener((observableValue, o, n) -> { + sourceHash = calculateSourceHash(LOADED); + }); } public static void initAdditional() throws Exception { @@ -105,7 +133,7 @@ public class SystemIconManager { } } } - SystemIconCache.refreshBuilt(); + sourceHash = calculateSourceHash(LOADED); } public static synchronized void reloadSources() throws Exception { @@ -146,8 +174,9 @@ public class SystemIconManager { } } reloadSources(); - SystemIconCache.rebuildCache(LOADED); - SystemIconCache.refreshBuilt(); + sourceHash = calculateSourceHash(LOADED); + SystemIconCache.rebuildCache(LOADED, sourceHash); + cacheSourceHash = sourceHash; reloadImages(); } diff --git a/dist/changelog/19.0.md b/dist/changelog/19.0.md index 25b9d7097..dd932a995 100644 --- a/dist/changelog/19.0.md +++ b/dist/changelog/19.0.md @@ -59,6 +59,7 @@ Lastly, there are also now bug bounties available, meaning that you can get an X - Improve caching of various shell operations for speed improvements - Don't accept 7zip drag-and-drop to prevent confusion about non-existent files - Improve browser drag-and-drop to also work on the navigation bar +- The custom icon cache now always registers when it is out of date, prompting you to refresh ## Fixes