Various fixes

This commit is contained in:
crschnick
2025-01-23 23:17:45 +00:00
parent 1c7b6785ba
commit c21a1b2bdc
17 changed files with 108 additions and 82 deletions

View File

@@ -5,7 +5,7 @@ import io.xpipe.app.beacon.BlobManager;
import io.xpipe.app.util.FixedSizeInputStream;
import io.xpipe.beacon.BeaconClientException;
import io.xpipe.beacon.api.FsReadExchange;
import io.xpipe.core.store.ConnectionFileSystem;
import io.xpipe.app.ext.ConnectionFileSystem;
import com.sun.net.httpserver.HttpExchange;
import lombok.SneakyThrows;

View File

@@ -3,7 +3,7 @@ package io.xpipe.app.beacon.impl;
import io.xpipe.app.beacon.AppBeaconServer;
import io.xpipe.app.beacon.BlobManager;
import io.xpipe.beacon.api.FsWriteExchange;
import io.xpipe.core.store.ConnectionFileSystem;
import io.xpipe.app.ext.ConnectionFileSystem;
import com.sun.net.httpserver.HttpExchange;
import lombok.SneakyThrows;

View File

@@ -7,7 +7,7 @@ import io.xpipe.app.util.FileBridge;
import io.xpipe.app.util.FileOpener;
import io.xpipe.core.process.ElevationFunction;
import io.xpipe.core.process.OsType;
import io.xpipe.core.store.ConnectionFileSystem;
import io.xpipe.app.ext.ConnectionFileSystem;
import io.xpipe.core.store.FileEntry;
import io.xpipe.core.store.FileInfo;
import io.xpipe.core.store.FileNames;

View File

