From ba9918e166fc3a3b013d064805cdbb8f42786451 Mon Sep 17 00:00:00 2001 From: crschnick Date: Sat, 21 Sep 2024 16:54:45 +0000 Subject: [PATCH] Rework validation and browser progress --- .../impl/ConnectionAddExchangeImpl.java | 2 +- .../impl/ConnectionRefreshExchangeImpl.java | 2 +- .../app/browser/BrowserStatusBarComp.java | 6 +- .../app/browser/BrowserTransferProgress.java | 8 -- .../file/BrowserFileTransferOperation.java | 26 +++--- .../app/browser/fs/OpenFileSystemModel.java | 5 +- .../io/xpipe/app/comp/base/OsLogoComp.java | 9 +- .../app/comp/store/StoreCreationComp.java | 5 +- .../java/io/xpipe/app/ext/ScanProvider.java | 4 +- .../io/xpipe/app/storage/DataStoreEntry.java | 87 +++++++++---------- .../java/io/xpipe/app/util/ScanAlert.java | 2 +- .../java/io/xpipe/core/store/ShellStore.java | 6 +- .../io/xpipe/core/store/ValidatableStore.java | 6 +- lang/app/strings/translations_da.properties | 2 +- lang/app/strings/translations_de.properties | 2 +- lang/app/strings/translations_en.properties | 1 + lang/app/strings/translations_es.properties | 2 +- lang/app/strings/translations_fr.properties | 2 +- lang/app/strings/translations_it.properties | 2 +- lang/app/strings/translations_ja.properties | 2 +- lang/app/strings/translations_nl.properties | 2 +- lang/app/strings/translations_pt.properties | 2 +- lang/app/strings/translations_ru.properties | 2 +- lang/app/strings/translations_tr.properties | 2 +- lang/app/strings/translations_zh.properties | 2 +- 25 files changed, 93 insertions(+), 98 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionAddExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionAddExchangeImpl.java index 325f0db3e..7cf0c747f 100644 --- a/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionAddExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionAddExchangeImpl.java @@ -21,7 +21,7 @@ public class ConnectionAddExchangeImpl extends ConnectionAddExchange { try { DataStorage.get().addStoreEntryInProgress(entry); if (msg.getValidate()) { - entry.validateOrThrow(true); + entry.validateOrThrow(); } } catch (Throwable ex) { if (ex instanceof ValidationException) { diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionRefreshExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionRefreshExchangeImpl.java index 6df2edf0a..1b33eee84 100644 --- a/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionRefreshExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionRefreshExchangeImpl.java @@ -17,7 +17,7 @@ public class ConnectionRefreshExchangeImpl extends ConnectionRefreshExchange { if (e.getStore() instanceof FixedHierarchyStore) { DataStorage.get().refreshChildren(e, true); } else { - e.validateOrThrow(true); + e.validateOrThrowAndClose(null); } return Response.builder().build(); } diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserStatusBarComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserStatusBarComp.java index 8d853d5fd..43edfb8e3 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserStatusBarComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserStatusBarComp.java @@ -55,7 +55,7 @@ public class BrowserStatusBarComp extends SimpleComp { private Comp createProgressEstimateStatus() { var text = BindingsHelper.map(model.getProgress(), p -> { - if (p == null || p.done()) { + if (p == null) { return null; } else { var expected = p.expectedTimeRemaining(); @@ -74,7 +74,7 @@ public class BrowserStatusBarComp extends SimpleComp { private Comp createProgressStatus() { var text = BindingsHelper.map(model.getProgress(), p -> { - if (p == null || p.done()) { + if (p == null) { return null; } else { var transferred = HumanReadableFormat.progressByteCount(p.getTransferred()); @@ -91,7 +91,7 @@ public class BrowserStatusBarComp extends SimpleComp { private Comp createProgressNameStatus() { var text = BindingsHelper.map(model.getProgress(), p -> { - if (p == null || p.done()) { + if (p == null) { return null; } else { return p.getName(); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserTransferProgress.java b/app/src/main/java/io/xpipe/app/browser/BrowserTransferProgress.java index bb1e16ec7..7486afdb6 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserTransferProgress.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserTransferProgress.java @@ -14,14 +14,6 @@ public class BrowserTransferProgress { long total; Instant start; - public static BrowserTransferProgress empty() { - return new BrowserTransferProgress(null, 0, 0, Instant.now()); - } - - static BrowserTransferProgress empty(String name, long size) { - return new BrowserTransferProgress(name, 0, size, Instant.now()); - } - public static BrowserTransferProgress finished(String name, long size) { return new BrowserTransferProgress(name, size, size, Instant.now()); } diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java index 65af868aa..6e49f8a4a 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java @@ -102,7 +102,7 @@ public class BrowserFileTransferOperation { public void execute() throws Exception { if (files.isEmpty()) { - updateProgress(BrowserTransferProgress.empty()); + updateProgress(null); return; } @@ -115,18 +115,22 @@ public class BrowserFileTransferOperation { } } - for (var file : files) { - if (same) { - handleSingleOnSameFileSystem(file); - } else { - handleSingleAcrossFileSystems(file); - } - } - - if (!same && doesMove) { + try { for (var file : files) { - deleteSingle(file); + if (same) { + handleSingleOnSameFileSystem(file); + } else { + handleSingleAcrossFileSystems(file); + } } + + if (!same && doesMove) { + for (var file : files) { + deleteSingle(file); + } + } + } finally { + updateProgress(null); } } diff --git a/app/src/main/java/io/xpipe/app/browser/fs/OpenFileSystemModel.java b/app/src/main/java/io/xpipe/app/browser/fs/OpenFileSystemModel.java index 0d70e52ae..ed3792239 100644 --- a/app/src/main/java/io/xpipe/app/browser/fs/OpenFileSystemModel.java +++ b/app/src/main/java/io/xpipe/app/browser/fs/OpenFileSystemModel.java @@ -47,8 +47,7 @@ public final class OpenFileSystemModel extends BrowserSessionTab overlay = new SimpleObjectProperty<>(); private final BooleanProperty inOverview = new SimpleBooleanProperty(); - private final Property progress = - new SimpleObjectProperty<>(BrowserTransferProgress.empty()); + private final Property progress = new SimpleObjectProperty<>(); private FileSystem fileSystem; private OpenFileSystemSavedState savedState; private OpenFileSystemCache cache; @@ -73,7 +72,7 @@ public final class OpenFileSystemModel extends BrowserSessionTab s != null); return new StackComp( - List.of(new SystemStateComp(state).hide(hide), new PrettyImageComp(img, 24, 24).visible(hide))) + List.of(new SystemStateComp(state).hide(hide), PrettyImageHelper.ofFixedSize(img, 24, 24).visible(hide))) .createRegion(); } @@ -70,7 +69,7 @@ public class OsLogoComp extends SimpleComp { && !path.toString().endsWith(LINUX_DEFAULT_24) && !path.toString().endsWith("-40.png")) .map(path -> FileNames.getFileName(path.toString())) .forEach(path -> { - var base = path.replace("-dark", ""); + var base = path.replace("-dark", "").replace("-24.png", ".svg"); ICONS.put(FileNames.getBaseName(base).split("-")[0], "os/" + base); }); } @@ -81,6 +80,6 @@ public class OsLogoComp extends SimpleComp { .filter(e -> name.toLowerCase().contains(e.getKey())) .findAny() .map(e -> e.getValue()) - .orElse("os/linux"); + .orElse("os/linux.svg"); } } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java index 5bf95762a..3f34c7353 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java @@ -322,7 +322,10 @@ public class StoreCreationComp extends DialogComp { try (var ignored = new BooleanScope(busy).start()) { DataStorage.get().addStoreEntryInProgress(entry.getValue()); - var context = entry.getValue().validateOrThrow(false); + var context = entry.getValue().validateAndKeepOpenOrThrowAndClose(null); + if (context == null) { + entry.getValue().validateRefreshChildrenOrThrow(); + } commit(context, true); } catch (Throwable ex) { if (ex instanceof ValidationException) { diff --git a/app/src/main/java/io/xpipe/app/ext/ScanProvider.java b/app/src/main/java/io/xpipe/app/ext/ScanProvider.java index 8bc28c6c9..e7bae26a9 100644 --- a/app/src/main/java/io/xpipe/app/ext/ScanProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/ScanProvider.java @@ -31,11 +31,11 @@ public abstract class ScanProvider { String nameKey; boolean disabled; boolean defaultSelected; - FailableRunnable scanner; + FailableRunnable scanner; String licenseFeatureId; public ScanOperation( - String nameKey, boolean disabled, boolean defaultSelected, FailableRunnable scanner) { + String nameKey, boolean disabled, boolean defaultSelected, FailableRunnable scanner) { this.nameKey = nameKey; this.disabled = disabled; this.defaultSelected = defaultSelected; diff --git a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java index a15c64ed2..d66670c01 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -1,19 +1,18 @@ package io.xpipe.app.storage; -import io.xpipe.app.ext.DataStoreProvider; -import io.xpipe.app.ext.DataStoreProviders; -import io.xpipe.app.issue.ErrorEvent; -import io.xpipe.app.resources.SystemIcons; -import io.xpipe.app.util.FixedHierarchyStore; -import io.xpipe.core.store.*; -import io.xpipe.core.util.JacksonMapper; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.resources.SystemIcons; +import io.xpipe.app.util.FixedHierarchyStore; +import io.xpipe.core.store.*; +import io.xpipe.core.util.JacksonMapper; import lombok.*; import lombok.experimental.NonFinal; import org.apache.commons.io.FileUtils; @@ -496,72 +495,72 @@ public class DataStoreEntry extends StorageElement { dirty = true; } - public > void validate() { + public void validate() { try { - validateOrThrow(true); + validateOrThrow(); } catch (Throwable ex) { ErrorEvent.fromThrowable(ex).handle(); } } - public > void validate(T context) { - try { - validateOrThrow(context); - } catch (Throwable ex) { - ErrorEvent.fromThrowable(ex).handle(); + public void validateOrThrow() throws Throwable { + var r = validateOrThrowAndClose(null); + if (!r) { + validateRefreshChildrenOrThrow(); } } - @SuppressWarnings("unchecked") - public > void validateOrThrow(T context) throws Throwable { - if (store == null) { + public void validateRefreshChildrenOrThrow() throws Throwable { + if (!(store instanceof FixedHierarchyStore h)) { return; } try { store.checkComplete(); incrementBusyCounter(); - if (store instanceof ValidatableStore l) { - ((ValidatableStore) l).validate(context); - } else if (store instanceof FixedHierarchyStore h) { - childrenCache = h.listChildren(this).stream() - .map(DataStoreEntryRef::get) - .collect(Collectors.toSet()); - } + childrenCache = h.listChildren(this).stream() + .map(DataStoreEntryRef::get) + .collect(Collectors.toSet()); } finally { decrementBusyCounter(); } } + public boolean validateOrThrowAndClose(ValidationContext existingContext) throws Throwable { + var subContext = validateAndKeepOpenOrThrowAndClose(existingContext); + if (subContext != null) { + subContext.close(); + return true; + } else { + return false; + } + } + @SuppressWarnings("unchecked") - public ValidationContext validateOrThrow(boolean close) throws Throwable { + public ValidationContext validateAndKeepOpenOrThrowAndClose(ValidationContext existingContext) throws Throwable { if (store == null) { return null; } + if (!(store instanceof ValidatableStore l)) { + return null; + } + try { store.checkComplete(); incrementBusyCounter(); - if (store instanceof ValidatableStore l) { - ValidationContext context = (ValidationContext) l.createContext(); - try { - ((ValidatableStore>) l).validate(context); - } catch (Throwable t) { - context.close(); - throw t; - } - if (close) { - context.close(); - } - return context; - } else if (store instanceof FixedHierarchyStore h) { - childrenCache = h.listChildren(this).stream() - .map(DataStoreEntryRef::get) - .collect(Collectors.toSet()); - return null; - } else { + ValidationContext context = existingContext != null ? (ValidationContext) existingContext : (ValidationContext) l.createContext(); + if (context == null) { return null; } + + try { + var r = ((ValidatableStore>) l).validate(context); + return r; + } catch (Throwable t) { + context.close(); + throw t; + } } finally { decrementBusyCounter(); } diff --git a/app/src/main/java/io/xpipe/app/util/ScanAlert.java b/app/src/main/java/io/xpipe/app/util/ScanAlert.java index 3db18fb49..5ba633d30 100644 --- a/app/src/main/java/io/xpipe/app/util/ScanAlert.java +++ b/app/src/main/java/io/xpipe/app/util/ScanAlert.java @@ -151,7 +151,7 @@ public class ScanAlert { try { a.getScanner().run(); - } catch (Exception ex) { + } catch (Throwable ex) { ErrorEvent.fromThrowable(ex).handle(); } } diff --git a/core/src/main/java/io/xpipe/core/store/ShellStore.java b/core/src/main/java/io/xpipe/core/store/ShellStore.java index 85a40be4c..2292586b4 100644 --- a/core/src/main/java/io/xpipe/core/store/ShellStore.java +++ b/core/src/main/java/io/xpipe/core/store/ShellStore.java @@ -18,16 +18,16 @@ public interface ShellStore extends DataStore, FileSystemStore, ValidatableStore } @Override - default void validate(ShellValidationContext context) throws Exception { + default ShellValidationContext validate(ShellValidationContext context) throws Exception { var c = control(context.get()); if (!isInStorage()) { c.withoutLicenseCheck(); } - try (ShellControl pc = c.start()) {} + return new ShellValidationContext(c.start()); } @Override default ShellValidationContext createContext() throws Exception { - return new ShellValidationContext(control().start()); + return new ShellValidationContext(parentControl().start()); } } diff --git a/core/src/main/java/io/xpipe/core/store/ValidatableStore.java b/core/src/main/java/io/xpipe/core/store/ValidatableStore.java index 48e1f2f2f..3fcde2c13 100644 --- a/core/src/main/java/io/xpipe/core/store/ValidatableStore.java +++ b/core/src/main/java/io/xpipe/core/store/ValidatableStore.java @@ -18,9 +18,7 @@ public interface ValidatableStore> extends DataSt * * @throws Exception if any part of the validation went wrong */ - default void validate(T context) throws Exception {} + T validate(T context) throws Exception; - default T createContext() throws Exception { - return null; - } + T createContext() throws Exception; } diff --git a/lang/app/strings/translations_da.properties b/lang/app/strings/translations_da.properties index d18cebd11..9de7e3471 100644 --- a/lang/app/strings/translations_da.properties +++ b/lang/app/strings/translations_da.properties @@ -488,7 +488,7 @@ closeOtherTabs=Luk andre faner closeAllTabs=Luk alle faner closeLeftTabs=Luk faner til venstre closeRightTabs=Luk faner til højre -addSerial=Seriel ... +addSerial=Seriel (eksperimentel) ... connect=Forbind workspaces=Arbejdsområder manageWorkspaces=Administrer arbejdsområder diff --git a/lang/app/strings/translations_de.properties b/lang/app/strings/translations_de.properties index 74f75bd96..3fc3526dc 100644 --- a/lang/app/strings/translations_de.properties +++ b/lang/app/strings/translations_de.properties @@ -482,7 +482,7 @@ closeOtherTabs=Andere Tabs schließen closeAllTabs=Alle Registerkarten schließen closeLeftTabs=Tabs nach links schließen closeRightTabs=Tabs nach rechts schließen -addSerial=Serielle ... +addSerial=Seriell (Experimentell) ... connect=Verbinden workspaces=Arbeitsbereiche manageWorkspaces=Arbeitsbereiche verwalten diff --git a/lang/app/strings/translations_en.properties b/lang/app/strings/translations_en.properties index 4971cd69d..8de2aefc3 100644 --- a/lang/app/strings/translations_en.properties +++ b/lang/app/strings/translations_en.properties @@ -486,6 +486,7 @@ closeOtherTabs=Close other tabs closeAllTabs=Close all tabs closeLeftTabs=Close tabs to the left closeRightTabs=Close tabs to the right +#context: Serial computer connection addSerial=Serial (Experimental) ... connect=Connect workspaces=Workspaces diff --git a/lang/app/strings/translations_es.properties b/lang/app/strings/translations_es.properties index b7480e1c9..444850eb3 100644 --- a/lang/app/strings/translations_es.properties +++ b/lang/app/strings/translations_es.properties @@ -469,7 +469,7 @@ closeOtherTabs=Cerrar otras pestañas closeAllTabs=Cerrar todas las pestañas closeLeftTabs=Cerrar pestañas a la izquierda closeRightTabs=Cerrar pestañas a la derecha -addSerial=Serie ... +addSerial=Serie (experimental) ... connect=Conecta workspaces=Espacios de trabajo manageWorkspaces=Gestionar espacios de trabajo diff --git a/lang/app/strings/translations_fr.properties b/lang/app/strings/translations_fr.properties index 8f7b980fb..a48927a75 100644 --- a/lang/app/strings/translations_fr.properties +++ b/lang/app/strings/translations_fr.properties @@ -469,7 +469,7 @@ closeOtherTabs=Fermer d'autres onglets closeAllTabs=Fermer tous les onglets closeLeftTabs=Ferme les onglets à gauche closeRightTabs=Ferme les onglets à droite -addSerial=Série ... +addSerial=Série (expérimental) ... connect=Connecter workspaces=Espaces de travail manageWorkspaces=Gérer les espaces de travail diff --git a/lang/app/strings/translations_it.properties b/lang/app/strings/translations_it.properties index aaf8da6db..3380b9ae0 100644 --- a/lang/app/strings/translations_it.properties +++ b/lang/app/strings/translations_it.properties @@ -469,7 +469,7 @@ closeOtherTabs=Chiudere altre schede closeAllTabs=Chiudi tutte le schede closeLeftTabs=Chiudere le schede a sinistra closeRightTabs=Chiudere le schede a destra -addSerial=Seriale ... +addSerial=Seriale (sperimentale) ... connect=Collegare workspaces=Spazi di lavoro manageWorkspaces=Gestire gli spazi di lavoro diff --git a/lang/app/strings/translations_ja.properties b/lang/app/strings/translations_ja.properties index 753657ee0..7b5d3ae36 100644 --- a/lang/app/strings/translations_ja.properties +++ b/lang/app/strings/translations_ja.properties @@ -469,7 +469,7 @@ closeOtherTabs=他のタブを閉じる closeAllTabs=すべてのタブを閉じる closeLeftTabs=タブを左に閉じる closeRightTabs=タブを右に閉じる -addSerial=シリアル ... +addSerial=シリアル(実験)... connect=接続する workspaces=ワークスペース manageWorkspaces=ワークスペースを管理する diff --git a/lang/app/strings/translations_nl.properties b/lang/app/strings/translations_nl.properties index b4abacecc..3a84f498e 100644 --- a/lang/app/strings/translations_nl.properties +++ b/lang/app/strings/translations_nl.properties @@ -469,7 +469,7 @@ closeOtherTabs=Andere tabbladen sluiten closeAllTabs=Alle tabbladen sluiten closeLeftTabs=Tabbladen naar links sluiten closeRightTabs=Tabbladen naar rechts sluiten -addSerial=Serieel ... +addSerial=Serieel (Experimenteel) ... connect=Maak verbinding met workspaces=Werkruimten manageWorkspaces=Werkruimten beheren diff --git a/lang/app/strings/translations_pt.properties b/lang/app/strings/translations_pt.properties index 343c319fa..ac62b4ecb 100644 --- a/lang/app/strings/translations_pt.properties +++ b/lang/app/strings/translations_pt.properties @@ -469,7 +469,7 @@ closeOtherTabs=Fecha outros separadores closeAllTabs=Fecha todos os separadores closeLeftTabs=Fecha os separadores à esquerda closeRightTabs=Fecha os separadores à direita -addSerial=Série ... +addSerial=Série (Experimental) ... connect=Liga-te workspaces=Espaços de trabalho manageWorkspaces=Gere espaços de trabalho diff --git a/lang/app/strings/translations_ru.properties b/lang/app/strings/translations_ru.properties index ad100d0c0..ad879ef92 100644 --- a/lang/app/strings/translations_ru.properties +++ b/lang/app/strings/translations_ru.properties @@ -469,7 +469,7 @@ closeOtherTabs=Закрыть другие вкладки closeAllTabs=Закрыть все вкладки closeLeftTabs=Закрыть вкладки слева closeRightTabs=Закрывать вкладки справа -addSerial=Серийный ... +addSerial=Последовательное (экспериментальное) ... connect=Connect workspaces=Рабочие пространства manageWorkspaces=Управляй рабочими пространствами diff --git a/lang/app/strings/translations_tr.properties b/lang/app/strings/translations_tr.properties index 353c1faca..844d99cc1 100644 --- a/lang/app/strings/translations_tr.properties +++ b/lang/app/strings/translations_tr.properties @@ -470,7 +470,7 @@ closeOtherTabs=Diğer sekmeleri kapatın closeAllTabs=Tüm sekmeleri kapat closeLeftTabs=Sekmeleri sola doğru kapatın closeRightTabs=Sekmeleri sağa doğru kapatın -addSerial=Seri ... +addSerial=Seri (Deneysel) ... connect=Bağlan workspaces=Çalışma Alanları manageWorkspaces=Çalışma alanlarını yönetme diff --git a/lang/app/strings/translations_zh.properties b/lang/app/strings/translations_zh.properties index 6e65c9583..a4027a775 100644 --- a/lang/app/strings/translations_zh.properties +++ b/lang/app/strings/translations_zh.properties @@ -469,7 +469,7 @@ closeOtherTabs=关闭其他标签页 closeAllTabs=关闭所有标签页 closeLeftTabs=向左关闭标签 closeRightTabs=向右关闭标签页 -addSerial=串行 ... +addSerial=串行(实验)... connect=连接 workspaces=工作空间 manageWorkspaces=管理工作区