mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Rework validation and browser progress
This commit is contained in:
parent
a146fbd936
commit
ba9918e166
25 changed files with 93 additions and 98 deletions
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,7 @@ public final class OpenFileSystemModel extends BrowserSessionTab<FileSystemStore
|
|||
private final OpenFileSystemHistory history = new OpenFileSystemHistory();
|
||||
private final Property<ModalOverlayComp.OverlayContent> overlay = new SimpleObjectProperty<>();
|
||||
private final BooleanProperty inOverview = new SimpleBooleanProperty();
|
||||
private final Property<BrowserTransferProgress> progress =
|
||||
new SimpleObjectProperty<>(BrowserTransferProgress.empty());
|
||||
private final Property<BrowserTransferProgress> progress = new SimpleObjectProperty<>();
|
||||
private FileSystem fileSystem;
|
||||
private OpenFileSystemSavedState savedState;
|
||||
private OpenFileSystemCache cache;
|
||||
|
@ -73,7 +72,7 @@ public final class OpenFileSystemModel extends BrowserSessionTab<FileSystemStore
|
|||
|
||||
@Override
|
||||
public boolean canImmediatelyClose() {
|
||||
return !progress.getValue().done()
|
||||
return (progress.getValue() == null || progress.getValue().done())
|
||||
|| (fileSystem != null
|
||||
&& fileSystem.getShell().isPresent()
|
||||
&& fileSystem.getShell().get().getLock().isLocked());
|
||||
|
|
|
@ -2,13 +2,12 @@ package io.xpipe.app.comp.base;
|
|||
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.fxcomps.impl.StackComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.core.process.OsNameState;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
@ -54,7 +53,7 @@ public class OsLogoComp extends SimpleComp {
|
|||
state);
|
||||
var hide = BindingsHelper.map(img, s -> 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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -31,11 +31,11 @@ public abstract class ScanProvider {
|
|||
String nameKey;
|
||||
boolean disabled;
|
||||
boolean defaultSelected;
|
||||
FailableRunnable<Exception> scanner;
|
||||
FailableRunnable<Throwable> scanner;
|
||||
String licenseFeatureId;
|
||||
|
||||
public ScanOperation(
|
||||
String nameKey, boolean disabled, boolean defaultSelected, FailableRunnable<Exception> scanner) {
|
||||
String nameKey, boolean disabled, boolean defaultSelected, FailableRunnable<Throwable> scanner) {
|
||||
this.nameKey = nameKey;
|
||||
this.disabled = disabled;
|
||||
this.defaultSelected = defaultSelected;
|
||||
|
|
|
@ -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 <T extends ValidationContext<?>> void validate() {
|
||||
public void validate() {
|
||||
try {
|
||||
validateOrThrow(true);
|
||||
validateOrThrow();
|
||||
} catch (Throwable ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends ValidationContext<?>> 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 <T extends ValidationContext<?>> 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<T>) 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 <T> ValidationContext<?> validateOrThrow(boolean close) throws Throwable {
|
||||
public <T> 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<T> context = (ValidationContext<T>) l.createContext();
|
||||
try {
|
||||
((ValidatableStore<ValidationContext<T>>) 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<T> context = existingContext != null ? (ValidationContext<T>) existingContext : (ValidationContext<T>) l.createContext();
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
var r = ((ValidatableStore<ValidationContext<T>>) l).validate(context);
|
||||
return r;
|
||||
} catch (Throwable t) {
|
||||
context.close();
|
||||
throw t;
|
||||
}
|
||||
} finally {
|
||||
decrementBusyCounter();
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ public class ScanAlert {
|
|||
|
||||
try {
|
||||
a.getScanner().run();
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,7 @@ public interface ValidatableStore<T extends ValidationContext<?>> 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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -469,7 +469,7 @@ closeOtherTabs=他のタブを閉じる
|
|||
closeAllTabs=すべてのタブを閉じる
|
||||
closeLeftTabs=タブを左に閉じる
|
||||
closeRightTabs=タブを右に閉じる
|
||||
addSerial=シリアル ...
|
||||
addSerial=シリアル(実験)...
|
||||
connect=接続する
|
||||
workspaces=ワークスペース
|
||||
manageWorkspaces=ワークスペースを管理する
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -469,7 +469,7 @@ closeOtherTabs=Закрыть другие вкладки
|
|||
closeAllTabs=Закрыть все вкладки
|
||||
closeLeftTabs=Закрыть вкладки слева
|
||||
closeRightTabs=Закрывать вкладки справа
|
||||
addSerial=Серийный ...
|
||||
addSerial=Последовательное (экспериментальное) ...
|
||||
connect=Connect
|
||||
workspaces=Рабочие пространства
|
||||
manageWorkspaces=Управляй рабочими пространствами
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -469,7 +469,7 @@ closeOtherTabs=关闭其他标签页
|
|||
closeAllTabs=关闭所有标签页
|
||||
closeLeftTabs=向左关闭标签
|
||||
closeRightTabs=向右关闭标签页
|
||||
addSerial=串行 ...
|
||||
addSerial=串行(实验)...
|
||||
connect=连接
|
||||
workspaces=工作空间
|
||||
manageWorkspaces=管理工作区
|
||||
|
|
Loading…
Reference in a new issue