mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-03 10:36:52 +13:00
Merge branch 1.7.5 into master [release]
This commit is contained in:
parent
63ab4cfef5
commit
eac9504e14
18 changed files with 69 additions and 41 deletions
|
@ -403,6 +403,10 @@ final class BrowserFileListComp extends SimpleComp {
|
||||||
VirtualFlow<?> flow = (VirtualFlow<?>) skin.getChildren().get(1);
|
VirtualFlow<?> flow = (VirtualFlow<?>) skin.getChildren().get(1);
|
||||||
ScrollBar vbar = (ScrollBar) flow.getChildrenUnmodifiable().get(2);
|
ScrollBar vbar = (ScrollBar) flow.getChildrenUnmodifiable().get(2);
|
||||||
|
|
||||||
|
if (!vbar.isVisible()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
double proximity = 100;
|
double proximity = 100;
|
||||||
Bounds tableBounds = tableView.localToScene(tableView.getBoundsInParent());
|
Bounds tableBounds = tableView.localToScene(tableView.getBoundsInParent());
|
||||||
double dragY = event.getSceneY();
|
double dragY = event.getSceneY();
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class BrowserTransferComp extends SimpleComp {
|
||||||
});
|
});
|
||||||
|
|
||||||
var listBox = new VerticalComp(List.of(list, dragNotice)).padding(new Insets(10, 10, 5, 10));
|
var listBox = new VerticalComp(List.of(list, dragNotice)).padding(new Insets(10, 10, 5, 10));
|
||||||
var stack = new LoadingOverlayComp(
|
var stack = LoadingOverlayComp.noProgress(
|
||||||
new StackComp(List.of(backgroundStack, listBox, clearPane))
|
new StackComp(List.of(backgroundStack, listBox, clearPane))
|
||||||
.apply(DragOverPseudoClassAugment.create())
|
.apply(DragOverPseudoClassAugment.create())
|
||||||
.apply(struc -> {
|
.apply(struc -> {
|
||||||
|
|
|
@ -104,7 +104,12 @@ public class FileSystemHelper {
|
||||||
throw ErrorEvent.unreportable(new IllegalArgumentException(String.format("Directory %s does not exist", path)));
|
throw ErrorEvent.unreportable(new IllegalArgumentException(String.format("Directory %s does not exist", path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
model.getFileSystem().directoryAccessible(path);
|
try {
|
||||||
|
model.getFileSystem().directoryAccessible(path);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ErrorEvent.unreportable(ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FileSystem localFileSystem;
|
private static FileSystem localFileSystem;
|
||||||
|
@ -229,7 +234,7 @@ public class FileSystemHelper {
|
||||||
|
|
||||||
if (sourceFile.getKind() == FileKind.DIRECTORY) {
|
if (sourceFile.getKind() == FileKind.DIRECTORY) {
|
||||||
target.getFileSystem().mkdirs(targetFile);
|
target.getFileSystem().mkdirs(targetFile);
|
||||||
} else {
|
} else if (sourceFile.getKind() == FileKind.FILE) {
|
||||||
try (var in = sourceFile.getFileSystem().openInput(sourceFile.getPath());
|
try (var in = sourceFile.getFileSystem().openInput(sourceFile.getPath());
|
||||||
var out = target.getFileSystem().openOutput(targetFile)) {
|
var out = target.getFileSystem().openOutput(targetFile)) {
|
||||||
in.transferTo(out);
|
in.transferTo(out);
|
||||||
|
|
|
@ -9,18 +9,25 @@ import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.property.SimpleDoubleProperty;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
|
||||||
public class LoadingOverlayComp extends Comp<CompStructure<StackPane>> {
|
public class LoadingOverlayComp extends Comp<CompStructure<StackPane>> {
|
||||||
|
|
||||||
|
public static LoadingOverlayComp noProgress(Comp<?> comp, ObservableValue<Boolean> loading) {
|
||||||
|
return new LoadingOverlayComp(comp, loading, new SimpleDoubleProperty(-1));
|
||||||
|
}
|
||||||
|
|
||||||
private final Comp<?> comp;
|
private final Comp<?> comp;
|
||||||
private final ObservableValue<Boolean> showLoading;
|
private final ObservableValue<Boolean> showLoading;
|
||||||
|
private final ObservableValue<Number> progress;
|
||||||
|
|
||||||
public LoadingOverlayComp(Comp<?> comp, ObservableValue<Boolean> loading) {
|
public LoadingOverlayComp(Comp<?> comp, ObservableValue<Boolean> loading, ObservableValue<Number> progress) {
|
||||||
this.comp = comp;
|
this.comp = comp;
|
||||||
this.showLoading = PlatformThread.sync(loading);
|
this.showLoading = PlatformThread.sync(loading);
|
||||||
|
this.progress = PlatformThread.sync(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,7 +36,7 @@ public class LoadingOverlayComp extends Comp<CompStructure<StackPane>> {
|
||||||
var r = compStruc.get();
|
var r = compStruc.get();
|
||||||
|
|
||||||
var loading = new RingProgressIndicator(0, false);
|
var loading = new RingProgressIndicator(0, false);
|
||||||
loading.setProgress(-1);
|
loading.progressProperty().bind(progress);
|
||||||
loading.visibleProperty().bind(Bindings.not(AppPrefs.get().performanceMode()));
|
loading.visibleProperty().bind(Bindings.not(AppPrefs.get().performanceMode()));
|
||||||
|
|
||||||
var loadingOverlay = new StackPane(loading);
|
var loadingOverlay = new StackPane(loading);
|
||||||
|
|
|
@ -103,7 +103,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
});
|
});
|
||||||
new ContextMenuAugment<>(() -> this.createContextMenu()).augment(new SimpleCompStructure<>(button));
|
new ContextMenuAugment<>(() -> this.createContextMenu()).augment(new SimpleCompStructure<>(button));
|
||||||
|
|
||||||
var loading = new LoadingOverlayComp(
|
var loading = LoadingOverlayComp.noProgress(
|
||||||
Comp.of(() -> button),
|
Comp.of(() -> button),
|
||||||
BindingsHelper.persist(
|
BindingsHelper.persist(
|
||||||
wrapper.getInRefresh().and(wrapper.getObserving().not())));
|
wrapper.getInRefresh().and(wrapper.getObserving().not())));
|
||||||
|
|
|
@ -164,7 +164,6 @@ public class StoreEntryListStatusComp extends SimpleComp {
|
||||||
});
|
});
|
||||||
alphabetical.accessibleTextKey("sortAlphabetical");
|
alphabetical.accessibleTextKey("sortAlphabetical");
|
||||||
alphabetical.apply(new FancyTooltipAugment<>("sortAlphabetical"));
|
alphabetical.apply(new FancyTooltipAugment<>("sortAlphabetical"));
|
||||||
alphabetical.shortcut(new KeyCodeCombination(KeyCode.P, KeyCombination.SHORTCUT_DOWN));
|
|
||||||
return alphabetical;
|
return alphabetical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +203,6 @@ public class StoreEntryListStatusComp extends SimpleComp {
|
||||||
});
|
});
|
||||||
date.accessibleTextKey("sortLastUsed");
|
date.accessibleTextKey("sortLastUsed");
|
||||||
date.apply(new FancyTooltipAugment<>("sortLastUsed"));
|
date.apply(new FancyTooltipAugment<>("sortLastUsed"));
|
||||||
date.shortcut(new KeyCodeCombination(KeyCode.L, KeyCombination.SHORTCUT_DOWN));
|
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ public class AppWindowHelper {
|
||||||
public static void setupContent(
|
public static void setupContent(
|
||||||
Stage stage, Function<Stage, Comp<?>> contentFunc, boolean bindSize, ObservableValue<Boolean> loading) {
|
Stage stage, Function<Stage, Comp<?>> contentFunc, boolean bindSize, ObservableValue<Boolean> loading) {
|
||||||
var baseComp = contentFunc.apply(stage);
|
var baseComp = contentFunc.apply(stage);
|
||||||
var content = loading != null ? new LoadingOverlayComp(baseComp, loading) : baseComp;
|
var content = loading != null ? LoadingOverlayComp.noProgress(baseComp, loading) : baseComp;
|
||||||
var contentR = content.createRegion();
|
var contentR = content.createRegion();
|
||||||
AppFont.small(contentR);
|
AppFont.small(contentR);
|
||||||
var scene = new Scene(bindSize ? new Pane(contentR) : contentR, -1, -1, false);
|
var scene = new Scene(bindSize ? new Pane(contentR) : contentR, -1, -1, false);
|
||||||
|
@ -175,7 +175,7 @@ public class AppWindowHelper {
|
||||||
scene.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
scene.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
||||||
if (AppProperties.get().isDeveloperMode() && event.getCode().equals(KeyCode.F6)) {
|
if (AppProperties.get().isDeveloperMode() && event.getCode().equals(KeyCode.F6)) {
|
||||||
var newBaseComp = contentFunc.apply(stage);
|
var newBaseComp = contentFunc.apply(stage);
|
||||||
var newComp = loading != null ? new LoadingOverlayComp(newBaseComp, loading) : newBaseComp;
|
var newComp = loading != null ? LoadingOverlayComp.noProgress(newBaseComp, loading) : newBaseComp;
|
||||||
var newR = newComp.createRegion();
|
var newR = newComp.createRegion();
|
||||||
AppFont.medium(newR);
|
AppFont.medium(newR);
|
||||||
scene.setRoot(bindSize ? new Pane(newR) : newR);
|
scene.setRoot(bindSize ? new Pane(newR) : newR);
|
||||||
|
|
|
@ -16,10 +16,6 @@ import java.util.List;
|
||||||
|
|
||||||
public class AboutComp extends Comp<CompStructure<?>> {
|
public class AboutComp extends Comp<CompStructure<?>> {
|
||||||
|
|
||||||
private Region createDepsList() {
|
|
||||||
return new ThirdPartyDependencyListComp().createRegion();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Comp<?> createLinks() {
|
private Comp<?> createLinks() {
|
||||||
return new OptionsBuilder()
|
return new OptionsBuilder()
|
||||||
.addComp(
|
.addComp(
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package io.xpipe.app.prefs;
|
package io.xpipe.app.prefs;
|
||||||
|
|
||||||
import atlantafx.base.controls.Tile;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.core.*;
|
import io.xpipe.app.core.AppProperties;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.impl.LabelComp;
|
import io.xpipe.app.fxcomps.impl.LabelComp;
|
||||||
|
import io.xpipe.app.util.JfxHelper;
|
||||||
import io.xpipe.app.util.OptionsBuilder;
|
import io.xpipe.app.util.OptionsBuilder;
|
||||||
import javafx.scene.control.Label;
|
|
||||||
import javafx.scene.image.ImageView;
|
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
|
||||||
public class PropertiesComp extends SimpleComp {
|
public class PropertiesComp extends SimpleComp {
|
||||||
|
@ -15,19 +14,13 @@ public class PropertiesComp extends SimpleComp {
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
var title = Comp.of(() -> {
|
var title = Comp.of(() -> {
|
||||||
var image = new ImageView(AppImages.image("logo/logo_48x48.png"));
|
return JfxHelper.createNamedEntry(AppI18n.get("xPipeClient"), "Version " + AppProperties.get().getVersion() + " ("
|
||||||
image.setPreserveRatio(true);
|
+ AppProperties.get().getArch() + ")", "logo/logo_48x48.png");
|
||||||
image.setSmooth(true);
|
|
||||||
image.setFitHeight(40);
|
|
||||||
var label = new Label(AppI18n.get("xPipeClient"), image);
|
|
||||||
label.getStyleClass().add("header");
|
|
||||||
AppFont.setSize(label, 5);
|
|
||||||
return new Tile(AppI18n.get("xPipeClient"), "Version " + AppProperties.get().getVersion() + " ("
|
|
||||||
+ AppProperties.get().getArch() + ")", image);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var section = new OptionsBuilder()
|
var section = new OptionsBuilder()
|
||||||
.addComp(title, null)
|
.addComp(title, null)
|
||||||
|
.addComp(Comp.vspacer(10))
|
||||||
.name("build")
|
.name("build")
|
||||||
.addComp(
|
.addComp(
|
||||||
new LabelComp(AppProperties.get().getBuild()),
|
new LabelComp(AppProperties.get().getBuild()),
|
||||||
|
|
|
@ -125,10 +125,6 @@ public class ScriptHelper {
|
||||||
.getShellDialect()
|
.getShellDialect()
|
||||||
.createScriptTextFileWriteCommand(processControl, content, file)
|
.createScriptTextFileWriteCommand(processControl, content, file)
|
||||||
.execute();
|
.execute();
|
||||||
var e = processControl.getShellDialect().getScriptPermissionsCommand(file);
|
|
||||||
if (e != null) {
|
|
||||||
processControl.executeSimpleCommand(e, "Failed to set script permissions of " + file);
|
|
||||||
}
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.browser .table-view:drag-into-current .table-row-cell {
|
.browser .table-view:drag-into-current .table-row-cell {
|
||||||
-fx-opacity: 0.8;
|
-fx-opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
|
||||||
.browser .table-row-cell:file:hover,.table-row-cell:folder:hover {
|
.browser .table-row-cell:file:hover,.table-row-cell:folder:hover {
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package io.xpipe.core.process;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class BufferedProcessInputStream extends BufferedInputStream {
|
||||||
|
|
||||||
|
public BufferedProcessInputStream(InputStream in, int size) {
|
||||||
|
super(in, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int bufferedAvailable() {
|
||||||
|
return count - pos;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,10 @@ public interface ShellControl extends ProcessControl {
|
||||||
|
|
||||||
ShellDialect getTargetTerminalShellDialect();
|
ShellDialect getTargetTerminalShellDialect();
|
||||||
|
|
||||||
|
BufferedProcessInputStream getStdout();
|
||||||
|
|
||||||
|
BufferedProcessInputStream getStderr();
|
||||||
|
|
||||||
default boolean hasLocalSystemAccess() {
|
default boolean hasLocalSystemAccess() {
|
||||||
return getSystemId().equals(XPipeSystemId.getLocal());
|
return getSystemId().equals(XPipeSystemId.getLocal());
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,6 @@ public class ConnectionFileSystem implements FileSystem {
|
||||||
try (var pc = shellControl
|
try (var pc = shellControl
|
||||||
.getShellDialect()
|
.getShellDialect()
|
||||||
.createFileExistsCommand(shellControl, file)
|
.createFileExistsCommand(shellControl, file)
|
||||||
.complex()
|
|
||||||
.start()) {
|
.start()) {
|
||||||
return pc.discardAndCheckExit();
|
return pc.discardAndCheckExit();
|
||||||
}
|
}
|
||||||
|
@ -124,7 +123,6 @@ public class ConnectionFileSystem implements FileSystem {
|
||||||
public void mkdirs(String file) throws Exception {
|
public void mkdirs(String file) throws Exception {
|
||||||
try (var pc = shellControl
|
try (var pc = shellControl
|
||||||
.command(proc -> proc.getShellDialect().getMkdirsCommand(file))
|
.command(proc -> proc.getShellDialect().getMkdirsCommand(file))
|
||||||
.complex()
|
|
||||||
.start()) {
|
.start()) {
|
||||||
pc.discardOrThrow();
|
pc.discardOrThrow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,10 @@ public interface FileSystem extends Closeable, AutoCloseable {
|
||||||
Stream<FileEntry> listFiles(String file) throws Exception;
|
Stream<FileEntry> listFiles(String file) throws Exception;
|
||||||
|
|
||||||
default List<FileEntry> listFilesRecursively(String file) throws Exception {
|
default List<FileEntry> listFilesRecursively(String file) throws Exception {
|
||||||
var base = listFiles(file).toList();
|
List<FileEntry> base;
|
||||||
|
try (var filesStream = listFiles(file)) {
|
||||||
|
base = filesStream.toList();
|
||||||
|
}
|
||||||
return base.stream()
|
return base.stream()
|
||||||
.flatMap(fileEntry -> {
|
.flatMap(fileEntry -> {
|
||||||
if (fileEntry.getKind() != FileKind.DIRECTORY) {
|
if (fileEntry.getKind() != FileKind.DIRECTORY) {
|
||||||
|
|
14
dist/changelogs/1.7.5.md
vendored
Normal file
14
dist/changelogs/1.7.5.md
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
## Changes in 1.7.5
|
||||||
|
|
||||||
|
- Implement some more performance improvements
|
||||||
|
- Fix file browser transfer freezing up when trying to copy/move nested directories
|
||||||
|
- Fix file browser transfer failing when trying to copy symbolic links
|
||||||
|
- Fix file browser jittering when dragging and dropping files
|
||||||
|
- Fix performance regression when transferring large files
|
||||||
|
|
||||||
|
## Previous changes in 1.7
|
||||||
|
|
||||||
|
- [1.7.4](https://github.com/xpipe-io/xpipe/releases/tag/1.7.4)
|
||||||
|
- [1.7.3](https://github.com/xpipe-io/xpipe/releases/tag/1.7.3)
|
||||||
|
- [1.7.2](https://github.com/xpipe-io/xpipe/releases/tag/1.7.2)
|
||||||
|
- [1.7.1](https://github.com/xpipe-io/xpipe/releases/tag/1.7.1)
|
|
@ -99,11 +99,6 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
|
||||||
var fileName = scriptStore.get().getName().toLowerCase(Locale.ROOT).replaceAll(" ", "_");
|
var fileName = scriptStore.get().getName().toLowerCase(Locale.ROOT).replaceAll(" ", "_");
|
||||||
var scriptFile = FileNames.join(targetDir, fileName + "." + d.getScriptFileEnding());
|
var scriptFile = FileNames.join(targetDir, fileName + "." + d.getScriptFileEnding());
|
||||||
d.createScriptTextFileWriteCommand(proc, content, scriptFile).execute();
|
d.createScriptTextFileWriteCommand(proc, content, scriptFile).execute();
|
||||||
|
|
||||||
var chmod = d.getScriptPermissionsCommand(scriptFile);
|
|
||||||
if (chmod != null) {
|
|
||||||
proc.executeSimpleBooleanCommand(chmod);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d.createTextFileWriteCommand(proc, String.valueOf(hash), hashFile).execute();
|
d.createTextFileWriteCommand(proc, String.valueOf(hash), hashFile).execute();
|
||||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
||||||
1.7.4
|
1.7.5
|
Loading…
Reference in a new issue