diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/ContextualFileReferenceChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/ContextualFileReferenceChoiceComp.java index 80904675..5d14994b 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/ContextualFileReferenceChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/ContextualFileReferenceChoiceComp.java @@ -4,9 +4,17 @@ import atlantafx.base.theme.Styles; import io.xpipe.app.browser.StandaloneFileBrowser; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.storage.ContextualFileReference; +import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.core.store.FileNames; import io.xpipe.core.store.FileSystemStore; +import javafx.application.Platform; +import javafx.beans.binding.Bindings; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -15,6 +23,9 @@ import javafx.scene.layout.Priority; import javafx.scene.layout.Region; import org.kordamp.ikonli.javafx.FontIcon; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.List; public class ContextualFileReferenceChoiceComp extends SimpleComp { @@ -22,7 +33,9 @@ public class ContextualFileReferenceChoiceComp extends SimpleComp { private final Property> fileSystem; private final Property filePath; - public ContextualFileReferenceChoiceComp(ObservableValue> fileSystem, Property filePath) { + public ContextualFileReferenceChoiceComp( + ObservableValue> fileSystem, Property filePath + ) { this.fileSystem = new SimpleObjectProperty<>(); SimpleChangeListener.apply(fileSystem, val -> { this.fileSystem.setValue(val); @@ -32,31 +45,59 @@ public class ContextualFileReferenceChoiceComp extends SimpleComp { @Override protected Region createSimple() { - var fileNameComp = new TextFieldComp(filePath) - .apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS)) - .styleClass(Styles.LEFT_PILL) - .grow(false, true); + var fileNameComp = new TextFieldComp(filePath).apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS)).styleClass(Styles.LEFT_PILL).grow( + false, true); var fileBrowseButton = new ButtonComp(null, new FontIcon("mdi2f-folder-open-outline"), () -> { - StandaloneFileBrowser.openSingleFile(() -> fileSystem.getValue(), fileStore -> { - if (fileStore == null) { - filePath.setValue(null); - fileSystem.setValue(null); - } else { - filePath.setValue(fileStore.getPath()); - fileSystem.setValue(fileStore.getFileSystem()); - } - }); - }) - .styleClass(Styles.RIGHT_PILL) - .grow(false, true); + StandaloneFileBrowser.openSingleFile(() -> fileSystem.getValue(), fileStore -> { + if (fileStore == null) { + filePath.setValue(null); + fileSystem.setValue(null); + } else { + filePath.setValue(fileStore.getPath()); + fileSystem.setValue(fileStore.getFileSystem()); + } + }); + }).styleClass(Styles.CENTER_PILL).grow(false, true); - var layout = new HorizontalComp(List.of(fileNameComp, fileBrowseButton)) + + var canGitShare = BindingsHelper.persist(Bindings.createBooleanBinding(() -> { + if (!AppPrefs.get().enableGitStorage().get() || filePath.getValue() == null || ContextualFileReference.of(filePath.getValue()) + .isInDataDirectory()) { + return false; + } + + return true; + }, filePath, AppPrefs.get().enableGitStorage())); + var gitShareButton = new ButtonComp(null, new FontIcon("mdi2g-git"), () -> { + if (filePath.getValue() == null || filePath.getValue().isBlank() || + !canGitShare.get()) { + return; + } + + try { + var data = DataStorage.get().getDataDir(); + var f = data.resolve(FileNames.getFileName(filePath.getValue())); + var source = Path.of(filePath.getValue()); + if (Files.exists(source)) { + Files.copy(source, f, StandardCopyOption.REPLACE_EXISTING); + Platform.runLater(() -> { + filePath.setValue(f.toString()); + }); + } + } catch (Exception e) { + ErrorEvent.fromThrowable(e).handle(); + } + }); + gitShareButton.apply(new FancyTooltipAugment<>("gitShareFileTooltip")); + gitShareButton.styleClass(Styles.RIGHT_PILL).grow(false, true); + + var layout = new HorizontalComp(List.of(fileNameComp, fileBrowseButton, gitShareButton)) .apply(struc -> struc.get().setFillHeight(true)); layout.apply(struc -> { struc.get().focusedProperty().addListener((observable, oldValue, newValue) -> { - struc.get().getChildren().get(1).requestFocus(); + struc.get().getChildren().getFirst().requestFocus(); }); }); diff --git a/app/src/main/resources/io/xpipe/app/resources/lang/preferences_en.properties b/app/src/main/resources/io/xpipe/app/resources/lang/preferences_en.properties index 6435d215..95581303 100644 --- a/app/src/main/resources/io/xpipe/app/resources/lang/preferences_en.properties +++ b/app/src/main/resources/io/xpipe/app/resources/lang/preferences_en.properties @@ -5,6 +5,7 @@ appearance=Appearance integrations=Integrations uiOptions=UI Options theme=Theme +gitShareFileTooltip=Add file to the git vault data directory so that it is automatically synced.\n\nThis action can only be used when the git vault is enabled in the settings. performanceMode=Performance mode performanceModeDescription=Disables all visual effects that are not required to improve the application performance. editorProgram=Default Program