Toasts – Diff between revs 58 and 59

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 58 Rev 59
Line 22... Line 22...
22 using System.Windows.Forms; 22 using System.Windows.Forms;
23 using System.Xml.Linq; 23 using System.Xml.Linq;
24 using TheArtOfDev.HtmlRenderer.WinForms; 24 using TheArtOfDev.HtmlRenderer.WinForms;
25 using Toasts.Properties; 25 using Toasts.Properties;
26 using Toasts.Utilities; 26 using Toasts.Utilities;
-   27 using static System.Net.Mime.MediaTypeNames;
-   28 using Image = System.Drawing.Image;
Line 27... Line 29...
27   29  
28 namespace Toasts 30 namespace Toasts
29 { 31 {
30 public partial class ToastForm : Form 32 public partial class ToastForm : Form
Line 78... Line 80...
78   80  
79 /// <summary> 81 /// <summary>
80 /// 82 ///
81 /// </summary> 83 /// </summary>
82 /// <remarks>clone the image for safety</remarks> 84 /// <remarks>clone the image for safety</remarks>
83 public Image Image 85 public System.Drawing.Image Image
84 { 86 {
85 get 87 get
86 { 88 {
87 if(_image == null) 89 if(_image == null)
Line 148... Line 150...
148   150  
Line 149... Line 151...
149 private string _title; 151 private string _title;
Line -... Line 152...
-   152  
-   153 private string _body;
-   154  
-   155 private TaskCompletionSource<int> _imageLoadedTaskCompletionSource;
150   156  
Line 151... Line 157...
151 private string _body; 157 private readonly ConcurrentDictionary<string, Image> _imagePreload = new ConcurrentDictionary<string, Image>();
152   158  
153 protected override bool ShowWithoutActivation => true; 159 protected override bool ShowWithoutActivation => true;
Line 308... Line 314...
308 } 314 }
309 } 315 }
Line 310... Line 316...
310   316  
311 private async void ToastForm_Load(object sender, EventArgs e) 317 private async void ToastForm_Load(object sender, EventArgs e)
-   318 {
-   319 Opacity = 0;
312 { 320  
313 if (EnableChime) 321 if (EnableChime)
314 { 322 {
315 try 323 try
316 { 324 {
Line 343... Line 351...
343   351  
Line 344... Line 352...
344 } 352 }
345   353  
-   354 // compute notification height from body
346 // compute notification height from body 355 var maxWidth = tableLayoutPanel4.Width;
347 var maxWidth = tableLayoutPanel4.Width; 356 var hasImage = false;
348 switch (ContentType) 357 switch (ContentType)
349 { 358 {
350 case "text/markdown": 359 case "text/markdown":
Line 355... Line 364...
355 if (htmlDocument.DocumentNode != null && htmlDocument.DocumentNode.Descendants().Any()) 364 if (htmlDocument.DocumentNode != null && htmlDocument.DocumentNode.Descendants().Any())
356 { 365 {
357 var imgNodes = htmlDocument.DocumentNode.SelectNodes("//img"); 366 var imgNodes = htmlDocument.DocumentNode.SelectNodes("//img");
358 if (imgNodes != null && imgNodes.Any()) 367 if (imgNodes != null && imgNodes.Any())
359 { 368 {
-   369 hasImage = true;
360 foreach (var node in imgNodes) 370 foreach (var node in imgNodes)
361 { 371 {
362 node.SetAttributeValue("style", $"max-width: {maxWidth}px"); 372 node.SetAttributeValue("style", $"max-width: {maxWidth}px");
363 } 373 }
364 } 374 }
365 } 375 }
Line 366... Line 376...
366   376  
367 _body = htmlDocument.DocumentNode.WriteTo(); 377 _body = htmlDocument.DocumentNode.WriteTo();
368 } 378 }
369 break; -  
370 default: -  
371 break; 379 break;
Line -... Line 380...
-   380 }
-   381  
-   382
-   383 if (hasImage)
-   384 {
-   385 _imageLoadedTaskCompletionSource = new TaskCompletionSource<int>();
-   386
372 } 387 }
373   388  
374 using (var image = HtmlRender.RenderToImage(_body, maxWidth, 0, Color.Empty)) -  
375 { 389 using (var image = HtmlRender.RenderToImage(_body, maxWidth, 0, Color.Empty, null, null, PreloadImage))
376 var height = image.Height + labelTitle.Height; 390 {
-   391 switch(hasImage)
-   392 {
-   393 case true:
-   394 {
-   395 var imageHeight = await _imageLoadedTaskCompletionSource.Task;
-   396 if(imageHeight == 0)
-   397 {
-   398 imageHeight = image.Height;
-   399 }
-   400 var height = imageHeight + labelTitle.Height;
377 if (height > Height) 401 if (height > Height)
-   402 {
-   403 Height = height;
-   404 }
-   405 }
-   406 break;
-   407 default:
-   408 {
-   409 var height = image.Height + labelTitle.Height;
-   410 if (height > Height)
-   411 {
-   412 Height = height;
-   413 }
378 { 414 }
379 Height = height; 415 break;
Line 380... Line 416...
380 } 416 }
381 } 417 }
Line 432... Line 468...
432   468  
433 // set the location of the toast 469 // set the location of the toast
Line 434... Line 470...
434 Location = new Point(_screenWidth - Width, _screenHeight - Height); 470 Location = new Point(_screenWidth - Width, _screenHeight - Height);
435   -  
436 OpenNotifications.Add(this); 471  
437 // show the form 472 OpenNotifications.Add(this);
Line 438... Line 473...
438 //Opacity = 1; 473 Opacity = 1;
439 } 474 }
440   475  
441 // set up the timer when the notification should be removed 476 // set up the timer when the notification should be removed
442 _toastTimer = new System.Timers.Timer { Enabled = true, AutoReset = false, Interval = LingerTime }; 477 _toastTimer = new System.Timers.Timer { Enabled = true, AutoReset = false, Interval = LingerTime };
Line 443... Line 478...
443 _toastTimer.Elapsed += ToastTimer_Elapsed; 478 _toastTimer.Elapsed += ToastTimer_Elapsed;
444 _toastTimer.Start(); 479 _toastTimer.Start();
445 } 480 }
446   481  
447 private async void HtmlPanel1_ImageLoad(object sender, TheArtOfDev.HtmlRenderer.Core.Entities.HtmlImageLoadEventArgs e) 482 private async void PreloadImage(object sender, TheArtOfDev.HtmlRenderer.Core.Entities.HtmlImageLoadEventArgs e)
448 { 483 {
Line 465... Line 500...
465 { 500 {
466 var image = Image.FromStream(responseStream); 501 var image = Image.FromStream(responseStream);
Line 467... Line 502...
467   502  
468 e.Callback(image); 503 e.Callback(image);
-   504 e.Handled = true;
-   505  
-   506 _imagePreload.TryAdd(e.Src, Image.FromStream(responseStream));
-   507  
-   508 if (_imageLoadedTaskCompletionSource != null)
-   509 {
-   510 var ratio = image.Height / (float)image.Width;
-   511 var width = tableLayoutPanel4.Width * ratio;
-   512 _imageLoadedTaskCompletionSource.TrySetResult((int)Math.Ceiling(width));
469 e.Handled = true; 513 }
470 } 514 }
471 } 515 }
472 } 516 }
473 catch 517 catch
474 { 518 {
-   519 Debug.WriteLine("Error downloading image.");
-   520  
-   521 if (_imageLoadedTaskCompletionSource != null)
-   522 {
-   523 _imageLoadedTaskCompletionSource.TrySetResult(0);
-   524 }
-   525 }
-   526 }
-   527  
-   528 private void HtmlPanel1_ImageLoad(object sender, TheArtOfDev.HtmlRenderer.Core.Entities.HtmlImageLoadEventArgs e)
-   529 {
-   530 if(_imagePreload.TryRemove(e.Src, out var image))
-   531 {
-   532 e.Callback(image);
475 Debug.WriteLine("Error downloading image."); 533 e.Handled = true;
476 } 534 }
Line 477... Line 535...
477 } 535 }
478   536