Skip to content

Commit 7cec2b1

Browse files
authored
feat: WinUI Update Center (#112)
* feat: Better updating backend * feat: Update center
1 parent d6d98f0 commit 7cec2b1

19 files changed

Lines changed: 513 additions & 580 deletions

libapplication/include/controllers/mainwindowcontroller.h

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
#include <libnick/app/datafilemanager.h>
1414
#include <libnick/app/windowgeometry.h>
1515
#include <libnick/events/event.h>
16+
#include <libnick/events/parameventargs.h>
1617
#include <libnick/notifications/notificationsenteventargs.h>
1718
#include <libnick/taskbar/taskbaritem.h>
1819
#include <libnick/update/updater.h>
20+
#include <libnick/update/version.h>
1921
#include "controllers/preferencesviewcontroller.h"
2022
#include "models/startupinformation.h"
2123
#include "models/theme.h"
@@ -43,6 +45,16 @@ namespace Nickvision::Application::Shared::Controllers
4345
* @return The notification sent event
4446
*/
4547
Nickvision::Events::Event<Nickvision::Notifications::NotificationSentEventArgs>& notificationSent();
48+
/**
49+
* @brief Gets the event for when an application update is available.
50+
* @return The application update available event
51+
*/
52+
Nickvision::Events::Event<Nickvision::Events::ParamEventArgs<Nickvision::Update::Version>>& appUpdateAvailable();
53+
/**
54+
* @brief Gets the event for when an application update's progress is changed.
55+
* @return The application update progress changed event
56+
*/
57+
Nickvision::Events::Event<Nickvision::Events::ParamEventArgs<double>>& appUpdateProgressChanged();
4658
/**
4759
* @brief Gets the AppInfo object for the application
4860
* @return The current AppInfo object
@@ -53,6 +65,16 @@ namespace Nickvision::Application::Shared::Controllers
5365
* @return The preferred theme
5466
*/
5567
Models::Theme getTheme();
68+
/**
69+
* @brief Gets the preferred update type for the application.
70+
* @return The preferred update type
71+
*/
72+
Update::VersionType getPreferredUpdateType();
73+
/**
74+
* @brief Sets the preferred update type for the application.
75+
* @param type The preferred update type
76+
*/
77+
void setPreferredUpdateType(Update::VersionType type);
5678
/**
5779
* @brief Gets the debugging information for the application.
5880
* @param extraInformation Extra, ui-specific, information to include in the debug info statement
@@ -78,26 +100,19 @@ namespace Nickvision::Application::Shared::Controllers
78100
const Models::StartupInformation& startup(HWND hwnd);
79101
#elif defined(__linux__)
80102
const Models::StartupInformation& startup(const std::string& desktopFile);
81-
#else
103+
#else
82104
const Models::StartupInformation& startup();
83105
#endif
84106
/**
85107
* @brief Shuts down the application.
86108
* @param geometry The window geometry to save
87109
*/
88110
void shutdown(const Nickvision::App::WindowGeometry& geometry);
89-
/**
90-
* @brief Checks for an application update and sends a notification if one is available.
91-
* @param noUpdateNotification Send an app notification if no update is available.
92-
*/
93-
void checkForUpdates(bool noUpdateNotification) const;
94111
#ifdef _WIN32
95112
/**
96-
* @brief Downloads and installs the latest application update in the background.
97-
* @brief Will send a notification if the update fails.
98-
* @brief MainWindowController::checkForUpdates() must be called before this method.
113+
* @brief Starts downloading and installing the latest application update for Windows in the background.
99114
*/
100-
void windowsUpdate();
115+
void startWindowsUpdate();
101116
#endif
102117
/**
103118
* @brief Gets the string for greeting on the home page.
@@ -138,6 +153,8 @@ namespace Nickvision::Application::Shared::Controllers
138153
private:
139154
bool m_started;
140155
std::vector<std::string> m_args;
156+
Nickvision::Events::Event<Nickvision::Events::ParamEventArgs<Nickvision::Update::Version>> m_appUpdateAvailable;
157+
Nickvision::Events::Event<Nickvision::Events::ParamEventArgs<double>> m_appUpdateProgressChanged;
141158
Nickvision::App::AppInfo m_appInfo;
142159
Nickvision::App::DataFileManager m_dataFileManager;
143160
std::shared_ptr<Nickvision::Update::Updater> m_updater;

libapplication/include/controllers/preferencesviewcontroller.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,6 @@ namespace Nickvision::Application::Shared::Controllers
4747
* @param index The index of the preferred translation language in the available languages list
4848
*/
4949
void setTranslationLanguage(size_t index);
50-
/**
51-
* @brief Gets whether or not to automatically check for application updates.
52-
* @return True to automatically check for updates, else false
53-
*/
54-
bool getAutomaticallyCheckForUpdates() const;
55-
/**
56-
* @brief Sets whether or not to automatically check for application updates.
57-
* @param check Whether or not to automatically check for updates
58-
*/
59-
void setAutomaticallyCheckForUpdates(bool check);
6050
/**
6151
* @brief Saves the current configuration to disk.
6252
*/

libapplication/include/models/configuration.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <string>
55
#include <libnick/app/datafilebase.h>
66
#include <libnick/app/windowgeometry.h>
7+
#include <libnick/update/versiontype.h>
78
#include "theme.h"
89

910
namespace Nickvision::Application::Shared::Models
@@ -54,15 +55,15 @@ namespace Nickvision::Application::Shared::Models
5455
*/
5556
void setWindowGeometry(const App::WindowGeometry& geometry);
5657
/**
57-
* @brief Gets whether or not to automatically check for application updates.
58-
* @return True to automatically check for updates, else false
58+
* @brief Gets the preferred update type for the application.
59+
* @return The preferred update type
5960
*/
60-
bool getAutomaticallyCheckForUpdates() const;
61+
Update::VersionType getPreferredUpdateType() const;
6162
/**
62-
* @brief Sets whether or not to automatically check for application updates.
63-
* @param check Whether or not to automatically check for updates
63+
* @brief Sets the preferred update type for the application.
64+
* @param type The new preferred update type
6465
*/
65-
void setAutomaticallyCheckForUpdates(bool check);
66+
void setPreferredUpdateType(Update::VersionType type);
6667
};
6768
}
6869

