From ce8c4349310f77b3e33b63eaa4b44ce5207ee0b3 Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Sat, 23 Mar 2019 20:05:48 +0300 Subject: [PATCH] v0.3.1 1. Add 'check for new versions' feature. 2. Fixed broken (was it broken?) error pop-up window. --- README.md | 10 +-- pom.xml | 2 +- src/main/java/nsusbloader/AppPreferences.java | 7 ++- .../Controllers/NSLMainController.java | 31 +++++++-- .../Controllers/SettingsController.java | 59 ++++++++++++++++- .../ModelControllers/UpdatesChecker.java | 63 +++++++++++++++++++ src/main/java/nsusbloader/NSLMain.java | 3 +- src/main/java/nsusbloader/ServiceWindow.java | 22 +++++-- src/main/resources/SettingsTab.fxml | 15 +++++ src/main/resources/locale.properties | 6 ++ src/main/resources/locale_fra.properties | 6 ++ src/main/resources/locale_rus.properties | 6 ++ src/main/resources/locale_ukr.properties | 8 ++- src/main/resources/res/app_dark.css | 6 ++ src/main/resources/res/app_light.css | 6 ++ 15 files changed, 229 insertions(+), 21 deletions(-) create mode 100644 src/main/java/nsusbloader/ModelControllers/UpdatesChecker.java diff --git a/README.md b/README.md index 9ce688d..25ab65e 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,6 @@ Double-click on downloaded .jar file. Follow instructions. Or see 'Linux' sectio Set 'Security & Privacy' settings if needed. -If you use different MacOS (not Mojave) - check release section for another JAR file. - ##### Windows: * Download Zadig: [https://zadig.akeo.ie/](https://zadig.akeo.ie/) @@ -102,7 +100,9 @@ usb4java since NS-USBloader-v0.2.3 switched to 1.2.0 instead of 1.3.0. This shou ### Translators! Traductores! Übersetzer! Թարգմանիչներ! If you want to see this app translated to your language, go grab [this file](https://github.com/developersu/ns-usbloader/blob/master/src/main/resources/locale.properties) and translate it. -Upload somewhere (pastebin? google drive? whatever else). [Create new issue](https://github.com/developersu/ns-usbloader/issues) and post a link. I'll grab it and add. +Upload somewhere (pastebin? google drive? whatever else). [Create new issue](https://github.com/developersu/ns-usbloader/issues) and post a link. I'll grab it and add. + +NOTE: actually it's not gonna work in real, because we should stay in touch and I'll need you when add something that should be translated =( #### Thanks for great work done by our translater~~s team~~! @@ -113,7 +113,7 @@ Français by [Stephane Meden (JackFromNice)](https://github.com/JackFromNice) - [x] macOS QA v0.1 (Mojave) - [x] macOS QA v0.2.2 (Mojave) - [x] macOS QA v0.2.3-DEV (High Sierra) -- [ ] macOS QA v0.3 (Mojave, High Sierra) +- [x] macOS QA v0.3 (all) - [x] Windows support - [x] code refactoring - [x] GoldLeaf support @@ -121,6 +121,8 @@ Français by [Stephane Meden (JackFromNice)](https://github.com/JackFromNice) - [ ] File order sort (non-critical) - [ ] More deep file analyze before uploading. - [x] Network mode support for TinFoil +- [x] 'Check for application updates' functionality + #### Thanks Appreciate assistance and support of both Vitaliy and Konstantin. Without you all this magic would not have happened. diff --git a/pom.xml b/pom.xml index 30bc6e0..8cd9b25 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ NS-USBloader ns-usbloader - 0.3-SNAPSHOT + 0.3.1-SNAPSHOT https://github.com/developersu/ns-usbloader/ diff --git a/src/main/java/nsusbloader/AppPreferences.java b/src/main/java/nsusbloader/AppPreferences.java index 83d03b1..d9f7968 100644 --- a/src/main/java/nsusbloader/AppPreferences.java +++ b/src/main/java/nsusbloader/AppPreferences.java @@ -22,7 +22,8 @@ public class AppPreferences { boolean NotServe, String HostIp, String HostPort, - String HostExtra + String HostExtra, + boolean autoCheck4Updates ){ setProtocol(Protocol); setRecent(PreviouslyOpened); @@ -36,6 +37,7 @@ public class AppPreferences { setHostIp(HostIp); setHostPort(HostPort); setHostExtra(HostExtra); + setAutoCheckUpdates(autoCheck4Updates); } public String getTheme(){ String theme = preferences.get("THEME", "/res/app_dark.css"); // Don't let user to change settings manually @@ -95,4 +97,7 @@ public class AppPreferences { public String getHostExtra(){ return preferences.get("HOSTEXTRA", "").replaceAll("(\\s)|(\t)", "");} // oh just shut up... public void setHostExtra(String postfix){preferences.put("HOSTEXTRA", postfix);} + + public boolean getAutoCheckUpdates(){return preferences.getBoolean("AUTOCHECK4UPDATES", false); } + public void setAutoCheckUpdates(boolean prop){preferences.putBoolean("AUTOCHECK4UPDATES", prop); } } diff --git a/src/main/java/nsusbloader/Controllers/NSLMainController.java b/src/main/java/nsusbloader/Controllers/NSLMainController.java index 9787119..a068344 100644 --- a/src/main/java/nsusbloader/Controllers/NSLMainController.java +++ b/src/main/java/nsusbloader/Controllers/NSLMainController.java @@ -1,5 +1,6 @@ package nsusbloader.Controllers; +import javafx.application.HostServices; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.concurrent.Task; @@ -11,11 +12,9 @@ import javafx.scene.input.TransferMode; import javafx.scene.layout.Pane; import javafx.scene.layout.Region; import javafx.stage.FileChooser; -import nsusbloader.AppPreferences; -import nsusbloader.MediatorControl; +import nsusbloader.*; +import nsusbloader.ModelControllers.UpdatesChecker; import nsusbloader.NET.NETCommunications; -import nsusbloader.NSLMain; -import nsusbloader.ServiceWindow; import nsusbloader.USB.UsbCommunications; import java.io.File; @@ -140,7 +139,28 @@ public class NSLMainController implements Initializable { this.switchThemeBtn.setOnAction(e->switchTheme()); previouslyOpenedPath = AppPreferences.getInstance().getRecent(); + + if (AppPreferences.getInstance().getAutoCheckUpdates()){ + Task> updTask = new UpdatesChecker(); + updTask.setOnSucceeded(event->{ + List result = updTask.getValue(); + if (result != null){ + if (!result.get(0).isEmpty()) + SettingsTabController.setNewVersionLink(result.get(0)); + ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionAval"), resourceBundle.getString("windowTitleNewVersionAval")+": "+result.get(0) + "\n\n" + result.get(1)); + } + else + ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionUnknown"), resourceBundle.getString("windowBodyNewVersionUnknown")); + }); + Thread updates = new Thread(updTask); + updates.setDaemon(true); + updates.start(); + } } + /** + * Provide hostServices to Settings tab + * */ + public void setHostServices(HostServices hs ){ SettingsTabController.registerHostServices(hs);} /** * Changes UI theme on the go * */ @@ -329,7 +349,8 @@ public class NSLMainController implements Initializable { SettingsTabController.getNotServeSelected(), SettingsTabController.getHostIp(), SettingsTabController.getHostPort(), - SettingsTabController.getHostExtra() + SettingsTabController.getHostExtra(), + SettingsTabController.getAutoCheckForUpdates() ); } } diff --git a/src/main/java/nsusbloader/Controllers/SettingsController.java b/src/main/java/nsusbloader/Controllers/SettingsController.java index 8289f49..c985934 100644 --- a/src/main/java/nsusbloader/Controllers/SettingsController.java +++ b/src/main/java/nsusbloader/Controllers/SettingsController.java @@ -1,15 +1,18 @@ package nsusbloader.Controllers; +import javafx.application.HostServices; +import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.fxml.Initializable; -import javafx.scene.control.CheckBox; -import javafx.scene.control.TextField; -import javafx.scene.control.TextFormatter; +import javafx.scene.control.*; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import nsusbloader.AppPreferences; import nsusbloader.ServiceWindow; +import nsusbloader.ModelControllers.UpdatesChecker; import java.net.URL; +import java.util.List; import java.util.ResourceBundle; public class SettingsController implements Initializable { @@ -36,6 +39,15 @@ public class SettingsController implements Initializable { @FXML private VBox expertSettingsVBox; + @FXML + private CheckBox autoCheckUpdCb; + @FXML + private Hyperlink newVersionLink; + @FXML + private Button checkForUpdBtn; + + private HostServices hs; + @Override public void initialize(URL url, ResourceBundle resourceBundle) { validateNSHostNameCb.setSelected(AppPreferences.getInstance().getNsIpValidationNeeded()); @@ -131,6 +143,39 @@ public class SettingsController implements Initializable { else return change; })); + + newVersionLink.setVisible(false); + newVersionLink.setOnAction(e->{ + hs.showDocument(newVersionLink.getText()); + }); + + autoCheckUpdCb.setSelected(AppPreferences.getInstance().getAutoCheckUpdates()); + + Region btnSwitchImage = new Region(); + btnSwitchImage.getStyleClass().add("regionUpdatesCheck"); + checkForUpdBtn.setGraphic(btnSwitchImage); + + checkForUpdBtn.setOnAction(e->{ + Task> updTask = new UpdatesChecker(); + updTask.setOnSucceeded(event->{ + List result = updTask.getValue(); + if (result != null){ + if (result.get(0).isEmpty()){ + ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionNOTAval"), resourceBundle.getString("windowBodyNewVersionNOTAval")); + } + else { + setNewVersionLink(result.get(0)); + ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionAval"), resourceBundle.getString("windowTitleNewVersionAval")+": "+result.get(0) + "\n\n" + result.get(1)); + } + } + else { + ServiceWindow.getInfoNotification(resourceBundle.getString("windowTitleNewVersionUnknown"), resourceBundle.getString("windowBodyNewVersionUnknown")); + } + }); + Thread updates = new Thread(updTask); + updates.setDaemon(true); + updates.start(); + }); } public boolean getExpertModeSelected(){ return expertModeCb.isSelected(); } @@ -143,4 +188,12 @@ public class SettingsController implements Initializable { public String getHostIp(){ return pcIpTextField.getText(); } public String getHostPort(){ return pcPortTextField.getText(); } public String getHostExtra(){ return pcExtraTextField.getText(); } + public boolean getAutoCheckForUpdates(){ return autoCheckUpdCb.isSelected(); } + + public void registerHostServices(HostServices hostServices){this.hs = hostServices;} + + public void setNewVersionLink(String newVer){ + newVersionLink.setVisible(true); + newVersionLink.setText("https://github.com/developersu/ns-usbloader/releases/tag/"+newVer); + } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/ModelControllers/UpdatesChecker.java b/src/main/java/nsusbloader/ModelControllers/UpdatesChecker.java new file mode 100644 index 0000000..7e00f1b --- /dev/null +++ b/src/main/java/nsusbloader/ModelControllers/UpdatesChecker.java @@ -0,0 +1,63 @@ +package nsusbloader.ModelControllers; + +import javafx.concurrent.Task; +import nsusbloader.NSLMain; + +import javax.net.ssl.HttpsURLConnection; +import java.io.*; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + + +public class UpdatesChecker extends Task> { + @Override + protected List call() { + String respondedJson; + try { + URL gitHubUrl = new URL("https://api.github.com/repos/developersu/ns-usbloader/releases/latest"); + HttpsURLConnection connection = (HttpsURLConnection) gitHubUrl.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Accept", "application/vnd.github.v3+json"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + + int status = connection.getResponseCode(); + if (status != 200) { + return null; + } + BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); + respondedJson = br.readLine(); + br.close(); + connection.disconnect(); + + if (respondedJson == null) + return null; + } + catch (IOException mue){ + return null; + } + + String newVersion = respondedJson.replaceAll("(^.*\"tag_name\":\")(.?|.+?)(\".+$)", "$2"); + String changeLog = respondedJson.replaceAll("(^.*\"body\":\")(.?|.+?)(\".+$)", "$2") + .replaceAll("\\\\r\\\\n","\n") + .replaceAll("#+?\\s", ""); // replace #### dsds | # dsds + + if (newVersion.matches("^v(([0-9])+?\\.)+[0-9]+(-.+)$")) // if new version have postfix like v0.1-Experimental + newVersion = newVersion.replaceAll("(-.*$)", ""); // cut postfix + + if ( ! newVersion.matches("^v(([0-9])+?\\.)+[0-9]+$")) { // check if new version structure valid + return null; + } + + List returningValue = new ArrayList<>(); + if (!newVersion.equals(NSLMain.appVersion)) { // if latest noted version in GitHub is different to this version + returningValue.add(newVersion); + returningValue.add(changeLog); + return returningValue; + } + returningValue.add(""); + returningValue.add(""); + return returningValue; + } +} \ No newline at end of file diff --git a/src/main/java/nsusbloader/NSLMain.java b/src/main/java/nsusbloader/NSLMain.java index e16d748..47eb5be 100644 --- a/src/main/java/nsusbloader/NSLMain.java +++ b/src/main/java/nsusbloader/NSLMain.java @@ -12,7 +12,7 @@ import java.util.Locale; import java.util.ResourceBundle; public class NSLMain extends Application { - public static final String appVersion = "v0.3"; + public static final String appVersion = "v0.3.1"; @Override public void start(Stage primaryStage) throws Exception{ @@ -48,6 +48,7 @@ public class NSLMain extends Application { }); NSLMainController controller = loader.getController(); + controller.setHostServices(getHostServices()); primaryStage.setOnHidden(e-> controller.exit()); } diff --git a/src/main/java/nsusbloader/ServiceWindow.java b/src/main/java/nsusbloader/ServiceWindow.java index dfc2b47..7c96933 100644 --- a/src/main/java/nsusbloader/ServiceWindow.java +++ b/src/main/java/nsusbloader/ServiceWindow.java @@ -2,24 +2,36 @@ package nsusbloader; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; +import javafx.scene.control.DialogPane; import javafx.scene.layout.Region; +import javafx.stage.Stage; import java.util.Optional; public class ServiceWindow { - /** - * Create window with notification - * */ + /** Create window with error notification */ public static void getErrorNotification(String title, String body){ - Alert alertBox = new Alert(Alert.AlertType.ERROR); + getNotification(title, body, Alert.AlertType.ERROR); + } + /** Create window with information notification */ + public static void getInfoNotification(String title, String body){ + getNotification(title, body, Alert.AlertType.INFORMATION); + } + /** Real window creator */ + private static void getNotification(String title, String body, Alert.AlertType type){ + Alert alertBox = new Alert(type); alertBox.setTitle(title); alertBox.setHeaderText(null); alertBox.setContentText(body); alertBox.getDialogPane().setMinWidth(Region.USE_PREF_SIZE); alertBox.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); alertBox.setResizable(true); // Java bug workaround for JDR11/OpenJFX. TODO: nothing. really. - alertBox.setResizable(false); alertBox.getDialogPane().getStylesheets().add(AppPreferences.getInstance().getTheme()); + + Stage dialogStage = (Stage) alertBox.getDialogPane().getScene().getWindow(); + dialogStage.setAlwaysOnTop(true); + dialogStage.toFront(); + alertBox.show(); } /** diff --git a/src/main/resources/SettingsTab.fxml b/src/main/resources/SettingsTab.fxml index 0414d18..a54e779 100644 --- a/src/main/resources/SettingsTab.fxml +++ b/src/main/resources/SettingsTab.fxml @@ -1,12 +1,15 @@ + + + @@ -69,6 +72,18 @@ + + + + + + + + + +