1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

UI - Added desktop notifications API

This commit is contained in:
SpoinkyNL 2021-01-10 12:49:36 +01:00
parent 883fccef7b
commit 30c4314f1d
15 changed files with 217 additions and 42 deletions

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json; using System.Globalization;
using Newtonsoft.Json;
namespace Artemis.Core.Services.Core namespace Artemis.Core.Services.Core
{ {
@ -10,22 +11,32 @@ namespace Artemis.Core.Services.Core
/// <summary> /// <summary>
/// Gets the unique ID of this build /// Gets the unique ID of this build
/// </summary> /// </summary>
[JsonProperty]
public int BuildId { get; internal set; } public int BuildId { get; internal set; }
/// <summary> /// <summary>
/// Gets the build number. This contains the date and the build count for that day. /// Gets the build number. This contains the date and the build count for that day.
/// <example>Per example 20210108.4</example> /// <para>Per example <c>20210108.4</c></para>
/// </summary> /// </summary>
[JsonProperty]
public double BuildNumber { get; internal set; } public double BuildNumber { get; internal set; }
/// <summary>
/// Gets the build number formatted as a string. This contains the date and the build count for that day.
/// <para>Per example <c>20210108.4</c></para>
/// </summary>
public string BuildNumberDisplay => BuildNumber.ToString(CultureInfo.InvariantCulture);
/// <summary> /// <summary>
/// Gets the branch of the triggering repo the build was created for. /// Gets the branch of the triggering repo the build was created for.
/// </summary> /// </summary>
[JsonProperty]
public string SourceBranch { get; internal set; } = null!; public string SourceBranch { get; internal set; } = null!;
/// <summary> /// <summary>
/// Gets the commit ID used to create this build /// Gets the commit ID used to create this build
/// </summary> /// </summary>
[JsonProperty]
public string SourceVersion { get; internal set; } = null!; public string SourceVersion { get; internal set; } = null!;
} }
} }

View File

@ -15,5 +15,6 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdatamodelvisualization/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdatamodelvisualization/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdialog/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdialog/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cinterfaces/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cinterfaces/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cmessage/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cwindow/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cwindow/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=utilities/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=utilities/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -13,6 +13,12 @@ namespace Artemis.UI.Shared.Services
/// </summary> /// </summary>
ISnackbarMessageQueue MainMessageQueue { get; } ISnackbarMessageQueue MainMessageQueue { get; }
/// <summary>
/// Sets up the notification provider that shows desktop notifications
/// </summary>
/// <param name="notificationProvider">The notification provider that shows desktop notifications</param>
void ConfigureNotificationProvider(INotificationProvider notificationProvider);
/// <summary> /// <summary>
/// Queues a notification message for display in a snackbar. /// Queues a notification message for display in a snackbar.
/// </summary> /// </summary>
@ -111,5 +117,28 @@ namespace Artemis.UI.Shared.Services
bool promote, bool promote,
bool neverConsiderToBeDuplicate, bool neverConsiderToBeDuplicate,
TimeSpan? durationOverride = null); TimeSpan? durationOverride = null);
/// <summary>
/// Shows a desktop notification
/// </summary>
/// <param name="title">The title of the notification</param>
/// <param name="message">The message of the notification</param>
void ShowNotification(string title, string message);
/// <summary>
/// Shows a desktop notification with a Material Design icon
/// </summary>
/// <param name="title">The title of the notification</param>
/// <param name="message">The message of the notification</param>
/// <param name="icon">The name of the icon</param>
void ShowNotification(string title, string message, PackIconKind icon);
/// <summary>
/// Shows a desktop notification with a Material Design icon
/// </summary>
/// <param name="title">The title of the notification</param>
/// <param name="message">The message of the notification</param>
/// <param name="icon">The name of the icon as a string</param>
void ShowNotification(string title, string message, string icon);
} }
} }

View File