libapplication/src/controllers/mainwindowcontroller.cpp

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ namespace Nickvision::Application::Shared::Controllers
5353
{
5454
Gettext::changeLanguage(translationLanguage);
5555
}
56-
#ifdef _WIN32
5756
m_updater = std::make_shared<Updater>(m_appInfo.getSourceRepo());
58-
#endif
5957
}
6058

6159
Event<EventArgs>& MainWindowController::configurationSaved()
@@ -68,6 +66,16 @@ namespace Nickvision::Application::Shared::Controllers
6866
return AppNotification::sent();
6967
}
7068

69+
Event<ParamEventArgs<Version>>& MainWindowController::appUpdateAvailable()
70+
{
71+
return m_appUpdateAvailable;
72+
}
73+
74+
Event<ParamEventArgs<double>>& MainWindowController::appUpdateProgressChanged()
75+
{
76+
return m_appUpdateProgressChanged;
77+
}
78+
7179
const AppInfo& MainWindowController::getAppInfo() const
7280
{
7381
return m_appInfo;
@@ -78,6 +86,16 @@ namespace Nickvision::Application::Shared::Controllers
7886
return m_dataFileManager.get<Configuration>(CONFIG_FILE_KEY).getTheme();
7987
}
8088

89+
VersionType MainWindowController::getPreferredUpdateType()
90+
{
91+
return m_dataFileManager.get<Configuration>(CONFIG_FILE_KEY).getPreferredUpdateType();
92+
}
93+
94+
void MainWindowController::setPreferredUpdateType(VersionType type)
95+
{
96+
m_dataFileManager.get<Configuration>(CONFIG_FILE_KEY).setPreferredUpdateType(type);
97+
}
98+
8199
std::string MainWindowController::getDebugInformation(const std::string& extraInformation) const
82100
{
83101
std::stringstream builder;
@@ -120,13 +138,22 @@ namespace Nickvision::Application::Shared::Controllers
120138
//Load taskbar item
121139
#ifdef _WIN32
122140
m_taskbar.connect(hwnd);
123-
if (m_dataFileManager.get<Configuration>(CONFIG_FILE_KEY).getAutomaticallyCheckForUpdates())
124-
{
125-
checkForUpdates(false);
126-
}
127141
#elif defined(__linux__)
128142
m_taskbar.connect(desktopFile);
129143
#endif
144+
//Start checking for app updates
145+
std::thread workerUpdates{ [this]()
146+
{
147+
Version latest{ m_updater->fetchCurrentVersion(getPreferredUpdateType()) };
148+
if(!latest.empty())
149+
{
150+
if(latest > m_appInfo.getVersion())
151+
{
152+
m_appUpdateAvailable.invoke({ latest });
153+
}
154+
}
155+
} };
156+
workerUpdates.detach();
130157
m_started = true;
131158
return info;
132159
}
@@ -138,46 +165,26 @@ namespace Nickvision::Application::Shared::Controllers
138165
config.save();
139166
}
140167

