diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs index 8da6dea1..b00d783a 100644 --- a/Core/FormBrowser.cs +++ b/Core/FormBrowser.cs @@ -56,7 +56,7 @@ public bool IsWaiting{ private VideoPlayer videoPlayer; private AnalyticsManager analytics; - public FormBrowser(UpdaterSettings updaterSettings){ + public FormBrowser(){ InitializeComponent(); Text = Program.BrandName; @@ -97,7 +97,7 @@ public FormBrowser(UpdaterSettings updaterSettings){ UpdateTrayIcon(); - this.updates = new UpdateHandler(browser, updaterSettings); + this.updates = new UpdateHandler(browser, Program.InstallerPath); this.updates.CheckFinished += updates_CheckFinished; this.updates.UpdateAccepted += updates_UpdateAccepted; this.updates.UpdateDismissed += updates_UpdateDismissed; @@ -237,25 +237,24 @@ 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.IsUpdateDismissed){ - if (update.IsUpdateNew){ - browser.ShowUpdateNotification(update.VersionTag, update.ReleaseNotes); - } - else{ - updates.StartTimer(); - } - } - }, ex => { - if (!ignoreUpdateCheckError){ - Program.Reporter.HandleException("Update Check Error", "An error occurred while checking for updates.", true, ex); - updates.StartTimer(); - } - }); - - ignoreUpdateCheckError = true; + e.Result.Handle(update => { + string tag = update.VersionTag; + + if (tag != Program.VersionTag && tag != Config.DismissedUpdate){ + updates.PrepareUpdate(update); + browser.ShowUpdateNotification(tag, update.ReleaseNotes); + } + else{ + updates.StartTimer(); + } + }, ex => { + if (!ignoreUpdateCheckError){ + Program.Reporter.HandleException("Update Check Error", "An error occurred while checking for updates.", true, ex); + updates.StartTimer(); + } }); + + ignoreUpdateCheckError = true; } private void updates_UpdateAccepted(object sender, UpdateEventArgs e){ diff --git a/Core/Other/Settings/TabSettingsGeneral.cs b/Core/Other/Settings/TabSettingsGeneral.cs index 2b79cfda..5bbb3ba4 100644 --- a/Core/Other/Settings/TabSettingsGeneral.cs +++ b/Core/Other/Settings/TabSettingsGeneral.cs @@ -218,19 +218,17 @@ private void btnCheckUpdates_Click(object sender, EventArgs e){ } private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){ - this.InvokeAsyncSafe(() => { - if (e.EventId == updateCheckEventId){ - btnCheckUpdates.Enabled = true; + if (e.EventId == updateCheckEventId){ + btnCheckUpdates.Enabled = true; - 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 Error", "An error occurred while checking for updates.", true, ex); - }); - } - }); + e.Result.Handle(update => { + if (update.VersionTag == Program.VersionTag){ + FormMessage.Information("No Updates Available", "Your version of TweetDuck is up to date.", FormMessage.OK); + } + }, ex => { + Program.Reporter.HandleException("Update Check Error", "An error occurred while checking for updates.", true, ex); + }); + } } private void zoomUpdateTimer_Tick(object sender, EventArgs e){ diff --git a/Program.cs b/Program.cs index 6b5d07bd..34f06cf5 100644 --- a/Program.cs +++ b/Program.cs @@ -31,7 +31,7 @@ static class Program{ public static readonly string PluginPath = Path.Combine(ProgramPath, "plugins"); public static readonly string PluginDataPath = Path.Combine(StoragePath, "TD_Plugins"); - private static readonly string InstallerPath = Path.Combine(StoragePath, "TD_Updates"); + public static readonly string InstallerPath = Path.Combine(StoragePath, "TD_Updates"); private static readonly string CefDataPath = Path.Combine(StoragePath, "TD_Chromium"); public static string UserConfigFilePath => Path.Combine(StoragePath, "TD_UserConfig.cfg"); @@ -150,13 +150,8 @@ private static void Main(){ Cef.Initialize(settings, false, new BrowserProcessHandler()); Application.ApplicationExit += (sender, args) => ExitCleanup(); - - UpdaterSettings updaterSettings = new UpdaterSettings(InstallerPath){ - AllowPreReleases = Arguments.HasFlag(Arguments.ArgDebugUpdates), - DismissedUpdate = UserConfig.DismissedUpdate - }; - - FormBrowser mainForm = new FormBrowser(updaterSettings); + + FormBrowser mainForm = new FormBrowser(); Application.Run(mainForm); if (mainForm.UpdateInstallerPath != null){ diff --git a/TweetDuck.csproj b/TweetDuck.csproj index 062e820f..c0bb15c8 100644 --- a/TweetDuck.csproj +++ b/TweetDuck.csproj @@ -325,7 +325,6 @@ <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Resources\ScriptLoader.cs" /> <Compile Include="Updates\Events\UpdateEventArgs.cs" /> - <Compile Include="Updates\UpdaterSettings.cs" /> </ItemGroup> <ItemGroup> <BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client"> diff --git a/Updates/Events/UpdateCheckEventArgs.cs b/Updates/Events/UpdateCheckEventArgs.cs index 5da32326..a5a49485 100644 --- a/Updates/Events/UpdateCheckEventArgs.cs +++ b/Updates/Events/UpdateCheckEventArgs.cs @@ -5,7 +5,7 @@ namespace TweetDuck.Updates.Events{ sealed class UpdateCheckEventArgs : EventArgs{ public int EventId { get; } public Result<UpdateInfo> Result { get; } - + public UpdateCheckEventArgs(int eventId, Result<UpdateInfo> result){ this.EventId = eventId; this.Result = result; diff --git a/Updates/UpdateCheckClient.cs b/Updates/UpdateCheckClient.cs index d4c793ac..ecb51c82 100644 --- a/Updates/UpdateCheckClient.cs +++ b/Updates/UpdateCheckClient.cs @@ -11,10 +11,10 @@ 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; + private readonly string installerFolder; - public UpdateCheckClient(UpdaterSettings settings){ - this.settings = settings; + public UpdateCheckClient(string installerFolder){ + this.installerFolder = installerFolder; } public Task<UpdateInfo> Check(){ @@ -57,7 +57,7 @@ string AssetDownloadUrl(JsonObject obj){ string releaseNotes = (string)root["body"]; string downloadUrl = ((Array)root["assets"]).Cast<JsonObject>().Where(IsUpdaterAsset).Select(AssetDownloadUrl).FirstOrDefault(); - return new UpdateInfo(settings, versionTag, releaseNotes, downloadUrl); + return new UpdateInfo(versionTag, releaseNotes, downloadUrl, installerFolder); } } } diff --git a/Updates/UpdateHandler.cs b/Updates/UpdateHandler.cs index 3be87a14..d9463d0a 100644 --- a/Updates/UpdateHandler.cs +++ b/Updates/UpdateHandler.cs @@ -1,18 +1,20 @@ using System; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using TweetDuck.Core.Controls; using TweetDuck.Core.Other.Interfaces; using TweetDuck.Data; using TweetDuck.Updates.Events; +using Timer = System.Windows.Forms.Timer; namespace TweetDuck.Updates{ sealed class UpdateHandler : IDisposable{ public const int CheckCodeUpdatesDisabled = -1; public const int CheckCodeNotOnTweetDeck = -2; - private readonly UpdaterSettings settings; private readonly UpdateCheckClient client; + private readonly TaskScheduler scheduler; private readonly ITweetDeckBrowser browser; private readonly Timer timer; @@ -24,9 +26,9 @@ sealed class UpdateHandler : IDisposable{ private ushort lastEventId; private UpdateInfo lastUpdateInfo; - public UpdateHandler(ITweetDeckBrowser browser, UpdaterSettings settings){ - this.settings = settings; - this.client = new UpdateCheckClient(settings); + public UpdateHandler(ITweetDeckBrowser browser, string installerFolder){ + this.client = new UpdateCheckClient(installerFolder); + this.scheduler = TaskScheduler.FromCurrentSynchronizationContext(); this.browser = browser; this.browser.RegisterBridge("$TDU", new Bridge(this)); @@ -66,10 +68,6 @@ public void StartTimer(){ public int Check(bool force){ if (Program.UserConfig.EnableUpdateCheck || force){ - if (force){ - settings.DismissedUpdate = null; - } - if (!browser.IsTweetDeckWebsite){ return CheckCodeNotOnTweetDeck; } @@ -77,8 +75,8 @@ public int Check(bool force){ int nextEventId = unchecked(++lastEventId); Task<UpdateInfo> checkTask = client.Check(); - checkTask.ContinueWith(task => HandleUpdateCheckSuccessful(nextEventId, task.Result), TaskContinuationOptions.OnlyOnRanToCompletion); - checkTask.ContinueWith(task => HandleUpdateCheckFailed(nextEventId, task.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted); + checkTask.ContinueWith(task => HandleUpdateCheckSuccessful(nextEventId, task.Result), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler); + checkTask.ContinueWith(task => HandleUpdateCheckFailed(nextEventId, task.Exception.InnerException), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler); return nextEventId; } @@ -86,6 +84,12 @@ public int Check(bool force){ return CheckCodeUpdatesDisabled; } + public void PrepareUpdate(UpdateInfo info){ + CleanupDownload(); + lastUpdateInfo = info; + lastUpdateInfo.BeginSilentDownload(); + } + public void BeginUpdateDownload(Form ownerForm, UpdateInfo updateInfo, Action<UpdateInfo> onFinished){ UpdateDownloadStatus status = updateInfo.DownloadStatus; @@ -121,12 +125,6 @@ public void CleanupDownload(){ } private void HandleUpdateCheckSuccessful(int eventId, UpdateInfo info){ - if (info.IsUpdateNew && !info.IsUpdateDismissed){ - CleanupDownload(); - lastUpdateInfo = info; - lastUpdateInfo.BeginSilentDownload(); - } - CheckFinished?.Invoke(this, new UpdateCheckEventArgs(eventId, new Result<UpdateInfo>(info))); } @@ -148,9 +146,7 @@ private void TriggerUpdateDelayedEvent(){ private void TriggerUpdateDismissedEvent(){ if (lastUpdateInfo != null){ - settings.DismissedUpdate = lastUpdateInfo.VersionTag; UpdateDismissed?.Invoke(this, new UpdateEventArgs(lastUpdateInfo)); - CleanupDownload(); } } diff --git a/Updates/UpdateInfo.cs b/Updates/UpdateInfo.cs index f2953cd3..567c822e 100644 --- a/Updates/UpdateInfo.cs +++ b/Updates/UpdateInfo.cs @@ -8,24 +8,21 @@ sealed class UpdateInfo{ 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 UpdaterSettings settings; private readonly string downloadUrl; + private readonly string installerFolder; private WebClient currentDownload; - public UpdateInfo(UpdaterSettings settings, string versionTag, string releaseNotes, string downloadUrl){ - this.settings = settings; + public UpdateInfo(string versionTag, string releaseNotes, string downloadUrl, string installerFolder){ this.downloadUrl = downloadUrl; + this.installerFolder = installerFolder; this.VersionTag = versionTag; this.ReleaseNotes = releaseNotes; - this.InstallerPath = Path.Combine(settings.InstallerDownloadFolder, "TweetDuck."+versionTag+".exe"); + this.InstallerPath = Path.Combine(installerFolder, $"TweetDuck.{versionTag}.exe");; } public void BeginSilentDownload(){ @@ -39,7 +36,7 @@ public void BeginSilentDownload(){ } try{ - Directory.CreateDirectory(settings.InstallerDownloadFolder); + Directory.CreateDirectory(installerFolder); }catch(Exception e){ DownloadError = e; DownloadStatus = UpdateDownloadStatus.Failed; diff --git a/Updates/UpdaterSettings.cs b/Updates/UpdaterSettings.cs deleted file mode 100644 index a7c48609..00000000 --- a/Updates/UpdaterSettings.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace TweetDuck.Updates{ - sealed class UpdaterSettings{ - public string InstallerDownloadFolder { get; } - - public string DismissedUpdate { get; set; } - - public UpdaterSettings(string installerDownloadFolder){ - this.InstallerDownloadFolder = installerDownloadFolder; - } - } -}