diff --git a/src/Artemis.Core/Services/Core/BuildInfo.cs b/src/Artemis.Core/Services/Core/BuildInfo.cs
index 2be8b4a96..a2caaa3cf 100644
--- a/src/Artemis.Core/Services/Core/BuildInfo.cs
+++ b/src/Artemis.Core/Services/Core/BuildInfo.cs
@@ -1,4 +1,5 @@
-using Newtonsoft.Json;
+using System.Globalization;
+using Newtonsoft.Json;
namespace Artemis.Core.Services.Core
{
@@ -10,22 +11,32 @@ namespace Artemis.Core.Services.Core
///
/// Gets the unique ID of this build
///
+ [JsonProperty]
public int BuildId { get; internal set; }
///
/// Gets the build number. This contains the date and the build count for that day.
- /// Per example 20210108.4
+ /// Per example 20210108.4
///
+ [JsonProperty]
public double BuildNumber { get; internal set; }
+ ///
+ /// Gets the build number formatted as a string. This contains the date and the build count for that day.
+ /// Per example 20210108.4
+ ///
+ public string BuildNumberDisplay => BuildNumber.ToString(CultureInfo.InvariantCulture);
+
///
/// Gets the branch of the triggering repo the build was created for.
///
+ [JsonProperty]
public string SourceBranch { get; internal set; } = null!;
///
/// Gets the commit ID used to create this build
///
+ [JsonProperty]
public string SourceVersion { get; internal set; } = null!;
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings
index 03aa1dd75..5a02b2339 100644
--- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings
+++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings
@@ -15,5 +15,6 @@
True
True
True
+ True
True
True
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IMessageService.cs b/src/Artemis.UI.Shared/Services/Message/IMessageService.cs
similarity index 79%
rename from src/Artemis.UI.Shared/Services/Interfaces/IMessageService.cs
rename to src/Artemis.UI.Shared/Services/Message/IMessageService.cs
index 3e86ada7a..07986be1e 100644
--- a/src/Artemis.UI.Shared/Services/Interfaces/IMessageService.cs
+++ b/src/Artemis.UI.Shared/Services/Message/IMessageService.cs
@@ -13,6 +13,12 @@ namespace Artemis.UI.Shared.Services
///
ISnackbarMessageQueue MainMessageQueue { get; }
+ ///
+ /// Sets up the notification provider that shows desktop notifications
+ ///
+ /// The notification provider that shows desktop notifications
+ void ConfigureNotificationProvider(INotificationProvider notificationProvider);
+
///
/// Queues a notification message for display in a snackbar.
///
@@ -111,5 +117,28 @@ namespace Artemis.UI.Shared.Services
bool promote,
bool neverConsiderToBeDuplicate,
TimeSpan? durationOverride = null);
+
+ ///
+ /// Shows a desktop notification
+ ///
+ /// The title of the notification
+ /// The message of the notification
+ void ShowNotification(string title, string message);
+
+ ///
+ /// Shows a desktop notification with a Material Design icon
+ ///
+ /// The title of the notification
+ /// The message of the notification
+ /// The name of the icon
+ void ShowNotification(string title, string message, PackIconKind icon);
+
+ ///
+ /// Shows a desktop notification with a Material Design icon
+ ///
+ /// The title of the notification
+ /// The message of the notification
+ /// The name of the icon as a string
+ void ShowNotification(string title, string message, string icon);
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/Message/INotificationProvider.cs b/src/Artemis.UI.Shared/Services/Message/INotificationProvider.cs
new file mode 100644
index 000000000..23757ef9f
--- /dev/null
+++ b/src/Artemis.UI.Shared/Services/Message/INotificationProvider.cs
@@ -0,0 +1,19 @@
+using MaterialDesignThemes.Wpf;
+
+namespace Artemis.UI.Shared.Services
+{
+ ///
+ /// Represents a class provides desktop notifications so that can us it to show desktop
+ /// notifications
+ ///
+ public interface INotificationProvider
+ {
+ ///
+ /// Shows a notification
+ ///
+ /// The title of the notification
+ /// The message of the notification
+ /// The Material Design icon to show in the notification
+ void ShowNotification(string title, string message, PackIconKind icon);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/MessageService.cs b/src/Artemis.UI.Shared/Services/Message/MessageService.cs
similarity index 71%
rename from src/Artemis.UI.Shared/Services/MessageService.cs
rename to src/Artemis.UI.Shared/Services/Message/MessageService.cs
index 3a3344a8c..aef6ffc7e 100644
--- a/src/Artemis.UI.Shared/Services/MessageService.cs
+++ b/src/Artemis.UI.Shared/Services/Message/MessageService.cs
@@ -5,13 +5,20 @@ namespace Artemis.UI.Shared.Services
{
internal class MessageService : IMessageService
{
+ private INotificationProvider _notificationProvider;
public ISnackbarMessageQueue MainMessageQueue { get; }
public MessageService(ISnackbarMessageQueue mainMessageQueue)
{
MainMessageQueue = mainMessageQueue;
}
-
+
+ ///
+ public void ConfigureNotificationProvider(INotificationProvider notificationProvider)
+ {
+ _notificationProvider = notificationProvider;
+ }
+
public void ShowMessage(object content)
{
MainMessageQueue.Enqueue(content);
@@ -63,5 +70,24 @@ namespace Artemis.UI.Shared.Services
{
MainMessageQueue.Enqueue(content, actionContent, actionHandler, actionArgument, promote, neverConsiderToBeDuplicate, durationOverride);
}
+
+ ///
+ public void ShowNotification(string title, string message)
+ {
+ _notificationProvider.ShowNotification(title, message, PackIconKind.None);
+ }
+
+ ///
+ public void ShowNotification(string title, string message, PackIconKind icon)
+ {
+ _notificationProvider.ShowNotification(title, message, icon);
+ }
+
+ ///
+ 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));
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/Window/IMainWindowManager.cs b/src/Artemis.UI.Shared/Services/Window/IMainWindowProvider.cs
similarity index 82%
rename from src/Artemis.UI.Shared/Services/Window/IMainWindowManager.cs
rename to src/Artemis.UI.Shared/Services/Window/IMainWindowProvider.cs
index eea24b7fb..9df991c85 100644
--- a/src/Artemis.UI.Shared/Services/Window/IMainWindowManager.cs
+++ b/src/Artemis.UI.Shared/Services/Window/IMainWindowProvider.cs
@@ -1,12 +1,13 @@
using System;
+using MaterialDesignThemes.Wpf;
namespace Artemis.UI.Shared.Services
{
///
- /// Represents a class that manages a main window, used by the to control the state of
+ /// Represents a class that provides the main window, so that can control the state of
/// the main window.
///
- public interface IMainWindowManager
+ public interface IMainWindowProvider
{
///
/// Gets a boolean indicating whether the main window is currently open
diff --git a/src/Artemis.UI.Shared/Services/Window/IWindowService.cs b/src/Artemis.UI.Shared/Services/Window/IWindowService.cs
index ed87006a8..262a2d75a 100644
--- a/src/Artemis.UI.Shared/Services/Window/IWindowService.cs
+++ b/src/Artemis.UI.Shared/Services/Window/IWindowService.cs
@@ -13,10 +13,10 @@ namespace Artemis.UI.Shared.Services
bool IsMainWindowOpen { get; }
///
- /// 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
///
- /// The main window manager to use to control the state of the main window
- void ConfigureMainWindowManager(IMainWindowManager mainWindowManager);
+ /// The main window provider to use to control the state of the main window
+ void ConfigureMainWindowProvider(IMainWindowProvider mainWindowProvider);
///
/// Opens the main window if it is not already open
diff --git a/src/Artemis.UI.Shared/Services/Window/WindowService.cs b/src/Artemis.UI.Shared/Services/Window/WindowService.cs
index 60b425089..c8b2a0ced 100644
--- a/src/Artemis.UI.Shared/Services/Window/WindowService.cs
+++ b/src/Artemis.UI.Shared/Services/Window/WindowService.cs
@@ -4,7 +4,7 @@ namespace Artemis.UI.Shared.Services
{
internal class WindowService : IWindowService
{
- private IMainWindowManager? _mainWindowManager;
+ private IMainWindowProvider? _mainWindowManager;
protected virtual void OnMainWindowOpened()
{
@@ -46,9 +46,9 @@ namespace Artemis.UI.Shared.Services
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)
{
@@ -56,7 +56,7 @@ namespace Artemis.UI.Shared.Services
_mainWindowManager.MainWindowClosed -= HandleMainWindowClosed;
}
- _mainWindowManager = mainWindowManager;
+ _mainWindowManager = mainWindowProvider;
_mainWindowManager.MainWindowOpened += HandleMainWindowOpened;
_mainWindowManager.MainWindowClosed += HandleMainWindowClosed;
diff --git a/src/Artemis.UI/Bootstrapper.cs b/src/Artemis.UI/Bootstrapper.cs
index 6d2049dfc..51af5da78 100644
--- a/src/Artemis.UI/Bootstrapper.cs
+++ b/src/Artemis.UI/Bootstrapper.cs
@@ -16,6 +16,7 @@ using Artemis.UI.Shared.Services;
using Artemis.UI.Stylet;
using Ninject;
using Serilog;
+using SharpVectors.Dom.Resources;
using Stylet;
namespace Artemis.UI
@@ -58,7 +59,11 @@ namespace Artemis.UI
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
- 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
Task.Run(async () =>
diff --git a/src/Artemis.UI/Screens/RootViewModel.cs b/src/Artemis.UI/Screens/RootViewModel.cs
index d2b5db909..35c55db05 100644
--- a/src/Artemis.UI/Screens/RootViewModel.cs
+++ b/src/Artemis.UI/Screens/RootViewModel.cs
@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
+using System.Globalization;
using System.Reflection;
using System.Threading.Tasks;
using System.Timers;
@@ -80,7 +81,7 @@ namespace Artemis.UI.Screens
PinSidebar = _settingsService.GetSetting("UI.PinSidebar", false);
AssemblyInformationalVersionAttribute versionAttribute = typeof(RootViewModel).Assembly.GetCustomAttribute();
- WindowTitle = $"Artemis {versionAttribute?.InformationalVersion} build {Constants.BuildInfo.BuildNumber}";
+ WindowTitle = $"Artemis {versionAttribute?.InformationalVersion} build {Constants.BuildInfo.BuildNumberDisplay}";
}
public PluginSetting PinSidebar { get; }
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs
index d076f56e3..3b852d910 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs
@@ -279,8 +279,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
bool updateFound = await _updateService.OfferUpdatesIfFound();
if (!updateFound)
_messageService.ShowMessage("You are already running the latest Artemis build. (☞゚ヮ゚)☞");
- else
- _messageService.ShowMessage("You are already running the latest Artemis build. (☞゚ヮ゚)☞");
CanOfferUpdatesIfFound = true;
}
diff --git a/src/Artemis.UI/Screens/TrayView.xaml b/src/Artemis.UI/Screens/TrayView.xaml
index 5cf870f5a..afac1218c 100644
--- a/src/Artemis.UI/Screens/TrayView.xaml
+++ b/src/Artemis.UI/Screens/TrayView.xaml
@@ -17,7 +17,8 @@
MenuActivation="LeftOrRightClick"
PopupActivation="DoubleClick"
ToolTipText="Artemis"
- DoubleClickCommand="{s:Action TrayBringToForeground}">
+ DoubleClickCommand="{s:Action TrayBringToForeground}"
+ TrayBalloonTipClicked="{s:Action OnTrayBalloonTipClicked}">