mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
Small fixes [release]
This commit is contained in:
parent
447ec12023
commit
f464c2c1ac
19 changed files with 62 additions and 42 deletions
|
@ -31,6 +31,7 @@ public class LoadingOverlayComp extends Comp<CompStructure<StackPane>> {
|
|||
|
||||
var loadingBg = new StackPane(loading);
|
||||
loadingBg.getStyleClass().add("loading-comp");
|
||||
loadingBg.getStyleClass().add("modal-pane");
|
||||
|
||||
loadingBg.setVisible(showLoading.getValue());
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package io.xpipe.app.comp.storage.store;
|
|||
|
||||
import io.xpipe.app.comp.base.ListBoxViewComp;
|
||||
import io.xpipe.app.comp.base.MultiContentComp;
|
||||
import io.xpipe.app.core.AppState;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||
|
@ -33,11 +32,10 @@ public class StoreEntryListComp extends SimpleComp {
|
|||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var initialCount = StoreViewState.get().getAllEntries().size();
|
||||
var initialCount = 1;
|
||||
var showIntro = Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
return initialCount == StoreViewState.get().getAllEntries().size()
|
||||
&& AppState.get().isInitialLaunch();
|
||||
return initialCount == StoreViewState.get().getAllEntries().size();
|
||||
},
|
||||
StoreViewState.get().getAllEntries());
|
||||
var map = new LinkedHashMap<Comp<?>, ObservableBooleanValue>();
|
||||
|
|
|
@ -206,7 +206,7 @@ public class StoreEntryWrapper implements StorageFilter.Filterable {
|
|||
|
||||
@Override
|
||||
public boolean shouldShow(String filter) {
|
||||
return getName().toLowerCase().contains(filter.toLowerCase())
|
||||
return filter == null || getName().toLowerCase().contains(filter.toLowerCase())
|
||||
|| (summary.get() != null && summary.get().toLowerCase().contains(filter.toLowerCase()))
|
||||
|| (information.get() != null && information.get().toLowerCase().contains(filter.toLowerCase()));
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import io.xpipe.app.storage.DataStorage;
|
|||
import io.xpipe.app.util.Hyperlinks;
|
||||
import io.xpipe.app.util.ScanAlert;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Button;
|
||||
|
@ -29,7 +28,7 @@ public class StoreIntroComp extends SimpleComp {
|
|||
|
||||
var introDesc = new Label(AppI18n.get("storeIntroDescription"));
|
||||
|
||||
var mfi = new FontIcon("mdi2m-magnify");
|
||||
var mfi = new FontIcon("mdi2p-playlist-plus");
|
||||
var machine = new Label(AppI18n.get("storeMachineDescription"), mfi);
|
||||
machine.heightProperty().addListener((c, o, n) -> {
|
||||
mfi.iconSizeProperty().set(n.intValue());
|
||||
|
@ -67,9 +66,8 @@ public class StoreIntroComp extends SimpleComp {
|
|||
v.getStyleClass().add("intro");
|
||||
|
||||
var sp = new StackPane(v);
|
||||
sp.setAlignment(Pos.BOTTOM_CENTER);
|
||||
sp.setAlignment(Pos.CENTER);
|
||||
sp.setPickOnBounds(false);
|
||||
sp.setPadding(new Insets(0, 0, 40, 0));
|
||||
return sp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
|
|||
e -> {
|
||||
try {
|
||||
DataStorage.get().addStoreEntry(e);
|
||||
if (e.getProvider().shouldHaveSubShells()) {
|
||||
if (e.getProvider().shouldHaveChildren()) {
|
||||
ScanAlert.showAsync(e);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
|
|
|
@ -20,7 +20,7 @@ public class AppActionLinkDetector {
|
|||
return content != null ? content.toString() : null;
|
||||
}
|
||||
|
||||
private static void handle(String content, boolean showAlert) {
|
||||
public static void handle(String content, boolean showAlert) {
|
||||
var detected = LauncherInput.of(content);
|
||||
if (detected.size() == 0) {
|
||||
return;
|
||||
|
|
|
@ -46,7 +46,7 @@ public interface DataStoreProvider {
|
|||
return true;
|
||||
}
|
||||
|
||||
default boolean shouldHaveSubShells() {
|
||||
default boolean shouldHaveChildren() {
|
||||
return canHaveSubShells();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package io.xpipe.app.fxcomps.impl;
|
||||
|
||||
import io.xpipe.app.core.AppActionLinkDetector;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.scene.Node;
|
||||
|
@ -14,6 +15,8 @@ import lombok.Builder;
|
|||
import lombok.Value;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class FilterComp extends Comp<FilterComp.Structure> {
|
||||
|
||||
private final Property<String> filterText;
|
||||
|
@ -31,9 +34,20 @@ public class FilterComp extends Comp<FilterComp.Structure> {
|
|||
filter.setAccessibleText("Filter");
|
||||
|
||||
SimpleChangeListener.apply(filterText, val -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> filter.setText(val));
|
||||
Platform.runLater(() -> {
|
||||
if (!Objects.equals(filter.getText(), val)) {
|
||||
filter.setText(val);
|
||||
}
|
||||
});
|
||||
});
|
||||
filter.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
// Handle pasted xpipe URLs
|
||||
if (newValue != null && newValue.startsWith("xpipe://")) {
|
||||
AppActionLinkDetector.handle(newValue, false);
|
||||
filter.setText(null);
|
||||
return;
|
||||
}
|
||||
|
||||
filterText.setValue(newValue);
|
||||
});
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ public class BindingsHelper {
|
|||
ObservableList<V> l2, ObservableValue<Predicate<V>> predicate) {
|
||||
ObservableList<V> l1 = FXCollections.observableList(new ArrayList<>());
|
||||
Runnable runnable = () -> {
|
||||
setContent(l1, l2.stream().filter(predicate.getValue()).toList());
|
||||
setContent(l1, predicate.getValue() != null ? l2.stream().filter(predicate.getValue()).toList() : l2);
|
||||
};
|
||||
runnable.run();
|
||||
l2.addListener((ListChangeListener<? super V>) c -> {
|
||||
|
|
|
@ -19,6 +19,7 @@ import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
|||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.util.LockChangeAlert;
|
||||
import io.xpipe.app.util.LockedSecretValue;
|
||||
import io.xpipe.core.util.ModuleHelper;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
|
@ -35,6 +36,10 @@ import java.util.*;
|
|||
|
||||
public class AppPrefs {
|
||||
|
||||
public boolean isDevelopmentEnvironment() {
|
||||
return developerMode().getValue() && !ModuleHelper.isImage();
|
||||
}
|
||||
|
||||
private static ObservableBooleanValue bindDeveloperTrue(ObservableBooleanValue o) {
|
||||
return Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
|
@ -588,7 +593,7 @@ public class AppPrefs {
|
|||
developerShowHiddenProviders)),
|
||||
Category.of("troubleshoot", Group.of(troubleshoot))));
|
||||
|
||||
categories.get(categories.size() - 1).setVisibilityProperty(VisibilityProperty.of(developerMode()));
|
||||
categories.get(categories.size() - 2).setVisibilityProperty(VisibilityProperty.of(developerMode()));
|
||||
|
||||
var handler = new PrefsHandlerImpl(categories);
|
||||
PrefsProvider.getAll().forEach(prov -> prov.addPrefs(handler));
|
||||
|
|
|
@ -182,6 +182,7 @@ public class DataStoreEntry extends StorageElement {
|
|||
public void setExpanded(boolean expanded) {
|
||||
this.dirty = true;
|
||||
this.expanded = expanded;
|
||||
listeners.forEach(l -> l.onUpdate());
|
||||
}
|
||||
|
||||
public DataStore getStore() {
|
||||
|
|
|
@ -94,9 +94,8 @@ public class StandardStorage extends DataStorage {
|
|||
|
||||
storeEntries.add(entry);
|
||||
} catch (Exception e) {
|
||||
// We only keep invalid entries in developer mode as there's no point in keeping them in
|
||||
// production.
|
||||
if (AppPrefs.get().developerMode().getValue()) {
|
||||
// We only keep invalid entries in developer mode as there's no point in keeping them in production.
|
||||
if (AppPrefs.get().isDevelopmentEnvironment()) {
|
||||
directoriesToKeep.add(path);
|
||||
}
|
||||
ErrorEvent.fromThrowable(e).omitted(true).build().handle();
|
||||
|
@ -107,7 +106,7 @@ public class StandardStorage extends DataStorage {
|
|||
storeEntries.forEach(dataStoreEntry -> dataStoreEntry.simpleRefresh());
|
||||
|
||||
// Remove even incomplete stores when in production
|
||||
if (!AppPrefs.get().developerMode().getValue()) {
|
||||
if (!AppPrefs.get().isDevelopmentEnvironment()) {
|
||||
storeEntries.removeIf(entry -> {
|
||||
return !entry.getState().isUsable();
|
||||
});
|
||||
|
|
|
@ -11,8 +11,7 @@ public class DesktopShortcuts {
|
|||
|
||||
private static void createWindowsShortcut(String target, String name) throws Exception {
|
||||
var icon = XPipeInstallation.getLocalDefaultInstallationIcon();
|
||||
var shortcutTarget = XPipeInstallation.getCurrentInstallationBasePath()
|
||||
.resolve(XPipeInstallation.getRelativeCliExecutablePath(OsType.WINDOWS));
|
||||
var shortcutTarget = XPipeInstallation.getLocalDefaultCliExecutable();
|
||||
var content = String.format(
|
||||
"""
|
||||
set "TARGET=%s"
|
||||
|
@ -26,8 +25,7 @@ public class DesktopShortcuts {
|
|||
}
|
||||
|
||||
private static void createLinuxShortcut(String target, String name) throws Exception {
|
||||
var exec = XPipeInstallation.getCurrentInstallationBasePath()
|
||||
.resolve(XPipeInstallation.getRelativeCliExecutablePath(OsType.LINUX));
|
||||
var exec = XPipeInstallation.getLocalDefaultCliExecutable();
|
||||
var icon = XPipeInstallation.getLocalDefaultInstallationIcon();
|
||||
var content = String.format(
|
||||
"""
|
||||
|
@ -47,8 +45,7 @@ public class DesktopShortcuts {
|
|||
}
|
||||
|
||||
private static void createMacOSShortcut(String target, String name) throws Exception {
|
||||
var exec = XPipeInstallation.getCurrentInstallationBasePath()
|
||||
.resolve(XPipeInstallation.getRelativeCliExecutablePath(OsType.MACOS));
|
||||
var exec = XPipeInstallation.getLocalDefaultCliExecutable();
|
||||
var icon = XPipeInstallation.getLocalDefaultInstallationIcon();
|
||||
var base = System.getProperty("user.home") + "/Desktop/" + name + ".app";
|
||||
var content = String.format(
|
||||
|
|
|
@ -40,7 +40,7 @@ public class ScanAlert {
|
|||
}
|
||||
|
||||
private static void showForOtherStore(DataStoreEntry entry) {
|
||||
showIfNeeded(() -> {
|
||||
show(entry, () -> {
|
||||
var providers = ScanProvider.getAll();
|
||||
var applicable = providers.stream()
|
||||
.map(scanProvider -> scanProvider.create(entry.getStore()))
|
||||
|
@ -51,7 +51,7 @@ public class ScanAlert {
|
|||
}
|
||||
|
||||
private static void showForShellStore(DataStoreEntry entry) {
|
||||
showIfNeeded(() -> {
|
||||
show(entry, () -> {
|
||||
try (var sc = ((ShellStore) entry.getStore()).control().start()) {
|
||||
var providers = ScanProvider.getAll();
|
||||
var applicable = new ArrayList<ScanProvider.ScanOperation>();
|
||||
|
@ -69,7 +69,7 @@ public class ScanAlert {
|
|||
});
|
||||
}
|
||||
|
||||
private static void showIfNeeded(Supplier<List<ScanProvider.ScanOperation>> applicable) {
|
||||
private static void show(DataStoreEntry entry, Supplier<List<ScanProvider.ScanOperation>> applicable) {
|
||||
var busy = new SimpleBooleanProperty();
|
||||
var selected = new SimpleListProperty<ScanProvider.ScanOperation>(FXCollections.observableArrayList());
|
||||
AppWindowHelper.showAlert(
|
||||
|
@ -104,6 +104,8 @@ public class ScanAlert {
|
|||
}
|
||||
}
|
||||
|
||||
entry.setExpanded(true);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
alert.setResult(ButtonType.OK);
|
||||
alert.close();
|
||||
|
|
|
@ -12,10 +12,10 @@ dataSourceIntroStructure=Structure data sources contain some form of object stru
|
|||
dataSourceIntroText=Text data sources contain readable text that can\ncome in a variety of different encodings and simple formats.
|
||||
dataSourceIntroBinary=Binary data sources contain binary data. They\ncan be used when the data should be handled and preserved byte by byte.
|
||||
dataSourceIntroCollection=Collection data sources contain multiple sub data sources. \nExamples are zip files or file system directories.
|
||||
storeIntroTitle=Adding Connections
|
||||
storeIntroDescription=Connect to remote systems, databases, and more.
|
||||
storeIntroTitle=Shell Connection Hub
|
||||
storeIntroDescription=Connect to shells, remote systems, databases, and more.
|
||||
storeStreamDescription=Stream connections produce raw byte data\nthat can be used to construct data sources from.
|
||||
storeMachineDescription=You can quickly search for available remote connections automatically.\nAlternatively, you can also of course add them manually.
|
||||
storeMachineDescription=To start off, here you can quickly detect available\nconnections automatically and choose which ones to add.
|
||||
detectConnections=Search for connections
|
||||
storeDatabaseDescription=Database connections allow you to connect to\na database server and interact with its contained data.
|
||||
storeDocumentation=In case you prefer a more structured approach to\nfamiliarizing yourself with XPipe, check out the documentation:
|
||||
|
|
|
@ -43,6 +43,6 @@
|
|||
}
|
||||
|
||||
.loading-comp {
|
||||
-fx-background-color: #0002;
|
||||
-fx-background-color: -color-modal-pane-overlay;
|
||||
}
|
||||
|
||||
|
|
|
@ -177,6 +177,11 @@ public class XPipeInstallation {
|
|||
}
|
||||
}
|
||||
|
||||
public static String getLocalDefaultCliExecutable() {
|
||||
Path path = ModuleHelper.isImage() ? getCurrentInstallationBasePath() : Path.of(getLocalDefaultInstallationBasePath(true));
|
||||
return path.resolve(getRelativeCliExecutablePath(OsType.getLocal())).toString();
|
||||
}
|
||||
|
||||
public static Path getLocalDefaultInstallationIcon() {
|
||||
Path path = getCurrentInstallationBasePath();
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import io.xpipe.app.ext.ActionProvider;
|
|||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.DesktopShortcuts;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
import io.xpipe.core.store.LaunchableStore;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.Value;
|
||||
|
||||
|
@ -29,30 +29,30 @@ public class LaunchShortcutAction implements ActionProvider {
|
|||
|
||||
@Override
|
||||
public DataStoreCallSite<?> getDataStoreCallSite() {
|
||||
return new DataStoreCallSite<ShellStore>() {
|
||||
return new DataStoreCallSite<LaunchableStore>() {
|
||||
|
||||
@Override
|
||||
public Action createAction(ShellStore store) {
|
||||
public Action createAction(LaunchableStore store) {
|
||||
return new Action(DataStorage.get().getStoreEntry(store));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<ShellStore> getApplicableClass() {
|
||||
return ShellStore.class;
|
||||
public Class<LaunchableStore> getApplicableClass() {
|
||||
return LaunchableStore.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(ShellStore store) {
|
||||
public ObservableValue<String> getName(LaunchableStore store) {
|
||||
return AppI18n.observable("createShortcut");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(ShellStore store) {
|
||||
public String getIcon(LaunchableStore store) {
|
||||
return "mdi2c-code-greater-than";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMajor(ShellStore o) {
|
||||
public boolean isMajor(LaunchableStore o) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ScanAction implements ActionProvider {
|
|||
|
||||
@Override
|
||||
public boolean isMajor(ShellStore o) {
|
||||
return DataStoreProviders.byStore(o).shouldHaveSubShells();
|
||||
return DataStoreProviders.byStore(o).shouldHaveChildren();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue