Various fixes

This commit is contained in:
crschnick 2024-04-13 15:26:56 +00:00
parent a035f9498d
commit 3a9788fa76
18 changed files with 119 additions and 33 deletions

View file

@ -38,18 +38,22 @@ public class BrowserTransferComp extends SimpleComp {
@Override
protected Region createSimple() {
var syncItems = PlatformThread.sync(model.getItems());
var syncDownloaded = PlatformThread.sync(model.getDownloading());
var syncAllDownloaded = PlatformThread.sync(model.getAllDownloaded());
var background = new LabelComp(AppI18n.observable("transferDescription"))
.apply(struc -> struc.get().setGraphic(new FontIcon("mdi2d-download-outline")))
.visible(Bindings.isEmpty(model.getItems()));
.visible(Bindings.isEmpty(syncItems));
var backgroundStack =
new StackComp(List.of(background)).grow(true, true).styleClass("download-background");
var binding = ListBindingsHelper.mappedContentBinding(model.getItems(), item -> item.getFileEntry());
var binding = ListBindingsHelper.mappedContentBinding(syncItems, item -> item.getFileEntry());
var list = new BrowserSelectionListComp(
binding,
entry -> Bindings.createStringBinding(
() -> {
var sourceItem = model.getItems().stream()
var sourceItem = syncItems.stream()
.filter(item -> item.getFileEntry() == entry)
.findAny();
if (sourceItem.isEmpty()) {
@ -64,27 +68,27 @@ public class BrowserTransferComp extends SimpleComp {
.orElse("?");
return FileNames.getFileName(entry.getPath()) + " (" + name + ")";
},
model.getAllDownloaded()))
syncAllDownloaded))
.apply(struc -> struc.get().setMinHeight(150))
.grow(false, true);
var dragNotice = new LabelComp(model.getAllDownloaded()
var dragNotice = new LabelComp(syncAllDownloaded
.flatMap(aBoolean ->
aBoolean ? AppI18n.observable("dragLocalFiles") : AppI18n.observable("dragFiles")))
.apply(struc -> struc.get().setGraphic(new FontIcon("mdi2h-hand-left")))
.hide(PlatformThread.sync(Bindings.isEmpty(model.getItems())))
.hide(Bindings.isEmpty(syncItems))
.grow(true, false)
.apply(struc -> struc.get().setPadding(new Insets(8)));
var downloadButton = new IconButtonComp("mdi2d-download", () -> {
model.download();
})
.hide(Bindings.isEmpty(model.getItems()))
.disable(PlatformThread.sync(model.getAllDownloaded()))
.hide(Bindings.isEmpty(syncItems))
.disable(syncAllDownloaded)
.apply(new TooltipAugment<>("downloadStageDescription"));
var clearButton = new IconButtonComp("mdi2c-close", () -> {
model.clear();
})
.hide(Bindings.isEmpty(model.getItems()));
.hide(Bindings.isEmpty(syncItems));
var clearPane = Comp.derive(
new HorizontalComp(List.of(downloadButton, clearButton))
.apply(struc -> struc.get().setSpacing(10)),
@ -144,11 +148,11 @@ public class BrowserTransferComp extends SimpleComp {
}
});
struc.get().setOnDragDetected(event -> {
if (model.getDownloading().get()) {
if (syncDownloaded.getValue()) {
return;
}
var selected = model.getItems().stream()
var selected = syncItems.stream()
.map(BrowserTransferModel.Item::getFileEntry)
.toList();
Dragboard db = struc.get().startDragAndDrop(TransferMode.COPY);
@ -158,7 +162,7 @@ public class BrowserTransferComp extends SimpleComp {
return;
}
var files = model.getItems().stream()
var files = syncItems.stream()
.filter(item -> item.downloadFinished().get())
.map(item -> {
try {
@ -195,7 +199,7 @@ public class BrowserTransferComp extends SimpleComp {
event.consume();
});
}),
PlatformThread.sync(model.getDownloading()));
syncDownloaded);
return stack.styleClass("transfer").createRegion();
}
}

View file

@ -4,16 +4,14 @@ import io.xpipe.app.browser.BrowserTransferProgress;
import io.xpipe.app.browser.fs.OpenFileSystemModel;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.core.process.OsType;
import io.xpipe.core.store.FileKind;
import io.xpipe.core.store.FileNames;
import io.xpipe.core.store.FileSystem;
import io.xpipe.core.store.LocalStore;
import io.xpipe.core.store.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
@ -153,6 +151,18 @@ public class FileSystemHelper {
Files.isDirectory(file) ? FileKind.DIRECTORY : FileKind.FILE);
}
public static FileSystem.FileEntry getRemoteWrapper(FileSystem fileSystem, String file) throws Exception {
return new FileSystem.FileEntry(
fileSystem,
file,
Instant.now(),
false,
false,
fileSystem.getFileSize(file),
null,
fileSystem.directoryExists(file) ? FileKind.DIRECTORY : FileKind.FILE);
}
public static void dropLocalFilesInto(
FileSystem.FileEntry entry,
List<Path> files,
@ -296,11 +306,8 @@ public class FileSystemHelper {
AtomicLong transferred = new AtomicLong();
for (var e : flatFiles.entrySet()) {
var sourceFile = e.getKey();
var targetFile = target.getFileSystem()
.getShell()
.orElseThrow()
.getOsType()
.makeFileSystemCompatible(FileNames.join(target.getPath(), e.getValue()));
var fixedRelPath = new FilePath(e.getValue()).fileSystemCompatible(target.getFileSystem().getShell().orElseThrow().getOsType());
var targetFile = FileNames.join(target.getPath(), fixedRelPath.toString());
if (sourceFile.getFileSystem().equals(target.getFileSystem())) {
throw new IllegalStateException();
}

View file

@ -65,13 +65,13 @@ public class App extends Application {
"XPipe %s (%s)", t.getValue(), AppProperties.get().getVersion());
var prefix = AppProperties.get().isStaging() ? "[Public Test Build, Not a proper release] " : "";
var suffix = u.getValue() != null
? String.format(
" (Update to %s ready)", u.getValue().getVersion())
? AppI18n.get("updateReadyTitle", u.getValue().getVersion())
: "";
return prefix + base + suffix;
},
u,
t);
t,
AppPrefs.get().language());
var appWindow = AppMainWindow.init(stage);
appWindow.getStage().titleProperty().bind(PlatformThread.sync(titleBinding));

