Merge pull request #1705 from SiboVG/updated_updater

Updated software updater layout
This commit is contained in:
Sibo Van Gool 2022-10-04 20:28:01 +02:00 committed by GitHub
commit 2e96683509
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 48 deletions

View File

@ -306,7 +306,7 @@ pref.dlg.Allthrustcurvefiles = All thrust curve files (*.eng; *.rse; *.zip; dire
pref.dlg.RASPfiles = RASP motor files (*.eng) pref.dlg.RASPfiles = RASP motor files (*.eng)
pref.dlg.RockSimfiles = RockSim engine files (*.rse) pref.dlg.RockSimfiles = RockSim engine files (*.rse)
pref.dlg.ZIParchives = ZIP archives (*.zip) pref.dlg.ZIParchives = ZIP archives (*.zip)
pref.dlg.checkbox.Checkupdates = Check for software updates at startup pref.dlg.checkbox.Checkupdates = Always check for software updates at startup
pref.dlg.checkbox.Checkupdates.ttip = Check for software updates every time you start up OpenRocket pref.dlg.checkbox.Checkupdates.ttip = Check for software updates every time you start up OpenRocket
pref.dlg.checkbox.CheckBetaupdates = Also check for beta releases pref.dlg.checkbox.CheckBetaupdates = Also check for beta releases
pref.dlg.checkbox.CheckBetaupdates.ttip = If checked, beta release updates are also notified. If unchecked, only official releases are considered. pref.dlg.checkbox.CheckBetaupdates.ttip = If checked, beta release updates are also notified. If unchecked, only official releases are considered.
@ -363,11 +363,11 @@ update.dlg.latestVersion = You are running the latest version of OpenRocket, ver
update.dlg.newerVersion.title = Newer version detected update.dlg.newerVersion.title = Newer version detected
update.dlg.newerVersion = You are either running a test/unofficial release of OpenRocket, or you have a time machine and are running an official release from the future.\n\nYour version: %s\nLatest official release: %s update.dlg.newerVersion = You are either running a test/unofficial release of OpenRocket, or you have a time machine and are running an official release from the future.\n\nYour version: %s\nLatest official release: %s
update.dlg.updateAvailable.title = Update available update.dlg.updateAvailable.title = Update available
update.dlg.updateAvailable.txtPane.title = OpenRocket version %s available! update.dlg.updateAvailable.lbl.title = A new version of OpenRocket is available!
update.dlg.updateAvailable.txtPane.yourVersion = Your current version: %s update.dlg.updateAvailable.lbl.yourVersion = OpenRocket %s is available! \u2015 you have %s. Would you like to download it now?
update.dlg.updateAvailable.txtPane.changelog = Changelog update.dlg.updateAvailable.lbl.releaseNotes = Release notes:
update.dlg.updateAvailable.txtPane.readMore = Read more on GitHub update.dlg.updateAvailable.txtPane.readMore = Read more on GitHub
update.dlg.updateAvailable.but.install = Install update update.dlg.updateAvailable.but.install = Install Update
update.dlg.updateAvailable.combo.noDownloads = No downloads available update.dlg.updateAvailable.combo.noDownloads = No downloads available
update.fetcher.badResponse = Bad response code from server: %d update.fetcher.badResponse = Bad response code from server: %d
update.fetcher.badConnection = Could not connect to the GitHub server. Please check your internet connection. update.fetcher.badConnection = Could not connect to the GitHub server. Please check your internet connection.

View File

@ -58,6 +58,7 @@ public abstract class Preferences implements ChangeSource {
private static final String CHECK_UPDATES = "CheckUpdates"; private static final String CHECK_UPDATES = "CheckUpdates";
private static final String IGNORE_VERSIONS = "IgnoreVersions";
private static final String CHECK_BETA_UPDATES = "CheckBetaUpdates"; private static final String CHECK_BETA_UPDATES = "CheckBetaUpdates";
public static final String MOTOR_DIAMETER_FILTER = "MotorDiameterMatch"; public static final String MOTOR_DIAMETER_FILTER = "MotorDiameterMatch";
@ -150,6 +151,14 @@ public abstract class Preferences implements ChangeSource {
this.putBoolean(CHECK_UPDATES, check); this.putBoolean(CHECK_UPDATES, check);
} }
public final List<String> getIgnoreVersions() {
return List.of(this.getString(IGNORE_VERSIONS, "").split("\n"));
}
public final void setIgnoreVersions(List<String> versions) {
this.putString(IGNORE_VERSIONS, String.join("\n", versions));
}
public final boolean getCheckBetaUpdates() { public final boolean getCheckBetaUpdates() {
return this.getBoolean(CHECK_BETA_UPDATES, BuildProperties.getDefaultCheckBetaUpdates()); return this.getBoolean(CHECK_BETA_UPDATES, BuildProperties.getDefaultCheckBetaUpdates());
} }

View File

@ -32,7 +32,7 @@ public class AssetHandler {
mapExtensionToPlatform.put(".sh", new UpdatePlatform[] {UpdatePlatform.LINUX, UpdatePlatform.UNIX}); mapExtensionToPlatform.put(".sh", new UpdatePlatform[] {UpdatePlatform.LINUX, UpdatePlatform.UNIX});
mapExtensionToPlatform.put(".jar", new UpdatePlatform[] {UpdatePlatform.JAR}); mapExtensionToPlatform.put(".jar", new UpdatePlatform[] {UpdatePlatform.JAR});
mapPlatformToName.put(UpdatePlatform.MAC_OS, "Mac OS"); mapPlatformToName.put(UpdatePlatform.MAC_OS, "macOS");
mapPlatformToName.put(UpdatePlatform.WINDOWS, "Windows"); mapPlatformToName.put(UpdatePlatform.WINDOWS, "Windows");
mapPlatformToName.put(UpdatePlatform.LINUX, "Linux"); mapPlatformToName.put(UpdatePlatform.LINUX, "Linux");
mapPlatformToName.put(UpdatePlatform.UNIX, "Linux"); mapPlatformToName.put(UpdatePlatform.UNIX, "Linux");
@ -42,7 +42,7 @@ public class AssetHandler {
/** /**
* Maps a list of asset URLs to their respective operating platform name. * Maps a list of asset URLs to their respective operating platform name.
* E.g. "https://github.com/openrocket/openrocket/releases/download/release-15.03/OpenRocket-15.03.dmg" is mapped a * E.g. "https://github.com/openrocket/openrocket/releases/download/release-15.03/OpenRocket-15.03.dmg" is mapped a
* map element with "Mac OS" as key and the url as value. * map element with "macOS" as key and the url as value.
* @param urls list of asset URLs * @param urls list of asset URLs
* @return map with as key the operating platform name and as value the corresponding asset URL * @return map with as key the operating platform name and as value the corresponding asset URL
*/ */
@ -70,7 +70,7 @@ public class AssetHandler {
} }
/** /**
* Get the name of a platform (e.g. for Platform.MAC_OS, return "Mac OS") * Get the name of a platform (e.g. for Platform.MAC_OS, return "macOS")
* @param platform platform to get the name from * @param platform platform to get the name from
* @return name of the platform * @return name of the platform
*/ */

View File

@ -7,6 +7,7 @@ import java.awt.Insets;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -28,6 +29,8 @@ import net.sf.openrocket.communication.AssetHandler;
import net.sf.openrocket.communication.AssetHandler.UpdatePlatform; import net.sf.openrocket.communication.AssetHandler.UpdatePlatform;
import net.sf.openrocket.communication.ReleaseInfo; import net.sf.openrocket.communication.ReleaseInfo;
import net.sf.openrocket.communication.UpdateInfo; import net.sf.openrocket.communication.UpdateInfo;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.configdialog.CommonStrings;
import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.Icons; import net.sf.openrocket.gui.util.Icons;
import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.gui.util.SwingPreferences;
@ -55,8 +58,19 @@ public class UpdateInfoDialog extends JDialog {
JPanel panel = new JPanel(new MigLayout("insets n n 8px n, fill")); JPanel panel = new JPanel(new MigLayout("insets n n 8px n, fill"));
panel.add(new JLabel(Icons.loadImageIcon("pix/icon/icon-about.png", "OpenRocket")), panel.add(new JLabel(Icons.getScaledIcon(Icons.loadImageIcon("pix/icon/icon-about.png", "OpenRocket"), 0.6)),
"split, span, top"); "spany, top, gapright 20px, cell 0 0");
// OpenRocket version available!
panel.add(new StyledLabel(trans.get("update.dlg.updateAvailable.lbl.title"), 8, StyledLabel.Style.BOLD), "spanx, wrap");
// Your version
ReleaseInfo release = info.getLatestRelease();
panel.add(new StyledLabel(String.format(trans.get("update.dlg.updateAvailable.lbl.yourVersion"),
release.getReleaseName(), BuildProperties.getVersion()), -1, StyledLabel.Style.PLAIN), "skip 1, spanx, wrap para");
// Release notes
panel.add(new StyledLabel(trans.get("update.dlg.updateAvailable.lbl.releaseNotes"), 1, StyledLabel.Style.BOLD), "spanx, wrap");
// Release information box // Release information box
final JTextPane textPane = new JTextPane(); final JTextPane textPane = new JTextPane();
@ -65,18 +79,10 @@ public class UpdateInfoDialog extends JDialog {
textPane.setMargin(new Insets(10, 10, 40, 10)); textPane.setMargin(new Insets(10, 10, 40, 10));
textPane.putClientProperty(JTextPane.HONOR_DISPLAY_PROPERTIES, true); textPane.putClientProperty(JTextPane.HONOR_DISPLAY_PROPERTIES, true);
ReleaseInfo release = info.getLatestRelease();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
// OpenRocket version available!
sb.append("<html>"); sb.append("<html>");
sb.append(String.format("<h1>%s</h1>", String.format(trans.get("update.dlg.updateAvailable.txtPane.title"), release.getReleaseName())));
// Your version // Release notes
sb.append(String.format("<i>%s</i> <br><br>", String.format(trans.get("update.dlg.updateAvailable.txtPane.yourVersion"), BuildProperties.getVersion())));
// Changelog
sb.append(String.format("<h2>%s</h2>", trans.get("update.dlg.updateAvailable.txtPane.changelog")));
String releaseNotes = release.getReleaseNotes(); String releaseNotes = release.getReleaseNotes();
releaseNotes = releaseNotes.replaceAll("^\"|\"$", ""); // Remove leading and trailing quotations releaseNotes = releaseNotes.replaceAll("^\"|\"$", ""); // Remove leading and trailing quotations
sb.append(MarkdownUtil.toHtml(releaseNotes)).append("<br><br>"); sb.append(MarkdownUtil.toHtml(releaseNotes)).append("<br><br>");
@ -103,7 +109,7 @@ public class UpdateInfoDialog extends JDialog {
textPane.setText(sb.toString()); textPane.setText(sb.toString());
textPane.setCaretPosition(0); // Scroll to the top textPane.setCaretPosition(0); // Scroll to the top
panel.add(new JScrollPane(textPane), "left, grow, span, push, gapleft 40px, gapbottom 6px, wrap"); panel.add(new JScrollPane(textPane), "skip 1, left, spanx, grow, push, gapbottom 6px, wrap");
//// Check for software updates at startup //// Check for software updates at startup
JCheckBox checkAtStartup = new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates")); JCheckBox checkAtStartup = new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates"));
@ -116,9 +122,36 @@ public class UpdateInfoDialog extends JDialog {
preferences.setCheckUpdates(checkAtStartup.isSelected()); preferences.setCheckUpdates(checkAtStartup.isSelected());
} }
}); });
panel.add(checkAtStartup); panel.add(checkAtStartup, "skip 1, spanx, wrap");
// Install operating system combo box // Lower row buttons
//// Remind me later button
JButton btnLater = new SelectColorButton("Remind Me Later");
btnLater.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
UpdateInfoDialog.this.dispose();
}
});
panel.add(btnLater, "skip 1, split 2");
//// Skip this version button
JButton btnSkip = new SelectColorButton("Skip This Version");
btnSkip.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
List<String> ignoreVersions = new ArrayList<>(preferences.getIgnoreVersions());
String ignore = release.getReleaseName();
if (!ignoreVersions.contains(ignore)) {
ignoreVersions.add(ignore);
preferences.setIgnoreVersions(ignoreVersions);
}
UpdateInfoDialog.this.dispose();
}
});
panel.add(btnSkip);
//// Install operating system combo box
List<String> assetURLs = release.getAssetURLs(); List<String> assetURLs = release.getAssetURLs();
Map<UpdatePlatform, String> mappedAssets = AssetHandler.mapURLToPlatform(assetURLs); Map<UpdatePlatform, String> mappedAssets = AssetHandler.mapURLToPlatform(assetURLs);
JComboBox<Object> comboBox; JComboBox<Object> comboBox;
@ -141,7 +174,7 @@ public class UpdateInfoDialog extends JDialog {
} }
panel.add(comboBox, "pushx, right"); panel.add(comboBox, "pushx, right");
// Install update button //// Install update button
JButton btnInstall = new SelectColorButton(trans.get("update.dlg.updateAvailable.but.install")); JButton btnInstall = new SelectColorButton(trans.get("update.dlg.updateAvailable.but.install"));
btnInstall.addActionListener(new ActionListener() { btnInstall.addActionListener(new ActionListener() {
@Override @Override
@ -159,25 +192,15 @@ public class UpdateInfoDialog extends JDialog {
if (mappedAssets == null || mappedAssets.size() == 0) { if (mappedAssets == null || mappedAssets.size() == 0) {
btnInstall.setEnabled(false); btnInstall.setEnabled(false);
} }
panel.add(btnInstall, "gapright 20"); panel.add(btnInstall, "wrap");
// Cancel button panel.setPreferredSize(new Dimension(850, 700));
JButton btnCancel = new SelectColorButton(trans.get("button.cancel"));
btnCancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
UpdateInfoDialog.this.dispose();
}
});
panel.add(btnCancel);
panel.setPreferredSize(new Dimension(900, 600));
this.add(panel); this.add(panel);
this.pack(); this.pack();
this.setLocationRelativeTo(null); this.setLocationRelativeTo(null);
GUIUtil.setDisposableDialogOptions(this, btnCancel); GUIUtil.setDisposableDialogOptions(this, btnLater);
} }
/** /**

View File

@ -326,6 +326,13 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
// Nothing went wrong (yay!) // Nothing went wrong (yay!)
ReleaseStatus status = info.getReleaseStatus(); ReleaseStatus status = info.getReleaseStatus();
ReleaseInfo release = info.getLatestRelease(); ReleaseInfo release = info.getLatestRelease();
// Do nothing if the release is part of the ignore versions
if (preferences.getIgnoreVersions().contains(release.getReleaseName())) {
return;
}
// Display software updater dialog, based on the current build version status
switch (status) { switch (status) {
case LATEST: case LATEST:
JOptionPane.showMessageDialog(this, JOptionPane.showMessageDialog(this,

View File

@ -7,6 +7,7 @@ import java.awt.desktop.PreferencesHandler;
import java.awt.desktop.QuitHandler; import java.awt.desktop.QuitHandler;
import java.awt.desktop.AppReopenedListener; import java.awt.desktop.AppReopenedListener;
import net.sf.openrocket.communication.UpdateInfoRetriever;
import net.sf.openrocket.gui.util.DummyFrameMenuOSX; import net.sf.openrocket.gui.util.DummyFrameMenuOSX;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -56,6 +57,10 @@ final class OSXSetup {
if (BasicFrame.isFramesEmpty()) { if (BasicFrame.isFramesEmpty()) {
log.info("App re-opened"); log.info("App re-opened");
BasicFrame.reopen(); BasicFrame.reopen();
// Also check for software updates
final UpdateInfoRetriever updateRetriever = SwingStartup.startUpdateChecker();
SwingStartup.checkUpdateStatus(updateRetriever);
} }
}; };

View File

@ -193,15 +193,7 @@ public class SwingStartup {
guiModule.startLoader(); guiModule.startLoader();
// Start update info fetching // Start update info fetching
final UpdateInfoRetriever updateRetriever; final UpdateInfoRetriever updateRetriever = startUpdateChecker();
if (Application.getPreferences().getCheckUpdates()) {
log.info("Starting update check");
updateRetriever = new UpdateInfoRetriever();
updateRetriever.startFetchUpdateInfo();
} else {
log.info("Update check disabled");
updateRetriever = null;
}
// Set the best available look-and-feel // Set the best available look-and-feel
log.info("Setting best LAF"); log.info("Setting best LAF");
@ -249,8 +241,20 @@ public class SwingStartup {
} }
public static UpdateInfoRetriever startUpdateChecker() {
final UpdateInfoRetriever updateRetriever;
if (Application.getPreferences().getCheckUpdates()) {
log.info("Starting update check");
updateRetriever = new UpdateInfoRetriever();
updateRetriever.startFetchUpdateInfo();
} else {
log.info("Update check disabled");
updateRetriever = null;
}
return updateRetriever;
}
private void checkUpdateStatus(final UpdateInfoRetriever updateRetriever) { public static void checkUpdateStatus(final UpdateInfoRetriever updateRetriever) {
if (updateRetriever == null) if (updateRetriever == null)
return; return;
@ -268,10 +272,12 @@ public class SwingStartup {
if (!updateRetriever.isRunning()) { if (!updateRetriever.isRunning()) {
timer.stop(); timer.stop();
final SwingPreferences preferences = (SwingPreferences) Application.getPreferences();
UpdateInfo info = updateRetriever.getUpdateInfo(); UpdateInfo info = updateRetriever.getUpdateInfo();
// Only display something when an update is found // Only display something when an update is found
if (info != null && info.getException() == null && info.getReleaseStatus() == ReleaseStatus.OLDER) { if (info != null && info.getException() == null && info.getReleaseStatus() == ReleaseStatus.OLDER &&
!preferences.getIgnoreVersions().contains(info.getLatestRelease().getReleaseName())) {
UpdateInfoDialog infoDialog = new UpdateInfoDialog(info); UpdateInfoDialog infoDialog = new UpdateInfoDialog(info);
infoDialog.setVisible(true); infoDialog.setVisible(true);
} }