mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-14 03:15:49 +02:00
Begin rewriting update checker to run within C#
This commit is contained in:
parent
f99d035621
commit
ad45cf8c72
@ -78,8 +78,9 @@ public FormBrowser(UpdaterSettings updaterSettings){
|
||||
Disposed += (sender, args) => {
|
||||
Config.MuteToggled -= Config_MuteToggled;
|
||||
Config.TrayBehaviorChanged -= Config_TrayBehaviorChanged;
|
||||
|
||||
|
||||
browser.Dispose();
|
||||
updates.Dispose();
|
||||
contextMenu.Dispose();
|
||||
|
||||
notificationScreenshotManager?.Dispose();
|
||||
@ -96,6 +97,7 @@ public FormBrowser(UpdaterSettings updaterSettings){
|
||||
UpdateTrayIcon();
|
||||
|
||||
this.updates = new UpdateHandler(browser, updaterSettings);
|
||||
this.updates.CheckFinished += updates_CheckFinished;
|
||||
this.updates.UpdateAccepted += updates_UpdateAccepted;
|
||||
this.updates.UpdateDismissed += updates_UpdateDismissed;
|
||||
|
||||
@ -233,6 +235,18 @@ private static void plugins_Executed(object sender, PluginErrorEventArgs e){
|
||||
}
|
||||
}
|
||||
|
||||
private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
|
||||
this.InvokeAsyncSafe(() => {
|
||||
e.Result.Handle(update => {
|
||||
if (!update.IsUpdateNew && !update.IsUpdateDismissed){
|
||||
updates.StartTimer();
|
||||
}
|
||||
}, ex => {
|
||||
// TODO show error and ask if the user wants to temporarily disable checks -- or maybe only do that for the first check of the day
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void updates_UpdateAccepted(object sender, UpdateEventArgs e){
|
||||
this.InvokeAsyncSafe(() => {
|
||||
FormManager.CloseAllDialogs();
|
||||
@ -241,13 +255,21 @@ private void updates_UpdateAccepted(object sender, UpdateEventArgs e){
|
||||
Config.DismissedUpdate = null;
|
||||
Config.Save();
|
||||
}
|
||||
|
||||
updates.BeginUpdateDownload(this, e.UpdateInfo, update => {
|
||||
if (update.DownloadStatus == UpdateDownloadStatus.Done){
|
||||
UpdateInstallerPath = update.InstallerPath;
|
||||
}
|
||||
|
||||
ForceClose();
|
||||
updates.BeginUpdateDownload(this, e.UpdateInfo, update => {
|
||||
UpdateDownloadStatus status = update.DownloadStatus;
|
||||
|
||||
if (status == UpdateDownloadStatus.Done){
|
||||
UpdateInstallerPath = update.InstallerPath;
|
||||
ForceClose();
|
||||
}
|
||||
else if (FormMessage.Error("Update Has Failed", "Could not automatically download the update: "+(update.DownloadError?.Message ?? "unknown error")+"\n\nWould you like to open the website and try downloading the update manually?", FormMessage.Yes, FormMessage.No)){
|
||||
BrowserUtils.OpenExternalBrowser(Program.Website);
|
||||
ForceClose();
|
||||
}
|
||||
else{
|
||||
Show();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -222,9 +222,13 @@ private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
|
||||
if (e.EventId == updateCheckEventId){
|
||||
btnCheckUpdates.Enabled = true;
|
||||
|
||||
if (!e.IsUpdateAvailable){
|
||||
FormMessage.Information("No Updates Available", "Your version of TweetDuck is up to date.", FormMessage.OK);
|
||||
}
|
||||
e.Result.Handle(update => {
|
||||
if (!update.IsUpdateNew){
|
||||
FormMessage.Information("No Updates Available", "Your version of TweetDuck is up to date.", FormMessage.OK);
|
||||
}
|
||||
}, ex => {
|
||||
Program.Reporter.HandleException("Update Check", "Encountered an error while checking updates.", true, ex);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,33 +1,9 @@
|
||||
(function($, $TDU){
|
||||
//
|
||||
// Variable: Current timeout ID for update checking.
|
||||
//
|
||||
var updateCheckTimeoutID;
|
||||
|
||||
//
|
||||
// Constant: Update exe file name.
|
||||
//
|
||||
const updateFileName = "TweetDuck.Update.exe";
|
||||
|
||||
//
|
||||
// Constant: Url that returns JSON data about latest version.
|
||||
//
|
||||
const updateCheckUrlLatest = "https://api.github.com/repos/chylex/TweetDuck/releases/latest";
|
||||
|
||||
//
|
||||
// Constant: Url that returns JSON data about all versions, including prereleases.
|
||||
//
|
||||
const updateCheckUrlAll = "https://api.github.com/repos/chylex/TweetDuck/releases";
|
||||
|
||||
//
|
||||
// Constant: Fallback url in case the update installer file is missing.
|
||||
//
|
||||
const updateDownloadFallback = "https://tweetduck.chylex.com";
|
||||
|
||||
//
|
||||
// Function: Creates the update notification element. Removes the old one if already exists.
|
||||
//
|
||||
var displayNotification = function(version, download, changelog){
|
||||
var displayNotification = function(version, changelog){
|
||||
|
||||
// styles
|
||||
var css = $("#tweetduck-update-css");
|
||||
|
||||
@ -167,7 +143,7 @@
|
||||
<div id='tweetduck-changelog'>
|
||||
<div id='tweetduck-changelog-box'>
|
||||
<h2>TweetDuck Update ${version}</h2>
|
||||
${changelog}
|
||||
${markdown(atob(changelog))}
|
||||
</div>
|
||||
</div>
|
||||
`).appendTo(document.body).css("display", "none");
|
||||
@ -219,17 +195,11 @@
|
||||
|
||||
buttonDiv.children(".tdu-btn-download").click(function(){
|
||||
hide();
|
||||
|
||||
if (download){
|
||||
$TDU.onUpdateAccepted();
|
||||
}
|
||||
else{
|
||||
$TDU.openBrowser(updateDownloadFallback);
|
||||
}
|
||||
$TDU.onUpdateAccepted();
|
||||
});
|
||||
|
||||
buttonDiv.children(".tdu-btn-later").click(function(){
|
||||
clearTimeout(updateCheckTimeoutID);
|
||||
$TDU.onUpdateDelayed();
|
||||
slide();
|
||||
});
|
||||
|
||||
@ -245,15 +215,6 @@
|
||||
return ele;
|
||||
};
|
||||
|
||||
//
|
||||
// Function: Returns milliseconds until the start of the next hour, with an extra offset in seconds that can skip an hour if the clock would roll over too soon.
|
||||
//
|
||||
var getTimeUntilNextHour = function(extra){
|
||||
var now = new Date();
|
||||
var offset = new Date(+now+extra*1000);
|
||||
return new Date(offset.getFullYear(), offset.getMonth(), offset.getDate(), offset.getHours()+1, 0, 0)-now;
|
||||
};
|
||||
|
||||
//
|
||||
// Function: Ghetto-converts markdown to HTML.
|
||||
//
|
||||
@ -273,33 +234,6 @@
|
||||
.replace(/\n\r?\n\r?/g, "<br>");
|
||||
};
|
||||
|
||||
//
|
||||
// Function: Runs an update check and updates all DOM elements appropriately.
|
||||
//
|
||||
var runUpdateCheck = function(eventID, versionTag, dismissedVersionTag, allowPre){
|
||||
clearTimeout(updateCheckTimeoutID);
|
||||
updateCheckTimeoutID = setTimeout($TDU.triggerUpdateCheck, getTimeUntilNextHour(60*30)); // 30 minute offset
|
||||
|
||||
$.getJSON(allowPre ? updateCheckUrlAll : updateCheckUrlLatest, function(response){
|
||||
var release = allowPre ? response[0] : response;
|
||||
|
||||
var tagName = release.tag_name;
|
||||
var hasUpdate = tagName !== versionTag && tagName !== dismissedVersionTag && release.assets.length > 0;
|
||||
|
||||
if (hasUpdate){
|
||||
var obj = release.assets.find(asset => asset.name === updateFileName) || { browser_download_url: "" };
|
||||
displayNotification(tagName, obj.browser_download_url, markdown(release.body));
|
||||
|
||||
if (eventID){ // ignore undefined and 0
|
||||
$TDU.onUpdateCheckFinished(eventID, tagName, obj.browser_download_url);
|
||||
}
|
||||
}
|
||||
else if (eventID){ // ignore undefined and 0
|
||||
$TDU.onUpdateCheckFinished(eventID, null, null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// Block: Check updates on startup.
|
||||
//
|
||||
@ -310,5 +244,5 @@
|
||||
//
|
||||
// Block: Setup global functions.
|
||||
//
|
||||
window.TDUF_runUpdateCheck = runUpdateCheck;
|
||||
window.TDUF_displayNotification = displayNotification;
|
||||
})($, $TDU);
|
||||
|
@ -69,6 +69,7 @@
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -316,6 +317,7 @@
|
||||
<Compile Include="Core\Management\BrowserCache.cs" />
|
||||
<Compile Include="Core\Utils\BrowserUtils.cs" />
|
||||
<Compile Include="Core\Utils\NativeMethods.cs" />
|
||||
<Compile Include="Updates\UpdateCheckClient.cs" />
|
||||
<Compile Include="Updates\UpdateDownloadStatus.cs" />
|
||||
<Compile Include="Updates\UpdateHandler.cs" />
|
||||
<Compile Include="Updates\UpdateInfo.cs" />
|
||||
|
@ -1,13 +1,14 @@
|
||||
using System;
|
||||
using TweetDuck.Data;
|
||||
|
||||
namespace TweetDuck.Updates.Events{
|
||||
sealed class UpdateCheckEventArgs : EventArgs{
|
||||
public int EventId { get; }
|
||||
public bool IsUpdateAvailable { get; }
|
||||
public Result<UpdateInfo> Result { get; }
|
||||
|
||||
public UpdateCheckEventArgs(int eventId, bool isUpdateAvailable){
|
||||
public UpdateCheckEventArgs(int eventId, Result<UpdateInfo> result){
|
||||
this.EventId = eventId;
|
||||
this.IsUpdateAvailable = isUpdateAvailable;
|
||||
this.Result = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Updates{
|
||||
sealed partial class FormUpdateDownload : Form{
|
||||
@ -22,19 +20,8 @@ private void btnCancel_Click(object sender, EventArgs e){
|
||||
}
|
||||
|
||||
private void timerDownloadCheck_Tick(object sender, EventArgs e){
|
||||
if (updateInfo.DownloadStatus == UpdateDownloadStatus.Done){
|
||||
if (updateInfo.DownloadStatus.IsFinished()){
|
||||
timerDownloadCheck.Stop();
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
else if (updateInfo.DownloadStatus == UpdateDownloadStatus.Failed){
|
||||
timerDownloadCheck.Stop();
|
||||
|
||||
if (FormMessage.Error("Update Has Failed", "Could not download the update: "+(updateInfo.DownloadError?.Message ?? "unknown error")+"\n\nDo you want to open the website and try downloading the update manually?", FormMessage.Yes, FormMessage.No)){
|
||||
BrowserUtils.OpenExternalBrowser(Program.Website);
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
63
Updates/UpdateCheckClient.cs
Normal file
63
Updates/UpdateCheckClient.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Script.Serialization;
|
||||
using TweetDuck.Core.Utils;
|
||||
using JsonObject = System.Collections.Generic.IDictionary<string, object>;
|
||||
|
||||
namespace TweetDuck.Updates{
|
||||
sealed class UpdateCheckClient{
|
||||
private const string ApiLatestRelease = "https://api.github.com/repos/chylex/TweetDuck/releases/latest";
|
||||
private const string UpdaterAssetName = "TweetDuck.Update.exe";
|
||||
|
||||
private readonly UpdaterSettings settings;
|
||||
|
||||
public UpdateCheckClient(UpdaterSettings settings){
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public Task<UpdateInfo> Check(){
|
||||
TaskCompletionSource<UpdateInfo> result = new TaskCompletionSource<UpdateInfo>();
|
||||
|
||||
WebClient client = BrowserUtils.CreateWebClient();
|
||||
client.Headers[HttpRequestHeader.Accept] = "application/vnd.github.v3+json"; // TODO could use .html to avoid custom markdown parsing
|
||||
|
||||
client.DownloadStringTaskAsync(ApiLatestRelease).ContinueWith(task => {
|
||||
if (task.IsCanceled){
|
||||
result.SetCanceled();
|
||||
}
|
||||
else if (task.IsFaulted){
|
||||
result.SetException(task.Exception.InnerException);
|
||||
}
|
||||
else{
|
||||
try{
|
||||
result.SetResult(ParseFromJson(task.Result));
|
||||
}catch(Exception e){
|
||||
result.SetException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result.Task;
|
||||
}
|
||||
|
||||
private UpdateInfo ParseFromJson(string json){
|
||||
bool IsUpdaterAsset(JsonObject obj){
|
||||
return UpdaterAssetName == (string)obj["name"];
|
||||
}
|
||||
|
||||
string AssetDownloadUrl(JsonObject obj){
|
||||
return (string)obj["browser_download_url"];
|
||||
}
|
||||
|
||||
JsonObject root = (JsonObject)new JavaScriptSerializer().DeserializeObject(json);
|
||||
|
||||
string versionTag = (string)root["tag_name"];
|
||||
string releaseNotes = (string)root["body"];
|
||||
string downloadUrl = ((Array)root["assets"]).Cast<JsonObject>().Where(IsUpdaterAsset).Select(AssetDownloadUrl).FirstOrDefault();
|
||||
|
||||
return new UpdateInfo(settings, versionTag, releaseNotes, downloadUrl);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,14 @@
|
||||
public enum UpdateDownloadStatus{
|
||||
None = 0,
|
||||
InProgress,
|
||||
AssetMissing,
|
||||
Done,
|
||||
Failed
|
||||
}
|
||||
|
||||
public static class UpdateDownloadStatusExtensions{
|
||||
public static bool IsFinished(this UpdateDownloadStatus status){
|
||||
return status == UpdateDownloadStatus.AssetMissing || status == UpdateDownloadStatus.Done || status == UpdateDownloadStatus.Failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,26 @@
|
||||
using CefSharp;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Other.Interfaces;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Data;
|
||||
using TweetDuck.Resources;
|
||||
using TweetDuck.Updates.Events;
|
||||
|
||||
namespace TweetDuck.Updates{
|
||||
sealed class UpdateHandler{
|
||||
sealed class UpdateHandler : IDisposable{
|
||||
public const int CheckCodeUpdatesDisabled = -1;
|
||||
public const int CheckCodeNotOnTweetDeck = -2;
|
||||
|
||||
private readonly ITweetDeckBrowser browser;
|
||||
|
||||
private readonly UpdaterSettings settings;
|
||||
private readonly UpdateCheckClient client;
|
||||
private readonly ITweetDeckBrowser browser;
|
||||
private readonly Timer timer;
|
||||
|
||||
public event EventHandler<UpdateEventArgs> UpdateAccepted;
|
||||
public event EventHandler<UpdateEventArgs> UpdateDelayed;
|
||||
public event EventHandler<UpdateEventArgs> UpdateDismissed;
|
||||
public event EventHandler<UpdateCheckEventArgs> CheckFinished;
|
||||
|
||||
@ -23,11 +28,44 @@ sealed class UpdateHandler{
|
||||
private UpdateInfo lastUpdateInfo;
|
||||
|
||||
public UpdateHandler(ITweetDeckBrowser browser, UpdaterSettings settings){
|
||||
this.browser = browser;
|
||||
this.settings = settings;
|
||||
this.client = new UpdateCheckClient(settings);
|
||||
|
||||
this.browser = browser;
|
||||
this.browser.OnFrameLoaded(OnFrameLoaded);
|
||||
this.browser.RegisterBridge("$TDU", new Bridge(this));
|
||||
|
||||
browser.OnFrameLoaded(OnFrameLoaded);
|
||||
browser.RegisterBridge("$TDU", new Bridge(this));
|
||||
this.timer = new Timer();
|
||||
this.timer.Tick += timer_Tick;
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
timer.Dispose();
|
||||
}
|
||||
|
||||
private void timer_Tick(object sender, EventArgs e){
|
||||
timer.Stop();
|
||||
Check(false);
|
||||
}
|
||||
|
||||
public void StartTimer(){
|
||||
if (timer.Enabled){
|
||||
return;
|
||||
}
|
||||
|
||||
timer.Stop();
|
||||
|
||||
if (Program.UserConfig.EnableUpdateCheck){
|
||||
DateTime now = DateTime.Now;
|
||||
TimeSpan nextHour = now.AddSeconds(60*(60-now.Minute)-now.Second)-now;
|
||||
|
||||
if (nextHour.TotalMinutes < 15){
|
||||
nextHour = nextHour.Add(TimeSpan.FromHours(1));
|
||||
}
|
||||
|
||||
timer.Interval = (int)Math.Ceiling(nextHour.TotalMilliseconds);
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFrameLoaded(IFrame frame){
|
||||
@ -43,17 +81,24 @@ public int Check(bool force){
|
||||
if (!browser.IsTweetDeckWebsite){
|
||||
return CheckCodeNotOnTweetDeck;
|
||||
}
|
||||
|
||||
int nextEventId = unchecked(++lastEventId);
|
||||
Task<UpdateInfo> checkTask = client.Check();
|
||||
|
||||
browser.ExecuteFunction("TDUF_runUpdateCheck", (int)unchecked(++lastEventId), Program.VersionTag, settings.DismissedUpdate ?? string.Empty, settings.AllowPreReleases);
|
||||
return lastEventId;
|
||||
checkTask.ContinueWith(task => HandleUpdateCheckSuccessful(nextEventId, task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||
checkTask.ContinueWith(task => HandleUpdateCheckFailed(nextEventId, task.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted);
|
||||
|
||||
return nextEventId;
|
||||
}
|
||||
|
||||
return CheckCodeUpdatesDisabled;
|
||||
}
|
||||
|
||||
public void BeginUpdateDownload(Form ownerForm, UpdateInfo updateInfo, Action<UpdateInfo> onSuccess){
|
||||
if (updateInfo.DownloadStatus == UpdateDownloadStatus.Done){
|
||||
onSuccess(updateInfo);
|
||||
public void BeginUpdateDownload(Form ownerForm, UpdateInfo updateInfo, Action<UpdateInfo> onFinished){
|
||||
UpdateDownloadStatus status = updateInfo.DownloadStatus;
|
||||
|
||||
if (status == UpdateDownloadStatus.Done || status == UpdateDownloadStatus.AssetMissing){
|
||||
onFinished(updateInfo);
|
||||
}
|
||||
else{
|
||||
FormUpdateDownload downloadForm = new FormUpdateDownload(updateInfo);
|
||||
@ -65,13 +110,7 @@ public void BeginUpdateDownload(Form ownerForm, UpdateInfo updateInfo, Action<Up
|
||||
|
||||
downloadForm.FormClosed += (sender, args) => {
|
||||
downloadForm.Dispose();
|
||||
|
||||
if (downloadForm.DialogResult == DialogResult.OK){ // success or manual download
|
||||
onSuccess(updateInfo);
|
||||
}
|
||||
else{
|
||||
ownerForm.Show();
|
||||
}
|
||||
onFinished(updateInfo);
|
||||
};
|
||||
|
||||
downloadForm.Show();
|
||||
@ -85,17 +124,41 @@ public void CleanupDownload(){
|
||||
}
|
||||
}
|
||||
|
||||
private void TriggerUpdateAcceptedEvent(UpdateEventArgs args){
|
||||
UpdateAccepted?.Invoke(this, args);
|
||||
private void HandleUpdateCheckSuccessful(int eventId, UpdateInfo info){
|
||||
if (info.IsUpdateNew && !info.IsUpdateDismissed){
|
||||
CleanupDownload();
|
||||
lastUpdateInfo = info;
|
||||
lastUpdateInfo.BeginSilentDownload();
|
||||
|
||||
browser.ExecuteFunction("TDUF_displayNotification", lastUpdateInfo.VersionTag, Convert.ToBase64String(Encoding.GetEncoding("iso-8859-1").GetBytes(lastUpdateInfo.ReleaseNotes))); // TODO move browser stuff outside
|
||||
}
|
||||
|
||||
CheckFinished?.Invoke(this, new UpdateCheckEventArgs(eventId, new Result<UpdateInfo>(info)));
|
||||
}
|
||||
|
||||
private void TriggerUpdateDismissedEvent(UpdateEventArgs args){
|
||||
settings.DismissedUpdate = args.UpdateInfo.VersionTag;
|
||||
UpdateDismissed?.Invoke(this, args);
|
||||
private void HandleUpdateCheckFailed(int eventId, Exception exception){
|
||||
CheckFinished?.Invoke(this, new UpdateCheckEventArgs(eventId, new Result<UpdateInfo>(exception)));
|
||||
}
|
||||
|
||||
private void TriggerCheckFinishedEvent(UpdateCheckEventArgs args){
|
||||
CheckFinished?.Invoke(this, args);
|
||||
private void TriggerUpdateAcceptedEvent(){
|
||||
if (lastUpdateInfo != null){
|
||||
UpdateAccepted?.Invoke(this, new UpdateEventArgs(lastUpdateInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private void TriggerUpdateDelayedEvent(){
|
||||
if (lastUpdateInfo != null){
|
||||
UpdateDelayed?.Invoke(this, new UpdateEventArgs(lastUpdateInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private void TriggerUpdateDismissedEvent(){
|
||||
if (lastUpdateInfo != null){
|
||||
settings.DismissedUpdate = lastUpdateInfo.VersionTag;
|
||||
UpdateDismissed?.Invoke(this, new UpdateEventArgs(lastUpdateInfo));
|
||||
|
||||
CleanupDownload();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Bridge{
|
||||
@ -109,31 +172,16 @@ public void TriggerUpdateCheck(){
|
||||
owner.Check(false);
|
||||
}
|
||||
|
||||
public void OnUpdateCheckFinished(int eventId, string versionTag, string downloadUrl){
|
||||
if (versionTag != null && (owner.lastUpdateInfo == null || owner.lastUpdateInfo.VersionTag != versionTag)){
|
||||
owner.CleanupDownload();
|
||||
owner.lastUpdateInfo = new UpdateInfo(owner.settings, eventId, versionTag, downloadUrl);
|
||||
owner.lastUpdateInfo.BeginSilentDownload();
|
||||
}
|
||||
|
||||
owner.TriggerCheckFinishedEvent(new UpdateCheckEventArgs(eventId, owner.lastUpdateInfo != null));
|
||||
public void OnUpdateAccepted(){
|
||||
owner.TriggerUpdateAcceptedEvent();
|
||||
}
|
||||
|
||||
public void OnUpdateAccepted(){
|
||||
if (owner.lastUpdateInfo != null){
|
||||
owner.TriggerUpdateAcceptedEvent(new UpdateEventArgs(owner.lastUpdateInfo));
|
||||
}
|
||||
public void OnUpdateDelayed(){
|
||||
owner.TriggerUpdateDelayedEvent();
|
||||
}
|
||||
|
||||
public void OnUpdateDismissed(){
|
||||
if (owner.lastUpdateInfo != null){
|
||||
owner.TriggerUpdateDismissedEvent(new UpdateEventArgs(owner.lastUpdateInfo));
|
||||
owner.CleanupDownload();
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenBrowser(string url){
|
||||
BrowserUtils.OpenExternalBrowser(url);
|
||||
owner.TriggerUpdateDismissedEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,40 +5,43 @@
|
||||
|
||||
namespace TweetDuck.Updates{
|
||||
sealed class UpdateInfo{
|
||||
public int EventId { get; }
|
||||
public string VersionTag { get; }
|
||||
public string ReleaseNotes { get; }
|
||||
public string InstallerPath { get; }
|
||||
|
||||
public bool IsUpdateNew => VersionTag != Program.VersionTag;
|
||||
public bool IsUpdateDismissed => VersionTag == settings.DismissedUpdate;
|
||||
|
||||
public UpdateDownloadStatus DownloadStatus { get; private set; }
|
||||
public Exception DownloadError { get; private set; }
|
||||
|
||||
private readonly string installerFolder;
|
||||
private readonly UpdaterSettings settings;
|
||||
private readonly string downloadUrl;
|
||||
private WebClient currentDownload;
|
||||
|
||||
public UpdateInfo(UpdaterSettings settings, int eventId, string versionTag, string downloadUrl){
|
||||
this.installerFolder = settings.InstallerDownloadFolder;
|
||||
public UpdateInfo(UpdaterSettings settings, string versionTag, string releaseNotes, string downloadUrl){
|
||||
this.settings = settings;
|
||||
this.downloadUrl = downloadUrl;
|
||||
|
||||
this.EventId = eventId;
|
||||
|
||||
this.VersionTag = versionTag;
|
||||
this.InstallerPath = Path.Combine(installerFolder, "TweetDuck."+versionTag+".exe");
|
||||
this.ReleaseNotes = releaseNotes;
|
||||
this.InstallerPath = Path.Combine(settings.InstallerDownloadFolder, "TweetDuck."+versionTag+".exe");
|
||||
}
|
||||
|
||||
public void BeginSilentDownload(){
|
||||
if (DownloadStatus == UpdateDownloadStatus.None || DownloadStatus == UpdateDownloadStatus.Failed){
|
||||
DownloadStatus = UpdateDownloadStatus.InProgress;
|
||||
|
||||
try{
|
||||
Directory.CreateDirectory(installerFolder);
|
||||
}catch(Exception e){
|
||||
DownloadError = e;
|
||||
DownloadStatus = UpdateDownloadStatus.Failed;
|
||||
if (string.IsNullOrEmpty(downloadUrl)){
|
||||
DownloadError = new InvalidDataException("Missing installer asset.");
|
||||
DownloadStatus = UpdateDownloadStatus.AssetMissing;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(downloadUrl)){
|
||||
DownloadError = new UriFormatException("Could not determine URL of the update installer");
|
||||
try{
|
||||
Directory.CreateDirectory(settings.InstallerDownloadFolder);
|
||||
}catch(Exception e){
|
||||
DownloadError = e;
|
||||
DownloadStatus = UpdateDownloadStatus.Failed;
|
||||
return;
|
||||
}
|
||||
@ -68,5 +71,13 @@ public void DeleteInstaller(){
|
||||
// rip
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj){
|
||||
return obj is UpdateInfo info && VersionTag == info.VersionTag;
|
||||
}
|
||||
|
||||
public override int GetHashCode(){
|
||||
return VersionTag.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user