diff --git a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java index 60c60e136..bd366a096 100644 --- a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java +++ b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java @@ -14,6 +14,7 @@ import io.xpipe.app.platform.PlatformThread; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefsComp; import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.terminal.TerminalDockHubManager; import io.xpipe.app.update.AppDistributionType; import io.xpipe.app.util.*; @@ -242,6 +243,15 @@ public class AppLayoutModel { null, () -> WebtopAppListDialog.show(List.of()), null)); + l.add( + new Entry( + AppI18n.observable("webtopMobileConnect"), + new LabelGraphic.IconGraphic("mdi2a-archive-sync-outline"), + null, + () -> { + ProcessControlProvider.get().showLocalWebtopMobileConnectDialog(); + }, + null)); } l.add(new Entry( diff --git a/app/src/main/java/io/xpipe/app/ext/ProcessControlProvider.java b/app/src/main/java/io/xpipe/app/ext/ProcessControlProvider.java index 8c0fe02a5..44bf96f9c 100644 --- a/app/src/main/java/io/xpipe/app/ext/ProcessControlProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/ProcessControlProvider.java @@ -93,5 +93,7 @@ public abstract class ProcessControlProvider { public abstract void showWebtopDeploymentDialog(); + public abstract void showLocalWebtopMobileConnectDialog(); + public abstract void importRdpFile(Path file) throws Exception; } diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreQuickConnect.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreQuickConnect.java index 6c790331f..38e761d91 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreQuickConnect.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreQuickConnect.java @@ -48,8 +48,15 @@ public class StoreQuickConnect { return false; } - var newStore = provider.get().createStore(arguments, quickConnectStore); - if (newStore == null) { + DataStore newStore; + + try { + newStore = provider.get().createStore(arguments, quickConnectStore); + if (newStore == null) { + return false; + } + } catch (Exception e) { + ErrorEventFactory.fromThrowable(e).expected().handle(); return false; } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSource.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSource.java index b2d3588ec..00301222d 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSource.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSource.java @@ -23,10 +23,7 @@ import lombok.Value; import lombok.extern.jackson.Jacksonized; import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; +import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; @@ -76,7 +73,11 @@ public interface ScriptCollectionSource { public void checkComplete() throws ValidationException { Validators.nonNull(path); // Check if path is invalid - path.toLocalAbsoluteFilePath().asLocalPath(); + try { + path.toLocalAbsoluteFilePath().asLocalPath(); + } catch (InvalidPathException e) { + throw new ValidationException(e.getMessage()); + } } @Override diff --git a/lang/strings/translations_en.properties b/lang/strings/translations_en.properties index 55ce72751..8cf94bbdb 100644 --- a/lang/strings/translations_en.properties +++ b/lang/strings/translations_en.properties @@ -2332,3 +2332,13 @@ remminaRdpArguments=Additional options remminaRdpArgumentsDescription=Add custom .remmina file options to be included when launching, each line represents one option remminaVncArguments=Additional options remminaVncArgumentsDescription=Add custom .remmina file options to be included when launching, each line represents one option +webtopMobileConnect=Mobile connect +webtopMobileConnectTitle=Secure mobile connect +webtopConnectHostConfiguration=Target host +webtopConnectHostConfigurationDescription=The externally reachable hostname/IP and the webtop container SSH port +direct=Direct +keyAuth=SSH key authentication +webtopConnectTailscaleDeviceName=Tailscale device name +webtopConnectTailscaleDeviceNameDescription=abc +webtopConnectAuth=Authentication +webtopConnectAuthDescription=The SSH authentication method to connect to the webtop remotely