mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-05-25 00:38:28 -04:00
Race condition fixes [stage]
This commit is contained in:
@@ -8,6 +8,7 @@ import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.*;
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppFontSizes;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.ext.ShellStore;
|
||||
@@ -19,6 +20,7 @@ import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.scene.layout.Region;
|
||||
@@ -101,14 +103,16 @@ public class BrowserFileChooserSessionComp extends ModalOverlayContentComp {
|
||||
});
|
||||
};
|
||||
|
||||
var bookmarkTopBar = new BrowserConnectionListFilterComp();
|
||||
var category = new SimpleObjectProperty<>(StoreViewState.get().getActiveCategory().getValue());
|
||||
var filter = new SimpleStringProperty();
|
||||
var bookmarkTopBar = new BrowserConnectionListFilterComp(category, filter);
|
||||
var bookmarksList = new BrowserConnectionListComp(
|
||||
BindingsHelper.map(
|
||||
model.getSelectedEntry(), v -> v != null ? v.getEntry().get() : null),
|
||||
applicable,
|
||||
action,
|
||||
bookmarkTopBar.getCategory(),
|
||||
bookmarkTopBar.getFilter());
|
||||
category,
|
||||
filter);
|
||||
var bookmarksContainer = new StackComp(List.of(bookmarksList)).styleClass("bookmarks-container");
|
||||
bookmarksContainer
|
||||
.apply(struc -> {
|
||||
|
||||
@@ -6,15 +6,13 @@ import io.xpipe.app.browser.file.BrowserTransferComp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.AnchorComp;
|
||||
import io.xpipe.app.comp.base.LeftSplitPaneComp;
|
||||
import io.xpipe.app.comp.base.LoadingOverlayComp;
|
||||
import io.xpipe.app.comp.base.StackComp;
|
||||
import io.xpipe.app.comp.base.VerticalComp;
|
||||
import io.xpipe.app.comp.base.*;
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.GlobalTimer;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
@@ -22,12 +20,16 @@ import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
@@ -43,7 +45,7 @@ public class BrowserFullSessionComp extends SimpleComp {
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var vertical = createLeftSide();
|
||||
var left = Comp.of(() -> createLeftSide());
|
||||
|
||||
var leftSplit = new SimpleDoubleProperty();
|
||||
var rightSplit = new SimpleDoubleProperty();
|
||||
@@ -57,7 +59,7 @@ public class BrowserFullSessionComp extends SimpleComp {
|
||||
AnchorPane.setRightAnchor(struc.get(), 0.0);
|
||||
});
|
||||
|
||||
vertical.apply(struc -> {
|
||||
left.apply(struc -> {
|
||||
struc.get()
|
||||
.paddingProperty()
|
||||
.bind(Bindings.createObjectBinding(
|
||||
@@ -74,7 +76,8 @@ public class BrowserFullSessionComp extends SimpleComp {
|
||||
|
||||
var loadingStack = new AnchorComp(List.of(tabs, pinnedStack, loadingIndicator));
|
||||
loadingStack.apply(struc -> struc.get().setPickOnBounds(false));
|
||||
var splitPane = new LeftSplitPaneComp(vertical, loadingStack)
|
||||
var delayedStack = new DelayedInitComp(left, () -> StoreViewState.get() != null && StoreViewState.get().isInitialized());
|
||||
var splitPane = new LeftSplitPaneComp(delayedStack, loadingStack)
|
||||
.withInitialWidth(AppLayoutModel.get().getSavedState().getBrowserConnectionsWidth())
|
||||
.withOnDividerChange(d -> {
|
||||
AppLayoutModel.get().getSavedState().setBrowserConnectionsWidth(d);
|
||||
@@ -104,7 +107,7 @@ public class BrowserFullSessionComp extends SimpleComp {
|
||||
return r;
|
||||
}
|
||||
|
||||
private Comp<CompStructure<VBox>> createLeftSide() {
|
||||
private Region createLeftSide() {
|
||||
Predicate<StoreEntryWrapper> applicable = storeEntryWrapper -> {
|
||||
if (!storeEntryWrapper.getEntry().getValidity().isUsable()) {
|
||||
return false;
|
||||
@@ -131,7 +134,10 @@ public class BrowserFullSessionComp extends SimpleComp {
|
||||
});
|
||||
};
|
||||
|
||||
var bookmarkTopBar = new BrowserConnectionListFilterComp();
|
||||
|
||||
var category = new SimpleObjectProperty<>(StoreViewState.get().getActiveCategory().getValue());
|
||||
var filter = new SimpleStringProperty();
|
||||
var bookmarkTopBar = new BrowserConnectionListFilterComp(category, filter);
|
||||
var bookmarksList = new BrowserConnectionListComp(
|
||||
BindingsHelper.map(
|
||||
model.getSelectedEntry(),
|
||||
@@ -140,8 +146,8 @@ public class BrowserFullSessionComp extends SimpleComp {
|
||||
: null),
|
||||
applicable,
|
||||
action,
|
||||
bookmarkTopBar.getCategory(),
|
||||
bookmarkTopBar.getFilter());
|
||||
category,
|
||||
filter);
|
||||
var bookmarksContainer = new StackComp(List.of(bookmarksList)).styleClass("bookmarks-container");
|
||||
bookmarksContainer
|
||||
.apply(struc -> {
|
||||
@@ -166,9 +172,8 @@ public class BrowserFullSessionComp extends SimpleComp {
|
||||
model.getSelectedEntry())));
|
||||
localDownloadStage.prefHeight(200);
|
||||
localDownloadStage.maxHeight(200);
|
||||
var vertical =
|
||||
new VerticalComp(List.of(bookmarkTopBar, bookmarksContainer, localDownloadStage)).styleClass("left");
|
||||
return vertical;
|
||||
var vertical = new VerticalComp(List.of(bookmarkTopBar, bookmarksContainer, localDownloadStage)).styleClass("left");
|
||||
return vertical.createRegion();
|
||||
}
|
||||
|
||||
private StackComp createSplitStack(SimpleDoubleProperty rightSplit, BrowserSessionTabsComp tabs) {
|
||||
|
||||
@@ -14,16 +14,17 @@ import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public final class BrowserConnectionListFilterComp extends SimpleComp {
|
||||
|
||||
private final Property<StoreCategoryWrapper> category =
|
||||
new SimpleObjectProperty<>(StoreViewState.get().getActiveCategory().getValue());
|
||||
private final Property<String> filter = new SimpleStringProperty();
|
||||
private final Property<StoreCategoryWrapper> category;
|
||||
private final Property<String> filter;
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.util.GlobalTimer;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class DelayedInitComp extends SimpleComp {
|
||||
|
||||
private final Comp<?> comp;
|
||||
private final Supplier<Boolean> condition;
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var stack = new StackPane();
|
||||
GlobalTimer.scheduleUntil(Duration.ofMillis(10), () -> {
|
||||
if (!condition.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
var r = comp.createRegion();
|
||||
stack.getChildren().add(r);
|
||||
});
|
||||
return true;
|
||||
});
|
||||
return stack;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.xpipe.app.comp.store;
|
||||
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.DelayedInitComp;
|
||||
import io.xpipe.app.comp.base.LeftSplitPaneComp;
|
||||
import io.xpipe.app.core.AppActionLinkDetector;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
@@ -20,36 +22,27 @@ public class StoreLayoutComp extends SimpleComp {
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var stack = new StackPane();
|
||||
GlobalTimer.scheduleUntil(Duration.ofMillis(10), () -> {
|
||||
if (StoreViewState.get() == null || !StoreViewState.get().isInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
var r = createContent();
|
||||
stack.getChildren().add(r);
|
||||
});
|
||||
return true;
|
||||
});
|
||||
return stack;
|
||||
var delayed = new DelayedInitComp(Comp.of(() -> createContent()), () -> StoreViewState.get() != null && StoreViewState.get().isInitialized());
|
||||
return delayed.createRegion();
|
||||
}
|
||||
|
||||
private Region createContent() {
|
||||
var struc = new LeftSplitPaneComp(new StoreSidebarComp(), new StoreEntryListComp())
|
||||
var left = new StoreSidebarComp();
|
||||
left.minWidth(270);
|
||||
left.maxWidth(500);
|
||||
var comp = new LeftSplitPaneComp(left, new StoreEntryListComp())
|
||||
.withInitialWidth(AppLayoutModel.get().getSavedState().getSidebarWidth())
|
||||
.withOnDividerChange(aDouble -> {
|
||||
AppLayoutModel.get().getSavedState().setSidebarWidth(aDouble);
|
||||
})
|
||||
.createStructure();
|
||||
struc.getLeft().setMinWidth(270);
|
||||
struc.getLeft().setMaxWidth(500);
|
||||
struc.get().getStyleClass().add("store-layout");
|
||||
InputHelper.onKeyCombination(
|
||||
struc.get(), new KeyCodeCombination(KeyCode.V, KeyCombination.SHORTCUT_DOWN), true, keyEvent -> {
|
||||
AppActionLinkDetector.detectOnPaste();
|
||||
keyEvent.consume();
|
||||
});
|
||||
return struc.get();
|
||||
comp.styleClass("store-layout");
|
||||
comp.apply(struc -> {
|
||||
InputHelper.onKeyCombination(
|
||||
struc.get(), new KeyCodeCombination(KeyCode.V, KeyCombination.SHORTCUT_DOWN), true, keyEvent -> {
|
||||
AppActionLinkDetector.detectOnPaste();
|
||||
keyEvent.consume();
|
||||
});
|
||||
});
|
||||
return comp.createRegion();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,17 +165,16 @@ public class TerminalCategory extends AppPrefsCategory {
|
||||
ref.addListener((observable, oldValue, newValue) -> {
|
||||
prefs.terminalProxy.setValue(newValue != null ? newValue.get().getUuid() : null);
|
||||
});
|
||||
var proxyChoice = new DelayedInitComp(Comp.of(() -> {
|
||||
var comp = new StoreChoiceComp<>(StoreChoiceComp.Mode.PROXY, null, ref, ShellStore.class,
|
||||
r -> TerminalProxyManager.canUseAsProxy(r), StoreViewState.get().getAllConnectionsCategory());
|
||||
return comp.createRegion();
|
||||
}), () -> StoreViewState.get() != null && StoreViewState.get().isInitialized());
|
||||
proxyChoice.maxWidth(getCompWidth());
|
||||
return new OptionsBuilder()
|
||||
.nameAndDescription("terminalEnvironment")
|
||||
.addComp(
|
||||
new StoreChoiceComp<>(
|
||||
StoreChoiceComp.Mode.PROXY,
|
||||
null,
|
||||
ref,
|
||||
ShellStore.class,
|
||||
r -> TerminalProxyManager.canUseAsProxy(r),
|
||||
StoreViewState.get().getAllConnectionsCategory())
|
||||
.maxWidth(getCompWidth()),
|
||||
proxyChoice,
|
||||
ref)
|
||||
.hide(OsType.getLocal() != OsType.WINDOWS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user