diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs index e0cf4c0f..34cc58a3 100644 --- a/Core/FormBrowser.cs +++ b/Core/FormBrowser.cs @@ -1,5 +1,4 @@ using System; -using System.Drawing; using System.Linq; using System.Windows.Forms; using CefSharp; @@ -8,6 +7,7 @@ using TweetDck.Core.Handling; using TweetDck.Core.Other; using TweetDck.Resources; +using TweetDck.Core.Utils; using TweetDck.Core.Controls; namespace TweetDck.Core{ @@ -18,6 +18,8 @@ private static UserConfig Config{ } } + public string UpdateInstallerPath { get; private set; } + private readonly ChromiumWebBrowser browser; private readonly TweetDeckBridge bridge; private readonly FormNotification notification; @@ -174,5 +176,24 @@ public void OpenAbout(){ public void OnTweetPopup(TweetNotification tweet){ notification.ShowNotification(tweet); } + + public void BeginUpdateProcess(string versionTag, string downloadUrl){ + Hide(); + + FormUpdateDownload downloadForm = new FormUpdateDownload(new UpdateInfo(versionTag,downloadUrl)); + downloadForm.MoveToCenter(this); + downloadForm.ShowDialog(); + + if (downloadForm.UpdateStatus == FormUpdateDownload.Status.Succeeded){ + UpdateInstallerPath = downloadForm.InstallerPath; + Close(); + } + else if (downloadForm.UpdateStatus == FormUpdateDownload.Status.Manual){ + Close(); + } + else{ + Show(); + } + } } } \ No newline at end of file diff --git a/Core/Handling/TweetDeckBridge.cs b/Core/Handling/TweetDeckBridge.cs index df2d9bc2..3f70a90e 100644 --- a/Core/Handling/TweetDeckBridge.cs +++ b/Core/Handling/TweetDeckBridge.cs @@ -58,6 +58,7 @@ public void OnTweetPopup(string tweetHtml, int tweetCharacters){ public void OnUpdateAccepted(string versionTag, string downloadUrl){ form.InvokeSafe(() => { + form.BeginUpdateProcess(versionTag,downloadUrl); }); } diff --git a/Core/Other/FormUpdateDownload.Designer.cs b/Core/Other/FormUpdateDownload.Designer.cs new file mode 100644 index 00000000..19358a70 --- /dev/null +++ b/Core/Other/FormUpdateDownload.Designer.cs @@ -0,0 +1,103 @@ +namespace TweetDck.Core.Other { + partial class FormUpdateDownload { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() { + this.progressDownload = new System.Windows.Forms.ProgressBar(); + this.btnCancel = new System.Windows.Forms.Button(); + this.labelDescription = new System.Windows.Forms.Label(); + this.labelStatus = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // progressDownload + // + this.progressDownload.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.progressDownload.Location = new System.Drawing.Point(12, 32); + this.progressDownload.MarqueeAnimationSpeed = 40; + this.progressDownload.Maximum = 1000; + this.progressDownload.Name = "progressDownload"; + this.progressDownload.Size = new System.Drawing.Size(361, 23); + this.progressDownload.Style = System.Windows.Forms.ProgressBarStyle.Marquee; + this.progressDownload.TabIndex = 0; + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.AutoSize = true; + this.btnCancel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnCancel.Location = new System.Drawing.Point(317, 61); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0); + this.btnCancel.Size = new System.Drawing.Size(56, 23); + this.btnCancel.TabIndex = 1; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // labelDescription + // + this.labelDescription.AutoSize = true; + this.labelDescription.Location = new System.Drawing.Point(13, 13); + this.labelDescription.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3); + this.labelDescription.Name = "labelDescription"; + this.labelDescription.Size = new System.Drawing.Size(0, 13); + this.labelDescription.TabIndex = 2; + // + // labelStatus + // + this.labelStatus.AutoSize = true; + this.labelStatus.Location = new System.Drawing.Point(12, 62); + this.labelStatus.Name = "labelStatus"; + this.labelStatus.Size = new System.Drawing.Size(0, 13); + this.labelStatus.TabIndex = 3; + // + // FormUpdateDownload + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(385, 96); + this.Controls.Add(this.labelStatus); + this.Controls.Add(this.labelDescription); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.progressDownload); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = global::TweetDck.Properties.Resources.icon; + this.MaximizeBox = false; + this.Name = "FormUpdateDownload"; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormUpdateDownload_FormClosing); + this.Shown += new System.EventHandler(this.FormUpdateDownload_Shown); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ProgressBar progressDownload; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label labelDescription; + private System.Windows.Forms.Label labelStatus; + } +} \ No newline at end of file diff --git a/Core/Other/FormUpdateDownload.cs b/Core/Other/FormUpdateDownload.cs new file mode 100644 index 00000000..09de5f8c --- /dev/null +++ b/Core/Other/FormUpdateDownload.cs @@ -0,0 +1,108 @@ +using System; +using System.ComponentModel; +using System.IO; +using System.Net; +using System.Windows.Forms; +using TweetDck.Core.Controls; +using TweetDck.Core.Utils; + +namespace TweetDck.Core.Other{ + sealed partial class FormUpdateDownload : Form{ + public string InstallerPath{ + get{ + return Path.Combine(Path.GetTempPath(),updateInfo.FileName); + } + } + + public enum Status{ + Waiting, Failed, Cancelled, Manual, Succeeded + } + + public Status UpdateStatus { get; private set; } + + private readonly WebClient webClient; + private readonly UpdateInfo updateInfo; + + public FormUpdateDownload(UpdateInfo info){ + InitializeComponent(); + + this.webClient = new WebClient{ Proxy = null }; + this.webClient.Headers[HttpRequestHeader.UserAgent] = BrowserUtils.HeaderUserAgent; + + this.updateInfo = info; + this.UpdateStatus = Status.Waiting; + + Disposed += (sender, args) => webClient.Dispose(); + + webClient.DownloadProgressChanged += webClient_DownloadProgressChanged; + webClient.DownloadFileCompleted += webClient_DownloadFileCompleted; + + Text = "Updating "+Program.BrandName; + labelDescription.Text = "Downloading version "+info.VersionTag+"..."; + } + + private void FormUpdateDownload_Shown(object sender, EventArgs e){ + webClient.DownloadFileAsync(new Uri(updateInfo.DownloadUrl),InstallerPath); + } + + private void btnCancel_Click(object sender, EventArgs e){ + webClient.CancelAsync(); + btnCancel.Enabled = false; + } + + private void FormUpdateDownload_FormClosing(object sender, FormClosingEventArgs e){ + if (UpdateStatus == Status.Waiting){ + e.Cancel = true; + webClient.CancelAsync(); + UpdateStatus = e.CloseReason == CloseReason.UserClosing ? Status.Cancelled : Status.Manual; // manual will exit the app + } + } + + private void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e){ + this.InvokeSafe(() => { + if (e.TotalBytesToReceive == -1){ + if (progressDownload.Style != ProgressBarStyle.Marquee){ + progressDownload.Style = ProgressBarStyle.Continuous; + progressDownload.SetValueInstant(1000); + } + + labelStatus.Text = (e.BytesReceived/(1024.0*1024.0)).ToString("0.0")+" MB"; + } + else{ + if (progressDownload.Style != ProgressBarStyle.Continuous){ + progressDownload.Style = ProgressBarStyle.Continuous; + } + + progressDownload.SetValueInstant(e.ProgressPercentage*10); + labelStatus.Text = (e.BytesReceived/(1024.0*1024.0)).ToString("0.0")+" / "+(e.TotalBytesToReceive/(1024.0*1024.0)).ToString("0.0")+" MB"; + } + }); + } + + private void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e){ + this.InvokeSafe(() => { + if (e.Cancelled){ + if (UpdateStatus == Status.Waiting){ + UpdateStatus = Status.Cancelled; + } + } + else if (e.Error != null){ + Program.Log(e.Error.ToString()); + + if (MessageBox.Show("Could not download the update: "+e.Error.Message+"\r\n\r\nDo you want to open the website and try downloading the update manually?","Update Has Failed",MessageBoxButtons.YesNo,MessageBoxIcon.Error,MessageBoxDefaultButton.Button1) == DialogResult.Yes){ + BrowserUtils.OpenExternalBrowser(Program.Website); + UpdateStatus = Status.Manual; + } + else{ + UpdateStatus = Status.Failed; + } + } + else{ + UpdateStatus = Status.Succeeded; + } + + Close(); + }); + } + } +} diff --git a/Core/Utils/UpdateInfo.cs b/Core/Utils/UpdateInfo.cs new file mode 100644 index 00000000..b89d4e54 --- /dev/null +++ b/Core/Utils/UpdateInfo.cs @@ -0,0 +1,17 @@ +namespace TweetDck.Core.Utils{ + class UpdateInfo{ + public readonly string VersionTag; + public readonly string DownloadUrl; + + public string FileName{ + get{ + return BrowserUtils.GetFileNameFromUrl(DownloadUrl) ?? Program.BrandName+".Update.exe"; + } + } + + public UpdateInfo(string versionTag, string downloadUrl){ + this.VersionTag = versionTag; + this.DownloadUrl = downloadUrl; + } + } +} diff --git a/Program.cs b/Program.cs index 66904f40..76ce33bb 100644 --- a/Program.cs +++ b/Program.cs @@ -91,7 +91,13 @@ private static void Main(){ Cef.Shutdown(); }; - Application.Run(new FormBrowser()); + FormBrowser mainForm = new FormBrowser(); + Application.Run(mainForm); + + if (mainForm.UpdateInstallerPath != null){ + Process.Start(mainForm.UpdateInstallerPath,"/SP- /SILENT /NOICONS /CLOSEAPPLICATIONS"); + Application.Exit(); + } } public static void HandleException(string message, Exception e){ diff --git a/Resources/code.js b/Resources/code.js index 6583dad6..8a4c5fe8 100644 --- a/Resources/code.js +++ b/Resources/code.js @@ -239,8 +239,8 @@ }); buttonDiv.children(".tdu-btn-download").click(function(){ + ele.remove(); $TD.onUpdateAccepted(version,download); - ele.slideUp(function(){ ele.remove(); }); }); buttonDiv.children(".tdu-btn-dismiss").click(function(){ @@ -267,9 +267,8 @@ $.getJSON("https://api.github.com/repos/chylex/"+$TD.brandName+"/releases/latest",function(response){ var tagName = response.tag_name; - if (tagName != $TD.versionTag && tagName != $TD.dismissedVersionTag){ - var dlLink = "https://github.com/chylex/"+$TD.brandName+"/releases/download/"+tagName+"/"+response.assets[0].name; - createUpdateNotificationElement(tagName,dlLink); + if (tagName != $TD.versionTag && tagName != $TD.dismissedVersionTag && response.assets.length > 0){ + createUpdateNotificationElement(tagName,response.assets[0].browser_download_url); } }); }; diff --git a/TweetDck.csproj b/TweetDck.csproj index ab795e05..9a4221b7 100644 --- a/TweetDck.csproj +++ b/TweetDck.csproj @@ -125,7 +125,14 @@ <Compile Include="Core\Other\FormSettings.Designer.cs"> <DependentUpon>FormSettings.cs</DependentUpon> </Compile> + <Compile Include="Core\Other\FormUpdateDownload.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="Core\Other\FormUpdateDownload.Designer.cs"> + <DependentUpon>FormUpdateDownload.cs</DependentUpon> + </Compile> <Compile Include="Core\Utils\BrowserUtils.cs" /> + <Compile Include="Core\Utils\UpdateInfo.cs" /> <Compile Include="Migration\FormMigrationQuestion.cs"> <SubType>Form</SubType> </Compile>