diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/tracker_config.cpp | 4 | ||||
| -rw-r--r-- | src/tracker_config.h | 2 | ||||
| -rw-r--r-- | src/tracker_frame.cpp | 101 | ||||
| -rw-r--r-- | src/tracker_frame.h | 4 | ||||
| -rw-r--r-- | src/version.h | 40 |
5 files changed, 148 insertions, 3 deletions
| diff --git a/src/tracker_config.cpp b/src/tracker_config.cpp index 96bb60a..c09d241 100644 --- a/src/tracker_config.cpp +++ b/src/tracker_config.cpp | |||
| @@ -12,6 +12,8 @@ void TrackerConfig::Load() { | |||
| 12 | ap_server = file["ap_server"].as<std::string>(); | 12 | ap_server = file["ap_server"].as<std::string>(); |
| 13 | ap_player = file["ap_player"].as<std::string>(); | 13 | ap_player = file["ap_player"].as<std::string>(); |
| 14 | ap_password = file["ap_password"].as<std::string>(); | 14 | ap_password = file["ap_password"].as<std::string>(); |
| 15 | asked_to_check_for_updates = file["asked_to_check_for_updates"].as<bool>(); | ||
| 16 | should_check_for_updates = file["should_check_for_updates"].as<bool>(); | ||
| 15 | } catch (const std::exception&) { | 17 | } catch (const std::exception&) { |
| 16 | // It's fine if the file can't be loaded. | 18 | // It's fine if the file can't be loaded. |
| 17 | } | 19 | } |
| @@ -22,6 +24,8 @@ void TrackerConfig::Save() { | |||
| 22 | output["ap_server"] = ap_server; | 24 | output["ap_server"] = ap_server; |
| 23 | output["ap_player"] = ap_player; | 25 | output["ap_player"] = ap_player; |
| 24 | output["ap_password"] = ap_password; | 26 | output["ap_password"] = ap_password; |
| 27 | output["asked_to_check_for_updates"] = asked_to_check_for_updates; | ||
| 28 | output["should_check_for_updates"] = should_check_for_updates; | ||
| 25 | 29 | ||
| 26 | std::ofstream filewriter(CONFIG_FILE_NAME); | 30 | std::ofstream filewriter(CONFIG_FILE_NAME); |
| 27 | filewriter << output; | 31 | filewriter << output; |
| diff --git a/src/tracker_config.h b/src/tracker_config.h index e2e6cd7..b9460d2 100644 --- a/src/tracker_config.h +++ b/src/tracker_config.h | |||
| @@ -12,6 +12,8 @@ class TrackerConfig { | |||
| 12 | std::string ap_server; | 12 | std::string ap_server; |
| 13 | std::string ap_player; | 13 | std::string ap_player; |
| 14 | std::string ap_password; | 14 | std::string ap_password; |
| 15 | bool asked_to_check_for_updates = false; | ||
| 16 | bool should_check_for_updates = false; | ||
| 15 | }; | 17 | }; |
| 16 | 18 | ||
| 17 | TrackerConfig& GetTrackerConfig(); | 19 | TrackerConfig& GetTrackerConfig(); |
| diff --git a/src/tracker_frame.cpp b/src/tracker_frame.cpp index 2a862a5..0308886 100644 --- a/src/tracker_frame.cpp +++ b/src/tracker_frame.cpp | |||
| @@ -1,11 +1,17 @@ | |||
| 1 | #include "tracker_frame.h" | 1 | #include "tracker_frame.h" |
| 2 | 2 | ||
| 3 | #include <wx/webrequest.h> | ||
| 4 | |||
| 5 | #include <nlohmann/json.hpp> | ||
| 6 | #include <sstream> | ||
| 7 | |||
| 3 | #include "ap_state.h" | 8 | #include "ap_state.h" |
| 4 | #include "connection_dialog.h" | 9 | #include "connection_dialog.h" |
| 5 | #include "tracker_config.h" | 10 | #include "tracker_config.h" |
| 6 | #include "tracker_panel.h" | 11 | #include "tracker_panel.h" |
| 12 | #include "version.h" | ||
| 7 | 13 | ||
| 8 | enum TrackerFrameIds { ID_CONNECT = 1 }; | 14 | enum TrackerFrameIds { ID_CONNECT = 1, ID_CHECK_FOR_UPDATES = 2 }; |
| 9 | 15 | ||
| 10 | wxDEFINE_EVENT(STATE_CHANGED, wxCommandEvent); | 16 | wxDEFINE_EVENT(STATE_CHANGED, wxCommandEvent); |
| 11 | wxDEFINE_EVENT(STATUS_CHANGED, wxCommandEvent); | 17 | wxDEFINE_EVENT(STATUS_CHANGED, wxCommandEvent); |
| @@ -25,6 +31,7 @@ TrackerFrame::TrackerFrame() | |||
| 25 | 31 | ||
| 26 | wxMenu *menuHelp = new wxMenu(); | 32 | wxMenu *menuHelp = new wxMenu(); |
| 27 | menuHelp->Append(wxID_ABOUT); | 33 | menuHelp->Append(wxID_ABOUT); |
| 34 | menuHelp->Append(ID_CHECK_FOR_UPDATES, "Check for Updates"); | ||
| 28 | 35 | ||
| 29 | wxMenuBar *menuBar = new wxMenuBar(); | 36 | wxMenuBar *menuBar = new wxMenuBar(); |
| 30 | menuBar->Append(menuFile, "&File"); | 37 | menuBar->Append(menuFile, "&File"); |
| @@ -38,10 +45,30 @@ TrackerFrame::TrackerFrame() | |||
| 38 | Bind(wxEVT_MENU, &TrackerFrame::OnAbout, this, wxID_ABOUT); | 45 | Bind(wxEVT_MENU, &TrackerFrame::OnAbout, this, wxID_ABOUT); |
| 39 | Bind(wxEVT_MENU, &TrackerFrame::OnExit, this, wxID_EXIT); | 46 | Bind(wxEVT_MENU, &TrackerFrame::OnExit, this, wxID_EXIT); |
| 40 | Bind(wxEVT_MENU, &TrackerFrame::OnConnect, this, ID_CONNECT); | 47 | Bind(wxEVT_MENU, &TrackerFrame::OnConnect, this, ID_CONNECT); |
| 48 | Bind(wxEVT_MENU, &TrackerFrame::OnCheckForUpdates, this, | ||
| 49 | ID_CHECK_FOR_UPDATES); | ||
| 41 | Bind(STATE_CHANGED, &TrackerFrame::OnStateChanged, this); | 50 | Bind(STATE_CHANGED, &TrackerFrame::OnStateChanged, this); |
| 42 | Bind(STATUS_CHANGED, &TrackerFrame::OnStatusChanged, this); | 51 | Bind(STATUS_CHANGED, &TrackerFrame::OnStatusChanged, this); |
| 43 | 52 | ||
| 44 | tracker_panel_ = new TrackerPanel(this); | 53 | tracker_panel_ = new TrackerPanel(this); |
| 54 | |||
| 55 | if (!GetTrackerConfig().asked_to_check_for_updates) { | ||
| 56 | GetTrackerConfig().asked_to_check_for_updates = true; | ||
| 57 | |||
| 58 | if (wxMessageBox( | ||
| 59 | "Check for updates automatically when the tracker is opened?", | ||
| 60 | "Lingo AP Tracker", wxYES_NO) == wxYES) { | ||
| 61 | GetTrackerConfig().should_check_for_updates = true; | ||
| 62 | } else { | ||
| 63 | GetTrackerConfig().should_check_for_updates = false; | ||
| 64 | } | ||
| 65 | |||
| 66 | GetTrackerConfig().Save(); | ||
| 67 | } | ||
| 68 | |||
| 69 | if (GetTrackerConfig().should_check_for_updates) { | ||
| 70 | CheckForUpdates(/*manual=*/false); | ||
| 71 | } | ||
| 45 | } | 72 | } |
| 46 | 73 | ||
| 47 | void TrackerFrame::SetStatusMessage(std::string message) { | 74 | void TrackerFrame::SetStatusMessage(std::string message) { |
| @@ -56,8 +83,12 @@ void TrackerFrame::UpdateIndicators() { | |||
| 56 | } | 83 | } |
| 57 | 84 | ||
| 58 | void TrackerFrame::OnAbout(wxCommandEvent &event) { | 85 | void TrackerFrame::OnAbout(wxCommandEvent &event) { |
| 59 | wxMessageBox("Lingo Archipelago Tracker by hatkirby", | 86 | std::ostringstream message_text; |
| 60 | "About lingo-ap-tracker", wxOK | wxICON_INFORMATION); | 87 | message_text << "Lingo Archipelago Tracker " << kTrackerVersion |
| 88 | << " by hatkirby"; | ||
| 89 | |||
| 90 | wxMessageBox(message_text.str(), "About lingo-ap-tracker", | ||
| 91 | wxOK | wxICON_INFORMATION); | ||
| 61 | } | 92 | } |
| 62 | 93 | ||
| 63 | void TrackerFrame::OnExit(wxCommandEvent &event) { Close(true); } | 94 | void TrackerFrame::OnExit(wxCommandEvent &event) { Close(true); } |
| @@ -76,6 +107,10 @@ void TrackerFrame::OnConnect(wxCommandEvent &event) { | |||
| 76 | } | 107 | } |
| 77 | } | 108 | } |
| 78 | 109 | ||
| 110 | void TrackerFrame::OnCheckForUpdates(wxCommandEvent &event) { | ||
| 111 | CheckForUpdates(/*manual=*/true); | ||
| 112 | } | ||
| 113 | |||
| 79 | void TrackerFrame::OnStateChanged(wxCommandEvent &event) { | 114 | void TrackerFrame::OnStateChanged(wxCommandEvent &event) { |
| 80 | tracker_panel_->UpdateIndicators(); | 115 | tracker_panel_->UpdateIndicators(); |
| 81 | Refresh(); | 116 | Refresh(); |
| @@ -84,3 +119,63 @@ void TrackerFrame::OnStateChanged(wxCommandEvent &event) { | |||
| 84 | void TrackerFrame::OnStatusChanged(wxCommandEvent &event) { | 119 | void TrackerFrame::OnStatusChanged(wxCommandEvent &event) { |
| 85 | SetStatusText(event.GetString()); | 120 | SetStatusText(event.GetString()); |
| 86 | } | 121 | } |
| 122 | |||
| 123 | void TrackerFrame::CheckForUpdates(bool manual) { | ||
| 124 | wxWebRequest request = wxWebSession::GetDefault().CreateRequest( | ||
| 125 | this, | ||
| 126 | "https://api.github.com/repos/hatkirby/lingo-ap-tracker/" | ||
| 127 | "releases?per_page=8"); | ||
| 128 | |||
| 129 | if (!request.IsOk()) { | ||
| 130 | if (manual) { | ||
| 131 | wxMessageBox("Could not check for updates.", "Error", | ||
| 132 | wxOK | wxICON_ERROR); | ||
| 133 | } else { | ||
| 134 | SetStatusText("Could not check for updates."); | ||
| 135 | } | ||
| 136 | |||
| 137 | return; | ||
| 138 | } | ||
| 139 | |||
| 140 | Bind(wxEVT_WEBREQUEST_STATE, [this, manual](wxWebRequestEvent &evt) { | ||
| 141 | if (evt.GetState() == wxWebRequest::State_Completed) { | ||
| 142 | std::string response = evt.GetResponse().AsString().ToStdString(); | ||
| 143 | nlohmann::json parsed_response = nlohmann::json::parse(response); | ||
| 144 | |||
| 145 | if (parsed_response.is_array() && !parsed_response.empty()) { | ||
| 146 | // This will parse to 0.0.0 if it's invalid, which will always be older | ||
| 147 | // than our current version. | ||
| 148 | Version latest_version( | ||
| 149 | parsed_response[0]["tag_name"].get<std::string>()); | ||
| 150 | if (kTrackerVersion < latest_version) { | ||
| 151 | std::ostringstream message_text; | ||
| 152 | message_text << "There is a newer version of Lingo AP Tracker " | ||
| 153 | "available. You have " | ||
| 154 | << kTrackerVersion << ", and the latest version is " | ||
| 155 | << latest_version << ". Would you like to update?"; | ||
| 156 | |||
| 157 | if (wxMessageBox(message_text.str(), "Update available", wxYES_NO) == | ||
| 158 | wxYES) { | ||
| 159 | wxLaunchDefaultBrowser( | ||
| 160 | parsed_response[0]["html_url"].get<std::string>()); | ||
| 161 | } | ||
| 162 | } else if (manual) { | ||
| 163 | wxMessageBox("Lingo AP Tracker is up to date!", "Lingo AP Tracker", | ||
| 164 | wxOK); | ||
| 165 | } | ||
| 166 | } else if (manual) { | ||
| 167 | wxMessageBox("Lingo AP Tracker is up to date!", "Lingo AP Tracker", | ||
| 168 | wxOK); | ||
| 169 | } | ||
| 170 | } else if (evt.GetState() == wxWebRequest::State_Failed) { | ||
| 171 | if (manual) { | ||
| 172 | wxMessageBox("Could not check for updates.", "Error", | ||
| 173 | wxOK | wxICON_ERROR); | ||
| 174 | } else { | ||
| 175 | SetStatusText("Could not check for updates."); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | }); | ||
| 179 | |||
| 180 | request.Start(); | ||
| 181 | } | ||
| diff --git a/src/tracker_frame.h b/src/tracker_frame.h index 6f4e4fc..f3470fd 100644 --- a/src/tracker_frame.h +++ b/src/tracker_frame.h | |||
| @@ -24,9 +24,13 @@ class TrackerFrame : public wxFrame { | |||
| 24 | void OnExit(wxCommandEvent &event); | 24 | void OnExit(wxCommandEvent &event); |
| 25 | void OnAbout(wxCommandEvent &event); | 25 | void OnAbout(wxCommandEvent &event); |
| 26 | void OnConnect(wxCommandEvent &event); | 26 | void OnConnect(wxCommandEvent &event); |
| 27 | void OnCheckForUpdates(wxCommandEvent &event); | ||
| 28 | |||
| 27 | void OnStateChanged(wxCommandEvent &event); | 29 | void OnStateChanged(wxCommandEvent &event); |
| 28 | void OnStatusChanged(wxCommandEvent &event); | 30 | void OnStatusChanged(wxCommandEvent &event); |
| 29 | 31 | ||
| 32 | void CheckForUpdates(bool manual); | ||
| 33 | |||
| 30 | TrackerPanel *tracker_panel_; | 34 | TrackerPanel *tracker_panel_; |
| 31 | }; | 35 | }; |
| 32 | 36 | ||
| diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..c45ff53 --- /dev/null +++ b/src/version.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | #ifndef VERSION_H_C757E53C | ||
| 2 | #define VERSION_H_C757E53C | ||
| 3 | |||
| 4 | #include <iostream> | ||
| 5 | #include <regex> | ||
| 6 | |||
| 7 | struct Version { | ||
| 8 | int major = 0; | ||
| 9 | int minor = 0; | ||
| 10 | int revision = 0; | ||
| 11 | |||
| 12 | constexpr Version(int major_arg, int minor_arg, int rev_arg) | ||
| 13 | : major(major_arg), minor(minor_arg), revision(rev_arg) {} | ||
| 14 | |||
| 15 | Version(const std::string& ver_str) { | ||
| 16 | const std::regex version_regex("v([0-9]*)\.([0-9]*)\.([0-9]*)"); | ||
| 17 | std::smatch version_match; | ||
| 18 | |||
| 19 | if (std::regex_match(ver_str, version_match, version_regex)) { | ||
| 20 | major = std::atoi(version_match[1].str().c_str()); | ||
| 21 | minor = std::atoi(version_match[2].str().c_str()); | ||
| 22 | revision = std::atoi(version_match[3].str().c_str()); | ||
| 23 | } | ||
| 24 | } | ||
| 25 | |||
| 26 | bool operator<(const Version& rhs) const { | ||
| 27 | return (major < rhs.major) || | ||
| 28 | (major == rhs.major && | ||
| 29 | (minor < rhs.minor || | ||
| 30 | (minor == rhs.minor && revision < rhs.revision))); | ||
| 31 | } | ||
| 32 | }; | ||
| 33 | |||
| 34 | std::ostream& operator<<(std::ostream& out, const Version& ver) { | ||
| 35 | return out << "v" << ver.major << "." << ver.minor << "." << ver.revision; | ||
| 36 | } | ||
| 37 | |||
| 38 | constexpr const Version kTrackerVersion = Version(0, 1, 0); | ||
| 39 | |||
| 40 | #endif /* end of include guard: VERSION_H_C757E53C */ \ No newline at end of file | ||
