Small fixes [release]

This commit is contained in:
crschnick 2023-07-06 06:38:48 +00:00
parent 447ec12023
commit f464c2c1ac
19 changed files with 62 additions and 42 deletions

View file

@ -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());

View file

@ -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>();

View file

@ -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()));
}

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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;

View file

@ -46,7 +46,7 @@ public interface DataStoreProvider {
return true;
}
default boolean shouldHaveSubShells() {
default boolean shouldHaveChildren() {
return canHaveSubShells();
}

View file

@ -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);
});

View file

@ -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 -> {

View file

@ -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));

View file

@ -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() {

View file

@ -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();
});

View file

@ -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(

View file

@ -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();

View file

@ -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:

View file

@ -43,6 +43,6 @@
}
.loading-comp {
-fx-background-color: #0002;
-fx-background-color: -color-modal-pane-overlay;
}

View file

@ -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();

View file

@ -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;
}
};

View file

@ -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