141-
void MainWindowController::checkForUpdates(bool noUpdateNotification) const
168+
#ifdef _WIN32
169+
void MainWindowController::startWindowsUpdate()
142170
{
143-
if(!m_updater)
144-
{
145-
return;
146-
}
147-
std::thread worker{ [this, noUpdateNotification]()
171+
std::thread worker{ [this]()
148172
{
149-
Version latest{ m_updater->fetchCurrentVersion(VersionType::Stable) };
150-
if(!latest.empty())
173+
m_appUpdateProgressChanged.invoke({ 0.0 });
174+
bool res{ m_updater->windowsUpdate(getPreferredUpdateType(), { [this](curl_off_t downloadTotal, curl_off_t downloadNow, curl_off_t, curl_off_t, intptr_t) -> bool
151175
{
152-
if(latest > m_appInfo.getVersion())
176+
if(downloadTotal == 0)
153177
{
154-
#ifdef PORTABLE_BUILD
155-
AppNotification::send({ _("New version of Application available"), NotificationSeverity::Success });
156-
#else
157-
AppNotification::send({ _("New version of Application available"), NotificationSeverity::Success, "update" });
158-
#endif
159-
return;
178+
return true;
160179
}
161-
}
162-
if(noUpdateNotification)
180+
m_appUpdateProgressChanged.invoke({ static_cast<double>(static_cast<long double>(downloadNow) / static_cast<long double>(downloadTotal)) });
181+
return true;
182+
} }) };
183+
if(res)
163184
{
164-
AppNotification::send({ _("No Application update available"), NotificationSeverity::Warning });
185+
m_appUpdateProgressChanged.invoke({ 1.0 });
165186
}
166-
} };
167-
worker.detach();
168-
}
169-
170-
#ifdef _WIN32
171-
void MainWindowController::windowsUpdate()
172-
{
173-
if(!m_updater)
174-
{
175-
return;
176-
}
177-
AppNotification::send({ _("The update is downloading in the background and will start once it finishes"), NotificationSeverity::Informational });
178-
std::thread worker{ [this]()
179-
{
180-
if(!m_updater->windowsUpdate(VersionType::Stable))
187+
else
181188
{
182189
AppNotification::send({ _("Unable to download and install update"), NotificationSeverity::Error });
183190
}

libapplication/src/controllers/preferencesviewcontroller.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,6 @@ namespace Nickvision::Application::Shared::Controllers
7777
}
7878
}
7979

80-
bool PreferencesViewController::getAutomaticallyCheckForUpdates() const
81-
{
82-
return m_configuration.getAutomaticallyCheckForUpdates();
83-
}
84-
85-
void PreferencesViewController::setAutomaticallyCheckForUpdates(bool check)
86-
{
87-
m_configuration.setAutomaticallyCheckForUpdates(check);
88-
}
89-
9080
void PreferencesViewController::saveConfiguration()
9181
{
9282
m_configuration.save();

libapplication/src/models/configuration.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#include "models/configuration.h"
2-
#include <libnick/system/environment.h>
32

43
using namespace Nickvision::App;
5-
using namespace Nickvision::System;
4+
using namespace Nickvision::Update;
65

76
namespace Nickvision::Application::Shared::Models
87
{
@@ -46,13 +45,13 @@ namespace Nickvision::Application::Shared::Models
4645
m_json["WindowGeometry"] = geometry.toJson();
4746
}
4847

49-
bool Configuration::getAutomaticallyCheckForUpdates() const
48+
VersionType Configuration::getPreferredUpdateType() const
5049
{
51-
return m_json["AutomaticallyCheckForUpdates"].is_bool() ? m_json["AutomaticallyCheckForUpdates"].as_bool() : Environment::getOperatingSystem() == OperatingSystem::Windows;
50+
return m_json["PreferredUpdateType"].is_int64() ? static_cast<VersionType>(m_json["PreferredUpdateType"].as_int64()) : VersionType::Stable;
5251
}
5352

54-
void Configuration::setAutomaticallyCheckForUpdates(bool check)
53+
void Configuration::setPreferredUpdateType(VersionType type)
5554
{
56-
m_json["AutomaticallyCheckForUpdates"] = check;
55+
m_json["PreferredUpdateType"] = static_cast<int>(type);
5756
}
5857
}

org.nickvision.application.winui/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ if(WIN32)
2222
"../resources/windows/${PROJECT_NAME}.manifest"
2323
"../resources/windows/${PROJECT_NAME}.rc"
2424
"pch.cpp" "pch.h"
25-
"Controls/AboutDialog.xaml.cpp" "Controls/AboutDialog.xaml.h" "Controls/AboutDialog.xaml" "Controls/AboutDialog.idl"
2625
"Controls/SettingsRow.xaml.cpp" "Controls/SettingsRow.xaml.h" "Controls/SettingsRow.xaml" "Controls/SettingsRow.idl"
2726
"Controls/StatusPage.xaml.cpp" "Controls/StatusPage.xaml.h" "Controls/StatusPage.xaml" "Controls/StatusPage.idl"
2827
"Controls/TitleBar.xaml.cpp" "Controls/TitleBar.xaml.h" "Controls/TitleBar.xaml" "Controls/TitleBar.idl"

org.nickvision.application.winui/Controls/AboutDialog.idl

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)