View file

@ -18,7 +18,7 @@ public class AppPtbCheck {
.setContent(AppWindowHelper.alertContentText("You are running a PTB build of XPipe."
+ " This version is unstable and might contain bugs."
+ " You should not use it as a daily driver."
+ " It will also not receive regular updates."
+ " It will also not receive regular updates after its testing period."
+ " You will have to install and launch the normal XPipe release for that."));
});
}

View file

@ -28,7 +28,7 @@ public interface OsType {
}
}
String makeFileSystemCompatible(String path);
String makeFileSystemCompatible(String name);
List<String> determineInterestingPaths(ShellControl pc) throws Exception;
@ -57,8 +57,8 @@ public interface OsType {
final class Windows implements OsType, Local, Any {
@Override
public String makeFileSystemCompatible(String path) {
return path.replaceAll("[<>:\"/\\\\|?*]", "_").replaceAll("\\p{C}", "");
public String makeFileSystemCompatible(String name) {
return name.replaceAll("[<>:\"/\\\\|?*]", "_").replaceAll("\\p{C}", "");
}
@Override
@ -124,8 +124,9 @@ public interface OsType {
class Unix implements OsType {
@Override
public String makeFileSystemCompatible(String path) {
return path.replaceAll("/", "_").replaceAll("\0", "");
public String makeFileSystemCompatible(String name) {
// Technically the backslash is supported, but it causes all kinds of troubles, so we also exclude it
return name.replaceAll("/\\\\", "_").replaceAll("\0", "");
}
@Override
@ -211,8 +212,9 @@ public interface OsType {
final class MacOs implements OsType, Local, Any {
@Override
public String makeFileSystemCompatible(String path) {
return path.replaceAll("[/:]", "_").replaceAll("\0", "");
public String makeFileSystemCompatible(String name) {
// Technically the backslash is supported, but it causes all kinds of troubles, so we also exclude it
return name.replaceAll("[\\\\/:]", "_").replaceAll("\0", "");
}
@Override

View file

@ -1,5 +1,6 @@
package io.xpipe.core.store;
import io.xpipe.core.process.OsType;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
@ -7,10 +8,19 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
@EqualsAndHashCode
public final class FilePath {
public static boolean isProbableFilePath(OsType osType, String s) {
if (osType.equals(OsType.WINDOWS) && s.length() >= 2 && s.charAt(1) == ':') {
return true;
}
return s.startsWith("/");
}
@NonNull
private final String value;
@ -24,6 +34,36 @@ public final class FilePath {
}
}
public FilePath fileSystemCompatible(OsType osType) {
var split = split();
var needsReplacement = split.stream().anyMatch(s -> !s.equals(osType.makeFileSystemCompatible(s)));
if (!needsReplacement) {
return this;
}
var backslash = value.contains("\\");
var p = Pattern.compile("[^/\\\\]+");
var m = p.matcher(value);
var replaced = m.replaceAll(matchResult -> osType.makeFileSystemCompatible(matchResult.group()));
return new FilePath(replaced);
}
public FilePath getRoot() {
if (value.startsWith("/")) {
return new FilePath("/");
} else if (value.length() >= 2 && value.charAt(1) == ':') {
// Without the trailing slash, many programs struggle with this
return new FilePath(value.substring(0, 2) + "\\");
} else if (value.startsWith("\\\\")) {
var split = split();
if (split.size() > 0) {
return new FilePath("\\\\" + split.getFirst());
}
}
throw new IllegalArgumentException("Unable to determine root of " + value);
}
public Path toLocalPath() {
return Path.of(value);
}

19
dist/licenses/vernacular-vnc.license vendored Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2018 ShinyHut Solutions Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,4 @@
name=Vernacular VNC
version=1.17
license=MIT License
link=https://github.com/shinyhut/vernacular-vnc

View file

@ -433,3 +433,4 @@ attributes=Attribute
modified=Geändert
isOnlySupported=wird nur mit einer professionellen Lizenz unterstützt
areOnlySupported=werden nur mit einer professionellen Lizenz unterstützt
updateReadyTitle=Update auf $VERSION$ bereit

View file

@ -438,3 +438,4 @@ attributes=Attributes
modified=Modified
isOnlySupported=is only supported with a professional license
areOnlySupported=are only supported with a professional license
updateReadyTitle=Update to $VERSION$ ready

View file

@ -423,3 +423,4 @@ attributes=Atributos
modified=Modificado
isOnlySupported=sólo es compatible con una licencia profesional
areOnlySupported=sólo son compatibles con una licencia profesional
updateReadyTitle=Actualiza a $VERSION$ ready

View file

@ -423,3 +423,4 @@ attributes=Attributs
modified=Modifié
isOnlySupported=n'est pris en charge qu'avec une licence professionnelle
areOnlySupported=ne sont pris en charge qu'avec une licence professionnelle
updateReadyTitle=Mise à jour de $VERSION$ ready

View file

@ -423,3 +423,4 @@ attributes=Attributi
modified=Modificato
isOnlySupported=è supportato solo con una licenza professionale
areOnlySupported=sono supportati solo con una licenza professionale
updateReadyTitle=Aggiornamento a $VERSION$ ready

View file

@ -423,3 +423,4 @@ attributes=属性
modified=変更された
isOnlySupported=プロフェッショナルライセンスでのみサポートされる
areOnlySupported=プロフェッショナルライセンスでのみサポートされる
updateReadyTitle=$VERSION$ に更新

View file

@ -423,3 +423,4 @@ attributes=Attributen
modified=Gewijzigd
isOnlySupported=wordt alleen ondersteund met een professionele licentie
areOnlySupported=worden alleen ondersteund met een professionele licentie
updateReadyTitle=Bijwerken naar $VERSION$ klaar

View file

@ -423,3 +423,4 @@ attributes=Atribui
modified=Modificado
isOnlySupported=só é suportado com uma licença profissional
areOnlySupported=só são suportados com uma licença profissional
updateReadyTitle=Actualiza para $VERSION$ ready

View file

@ -423,3 +423,4 @@ attributes=Атрибуты
modified=Изменено
isOnlySupported=поддерживается только при наличии профессиональной лицензии
areOnlySupported=поддерживаются только с профессиональной лицензией
updateReadyTitle=Обновление на $VERSION$ готово

View file

@ -423,3 +423,4 @@ attributes=属性
modified=已修改
isOnlySupported=只有专业许可证才支持
areOnlySupported=只有专业许可证才支持
updateReadyTitle=更新至$VERSION$ ready