@ -0,0 +1,19 @@
using MaterialDesignThemes.Wpf;
namespace Artemis.UI.Shared.Services
{
/// <summary>
/// Represents a class provides desktop notifications so that <see cref="IMessageService" /> can us it to show desktop
/// notifications
/// </summary>
public interface INotificationProvider
{
/// <summary>
/// Shows a notification
/// </summary>
/// <param name="title">The title of the notification</param>
/// <param name="message">The message of the notification</param>
/// <param name="icon">The Material Design icon to show in the notification</param>
void ShowNotification(string title, string message, PackIconKind icon);
}
}

View File

@ -5,13 +5,20 @@ namespace Artemis.UI.Shared.Services
{ {
internal class MessageService : IMessageService internal class MessageService : IMessageService
{ {
private INotificationProvider _notificationProvider;
public ISnackbarMessageQueue MainMessageQueue { get; } public ISnackbarMessageQueue MainMessageQueue { get; }
public MessageService(ISnackbarMessageQueue mainMessageQueue) public MessageService(ISnackbarMessageQueue mainMessageQueue)
{ {
MainMessageQueue = mainMessageQueue; MainMessageQueue = mainMessageQueue;
} }
/// <inheritdoc />
public void ConfigureNotificationProvider(INotificationProvider notificationProvider)
{
_notificationProvider = notificationProvider;
}
public void ShowMessage(object content) public void ShowMessage(object content)
{ {
MainMessageQueue.Enqueue(content); MainMessageQueue.Enqueue(content);
@ -63,5 +70,24 @@ namespace Artemis.UI.Shared.Services
{ {
MainMessageQueue.Enqueue(content, actionContent, actionHandler, actionArgument, promote, neverConsiderToBeDuplicate, durationOverride); MainMessageQueue.Enqueue(content, actionContent, actionHandler, actionArgument, promote, neverConsiderToBeDuplicate, durationOverride);
} }
/// <inheritdoc />
public void ShowNotification(string title, string message)
{
_notificationProvider.ShowNotification(title, message, PackIconKind.None);
}
/// <inheritdoc />
public void ShowNotification(string title, string message, PackIconKind icon)
{
_notificationProvider.ShowNotification(title, message, icon);
}
/// <inheritdoc />
public void ShowNotification(string title, string message, string icon)
{
Enum.TryParse(typeof(PackIconKind), icon, true, out object? iconKind);
_notificationProvider.ShowNotification(title, message, (PackIconKind) (iconKind ?? PackIconKind.None));
}
} }
} }

View File

@ -1,12 +1,13 @@
using System; using System;
using MaterialDesignThemes.Wpf;
namespace Artemis.UI.Shared.Services namespace Artemis.UI.Shared.Services
{ {
/// <summary> /// <summary>
/// Represents a class that manages a main window, used by the <see cref="IWindowService" /> to control the state of /// Represents a class that provides the main window, so that <see cref="IWindowService" /> can control the state of
/// the main window. /// the main window.
/// </summary> /// </summary>
public interface IMainWindowManager public interface IMainWindowProvider
{ {
/// <summary> /// <summary>
/// Gets a boolean indicating whether the main window is currently open /// Gets a boolean indicating whether the main window is currently open

View File

@ -13,10 +13,10 @@ namespace Artemis.UI.Shared.Services
bool IsMainWindowOpen { get; } bool IsMainWindowOpen { get; }
/// <summary> /// <summary>
/// Sets up the main window manager that controls the state of the main window /// Sets up the main window provider that controls the state of the main window
/// </summary> /// </summary>
/// <param name="mainWindowManager">The main window manager to use to control the state of the main window</param> /// <param name="mainWindowProvider">The main window provider to use to control the state of the main window</param>
void ConfigureMainWindowManager(IMainWindowManager mainWindowManager); void ConfigureMainWindowProvider(IMainWindowProvider mainWindowProvider);
/// <summary> /// <summary>
/// Opens the main window if it is not already open /// Opens the main window if it is not already open

View File

@ -4,7 +4,7 @@ namespace Artemis.UI.Shared.Services
{ {
internal class WindowService : IWindowService internal class WindowService : IWindowService
{ {
private IMainWindowManager? _mainWindowManager; private IMainWindowProvider? _mainWindowManager;
protected virtual void OnMainWindowOpened() protected virtual void OnMainWindowOpened()
{ {
@ -46,9 +46,9 @@ namespace Artemis.UI.Shared.Services
public bool IsMainWindowOpen { get; private set; } public bool IsMainWindowOpen { get; private set; }
public void ConfigureMainWindowManager(IMainWindowManager mainWindowManager) public void ConfigureMainWindowProvider(IMainWindowProvider mainWindowProvider)
{ {
if (mainWindowManager == null) throw new ArgumentNullException(nameof(mainWindowManager)); if (mainWindowProvider == null) throw new ArgumentNullException(nameof(mainWindowProvider));
if (_mainWindowManager != null) if (_mainWindowManager != null)
{ {
@ -56,7 +56,7 @@ namespace Artemis.UI.Shared.Services
_mainWindowManager.MainWindowClosed -= HandleMainWindowClosed; _mainWindowManager.MainWindowClosed -= HandleMainWindowClosed;
} }
_mainWindowManager = mainWindowManager; _mainWindowManager = mainWindowProvider;
_mainWindowManager.MainWindowOpened += HandleMainWindowOpened; _mainWindowManager.MainWindowOpened += HandleMainWindowOpened;
_mainWindowManager.MainWindowClosed += HandleMainWindowClosed; _mainWindowManager.MainWindowClosed += HandleMainWindowClosed;

View File

@ -16,6 +16,7 @@ using Artemis.UI.Shared.Services;
using Artemis.UI.Stylet; using Artemis.UI.Stylet;
using Ninject; using Ninject;
using Serilog; using Serilog;
using SharpVectors.Dom.Resources;
using Stylet; using Stylet;
namespace Artemis.UI namespace Artemis.UI
@ -58,7 +59,11 @@ namespace Artemis.UI
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))); FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
// Create and bind the root view, this is a tray icon so don't show it with the window manager // Create and bind the root view, this is a tray icon so don't show it with the window manager
Execute.OnUIThread(() => viewManager.CreateAndBindViewForModelIfNecessary(RootViewModel)); Execute.OnUIThread(() =>
{
UIElement view = viewManager.CreateAndBindViewForModelIfNecessary(RootViewModel);
((TrayViewModel) RootViewModel).SetTaskbarIcon(view);
});
// Initialize the core async so the UI can show the progress // Initialize the core async so the UI can show the progress
Task.Run(async () => Task.Run(async () =>

View File

@ -1,5 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Globalization;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Timers; using System.Timers;
@ -80,7 +81,7 @@ namespace Artemis.UI.Screens
PinSidebar = _settingsService.GetSetting("UI.PinSidebar", false); PinSidebar = _settingsService.GetSetting("UI.PinSidebar", false);
AssemblyInformationalVersionAttribute versionAttribute = typeof(RootViewModel).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>(); AssemblyInformationalVersionAttribute versionAttribute = typeof(RootViewModel).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
WindowTitle = $"Artemis {versionAttribute?.InformationalVersion} build {Constants.BuildInfo.BuildNumber}"; WindowTitle = $"Artemis {versionAttribute?.InformationalVersion} build {Constants.BuildInfo.BuildNumberDisplay}";
} }
public PluginSetting<bool> PinSidebar { get; } public PluginSetting<bool> PinSidebar { get; }

View File

@ -279,8 +279,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
bool updateFound = await _updateService.OfferUpdatesIfFound(); bool updateFound = await _updateService.OfferUpdatesIfFound();
if (!updateFound) if (!updateFound)
_messageService.ShowMessage("You are already running the latest Artemis build. (☞゚ヮ゚)☞"); _messageService.ShowMessage("You are already running the latest Artemis build. (☞゚ヮ゚)☞");
else
_messageService.ShowMessage("You are already running the latest Artemis build. (☞゚ヮ゚)☞");
CanOfferUpdatesIfFound = true; CanOfferUpdatesIfFound = true;
} }

View File

@ -17,7 +17,8 @@
MenuActivation="LeftOrRightClick" MenuActivation="LeftOrRightClick"
PopupActivation="DoubleClick" PopupActivation="DoubleClick"
ToolTipText="Artemis" ToolTipText="Artemis"
DoubleClickCommand="{s:Action TrayBringToForeground}"> DoubleClickCommand="{s:Action TrayBringToForeground}"
TrayBalloonTipClicked="{s:Action OnTrayBalloonTipClicked}">
<tb:TaskbarIcon.ContextMenu> <tb:TaskbarIcon.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="Home" Command="{s:Action TrayActivateSidebarItem}" CommandParameter="Home"> <MenuItem Header="Home" Command="{s:Action TrayActivateSidebarItem}" CommandParameter="Home">

View File

@ -1,31 +1,42 @@
using System; using System;
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Events; using Artemis.UI.Events;
using Artemis.UI.Screens.Splash; using Artemis.UI.Screens.Splash;
using Artemis.UI.Services; using Artemis.UI.Services;
using Artemis.UI.Services.Interfaces; using Artemis.UI.Services.Interfaces;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
using Hardcodet.Wpf.TaskbarNotification;
using MaterialDesignThemes.Wpf;
using Ninject; using Ninject;
using Stylet; using Stylet;
using Icon = System.Drawing.Icon;
namespace Artemis.UI.Screens namespace Artemis.UI.Screens
{ {
public class TrayViewModel : Screen, IMainWindowManager public class TrayViewModel : Screen, IMainWindowProvider, INotificationProvider
{ {
private readonly IDebugService _debugService; private readonly IDebugService _debugService;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IKernel _kernel; private readonly IKernel _kernel;
private readonly IWindowManager _windowManager; private readonly IWindowManager _windowManager;
private bool _canShowRootViewModel; private bool _canShowRootViewModel;
private SplashViewModel _splashViewModel;
private RootViewModel _rootViewModel; private RootViewModel _rootViewModel;
private SplashViewModel _splashViewModel;
private TaskbarIcon _taskBarIcon;
public TrayViewModel(IKernel kernel, public TrayViewModel(IKernel kernel,
IWindowManager windowManager, IWindowManager windowManager,
IWindowService windowService, IWindowService windowService,
IMessageService messageService,
IUpdateService updateService, IUpdateService updateService,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
ICoreService coreService, ICoreService coreService,
IDebugService debugService, IDebugService debugService,
ISettingsService settingsService) ISettingsService settingsService)
{ {
@ -35,7 +46,8 @@ namespace Artemis.UI.Screens
_debugService = debugService; _debugService = debugService;
CanShowRootViewModel = true; CanShowRootViewModel = true;
windowService.ConfigureMainWindowManager(this); windowService.ConfigureMainWindowProvider(this);
messageService.ConfigureNotificationProvider(this);
bool autoRunning = Bootstrapper.StartupArguments.Contains("--autorun"); bool autoRunning = Bootstrapper.StartupArguments.Contains("--autorun");
bool showOnAutoRun = settingsService.GetSetting("UI.ShowOnStartup", true).Value; bool showOnAutoRun = settingsService.GetSetting("UI.ShowOnStartup", true).Value;
if (!autoRunning || showOnAutoRun) if (!autoRunning || showOnAutoRun)
@ -43,8 +55,8 @@ namespace Artemis.UI.Screens
ShowSplashScreen(); ShowSplashScreen();
coreService.Initialized += (_, _) => TrayBringToForeground(); coreService.Initialized += (_, _) => TrayBringToForeground();
} }
else
updateService.AutoUpdate(); updateService.AutoUpdate();
} }
public bool CanShowRootViewModel public bool CanShowRootViewModel
@ -91,6 +103,28 @@ namespace Artemis.UI.Screens
_debugService.ShowDebugger(); _debugService.ShowDebugger();
} }
public void SetTaskbarIcon(UIElement view)
{
_taskBarIcon = (TaskbarIcon) ((ContentControl) view).Content;
}
public void OnTrayBalloonTipClicked(object sender, EventArgs e)
{
if (CanShowRootViewModel)
TrayBringToForeground();
else
{
// Wrestle the main window to the front
Window mainWindow = ((Window) _rootViewModel.View);
if (mainWindow.WindowState == WindowState.Minimized)
mainWindow.WindowState = WindowState.Normal;
mainWindow.Activate();
mainWindow.Topmost = true;
mainWindow.Topmost = false;
mainWindow.Focus();
}
}
private void ShowSplashScreen() private void ShowSplashScreen()
{ {
Execute.OnUIThread(() => Execute.OnUIThread(() =>
@ -109,12 +143,47 @@ namespace Artemis.UI.Screens
OnMainWindowClosed(); OnMainWindowClosed();
} }
#region Implementation of IMainWindowManager #region Implementation of INotificationProvider
/// <inheritdoc /> /// <inheritdoc />
public void ShowNotification(string title, string message, PackIconKind icon)
{
Execute.OnUIThread(() =>
{
// Convert the PackIcon to an icon by drawing it on a visual
DrawingVisual drawingVisual = new();
DrawingContext drawingContext = drawingVisual.RenderOpen();
PackIcon packIcon = new() {Kind = icon};
Geometry geometry = Geometry.Parse(packIcon.Data);
// Scale the icon up to fit a 256x256 image and draw it
geometry = Geometry.Combine(geometry, Geometry.Empty, GeometryCombineMode.Union, new ScaleTransform(256 / geometry.Bounds.Right, 256 / geometry.Bounds.Bottom));
drawingContext.DrawGeometry(new SolidColorBrush(Colors.White), null, geometry);
drawingContext.Close();
// Render the visual and add it to a PNG encoder (we want opacity in our icon)
RenderTargetBitmap renderTargetBitmap = new(256, 256, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(drawingVisual);
PngBitmapEncoder encoder = new();
encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
// Save the PNG and get an icon handle
using MemoryStream stream = new();
encoder.Save(stream);
Icon convertedIcon = Icon.FromHandle(new Bitmap(stream).GetHicon());
// Show the 'balloon'
_taskBarIcon.ShowBalloonTip(title, message, convertedIcon, true);
});
}
#endregion
#region Implementation of IMainWindowProvider
public bool IsMainWindowOpen { get; private set; } public bool IsMainWindowOpen { get; private set; }
/// <inheritdoc />
public bool OpenMainWindow() public bool OpenMainWindow()
{ {
if (CanShowRootViewModel) if (CanShowRootViewModel)
@ -124,17 +193,14 @@ namespace Artemis.UI.Screens
return true; return true;
} }
/// <inheritdoc />
public bool CloseMainWindow() public bool CloseMainWindow()
{ {
_rootViewModel.RequestClose(); _rootViewModel.RequestClose();
return _rootViewModel.ScreenState == ScreenState.Closed; return _rootViewModel.ScreenState == ScreenState.Closed;
} }
/// <inheritdoc />
public event EventHandler MainWindowOpened; public event EventHandler MainWindowOpened;
/// <inheritdoc />
public event EventHandler MainWindowClosed; public event EventHandler MainWindowClosed;
protected virtual void OnMainWindowOpened() protected virtual void OnMainWindowOpened()

View File

@ -1,10 +1,12 @@
using System; using System;
using System.Globalization;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Services.Interfaces; using Artemis.UI.Services.Interfaces;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
using MaterialDesignThemes.Wpf;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Serilog; using Serilog;
@ -17,12 +19,14 @@ namespace Artemis.UI.Services
private readonly PluginSetting<bool> _checkForUpdates; private readonly PluginSetting<bool> _checkForUpdates;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IDialogService _dialogService; private readonly IDialogService _dialogService;
private readonly IMessageService _messageService;
private readonly IWindowService _windowService; private readonly IWindowService _windowService;
public UpdateService(ILogger logger, ISettingsService settingsService, IDialogService dialogService, IWindowService windowService) public UpdateService(ILogger logger, ISettingsService settingsService, IDialogService dialogService, IMessageService messageService, IWindowService windowService)
{ {
_logger = logger; _logger = logger;
_dialogService = dialogService; _dialogService = dialogService;
_messageService = messageService;
_windowService = windowService; _windowService = windowService;
_windowService.MainWindowOpened += WindowServiceOnMainWindowOpened; _windowService.MainWindowOpened += WindowServiceOnMainWindowOpened;
@ -41,25 +45,24 @@ namespace Artemis.UI.Services
// Make the request // Make the request
using HttpClient client = new(); using HttpClient client = new();
HttpResponseMessage httpResponseMessage = await client.GetAsync(latestBuildUrl); HttpResponseMessage httpResponseMessage = await client.GetAsync(latestBuildUrl);
// Ensure it returned correctly // Ensure it returned correctly
if (!httpResponseMessage.IsSuccessStatusCode) if (!httpResponseMessage.IsSuccessStatusCode)
{ {
_logger.Warning("Failed to check for updates, request returned {statusCode}", httpResponseMessage.StatusCode); _logger.Warning("Failed to check for updates, request returned {statusCode}", httpResponseMessage.StatusCode);
return 0; return 0;
} }
// Parse the response // Parse the response
string response = await httpResponseMessage.Content.ReadAsStringAsync(); string response = await httpResponseMessage.Content.ReadAsStringAsync();
try try
{ {
JToken buildNumberToken = JObject.Parse(response).SelectToken("value[0].buildNumber"); JToken buildNumberToken = JObject.Parse(response).SelectToken("value[0].buildNumber");
if (buildNumberToken != null) if (buildNumberToken != null)
return buildNumberToken.Value<double>(); return buildNumberToken.Value<double>();
_logger.Warning("Failed to find build number at \"value[0].buildNumber\""); _logger.Warning("Failed to find build number at \"value[0].buildNumber\"");
return 0; return 0;
} }
catch (Exception e) catch (Exception e)
{ {
@ -73,20 +76,34 @@ namespace Artemis.UI.Services
_logger.Information("Checking for updates"); _logger.Information("Checking for updates");
double buildNumber = await GetLatestBuildNumber(); double buildNumber = await GetLatestBuildNumber();
_logger.Information("Latest build is {buildNumber}, we're running {localBuildNumber}", buildNumber, Constants.BuildInfo.BuildNumber); string buildNumberDisplay = buildNumber.ToString(CultureInfo.InvariantCulture);
_logger.Information("Latest build is {buildNumber}, we're running {localBuildNumber}", buildNumberDisplay, Constants.BuildInfo.BuildNumberDisplay);
if (buildNumber < Constants.BuildInfo.BuildNumber) if (buildNumber < Constants.BuildInfo.BuildNumber)
return false; return false;
if (_windowService.IsMainWindowOpen) if (_windowService.IsMainWindowOpen)
{ {
}
else if (_autoInstallUpdates.Value)
{
// Lets go
_messageService.ShowNotification(
"Installing new version",
$"Build {buildNumberDisplay} is available, currently on {Constants.BuildInfo.BuildNumberDisplay}.",
PackIconKind.Update
);
} }
else else
{ {
// If auto-install is disabled and the window is closed, best we can do is notify the user and stop.
_messageService.ShowNotification(
"New version available",
$"Build {buildNumberDisplay} is available, currently on {Constants.BuildInfo.BuildNumberDisplay}.",
PackIconKind.Update
);
} }
return true; return true;
} }

View File

@ -1,6 +1,6 @@
{ {
"BuildId": 0, "BuildId": 0,
"BuildNumber": 0, "BuildNumber": 13370101.1,
"SourceBranch": "local", "SourceBranch": "local",
"SourceVersion": "local" "SourceVersion": "local"
} }