mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-01 17:47:30 +13:00
Show changelog before installing update
This commit is contained in:
parent
ea24d3e46e
commit
5b0fca5a14
7 changed files with 64 additions and 14 deletions
|
@ -16,6 +16,7 @@ import io.xpipe.core.store.FileSystem;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.css.PseudoClass;
|
import javafx.css.PseudoClass;
|
||||||
import javafx.geometry.Bounds;
|
import javafx.geometry.Bounds;
|
||||||
|
@ -89,7 +90,29 @@ final class FileListComp extends AnchorPane {
|
||||||
table.getStyleClass().add(Styles.STRIPED);
|
table.getStyleClass().add(Styles.STRIPED);
|
||||||
table.getColumns().setAll(filenameCol, sizeCol, mtimeCol);
|
table.getColumns().setAll(filenameCol, sizeCol, mtimeCol);
|
||||||
table.getSortOrder().add(filenameCol);
|
table.getSortOrder().add(filenameCol);
|
||||||
table.setSortPolicy(param -> true);
|
table.setSortPolicy(param -> {
|
||||||
|
var comp = table.getComparator();
|
||||||
|
if (comp == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parentFirst = new Comparator<FileSystem.FileEntry>() {
|
||||||
|
@Override
|
||||||
|
public int compare(FileSystem.FileEntry o1, FileSystem.FileEntry o2) {
|
||||||
|
var c = fileList.getFileSystemModel().getCurrentParentDirectory();
|
||||||
|
if (c == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return o1.getPath().equals(c.getPath()) ? -1 : (o2.getPath().equals(c.getPath()) ? 1 : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var dirsFirst = Comparator.<FileSystem.FileEntry, Boolean>comparing(path -> !path.isDirectory());
|
||||||
|
|
||||||
|
Comparator<? super FileSystem.FileEntry> us = parentFirst.thenComparing(dirsFirst).thenComparing(comp);
|
||||||
|
FXCollections.sort(table.getItems(), us);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||||
filenameCol.minWidthProperty().bind(table.widthProperty().multiply(0.5));
|
filenameCol.minWidthProperty().bind(table.widthProperty().multiply(0.5));
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import io.xpipe.app.update.AppUpdater;
|
import io.xpipe.app.update.AppUpdater;
|
||||||
|
import io.xpipe.app.update.UpdateAvailableAlert;
|
||||||
import io.xpipe.app.util.Hyperlinks;
|
import io.xpipe.app.util.Hyperlinks;
|
||||||
import io.xpipe.app.util.XPipeDistributionType;
|
import io.xpipe.app.util.XPipeDistributionType;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
|
@ -41,7 +42,7 @@ public class UpdateCheckComp extends SimpleComp {
|
||||||
|
|
||||||
private void restart() {
|
private void restart() {
|
||||||
AppUpdater.get().refreshUpdateCheckSilent();
|
AppUpdater.get().refreshUpdateCheckSilent();
|
||||||
AppUpdater.get().executeUpdateAndClose();
|
UpdateAvailableAlert.showIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void download() {
|
private void download() {
|
||||||
|
|
|
@ -34,6 +34,10 @@ public class AppCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clear() {
|
public static void clear() {
|
||||||
|
if (!Files.exists(getBasePath())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FileUtils.cleanDirectory(getBasePath().toFile());
|
FileUtils.cleanDirectory(getBasePath().toFile());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
|
||||||
import io.xpipe.app.comp.storage.store.StoreViewState;
|
import io.xpipe.app.comp.storage.store.StoreViewState;
|
||||||
import io.xpipe.app.core.*;
|
import io.xpipe.app.core.*;
|
||||||
import io.xpipe.app.issue.TrackEvent;
|
import io.xpipe.app.issue.TrackEvent;
|
||||||
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.app.update.UpdateAvailableAlert;
|
import io.xpipe.app.update.UpdateAvailableAlert;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
@ -74,7 +75,12 @@ public abstract class PlatformMode extends OperationMode {
|
||||||
ThreadHelper.sleep(100);
|
ThreadHelper.sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateAvailableAlert.showIfNeeded();
|
|
||||||
|
// If we downloaded an update, and decided to no longer automatically update, don't remind us!
|
||||||
|
// You can still update manually in the about tab
|
||||||
|
if (AppPrefs.get().automaticallyUpdate().get()) {
|
||||||
|
UpdateAvailableAlert.showIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
SourceCollectionViewState.init();
|
SourceCollectionViewState.init();
|
||||||
StoreViewState.init();
|
StoreViewState.init();
|
||||||
|
|
|
@ -12,6 +12,8 @@ import javafx.scene.control.TextField;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class TextFieldComp extends Comp<CompStructure<TextField>> {
|
public class TextFieldComp extends Comp<CompStructure<TextField>> {
|
||||||
|
|
||||||
private final Property<String> lastAppliedValue;
|
private final Property<String> lastAppliedValue;
|
||||||
|
@ -42,6 +44,9 @@ public class TextFieldComp extends Comp<CompStructure<TextField>> {
|
||||||
lastAppliedValue.addListener((c, o, n) -> {
|
lastAppliedValue.addListener((c, o, n) -> {
|
||||||
currentValue.setValue(n);
|
currentValue.setValue(n);
|
||||||
PlatformThread.runLaterIfNeeded(() -> {
|
PlatformThread.runLaterIfNeeded(() -> {
|
||||||
|
if (Objects.equals(text.getText(),n)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
text.setText(n);
|
text.setText(n);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -204,7 +204,7 @@ public class AppUpdater {
|
||||||
event("Executing update ...");
|
event("Executing update ...");
|
||||||
OperationMode.executeAfterShutdown(() -> {
|
OperationMode.executeAfterShutdown(() -> {
|
||||||
try {
|
try {
|
||||||
AppInstaller.installFileLocal(lastUpdateCheckResult.getValue().getAssetType(), downloadFile);
|
AppInstaller.installFileLocal(downloadedUpdate.getValue().getAssetType(), downloadFile);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package io.xpipe.app.update;
|
package io.xpipe.app.update;
|
||||||
|
|
||||||
|
import io.xpipe.app.comp.base.MarkdownComp;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.core.AppWindowHelper;
|
import io.xpipe.app.core.AppWindowHelper;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.ButtonBar;
|
||||||
|
import javafx.scene.control.ButtonType;
|
||||||
|
|
||||||
public class UpdateAvailableAlert {
|
public class UpdateAvailableAlert {
|
||||||
|
|
||||||
|
@ -12,17 +14,26 @@ public class UpdateAvailableAlert {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we downloaded an update, and decided to no longer automatically update, don't remind us!
|
var u = AppUpdater.get().getDownloadedUpdate().getValue();
|
||||||
// You can still update manually in the about tab
|
|
||||||
if (!AppPrefs.get().automaticallyUpdate().get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var update = AppWindowHelper.showBlockingAlert(alert -> {
|
var update = AppWindowHelper.showBlockingAlert(alert -> {
|
||||||
alert.setTitle(AppI18n.get("updateReadyAlertTitle"));
|
alert.setTitle(AppI18n.get("updateReadyAlertTitle"));
|
||||||
alert.setHeaderText(AppI18n.get("updateReadyAlertHeader", AppUpdater.get().getDownloadedUpdate().getValue().getVersion()));
|
alert.setAlertType(Alert.AlertType.NONE);
|
||||||
alert.getDialogPane().setContent(AppWindowHelper.alertContentText(AppI18n.get("updateReadyAlertContent")));
|
|
||||||
alert.setAlertType(Alert.AlertType.INFORMATION);
|
if (u.getBody() != null && !u.getBody().isBlank()) {
|
||||||
|
var markdown = new MarkdownComp(u.getBody(), s -> {
|
||||||
|
var header = "<h1>" + AppI18n.get("whatsNew", u.getVersion()) + "</h1>";
|
||||||
|
return header + s;
|
||||||
|
})
|
||||||
|
.createRegion();
|
||||||
|
alert.getDialogPane().setContent(markdown);
|
||||||
|
} else {
|
||||||
|
alert.getDialogPane()
|
||||||
|
.setContent(AppWindowHelper.alertContentText(AppI18n.get("updateReadyAlertContent")));
|
||||||
|
}
|
||||||
|
|
||||||
|
alert.getButtonTypes().clear();
|
||||||
|
alert.getButtonTypes().add(new ButtonType(AppI18n.get("update"), ButtonBar.ButtonData.OK_DONE));
|
||||||
|
alert.getButtonTypes().add(new ButtonType(AppI18n.get("ignore"), ButtonBar.ButtonData.NO));
|
||||||
})
|
})
|
||||||
.map(buttonType -> buttonType.getButtonData().isDefaultButton())
|
.map(buttonType -> buttonType.getButtonData().isDefaultButton())
|
||||||
.orElse(false);
|
.orElse(false);
|
||||||
|
|
Loading…
Reference in a new issue