mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
Rework updater to fix some bugs [release]
This commit is contained in:
parent
5444bc785f
commit
b1f2272fc2
9 changed files with 104 additions and 113 deletions
|
@ -38,6 +38,7 @@ public class FileBrowserComp extends SimpleComp {
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
var bookmarksList = new BookmarkList(model).createRegion();
|
var bookmarksList = new BookmarkList(model).createRegion();
|
||||||
|
VBox.setVgrow(bookmarksList, Priority.ALWAYS);
|
||||||
var localDownloadStage = new LocalFileTransferComp(model.getLocalTransfersStage()).hide(Bindings.createBooleanBinding(() -> {
|
var localDownloadStage = new LocalFileTransferComp(model.getLocalTransfersStage()).hide(Bindings.createBooleanBinding(() -> {
|
||||||
if (model.getOpenFileSystems().size() == 0) {
|
if (model.getOpenFileSystems().size() == 0) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -40,20 +40,16 @@ public class UpdateCheckComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restart() {
|
private void restart() {
|
||||||
// Check if we're still on latest
|
AppUpdater.get().refreshUpdateCheckSilent();
|
||||||
if (!AppUpdater.get().isDownloadedUpdateStillLatest()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppUpdater.get().executeUpdateAndClose();
|
AppUpdater.get().executeUpdateAndClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update() {
|
private void download() {
|
||||||
AppUpdater.get().downloadUpdateAsync();
|
AppUpdater.get().downloadUpdateAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refresh() {
|
private void refresh() {
|
||||||
AppUpdater.get().checkForUpdateAsync(true);
|
AppUpdater.get().checkForUpdateAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObservableValue<String> descriptionText() {
|
private ObservableValue<String> descriptionText() {
|
||||||
|
@ -131,8 +127,6 @@ public class UpdateCheckComp extends SimpleComp {
|
||||||
updateReady));
|
updateReady));
|
||||||
button.getStyleClass().add("button-comp");
|
button.getStyleClass().add("button-comp");
|
||||||
button.setOnAction(e -> {
|
button.setOnAction(e -> {
|
||||||
AppUpdater.get().refreshUpdateState();
|
|
||||||
|
|
||||||
if (updateReady.getValue()) {
|
if (updateReady.getValue()) {
|
||||||
restart();
|
restart();
|
||||||
return;
|
return;
|
||||||
|
@ -142,7 +136,7 @@ public class UpdateCheckComp extends SimpleComp {
|
||||||
Hyperlinks.open(
|
Hyperlinks.open(
|
||||||
AppUpdater.get().getLastUpdateCheckResult().getValue().getReleaseUrl());
|
AppUpdater.get().getLastUpdateCheckResult().getValue().getReleaseUrl());
|
||||||
} else if (updateAvailable.getValue()) {
|
} else if (updateAvailable.getValue()) {
|
||||||
update();
|
download();
|
||||||
} else {
|
} else {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class TerminalErrorHandler implements ErrorHandler {
|
||||||
private static void handleProbableUpdate() {
|
private static void handleProbableUpdate() {
|
||||||
try {
|
try {
|
||||||
AppUpdater.init();
|
AppUpdater.init();
|
||||||
var rel = AppUpdater.get().checkForUpdate(true);
|
var rel = AppUpdater.get().refreshUpdateCheck();
|
||||||
if (rel != null && rel.isUpdate()) {
|
if (rel != null && rel.isUpdate()) {
|
||||||
var update = AppWindowHelper.showBlockingAlert(alert -> {
|
var update = AppWindowHelper.showBlockingAlert(alert -> {
|
||||||
alert.setAlertType(Alert.AlertType.INFORMATION);
|
alert.setAlertType(Alert.AlertType.INFORMATION);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.xpipe.app.update;
|
package io.xpipe.app.update;
|
||||||
|
|
||||||
|
import io.xpipe.app.core.AppProperties;
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.issue.TrackEvent;
|
import io.xpipe.app.issue.TrackEvent;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
|
@ -96,26 +97,41 @@ public class AppDownloads {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getLatestVersion(boolean omitErrors) {
|
public static String getLatestVersion() throws IOException {
|
||||||
return getLatestSuitableRelease(omitErrors)
|
return getLatestSuitableRelease()
|
||||||
.map(ghRelease -> ghRelease.getTagName())
|
.map(ghRelease -> ghRelease.getTagName())
|
||||||
.orElse("?");
|
.orElse("?");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<GHRelease> getLatestSuitableRelease(boolean omitErrors) {
|
|
||||||
try {
|
|
||||||
var repo = getRepository();
|
|
||||||
|
|
||||||
// Always choose most up-to-date release as we assume that there are only full releases and prereleases
|
public static Optional<GHRelease> getLatestIncludingPreRelease() throws IOException {
|
||||||
if (AppPrefs.get() != null && AppPrefs.get().updateToPrereleases().get()) {
|
var repo = getRepository();
|
||||||
return Optional.ofNullable(repo.listReleases().iterator().next());
|
return Optional.ofNullable(repo.listReleases().iterator().next());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.ofNullable(repo.getLatestRelease());
|
public static Optional<GHRelease> getLatestRelease() throws IOException {
|
||||||
} catch (IOException e) {
|
var repo = getRepository();
|
||||||
ErrorEvent.fromThrowable("Unable to fetch latest release information", e).omitted(omitErrors).handle();
|
return Optional.ofNullable(repo.getLatestRelease());
|
||||||
return Optional.empty();
|
}
|
||||||
|
|
||||||
|
public static Optional<GHRelease> getLatestSuitableRelease() throws IOException {
|
||||||
|
var preIncluding = getLatestIncludingPreRelease();
|
||||||
|
|
||||||
|
if (AppPrefs.get() != null && AppPrefs.get().updateToPrereleases().get()) {
|
||||||
|
return preIncluding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are currently running a prerelease, always return this as the suitable release!
|
||||||
|
if (preIncluding.isPresent() && AppProperties.get().getVersion().equals(preIncluding.get().getTagName())) {
|
||||||
|
return preIncluding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this release is not a prerelease, just return it to prevent querying another release
|
||||||
|
if (preIncluding.isPresent() && !preIncluding.get().isPrerelease()) {
|
||||||
|
return preIncluding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getLatestRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<GHRelease> getRelease(String version, boolean omitErrors) {
|
public static Optional<GHRelease> getRelease(String version, boolean omitErrors) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import lombok.With;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
import org.kohsuke.github.GHRelease;
|
import org.kohsuke.github.GHRelease;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
@ -50,6 +51,8 @@ public class AppUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadedUpdate.setValue(AppCache.get("downloadedUpdate", DownloadedUpdate.class, () -> null));
|
downloadedUpdate.setValue(AppCache.get("downloadedUpdate", DownloadedUpdate.class, () -> null));
|
||||||
|
|
||||||
|
// Check if the original version this was downloaded from is still the same
|
||||||
if (downloadedUpdate.getValue() != null
|
if (downloadedUpdate.getValue() != null
|
||||||
&& !downloadedUpdate
|
&& !downloadedUpdate
|
||||||
.getValue()
|
.getValue()
|
||||||
|
@ -57,6 +60,16 @@ public class AppUpdater {
|
||||||
.equals(AppProperties.get().getVersion())) {
|
.equals(AppProperties.get().getVersion())) {
|
||||||
downloadedUpdate.setValue(null);
|
downloadedUpdate.setValue(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if somehow the downloaded version is equal to the current one
|
||||||
|
if (downloadedUpdate.getValue() != null
|
||||||
|
&& downloadedUpdate
|
||||||
|
.getValue()
|
||||||
|
.getVersion()
|
||||||
|
.equals(AppProperties.get().getVersion())) {
|
||||||
|
downloadedUpdate.setValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
if (!XPipeDistributionType.get().supportsUpdate()) {
|
if (!XPipeDistributionType.get().supportsUpdate()) {
|
||||||
downloadedUpdate.setValue(null);
|
downloadedUpdate.setValue(null);
|
||||||
}
|
}
|
||||||
|
@ -64,20 +77,10 @@ public class AppUpdater {
|
||||||
downloadedUpdate.addListener((c, o, n) -> {
|
downloadedUpdate.addListener((c, o, n) -> {
|
||||||
AppCache.update("downloadedUpdate", n);
|
AppCache.update("downloadedUpdate", n);
|
||||||
});
|
});
|
||||||
|
|
||||||
lastUpdateCheckResult.setValue(AppCache.get("lastUpdateCheckResult", AvailableRelease.class, () -> null));
|
|
||||||
if (lastUpdateCheckResult.getValue() != null
|
|
||||||
&& lastUpdateCheckResult.getValue().getSourceVersion() != null
|
|
||||||
&& !lastUpdateCheckResult
|
|
||||||
.getValue()
|
|
||||||
.getSourceVersion()
|
|
||||||
.equals(AppProperties.get().getVersion())) {
|
|
||||||
lastUpdateCheckResult.setValue(null);
|
|
||||||
}
|
|
||||||
event("Last update check result was " + lastUpdateCheckResult.getValue());
|
|
||||||
lastUpdateCheckResult.addListener((c, o, n) -> {
|
lastUpdateCheckResult.addListener((c, o, n) -> {
|
||||||
AppCache.update("lastUpdateCheckResult", n);
|
downloadedUpdate.setValue(null);
|
||||||
});
|
});
|
||||||
|
refreshUpdateCheckSilent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void event(String msg) {
|
private static void event(String msg) {
|
||||||
|
@ -94,14 +97,17 @@ public class AppUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANCE = new AppUpdater();
|
INSTANCE = new AppUpdater();
|
||||||
|
startBackgroundUpdater();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startBackgroundUpdater() {
|
||||||
if (XPipeDistributionType.get().supportsUpdate()
|
if (XPipeDistributionType.get().supportsUpdate()
|
||||||
&& XPipeDistributionType.get() != XPipeDistributionType.DEVELOPMENT) {
|
&& XPipeDistributionType.get() != XPipeDistributionType.DEVELOPMENT) {
|
||||||
ThreadHelper.create("updater", true, () -> {
|
ThreadHelper.create("updater", true, () -> {
|
||||||
ThreadHelper.sleep(Duration.ofMinutes(10).toMillis());
|
ThreadHelper.sleep(Duration.ofMinutes(10).toMillis());
|
||||||
event("Starting background updater thread");
|
event("Starting background updater thread");
|
||||||
while (true) {
|
while (true) {
|
||||||
var rel = INSTANCE.checkForUpdate(false);
|
var rel = INSTANCE.refreshUpdateCheckSilent();
|
||||||
if (rel != null
|
if (rel != null
|
||||||
&& AppPrefs.get().automaticallyUpdate().get() && rel.isUpdate()) {
|
&& AppPrefs.get().automaticallyUpdate().get() && rel.isUpdate()) {
|
||||||
event("Performing background update");
|
event("Performing background update");
|
||||||
|
@ -115,7 +121,7 @@ public class AppUpdater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isUpdate(String currentVersion) {
|
private static boolean isUpdate(String releaseVersion) {
|
||||||
if (AppPrefs.get() != null
|
if (AppPrefs.get() != null
|
||||||
&& AppPrefs.get().developerMode().getValue()
|
&& AppPrefs.get().developerMode().getValue()
|
||||||
&& AppPrefs.get().developerDisableUpdateVersionCheck().get()) {
|
&& AppPrefs.get().developerDisableUpdateVersionCheck().get()) {
|
||||||
|
@ -123,10 +129,7 @@ public class AppUpdater {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (!AppProperties.get().getVersion().equals(releaseVersion)) {
|
||||||
// true
|
|
||||||
// ||
|
|
||||||
!AppProperties.get().getVersion().equals(currentVersion)) {
|
|
||||||
event("Release has a different version");
|
event("Release has a different version");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -134,13 +137,6 @@ public class AppUpdater {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshUpdateState() {
|
|
||||||
if (lastUpdateCheckResult.getValue() != null
|
|
||||||
&& !isUpdate(lastUpdateCheckResult.getValue().getVersion())) {
|
|
||||||
lastUpdateCheckResult.setValue(lastUpdateCheckResult.getValue().withUpdate(false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void downloadUpdateAsync() {
|
public void downloadUpdateAsync() {
|
||||||
ThreadHelper.runAsync(() -> downloadUpdate());
|
ThreadHelper.runAsync(() -> downloadUpdate());
|
||||||
}
|
}
|
||||||
|
@ -158,6 +154,10 @@ public class AppUpdater {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!lastUpdateCheckResult.getValue().isUpdate()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try (var ignored = new BusyProperty(busy)) {
|
try (var ignored = new BusyProperty(busy)) {
|
||||||
event("Performing update download ...");
|
event("Performing update download ...");
|
||||||
try {
|
try {
|
||||||
|
@ -184,20 +184,12 @@ public class AppUpdater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldPerformUpdate() {
|
public void executeUpdateAndClose() {
|
||||||
if (busy.getValue()) {
|
if (busy.getValue()) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadedUpdate.getValue() == null) {
|
if (downloadedUpdate.getValue() == null) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void executeUpdateAndClose() {
|
|
||||||
if (!shouldPerformUpdate()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,69 +214,57 @@ public class AppUpdater {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkForUpdateAsync(boolean forceCheck) {
|
public void checkForUpdateAsync() {
|
||||||
ThreadHelper.runAsync(() -> checkForUpdate(forceCheck));
|
ThreadHelper.runAsync(() -> refreshUpdateCheckSilent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean isDownloadedUpdateStillLatest() {
|
public synchronized AvailableRelease refreshUpdateCheckSilent() {
|
||||||
if (downloadedUpdate.getValue() == null) {
|
try {
|
||||||
return false;
|
return refreshUpdateCheck();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ErrorEvent.fromThrowable(ex).omit().handle();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var available = checkForUpdate(true);
|
|
||||||
if (available == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return downloadedUpdate.getValue() != null
|
|
||||||
&& available.getVersion().equals(downloadedUpdate.getValue().getVersion());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized AvailableRelease checkForUpdate(boolean forceCheck) {
|
public synchronized AvailableRelease refreshUpdateCheck() throws IOException {
|
||||||
if (busy.getValue()) {
|
if (busy.getValue()) {
|
||||||
return lastUpdateCheckResult.getValue();
|
return lastUpdateCheckResult.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forceCheck
|
|
||||||
&& lastUpdateCheckResult.getValue() != null
|
|
||||||
&& Duration.between(lastUpdateCheckResult.getValue().getCheckTime(), Instant.now())
|
|
||||||
.compareTo(Duration.ofHours(1))
|
|
||||||
<= 0) {
|
|
||||||
return lastUpdateCheckResult.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
try (var ignored = new BusyProperty(busy)) {
|
try (var ignored = new BusyProperty(busy)) {
|
||||||
var rel = AppDownloads.getLatestSuitableRelease(!forceCheck);
|
var rel = AppDownloads.getLatestSuitableRelease();
|
||||||
event("Determined latest suitable release "
|
event("Determined latest suitable release "
|
||||||
+ rel.map(GHRelease::getName).orElse(null));
|
+ rel.map(GHRelease::getName).orElse(null));
|
||||||
lastUpdateCheckResult.setValue(null);
|
|
||||||
if (rel.isEmpty()) {
|
if (rel.isEmpty()) {
|
||||||
|
lastUpdateCheckResult.setValue(null);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isUpdate = isUpdate(rel.get().getTagName());
|
// Don't update value if result is the same
|
||||||
try {
|
if (lastUpdateCheckResult.getValue() != null && lastUpdateCheckResult.getValue().getVersion().equals(rel.get().getTagName())) {
|
||||||
var assetType = AppInstaller.getSuitablePlatformAsset();
|
return lastUpdateCheckResult.getValue();
|
||||||
var ghAsset = rel.orElseThrow().listAssets().toList().stream()
|
|
||||||
.filter(g -> assetType.isCorrectAsset(g.getName()))
|
|
||||||
.findAny();
|
|
||||||
if (ghAsset.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
event("Selected asset " + ghAsset.get().getName());
|
|
||||||
lastUpdateCheckResult.setValue(new AvailableRelease(
|
|
||||||
AppProperties.get().getVersion(),
|
|
||||||
rel.get().getTagName(),
|
|
||||||
rel.get().getHtmlUrl().toString(),
|
|
||||||
ghAsset.get().getBrowserDownloadUrl(),
|
|
||||||
assetType,
|
|
||||||
Instant.now(),
|
|
||||||
isUpdate));
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ErrorEvent.fromThrowable(ex).omit().handle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isUpdate = isUpdate(rel.get().getTagName());
|
||||||
|
var assetType = AppInstaller.getSuitablePlatformAsset();
|
||||||
|
var ghAsset = rel.orElseThrow().listAssets().toList().stream()
|
||||||
|
.filter(g -> assetType.isCorrectAsset(g.getName()))
|
||||||
|
.findAny();
|
||||||
|
if (ghAsset.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
event("Selected asset " + ghAsset.get().getName());
|
||||||
|
lastUpdateCheckResult.setValue(new AvailableRelease(
|
||||||
|
AppProperties.get().getVersion(),
|
||||||
|
rel.get().getTagName(),
|
||||||
|
rel.get().getHtmlUrl().toString(),
|
||||||
|
ghAsset.get().getBrowserDownloadUrl(),
|
||||||
|
assetType,
|
||||||
|
Instant.now(),
|
||||||
|
isUpdate));
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastUpdateCheckResult.getValue();
|
return lastUpdateCheckResult.getValue();
|
||||||
|
|
|
@ -18,11 +18,6 @@ public class UpdateAvailableAlert {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AppUpdater.get().getDownloadedUpdate().getValue() != null && !AppUpdater.get().isDownloadedUpdateStillLatest()) {
|
|
||||||
AppUpdater.get().getDownloadedUpdate().setValue(null);
|
|
||||||
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.setHeaderText(AppI18n.get("updateReadyAlertHeader", AppUpdater.get().getDownloadedUpdate().getValue().getVersion()));
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class ProxyManagerProviderImpl extends ProxyManagerProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> checkCompatibility(ShellControl s) throws Exception {
|
public Optional<String> checkCompatibility(ShellControl s) throws Exception {
|
||||||
var version = ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion(true);
|
var version = ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion();
|
||||||
|
|
||||||
if (AppPrefs.get().developerDisableConnectorInstallationVersionCheck().get()) {
|
if (AppPrefs.get().developerDisableConnectorInstallationVersionCheck().get()) {
|
||||||
return Optional.of(AppI18n.get("versionCheckOverride"));
|
return Optional.of(AppI18n.get("versionCheckOverride"));
|
||||||
|
@ -59,7 +59,7 @@ public class ProxyManagerProviderImpl extends ProxyManagerProvider {
|
||||||
if (message.isPresent()) {
|
if (message.isPresent()) {
|
||||||
if (showAlert()) {
|
if (showAlert()) {
|
||||||
var version =
|
var version =
|
||||||
ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion(true);
|
ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion();
|
||||||
AppInstaller.installOnRemoteMachine(s, version);
|
AppInstaller.installOnRemoteMachine(s, version);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
5
dist/changelogs/0.5.29.md
vendored
Normal file
5
dist/changelogs/0.5.29.md
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
- Introduce new download functionality in the file browser
|
||||||
|
- Allow for the creation of desktop shortcuts on portable distributions as well
|
||||||
|
- Fix file sizes sometimes being incorrectly displayed
|
||||||
|
- Fix background updater downloading the same version
|
||||||
|
- Fix various small bugs
|
2
version
2
version
|
@ -1 +1 @@
|
||||||
0.5.28
|
0.5.29
|
Loading…
Reference in a new issue