@@ -100,9 +100,9 @@ public class AppI18n {
Locale.setDefault(Locale.ENGLISH);
// Load bundled JDK locale resources by initializing the classes
SupportedLocale.ALL.forEach(supportedLocale -> {
supportedLocale.getLocale().getDisplayName();
});
for (var value : SupportedLocale.values()) {
value.getLocale().getDisplayName();
}
}
if (currentLanguage.getValue() == null && PlatformState.getCurrent() == PlatformState.RUNNING) {

View File

@@ -30,7 +30,6 @@ public class AppProperties {
UUID buildUuid;
String sentryUrl;
String arch;
List<String> languages;
@Getter
boolean image;
@@ -95,9 +94,6 @@ public class AppProperties {
.orElse(UUID.randomUUID());
sentryUrl = System.getProperty("io.xpipe.app.sentryUrl");
arch = System.getProperty("io.xpipe.app.arch");
languages = Arrays.stream(System.getProperty("io.xpipe.app.languages").split(","))
.sorted()
.toList();
staging = Optional.ofNullable(System.getProperty("io.xpipe.app.staging"))
.map(Boolean::parseBoolean)
.orElse(false);

View File

@@ -1,9 +1,12 @@
package io.xpipe.core.store;
package io.xpipe.app.ext;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.ShellControl;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.xpipe.core.store.FileEntry;
import io.xpipe.core.store.FileSystem;
import lombok.Getter;
import java.io.InputStream;
@@ -172,7 +175,8 @@ public class ConnectionFileSystem implements FileSystem {
// Since we are only closing, just swallow all exceptions
try {
shellControl.close();
} catch (Exception ignored) {
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).omit().expected().handle();
}
}
}

View File

@@ -9,7 +9,6 @@ import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.terminal.ExternalTerminalType;
import io.xpipe.app.update.XPipeDistributionType;
import io.xpipe.app.util.LocalShell;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.process.OsType;
import io.xpipe.core.util.ModuleHelper;
@@ -91,7 +90,7 @@ public class AppPrefs {
public final BooleanProperty denyTempScriptCreation =
mapVaultShared(new SimpleBooleanProperty(false), "denyTempScriptCreation", Boolean.class, false);
final Property<ExternalPasswordManager> passwordManager =
mapVaultShared(new SimpleObjectProperty<>(), "passwordManager", ExternalPasswordManager.class, false);
mapVaultShared(new SimpleObjectProperty<>(ExternalPasswordManager.NONE), "passwordManager", ExternalPasswordManager.class, false);
final StringProperty passwordManagerCommand =
mapLocal(new SimpleStringProperty(""), "passwordManagerCommand", String.class, false);
final ObjectProperty<StartupBehaviour> startupBehaviour = mapLocal(
@@ -144,7 +143,7 @@ public class AppPrefs {
mapLocal(new SimpleBooleanProperty(false), "developerPrintInitFiles", Boolean.class, false);
final ObjectProperty<SupportedLocale> language = mapLocal(
new SimpleObjectProperty<>(SupportedLocale.getEnglish()), "language", SupportedLocale.class, false);
new SimpleObjectProperty<>(SupportedLocale.getInitial()), "language", SupportedLocale.class, false);
final BooleanProperty requireDoubleClickForConnections =
mapLocal(new SimpleBooleanProperty(false), "requireDoubleClickForConnections", Boolean.class, false);

View File

@@ -19,6 +19,7 @@ import atlantafx.base.controls.ProgressSliderSkin;
import atlantafx.base.theme.Styles;
import org.kordamp.ikonli.javafx.FontIcon;
import java.util.Arrays;
import java.util.List;
public class AppearanceCategory extends AppPrefsCategory {
@@ -71,7 +72,7 @@ public class AppearanceCategory extends AppPrefsCategory {
private Comp<?> languageChoice() {
var prefs = AppPrefs.get();
var c = ChoiceComp.ofTranslatable(prefs.language, SupportedLocale.ALL, false);
var c = ChoiceComp.ofTranslatable(prefs.language, Arrays.asList(SupportedLocale.values()), false);
var visit = new ButtonComp(AppI18n.observable("translate"), new FontIcon("mdi2w-web"), () -> {
Hyperlinks.open(Hyperlinks.TRANSLATE);
});

View File

@@ -16,6 +16,23 @@ public interface ExternalPasswordManager extends PrefsChoiceValue {
String retrievePassword(String key);
ExternalPasswordManager NONE = new ExternalPasswordManager() {
@Override
public String getDocsLink() {
return null;
}
@Override
public String retrievePassword(String key) {
return null;
}
@Override
public String getId() {
return "none";
}
};
ExternalPasswordManager COMMAND = new ExternalPasswordManager() {
private static ShellControl SHELL;
@@ -153,7 +170,7 @@ public interface ExternalPasswordManager extends PrefsChoiceValue {
}
};
List<ExternalPasswordManager> ALL = Stream.of(COMMAND, WINDOWS_CREDENTIAL_MANAGER)
List<ExternalPasswordManager> ALL = Stream.of(NONE, COMMAND, WINDOWS_CREDENTIAL_MANAGER)
.filter(externalPasswordManager -> externalPasswordManager.isSelectable())
.toList();
}

View File

@@ -34,6 +34,11 @@ public class PasswordManagerCategory extends AppPrefsCategory {
@Value
private static class Choice {
public static Choice ofOther(ExternalPasswordManager externalPasswordManager) {
return new Choice(externalPasswordManager.getId(), null, externalPasswordManager.getDocsLink(),externalPasswordManager);
}
String id;
String template;
String docsLink;
@@ -48,6 +53,7 @@ public class PasswordManagerCategory extends AppPrefsCategory {
@Override
protected Comp<?> create() {
var choices = new ArrayList<Choice>();
choices.add(Choice.ofOther(ExternalPasswordManager.NONE));
ExternalPasswordManagerTemplate.ALL.forEach(externalPasswordManagerTemplate -> {
choices.add(new Choice(
externalPasswordManagerTemplate.getId(),
@@ -55,15 +61,7 @@ public class PasswordManagerCategory extends AppPrefsCategory {
externalPasswordManagerTemplate.getDocsLink(),
ExternalPasswordManager.COMMAND));
});
ExternalPasswordManager.ALL.stream()
.filter(externalPasswordManager -> externalPasswordManager != ExternalPasswordManager.COMMAND)
.forEach(externalPasswordManager -> {
choices.add(new Choice(
externalPasswordManager.getId(),
null,
externalPasswordManager.getDocsLink(),
externalPasswordManager));
});
choices.add(Choice.ofOther(ExternalPasswordManager.WINDOWS_CREDENTIAL_MANAGER));
var prefs = AppPrefs.get();
var testPasswordManagerValue = new SimpleStringProperty();

View File

@@ -1,6 +1,5 @@
package io.xpipe.app.prefs;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.ext.PrefsChoiceValue;
import javafx.beans.property.SimpleStringProperty;
@@ -9,25 +8,43 @@ import javafx.beans.value.ObservableValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.List;
import java.util.Arrays;
import java.util.Locale;
@AllArgsConstructor
@Getter
public class SupportedLocale implements PrefsChoiceValue {
public enum SupportedLocale implements PrefsChoiceValue {
ENGLISH(Locale.ENGLISH, "en", false),
GERMAN(Locale.GERMAN, "de", false),
DUTCH(Locale.of("nl"), "nl", false),
SPANISH(Locale.of("es"), "es", false),
FRENCH(Locale.FRENCH, "fr", true),
ITALIAN(Locale.ITALIAN, "it", false),
PORTUGUESE(Locale.of("pt"), "pt", false),
RUSSIAN(Locale.of("ru"), "ru", true),
JAPANESE(Locale.of("ja"), "ja", false),
CHINESE(Locale.CHINESE, "zh", true),
DANISH(Locale.of("da"), "da", false),
INDONESIAN(Locale.of("id"), "id", false),
SWEDISH(Locale.of("sv"), "sv", false),
POLISH(Locale.of("pl"), "pl", false),
TURKISH(Locale.of("tr"), "tr", true);
public static final List<SupportedLocale> ALL = AppProperties.get().getLanguages().stream()
.map(s -> {
var split = s.split("-");
var loc = split.length == 2 ? Locale.of(split[0], split[1]) : Locale.of(s);
return new SupportedLocale(loc, s);
})
.toList();
private final Locale locale;
private final String id;
private final boolean setDefault;
public static SupportedLocale getInitial() {
var s = Locale.getDefault();
return Arrays.stream(values())
.filter(supportedLocale -> supportedLocale.isSetDefault() && supportedLocale.getLocale().getLanguage().equals(s.getLanguage()))
.findFirst()
.orElse(getEnglish());
}
public static SupportedLocale getEnglish() {
return ALL.stream()
return Arrays.stream(values())
.filter(supportedLocale -> supportedLocale.getId().equals("en"))
.findFirst()
.orElseThrow();

View File

@@ -5,6 +5,7 @@ import io.xpipe.app.core.AppProperties;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.util.LocalShell;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType;
import io.xpipe.core.util.ModuleHelper;
import io.xpipe.core.util.XPipeInstallation;
@@ -22,6 +23,8 @@ public enum XPipeDistributionType {
PORTABLE("portable", false, () -> new PortableUpdater(true)),
NATIVE_INSTALLATION("install", true, () -> new GitHubUpdater(true)),
HOMEBREW("homebrew", true, () -> new PortableUpdater(true)),
APT_REPO("apt", true, () -> new PortableUpdater(true)),
RPM_REPO("rpm", true, () -> new PortableUpdater(true)),
WEBTOP("webtop", true, () -> new PortableUpdater(false)),
CHOCO("choco", true, () -> new PortableUpdater(true));
@@ -132,6 +135,23 @@ public enum XPipeDistributionType {
}
}
}
if (OsType.getLocal() == OsType.LINUX) {
var aptOut = sc.command("apt show xpipe").readStdoutIfPossible();
if (aptOut.isPresent()) {
var fromRepo = aptOut.get().lines().anyMatch(s -> {
return s.contains("APT-Sources") && s.contains("apt.xpipe.io");
});
if (fromRepo) {
return APT_REPO;
}
}
var yumRepo = sc.command(CommandBuilder.of().add("test", "-f").addFile("/etc/yum.repos.d/rpm.xpipe.io.repo")).executeAndCheck();
if (yumRepo) {
return RPM_REPO;
}
}
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).handle();
}

View File

@@ -126,7 +126,6 @@ project.ext {
authors = 'Christopher Schnick'
javafxVersion = '24-ea+15'
platformName = getPlatformName()
languages = ["en", "nl", "es", "fr", "de", "it", "pt", "ru", "ja", "zh", "tr", "da", "id", "sv", "pl"]
jvmRunArgs = [
"--add-opens", "java.base/java.lang=io.xpipe.app",
"--add-opens", "java.base/java.lang=io.xpipe.core",
@@ -140,7 +139,6 @@ project.ext {
"--add-opens", "javafx.graphics/com.sun.javafx.tk.quantum=io.xpipe.app",
"-Xmx2g",
"-Dio.xpipe.app.arch=$rootProject.arch",
"-Dio.xpipe.app.languages=${String.join(",", languages)}",
"-Dfile.encoding=UTF-8",
"-Dvisualvm.display.name=XPipe",
"-Djavafx.preloader=io.xpipe.app.core.AppPreloader",

View File

@@ -59,7 +59,6 @@ jlink {
// '--strip-debug',
'--no-header-files',
'--no-man-pages',
'--include-locales', "${String.join(",", languages)}",
'--compress', 'zip-9',
'--ignore-signing-information'
]

View File

@@ -3,6 +3,7 @@ package io.xpipe.ext.base.service;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.store.*;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreUsageCategory;
import io.xpipe.app.ext.SingletonSessionStoreProvider;
@@ -20,6 +21,24 @@ import java.util.List;
public abstract class AbstractServiceStoreProvider implements SingletonSessionStoreProvider, DataStoreProvider {
@Override
public ActionProvider.Action launchAction(DataStoreEntry store) {
return new ActionProvider.Action() {
@Override
public void execute() throws Exception {
AbstractServiceStore serviceStore = store.getStore().asNeeded();
serviceStore.startSessionIfNeeded();
var l = serviceStore.requiresTunnel()
? serviceStore.getSession().getLocalPort()
: serviceStore.getRemotePort();
var base = "localhost:" + l;
var full = serviceStore.getServiceProtocolType().formatAddress(base);
serviceStore.getServiceProtocolType().open(full);
}
};
}
public String displayName(DataStoreEntry entry) {
AbstractServiceStore s = entry.getStore().asNeeded();
return DataStorage.get().getStoreEntryDisplayName(s.getHost().get()) + " - Port " + s.getRemotePort();

View File

@@ -1,41 +0,0 @@
package io.xpipe.ext.base.service;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.storage.DataStoreEntryRef;
import lombok.Value;
public class ServiceOpenAction implements ActionProvider {
@Override
public DefaultDataStoreCallSite<?> getDefaultDataStoreCallSite() {
return new DefaultDataStoreCallSite<AbstractServiceStore>() {
@Override
public ActionProvider.Action createAction(DataStoreEntryRef<AbstractServiceStore> store) {
return new Action(store.getStore());
}
@Override
public Class<AbstractServiceStore> getApplicableClass() {
return AbstractServiceStore.class;
}
};
}
@Value
static class Action implements ActionProvider.Action {
AbstractServiceStore serviceStore;
@Override
public void execute() throws Exception {
serviceStore.startSessionIfNeeded();
var l = serviceStore.requiresTunnel()
? serviceStore.getSession().getLocalPort()
: serviceStore.getRemotePort();
var base = "localhost:" + l;
var full = serviceStore.getServiceProtocolType().formatAddress(base);
serviceStore.getServiceProtocolType().open(full);
}
}
}

View File

@@ -80,7 +80,6 @@ open module io.xpipe.ext.base {
StoreStartAction,
StorePauseAction,
StoreRestartAction,
ServiceOpenAction,
ServiceCopyAddressAction,
CloneStoreAction,
RefreshChildrenStoreAction,