mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 00:50:31 +00:00
Various fixes [stage]
This commit is contained in:
parent
7f0d9746d1
commit
9d4903e665
26 changed files with 76 additions and 42 deletions
|
@ -24,16 +24,16 @@ public interface LeafAction extends BrowserAction {
|
|||
default Button toButton(Region root, OpenFileSystemModel model, List<BrowserEntry> selected) {
|
||||
var b = new Button();
|
||||
b.setOnAction(event -> {
|
||||
if (model == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only accept shortcut actions in the current tab
|
||||
if (!model.equals(model.getBrowserModel().getSelectedEntry().getValue())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
if (model.getFileSystem() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BooleanScope.executeExclusive(model.getBusy(), () -> {
|
||||
// Start shell in case we exited
|
||||
model.getFileSystem().getShell().orElseThrow().start();
|
||||
|
@ -83,6 +83,10 @@ public interface LeafAction extends BrowserAction {
|
|||
}));
|
||||
mi.setOnAction(event -> {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
if (model.getFileSystem() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BooleanScope.executeExclusive(model.getBusy(), () -> {
|
||||
// Start shell in case we exited
|
||||
model.getFileSystem().getShell().orElseThrow().start();
|
||||
|
|
|
@ -14,6 +14,7 @@ import io.xpipe.app.core.AppLayoutModel;
|
|||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.StackComp;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
|
@ -31,6 +32,7 @@ import javafx.scene.layout.HBox;
|
|||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
@ -103,6 +105,17 @@ public class BrowserChooserComp extends SimpleComp {
|
|||
action,
|
||||
bookmarkTopBar.getCategory(),
|
||||
bookmarkTopBar.getFilter());
|
||||
var bookmarksContainer = new StackComp(List.of(bookmarksList)).styleClass("bookmarks-container");
|
||||
bookmarksContainer
|
||||
.apply(struc -> {
|
||||
var rec = new Rectangle();
|
||||
rec.widthProperty().bind(struc.get().widthProperty());
|
||||
rec.heightProperty().bind(struc.get().heightProperty());
|
||||
rec.setArcHeight(7);
|
||||
rec.setArcWidth(7);
|
||||
struc.get().getChildren().getFirst().setClip(rec);
|
||||
})
|
||||
.vgrow();
|
||||
|
||||
var stack = Comp.of(() -> {
|
||||
var s = new StackPane();
|
||||
|
@ -118,7 +131,7 @@ public class BrowserChooserComp extends SimpleComp {
|
|||
return s;
|
||||
});
|
||||
|
||||
var vertical = new VerticalComp(List.of(bookmarkTopBar, bookmarksList)).styleClass("left");
|
||||
var vertical = new VerticalComp(List.of(bookmarkTopBar, bookmarksContainer)).styleClass("left");
|
||||
var splitPane = new SideSplitPaneComp(vertical, stack)
|
||||
.withInitialWidth(AppLayoutModel.get().getSavedState().getBrowserConnectionsWidth())
|
||||
.withOnDividerChange(AppLayoutModel.get().getSavedState()::setBrowserConnectionsWidth)
|
||||
|
@ -163,6 +176,7 @@ public class BrowserChooserComp extends SimpleComp {
|
|||
var field = new TextField(
|
||||
s.getRawFileEntry().getPath());
|
||||
field.setEditable(false);
|
||||
field.getStyleClass().add("chooser-selection");
|
||||
HBox.setHgrow(field, Priority.ALWAYS);
|
||||
return field;
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.comp;
|
|||
|
||||
import io.xpipe.app.comp.base.MultiContentComp;
|
||||
import io.xpipe.app.comp.base.SideMenuBarComp;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
|
@ -52,6 +53,10 @@ public class AppLayoutComp extends Comp<CompStructure<Pane>> {
|
|||
AppPrefs.get().save();
|
||||
DataStorage.get().saveAsync();
|
||||
}
|
||||
|
||||
if (o != null && o.equals(model.getEntries().get(1))) {
|
||||
StoreViewState.get().updateDisplay();
|
||||
}
|
||||
});
|
||||
pane.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
||||
sidebarR.getChildrenUnmodifiable().forEach(node -> {
|
||||
|
|
|
@ -25,6 +25,7 @@ public class StoreEntryWrapper {
|
|||
private final Property<String> name;
|
||||
private final DataStoreEntry entry;
|
||||
private final Property<Instant> lastAccess;
|
||||
private final Property<Instant> lastAccessApplied = new SimpleObjectProperty<>();
|
||||
private final BooleanProperty disabled = new SimpleBooleanProperty();
|
||||
private final BooleanProperty busy = new SimpleBooleanProperty();
|
||||
private final Property<DataStoreEntry.Validity> validity = new SimpleObjectProperty<>();
|
||||
|
@ -44,6 +45,7 @@ public class StoreEntryWrapper {
|
|||
this.entry = entry;
|
||||
this.name = new SimpleStringProperty(entry.getName());
|
||||
this.lastAccess = new SimpleObjectProperty<>(entry.getLastAccess().minus(Duration.ofMillis(500)));
|
||||
this.lastAccessApplied.setValue(lastAccess.getValue());
|
||||
ActionProvider.ALL.stream()
|
||||
.filter(dataStoreActionProvider -> {
|
||||
return !entry.isDisabled()
|
||||
|
@ -62,6 +64,10 @@ public class StoreEntryWrapper {
|
|||
setupListeners();
|
||||
}
|
||||
|
||||
public void applyLastAccess() {
|
||||
this.lastAccessApplied.setValue(lastAccess.getValue());
|
||||
}
|
||||
|
||||
public void moveTo(DataStoreCategory category) {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
DataStorage.get().updateCategory(entry, category);
|
||||
|
|
|
@ -56,7 +56,7 @@ public interface StoreSortMode {
|
|||
.map(this::representative),
|
||||
Stream.of(s))
|
||||
.max(Comparator.comparing(
|
||||
section -> section.getWrapper().getEntry().getLastAccess()))
|
||||
section -> section.getWrapper().getLastAccessApplied().getValue()))
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ public interface StoreSortMode {
|
|||
@Override
|
||||
public Comparator<StoreSection> comparator() {
|
||||
return Comparator.comparing(e -> {
|
||||
return e.getWrapper().getEntry().getLastAccess();
|
||||
return e.getWrapper().getLastAccessApplied().getValue();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -84,7 +84,7 @@ public interface StoreSortMode {
|
|||
.map(this::representative),
|
||||
Stream.of(s))
|
||||
.max(Comparator.comparing(
|
||||
section -> section.getWrapper().getEntry().getLastAccess()))
|
||||
section -> section.getWrapper().getLastAccessApplied().getValue()))
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ public interface StoreSortMode {
|
|||
@Override
|
||||
public Comparator<StoreSection> comparator() {
|
||||
return Comparator.<StoreSection, Instant>comparing(e -> {
|
||||
return e.getWrapper().getEntry().getLastAccess();
|
||||
return e.getWrapper().getLastAccessApplied().getValue();
|
||||
})
|
||||
.reversed();
|
||||
}
|
||||
|
|
|
@ -121,6 +121,11 @@ public class StoreViewState {
|
|||
.orElseThrow()));
|
||||
}
|
||||
|
||||
public void updateDisplay() {
|
||||
allEntries.getList().forEach(e -> e.applyLastAccess());
|
||||
toggleStoreListUpdate();
|
||||
}
|
||||
|
||||
public void toggleStoreListUpdate() {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
entriesListUpdateObservable.set(entriesListUpdateObservable.get() + 1);
|
||||
|
|
|
@ -17,12 +17,10 @@ import io.xpipe.beacon.api.DaemonOpenExchange;
|
|||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.util.XPipeDaemonMode;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -119,9 +117,9 @@ public class LauncherCommand implements Callable<Integer> {
|
|||
// there might be another instance running, for example
|
||||
// starting up or listening on another port
|
||||
if (!AppDataLock.lock()) {
|
||||
throw new IOException(
|
||||
"Data directory " + AppProperties.get().getDataDir().toString()
|
||||
+ " is already locked. Is another instance running?");
|
||||
TrackEvent.info("Data directory " + AppProperties.get().getDataDir().toString()
|
||||
+ " is already locked. Is another instance running?");
|
||||
OperationMode.halt(1);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
var cli = XPipeInstallation.getLocalDefaultCliExecutable();
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
.bookmarks-container {
|
||||
-fx-background-color: -color-border-default, -color-bg-subtle;
|
||||
-fx-background-radius: 4 0 0 4;
|
||||
-fx-background-insets: 0 8 8 8, 1 9 9 9;
|
||||
-fx-padding: 1 1 9 9;
|
||||
-fx-background-insets: 0 7 8 8, 1 8 9 9;
|
||||
-fx-padding: 1 0 9 9;
|
||||
}
|
||||
|
||||
.root:pretty .bookmarks-container {
|
||||
|
@ -40,5 +40,5 @@
|
|||
-fx-min-height: 3.5em;
|
||||
-fx-pref-height: 3.5em;
|
||||
-fx-max-height: 3.5em;
|
||||
-fx-padding: 9 8;
|
||||
-fx-padding: 9 6 9 8;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
}
|
||||
|
||||
.transfer {
|
||||
-fx-padding: 0 8 8 8;
|
||||
-fx-padding: 0 6 8 8;
|
||||
}
|
||||
|
||||
.root:pretty .browser .transfer {
|
||||
|
@ -178,11 +178,8 @@
|
|||
-fx-border-color: -color-border-default;
|
||||
}
|
||||
|
||||
.chooser-bar {
|
||||
-fx-border-color: -color-border-default;
|
||||
-fx-border-width: 1 0 0 0;
|
||||
-fx-padding: 0.4em 0.7em;
|
||||
-fx-background-color: -color-neutral-muted;
|
||||
.browser .chooser-selection {
|
||||
-fx-background-color: -color-bg-default;
|
||||
}
|
||||
|
||||
.browser .singular {
|
||||
|
@ -257,7 +254,7 @@
|
|||
|
||||
.browser .split-pane-divider {
|
||||
-fx-border-color: -color-border-default, -color-bg-inset;
|
||||
-fx-padding: 0 3;
|
||||
-fx-padding: 0 2 0 3;
|
||||
-fx-border-width: 2.7em 0 0 0, 2.65em 0 0 0;
|
||||
-fx-opacity: 1.0;
|
||||
-fx-background-color: transparent;
|
||||
|
|
|
@ -23,7 +23,7 @@ public class XPipeInstallation {
|
|||
.orElse(false);
|
||||
|
||||
public static int getDefaultBeaconPort() {
|
||||
var offset = isStaging() ? 2 : 0;
|
||||
var offset = isStaging() ? 1 : 0;
|
||||
return 21721 + offset;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public class RunScriptAction implements BrowserAction, BranchAction {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (script.assemble(sc) == null) {
|
||||
if (!script.isCompatible(sc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,15 +32,20 @@ public class SimpleScriptStore extends ScriptStore implements ShellInitCommand.T
|
|||
private final boolean shellScript;
|
||||
private final boolean fileScript;
|
||||
|
||||
public String assemble(ShellControl shellControl) {
|
||||
public boolean isCompatible(ShellControl shellControl) {
|
||||
var targetType = shellControl.getOriginalShellDialect();
|
||||
if (minimumDialect.isCompatibleTo(targetType)) {
|
||||
return minimumDialect.isCompatibleTo(targetType);
|
||||
}
|
||||
|
||||
public String assemble(ShellControl shellControl) {
|
||||
if (isCompatible(shellControl)) {
|
||||
var shebang = commands.startsWith("#");
|
||||
// Fix new lines and shebang
|
||||
var fixedCommands = commands.lines()
|
||||
.skip(shebang ? 1 : 0)
|
||||
.collect(Collectors.joining(
|
||||
shellControl.getShellDialect().getNewLine().getNewLineString()));
|
||||
var targetType = shellControl.getOriginalShellDialect();
|
||||
var script = ScriptHelper.createExecScript(targetType, shellControl, fixedCommands);
|
||||
return targetType.sourceScriptCommand(shellControl, script.toString());
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ useCommunity=Fortsæt med fællesskab
|
|||
previewDescription=Afprøv nye funktioner i et par uger efter udgivelsen.
|
||||
tryPreview=Aktiver forhåndsvisning af XPipe
|
||||
previewItem1=Fuld adgang til nyligt udgivne professionelle funktioner i 2 uger efter udgivelsen
|
||||
previewItem2=Indeholder alle funktioner i community-udgaven
|
||||
previewItem2=Prøv nye funktioner uden nogen forpligtelse
|
||||
licensedTo=Licenseret til
|
||||
#custom
|
||||
email=E-mailadresse
|
||||
|
|
|
@ -21,7 +21,7 @@ useCommunity=Weiter mit Community
|
|||
previewDescription=Teste die neuen Funktionen ein paar Wochen lang nach der Veröffentlichung.
|
||||
tryPreview=Aktiviere die XPipe-Vorschau
|
||||
previewItem1=Voller Zugang zu neu veröffentlichten professionellen Funktionen für 2 Wochen nach der Veröffentlichung
|
||||
previewItem2=Enthält alle Funktionen der Community Edition
|
||||
previewItem2=Probiere neue Funktionen unverbindlich aus
|
||||
licensedTo=Lizensiert für
|
||||
email=E-Mail Adresse
|
||||
apply=Anwenden
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=Continue with community
|
|||
previewDescription=Try out new features for a couple of weeks after release.
|
||||
tryPreview=Activate XPipe preview
|
||||
previewItem1=Full access to newly released professional features for 2 weeks after release
|
||||
previewItem2=Includes all community edition features
|
||||
previewItem2=Try out new features without any commitment
|
||||
licensedTo=Licensed to
|
||||
email=Email address
|
||||
#context: Apply changes
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=Continuar con la comunidad
|
|||
previewDescription=Prueba las nuevas funciones durante un par de semanas después del lanzamiento.
|
||||
tryPreview=Activar la vista previa de XPipe
|
||||
previewItem1=Acceso completo a las nuevas funciones profesionales durante 2 semanas después del lanzamiento
|
||||
previewItem2=Incluye todas las funciones de la edición comunitaria
|
||||
previewItem2=Prueba nuevas funciones sin compromiso
|
||||
licensedTo=Con licencia
|
||||
email=Dirección de correo electrónico
|
||||
apply=Aplica
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=Continue avec la communauté
|
|||
previewDescription=Essaie les nouvelles fonctionnalités pendant quelques semaines après leur publication.
|
||||
tryPreview=Activer l'aperçu de XPipe
|
||||
previewItem1=Accès complet aux fonctionnalités professionnelles nouvellement publiées pendant 2 semaines après la sortie de la version
|
||||
previewItem2=Comprend toutes les fonctionnalités de l'édition communautaire
|
||||
previewItem2=Essaie les nouvelles fonctions sans t'engager
|
||||
licensedTo=Sous licence
|
||||
email=Adresse électronique
|
||||
apply=Appliquer
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=Continua con la comunità
|
|||
previewDescription=Prova le nuove funzionalità per un paio di settimane dopo il rilascio.
|
||||
tryPreview=Attiva l'anteprima di XPipe
|
||||
previewItem1=Accesso completo alle funzioni professionali appena rilasciate per 2 settimane dal rilascio
|
||||
previewItem2=Include tutte le funzioni della community edition
|
||||
previewItem2=Prova nuove funzionalità senza alcun impegno
|
||||
licensedTo=Con licenza di
|
||||
email=Indirizzo e-mail
|
||||
apply=Applicare
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=コミュニティに続く
|
|||
previewDescription=リリース後数週間は新機能を試す。
|
||||
tryPreview=XPipeプレビューを有効にする
|
||||
previewItem1=リリース後2週間、新しくリリースされたプロフェッショナル機能にフルアクセスできる
|
||||
previewItem2=コミュニティ版の全機能を含む
|
||||
previewItem2=コミットメントなしで新機能を試す
|
||||
licensedTo=ライセンス対象
|
||||
email=電子メールアドレス
|
||||
apply=適用する
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=Verder met gemeenschap
|
|||
previewDescription=Probeer nieuwe functies een paar weken na de release uit.
|
||||
tryPreview=XPipe voorvertoning activeren
|
||||
previewItem1=Volledige toegang tot nieuwe professionele functies gedurende 2 weken na de release
|
||||
previewItem2=Omvat alle community-editie functies
|
||||
previewItem2=Nieuwe functies uitproberen zonder enige verplichting
|
||||
licensedTo=Gelicentieerd aan
|
||||
email=E-mailadres
|
||||
apply=Toepassen
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=Continua com a comunidade
|
|||
previewDescription=Experimenta as novas funcionalidades durante algumas semanas após o lançamento.
|
||||
tryPreview=Ativar a pré-visualização do XPipe
|
||||
previewItem1=Acesso total às novas funcionalidades profissionais durante 2 semanas após o lançamento
|
||||
previewItem2=Inclui todas as funcionalidades da edição comunitária
|
||||
previewItem2=Experimenta novas funcionalidades sem qualquer compromisso
|
||||
licensedTo=Licenciado para
|
||||
email=Endereço de correio eletrónico
|
||||
apply=Aplica-te
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=Продолжайте общаться
|
|||
previewDescription=Опробуй новые возможности в течение пары недель после релиза.
|
||||
tryPreview=Активировать предварительный просмотр XPipe
|
||||
previewItem1=Полный доступ к новым профессиональным функциям в течение 2 недель после релиза
|
||||
previewItem2=Включает в себя все возможности community edition
|
||||
previewItem2=Опробуй новые возможности без каких-либо обязательств
|
||||
licensedTo=Лицензия на
|
||||
email=Адрес электронной почты
|
||||
apply=Применяй
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=Topluluk ile devam edin
|
|||
previewDescription=Yayınlandıktan sonra birkaç hafta boyunca yeni özellikleri deneyin.
|
||||
tryPreview=XPipe önizlemesini etkinleştirme
|
||||
previewItem1=Piyasaya sürüldükten sonra 2 hafta boyunca yeni çıkan profesyonel özelliklere tam erişim
|
||||
previewItem2=Tüm topluluk sürümü özelliklerini içerir
|
||||
previewItem2=Herhangi bir taahhütte bulunmadan yeni özellikleri deneyin
|
||||
licensedTo=Lisanslı
|
||||
email=E-posta adresi
|
||||
apply=Başvurmak
|
||||
|
|
|
@ -19,7 +19,7 @@ useCommunity=继续社区
|
|||
previewDescription=新功能发布后试用几周。
|
||||
tryPreview=激活 XPipe 预览
|
||||
previewItem1=新发布的专业功能发布后两周内可完全访问
|
||||
previewItem2=包括社区版的所有功能
|
||||
previewItem2=无需任何承诺即可试用新功能
|
||||
licensedTo=授权给
|
||||
email=电子邮件地址
|
||||
apply=应用
|
||||
|
|
|
@ -28,7 +28,7 @@ externalDocs:
|
|||
description: XPipe - Plans and pricing
|
||||
url: https://xpipe.io/pricing
|
||||
servers:
|
||||
- url: http://localhost:21723
|
||||
- url: http://localhost:21721
|
||||
description: XPipe Daemon API
|
||||
paths:
|
||||
/handshake:
|
||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
|||
10.0-21
|
||||
10.0-22
|
||||
|
|
Loading…
Reference in a new issue