Improve display names

This commit is contained in:
crschnick 2024-07-24 03:52:53 +00:00
parent d6b1d78e6e
commit 2f4d72c63f
12 changed files with 26 additions and 186 deletions

View file

@ -147,7 +147,7 @@ public class BrowserWelcomeComp extends SimpleComp {
entry.get().getProvider().getDisplayIconFileName(entry.get().getStore()); entry.get().getProvider().getDisplayIconFileName(entry.get().getStore());
var view = PrettyImageHelper.ofFixedSize(graphic, 30, 24); var view = PrettyImageHelper.ofFixedSize(graphic, 30, 24);
return new ButtonComp( return new ButtonComp(
new SimpleStringProperty(DataStorage.get().getStoreDisplayName(entry.get())), new SimpleStringProperty(DataStorage.get().getStoreEntryDisplayName(entry.get())),
view.createRegion(), view.createRegion(),
() -> { () -> {
ThreadHelper.runAsync(() -> { ThreadHelper.runAsync(() -> {
@ -158,7 +158,7 @@ public class BrowserWelcomeComp extends SimpleComp {
}); });
}) })
.minWidth(250) .minWidth(250)
.accessibleText(DataStorage.get().getStoreDisplayName(entry.get())) .accessibleText(DataStorage.get().getStoreEntryDisplayName(entry.get()))
.disable(disable) .disable(disable)
.styleClass("entry-button") .styleClass("entry-button")
.styleClass(Styles.LEFT_PILL) .styleClass(Styles.LEFT_PILL)

View file

@ -22,7 +22,7 @@ public abstract class BrowserSessionTab<T extends DataStore> {
public BrowserSessionTab(BrowserAbstractSessionModel<?> browserModel, DataStoreEntryRef<? extends T> entry) { public BrowserSessionTab(BrowserAbstractSessionModel<?> browserModel, DataStoreEntryRef<? extends T> entry) {
this.browserModel = browserModel; this.browserModel = browserModel;
this.entry = entry; this.entry = entry;
this.name = DataStorage.get().getStoreDisplayName(entry.get()); this.name = DataStorage.get().getStoreEntryDisplayName(entry.get());
this.tooltip = DataStorage.get().getStorePath(entry.getEntry()).toString(); this.tooltip = DataStorage.get().getStorePath(entry.getEntry()).toString();
} }

View file

@ -478,7 +478,7 @@ public abstract class StoreEntryComp extends SimpleComp {
ThreadHelper.runFailableAsync(() -> { ThreadHelper.runFailableAsync(() -> {
DesktopShortcuts.create( DesktopShortcuts.create(
url, url,
getWrapper().nameProperty().getValue() + " (" DataStorage.get().getStoreEntryDisplayName(getWrapper().getEntry()) + " ("
+ p.getLeafDataStoreCallSite() + p.getLeafDataStoreCallSite()
.getName(getWrapper().getEntry().ref()) .getName(getWrapper().getEntry().ref())
.getValue() + ")"); .getValue() + ")");

View file

@ -10,11 +10,9 @@ import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppImages; import io.xpipe.app.core.AppImages;
import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.core.util.JacksonizedValue; import io.xpipe.core.util.JacksonizedValue;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property; import javafx.beans.property.Property;
@ -73,9 +71,8 @@ public interface DataStoreProvider {
return null; return null;
} }
default String browserDisplayName(DataStore store) { default String browserDisplayName(DataStoreEntry entry) {
var e = DataStorage.get().getStoreDisplayName(store); return entry.getName();
return e.orElse("?");
} }
default List<String> getSearchableTerms(DataStore store) { default List<String> getSearchableTerms(DataStore store) {

View file

@ -205,7 +205,7 @@ public class ErrorHandlerComp extends SimpleComp {
header.setGraphicTextGap(6); header.setGraphicTextGap(6);
AppFont.setSize(header, 3); AppFont.setSize(header, 3);
var descriptionField = new TextArea(desc); var descriptionField = new TextArea(desc);
descriptionField.setPrefRowCount(Math.min((int) desc.lines().count(), 14)); descriptionField.setPrefRowCount(Math.max(5, Math.min((int) desc.lines().count(), 14)));
descriptionField.setWrapText(true); descriptionField.setWrapText(true);
descriptionField.setEditable(false); descriptionField.setEditable(false);
descriptionField.setPadding(Insets.EMPTY); descriptionField.setPadding(Insets.EMPTY);

View file

@ -870,24 +870,16 @@ public abstract class DataStorage {
.findFirst(); .findFirst();
} }
public Optional<String> getStoreDisplayName(DataStore store) { public String getStoreEntryDisplayName(DataStoreEntry entry) {
if (store == null) { if (entry == null) {
return Optional.empty();
}
return getStoreEntryIfPresent(store, true).map(dataStoreEntry -> dataStoreEntry.getName());
}
public String getStoreDisplayName(DataStoreEntry store) {
if (store == null) {
return "?"; return "?";
} }
if (!store.getValidity().isUsable()) { if (!entry.getValidity().isUsable()) {
return "?"; return "?";
} }
return store.getProvider().browserDisplayName(store.getStore()); return entry.getProvider().browserDisplayName(entry);
} }
public Optional<DataStoreEntry> getStoreEntryIfPresent(UUID id) { public Optional<DataStoreEntry> getStoreEntryIfPresent(UUID id) {

View file

@ -2,17 +2,11 @@ package io.xpipe.app.util;
import io.xpipe.app.comp.store.StoreEntryWrapper; import io.xpipe.app.comp.store.StoreEntryWrapper;
import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.core.process.ShellDialects; import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.process.ShellStoreState; import io.xpipe.core.process.ShellStoreState;
import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.ShellStore;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import java.util.function.IntFunction;
public class DataStoreFormatter { public class DataStoreFormatter {
public static String formattedOsName(String osName) { public static String formattedOsName(String osName) {
@ -61,49 +55,10 @@ public class DataStoreFormatter {
return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase();
} }
public static String formatSubHost(IntFunction<String> func, DataStore at, int length) {
var atString = at instanceof ShellStore shellStore && !ShellStore.isLocal(shellStore)
? DataStorage.get().getStoreDisplayName(at).orElse(null)
: null;
if (atString == null) {
return func.apply(length);
}
var fileString = func.apply(length - atString.length() - 1);
return String.format("%s/%s", atString, fileString);
}
public static String formatAtHost(IntFunction<String> func, DataStore at, int length) {
var atString = at instanceof ShellStore shellStore && !ShellStore.isLocal(shellStore)
? DataStorage.get().getStoreDisplayName(at).orElse(null)
: null;
if (atString == null) {
return func.apply(length);
}
var fileString = func.apply(length - atString.length() - 3);
return String.format("%s @ %s", fileString, atString);
}
public static String formatViaProxy(IntFunction<String> func, DataStoreEntry at, int length) {
var atString =
at.getStore() instanceof ShellStore shellStore && !ShellStore.isLocal(shellStore) ? at.getName() : null;
if (atString == null) {
return func.apply(length);
}
var fileString = func.apply(length - atString.length() - 3);
return String.format("%s > %s", atString, fileString);
}
public static String toApostropheName(DataStoreEntry input) { public static String toApostropheName(DataStoreEntry input) {
return toName(input, Integer.MAX_VALUE) + "'s"; return toName(input, Integer.MAX_VALUE) + "'s";
} }
public static String toName(DataStoreEntry input) {
return toName(input, Integer.MAX_VALUE);
}
public static String toName(DataStoreEntry input, int length) { public static String toName(DataStoreEntry input, int length) {
if (input == null) { if (input == null) {
return "?"; return "?";

View file

@ -1,116 +0,0 @@
package io.xpipe.app.util;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.core.dialog.Dialog;
import io.xpipe.core.dialog.QueryConverter;
import io.xpipe.core.store.*;
import io.xpipe.core.util.NewLine;
import io.xpipe.core.util.SecretValue;
import io.xpipe.core.util.StreamCharset;
import lombok.Value;
public class DialogHelper {
public static Dialog addressQuery(Address address) {
var hostNameQuery = Dialog.query("Hostname", false, true, false, address.getHostname(), QueryConverter.STRING);
var portQuery = Dialog.query("Port", false, true, false, address.getPort(), QueryConverter.INTEGER);
return Dialog.chain(hostNameQuery, portQuery)
.evaluateTo(() -> new Address(hostNameQuery.getResult(), portQuery.getResult()));
}
public static Dialog machineQuery(DataStore store) {
var storeName = DataStorage.get().getStoreDisplayName(store).orElse("localhost");
return Dialog.query("Machine", false, true, false, storeName, QueryConverter.STRING)
.map((String name) -> {
if (name.equals("local") || name.equals("localhost")) {
return new LocalStore();
}
var stored = DataStorage.get().getStoreEntryIfPresent(name).map(entry -> entry.getStore());
if (stored.isEmpty()) {
throw new IllegalArgumentException(String.format("Store not found: %s", name));
}
if (!(stored.get() instanceof FileSystem)) {
throw new IllegalArgumentException(String.format("Store not a machine store: %s", name));
}
return stored.get();
});
}
public static Dialog shellQuery(String displayName, DataStore store) {
var storeName = DataStorage.get().getStoreDisplayName(store).orElse("localhost");
return Dialog.query(displayName, false, true, false, storeName, QueryConverter.STRING)
.map((String name) -> {
if (name.equals("local") || name.equals("localhost")) {
return new LocalStore();
}
var stored = DataStorage.get().getStoreEntryIfPresent(name).map(entry -> entry.getStore());
if (stored.isEmpty()) {
throw new IllegalArgumentException(String.format("Store not found: %s", name));
}
if (!(stored.get() instanceof ShellStore)) {
throw new IllegalArgumentException(String.format("Store not a shell store: %s", name));
}
return stored.get();
});
}
public static Dialog charsetQuery(StreamCharset c, boolean preferQuiet) {
return Dialog.query("Charset", false, true, c != null && preferQuiet, c, QueryConverter.CHARSET);
}
public static Dialog newLineQuery(NewLine n, boolean preferQuiet) {
return Dialog.query("Newline", false, true, n != null && preferQuiet, n, QueryConverter.NEW_LINE);
}
public static <T> Dialog query(String desc, T value, boolean required, QueryConverter<T> c, boolean preferQuiet) {
return Dialog.query(desc, false, required, value != null && preferQuiet, value, c);
}
public static Dialog booleanChoice(String desc, boolean value, boolean preferQuiet) {
return Dialog.choice(desc, val -> val.toString(), true, preferQuiet, value, Boolean.TRUE, Boolean.FALSE);
}
public static Dialog fileQuery(String name) {
return Dialog.query("File", true, true, false, name, QueryConverter.STRING);
}
public static Dialog userQuery(String name) {
return Dialog.query("User", false, true, false, name, QueryConverter.STRING);
}
public static Dialog namedStoreQuery(DataStore store, Class<? extends DataStore> filter) {
var name = DataStorage.get().getStoreDisplayName(store).orElse(null);
return Dialog.query("Store", false, true, false, name, QueryConverter.STRING)
.map((String newName) -> {
var found = DataStorage.get()
.getStoreEntryIfPresent(newName)
.map(entry -> entry.getStore())
.orElseThrow();
if (!filter.isAssignableFrom(found.getClass())) {
throw new IllegalArgumentException("Incompatible store type");
}
return found;
});
}
public static Dialog passwordQuery(SecretValue password) {
return Dialog.querySecret("Password", false, true, password);
}
public static Dialog timeoutQuery(Integer timeout) {
return Dialog.query("Timeout", false, true, false, timeout, QueryConverter.INTEGER);
}
@Value
public static class Address {
String hostname;
Integer port;
}
}

View file

@ -1,7 +1,7 @@
## File browser improvements ## File browser improvements
- Add right click context menu to browser tabs - Add right click context menu to browser tabs
- Add ability to select tabs with function keys, e.g. F1 - Add ability to select tabs with function keys, e.g. F1, F2, ...
- Add ability to cycle between tabs with CTRL+TAB and CTRL+SHIFT+TAB - Add ability to cycle between tabs with CTRL+TAB and CTRL+SHIFT+TAB
- Fix some keyboard shortcuts being broken - Fix some keyboard shortcuts being broken
- Fix pressing enter on rename also opening file - Fix pressing enter on rename also opening file
@ -18,7 +18,7 @@
- Add support for VNC RSA-AES authentication schemes, allowing to connect to more types of VNC servers - Add support for VNC RSA-AES authentication schemes, allowing to connect to more types of VNC servers
- Services can now be opened in a browser using either HTTP or HTTPs - Services can now be opened in a browser using either HTTP or HTTPs
- You can now create shortcuts to automatically forward and open services in a browser - You can now create shortcuts to automatically forward and open services in a browser
- Fix doctor containers in some cases not persisting, leaving invalid orphan connections behind on the bottom - Fix docker containers in some cases not persisting, leaving invalid orphan connections behind on the bottom
- Improve description for service groups - Improve description for service groups
- Publish API libraries to maven central - Publish API libraries to maven central
- Show warning when launching PowerShell in constrained language mode - Show warning when launching PowerShell in constrained language mode

View file

@ -90,7 +90,7 @@ public class LaunchStoreAction implements ActionProvider {
@Override @Override
public void execute() throws Exception { public void execute() throws Exception {
var storeName = DataStorage.get().getStoreDisplayName(entry); var storeName = DataStorage.get().getStoreEntryDisplayName(entry);
if (entry.getStore() instanceof ShellStore s) { if (entry.getStore() instanceof ShellStore s) {
TerminalLauncher.open(entry, storeName, null, ScriptStore.controlWithDefaultScripts(s.control())); TerminalLauncher.open(entry, storeName, null, ScriptStore.controlWithDefaultScripts(s.control()));
return; return;

View file

@ -23,6 +23,11 @@ import java.util.List;
public abstract class AbstractServiceStoreProvider implements SingletonSessionStoreProvider, DataStoreProvider { public abstract class AbstractServiceStoreProvider implements SingletonSessionStoreProvider, DataStoreProvider {
public String browserDisplayName(DataStoreEntry entry) {
AbstractServiceStore s = entry.getStore().asNeeded();
return DataStorage.get().getStoreEntryDisplayName(s.getHost().get()) + " - Port " + s.getRemotePort();
}
@Override @Override
public DataStoreUsageCategory getUsageCategory() { public DataStoreUsageCategory getUsageCategory() {
return DataStoreUsageCategory.TUNNEL; return DataStoreUsageCategory.TUNNEL;

View file

@ -1,6 +1,8 @@
package io.xpipe.ext.base.service; package io.xpipe.ext.base.service;
import io.xpipe.app.comp.store.StoreSection; import io.xpipe.app.comp.store.StoreSection;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@ -8,6 +10,11 @@ import java.util.List;
public class MappedServiceStoreProvider extends FixedServiceStoreProvider { public class MappedServiceStoreProvider extends FixedServiceStoreProvider {
public String browserDisplayName(DataStoreEntry entry) {
MappedServiceStore s = entry.getStore().asNeeded();
return DataStorage.get().getStoreEntryDisplayName(s.getHost().get()) + " - Port " + s.getContainerPort();
}
@Override @Override
public List<String> getPossibleNames() { public List<String> getPossibleNames() {
return List.of("mappedService"); return List.of("mappedService");