diff --git a/misc/BreCalApi.cs b/misc/BreCalApi.cs
index 5494860..9013f76 100644
--- a/misc/BreCalApi.cs
+++ b/misc/BreCalApi.cs
@@ -1,8 +1,8 @@
//----------------------
//
-// Generated REST API Client Code Generator v1.16.0.0 on 10.12.2024 08:56:03
-// Using the tool OpenAPI Generator v7.9.0
+// Generated REST API Client Code Generator v1.17.0.0 on 19.12.2024 11:34:56
+// Using the tool OpenAPI Generator v7.10.0
//
//----------------------
@@ -3829,7 +3829,7 @@ namespace BreCalClient.misc.Client
if (response.Headers != null)
{
var filePath = string.IsNullOrEmpty(_configuration.TempFolderPath)
- ? Path.GetTempPath()
+ ? global::System.IO.Path.GetTempPath()
: _configuration.TempFolderPath;
var regex = new Regex(@"Content-Disposition=.*filename=['""]?([^'""\s]+)['""]?$");
foreach (var header in response.Headers)
@@ -4069,7 +4069,7 @@ namespace BreCalClient.misc.Client
var bytes = ClientUtils.ReadAsBytes(file);
var fileStream = file as FileStream;
if (fileStream != null)
- request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name));
+ request.AddFile(fileParam.Key, bytes, global::System.IO.Path.GetFileName(fileStream.Name));
else
request.AddFile(fileParam.Key, bytes, "no_file_name_provided");
}
@@ -4139,7 +4139,7 @@ namespace BreCalClient.misc.Client
var clientOptions = new RestClientOptions(baseUrl)
{
ClientCertificates = configuration.ClientCertificates,
- MaxTimeout = configuration.Timeout,
+ Timeout = configuration.Timeout,
Proxy = configuration.Proxy,
UserAgent = configuration.UserAgent,
UseDefaultCredentials = configuration.UseDefaultCredentials,
@@ -4209,11 +4209,11 @@ namespace BreCalClient.misc.Client
return result;
}
}
- private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult)
+ private async Task> DeserializeRestResponseFromPolicyAsync(RestClient client, RestRequest request, PolicyResult policyResult, CancellationToken cancellationToken = default)
{
if (policyResult.Outcome == OutcomeType.Successful)
{
- return client.Deserialize(policyResult.Result);
+ return await client.Deserialize(policyResult.Result, cancellationToken);
}
else
{
@@ -4243,7 +4243,7 @@ namespace BreCalClient.misc.Client
{
var policy = RetryConfiguration.RetryPolicy;
var policyResult = policy.ExecuteAndCapture(() => client.Execute(request));
- return Task.FromResult(DeserializeRestResponseFromPolicy(client, request, policyResult));
+ return DeserializeRestResponseFromPolicyAsync(client, request, policyResult);
}
else
{
@@ -4264,7 +4264,7 @@ namespace BreCalClient.misc.Client
{
var policy = RetryConfiguration.AsyncRetryPolicy;
var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false);
- return DeserializeRestResponseFromPolicy(client, request, policyResult);
+ return await DeserializeRestResponseFromPolicyAsync(client, request, policyResult, cancellationToken);
}
else
{
@@ -5000,7 +5000,7 @@ namespace BreCalClient.misc.Client
{
};
// Setting Timeout has side effects (forces ApiClient creation).
- Timeout = 100000;
+ Timeout = TimeSpan.FromSeconds(100);
}
///
/// Initializes a new instance of the class
@@ -5072,9 +5072,9 @@ namespace BreCalClient.misc.Client
///
public virtual IDictionary DefaultHeaders { get; set; }
///
- /// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds.
+ /// Gets or sets the HTTP timeout of ApiClient. Defaults to 100 seconds.
///
- public virtual int Timeout { get; set; }
+ public virtual TimeSpan Timeout { get; set; }
///
/// Gets or sets the proxy
///
@@ -5713,10 +5713,10 @@ namespace BreCalClient.misc.Client
/// Temp folder path.
string TempFolderPath { get; }
///
- /// Gets the HTTP connection timeout (in milliseconds)
+ /// Gets the HTTP connection timeout.
///
/// HTTP connection timeout.
- int Timeout { get; }
+ TimeSpan Timeout { get; }
///
/// Gets the proxy.
///
@@ -7097,24 +7097,26 @@ namespace BreCalClient.misc.Model
public partial class Notification : IValidatableObject
{
///
- /// Gets or Sets NotificationType
+ /// Gets or Sets Type
///
- [DataMember(Name = "notification_type", EmitDefaultValue = true)]
- public NotificationType? NotificationType { get; set; }
+ [DataMember(Name = "type", EmitDefaultValue = true)]
+ public NotificationType? Type { get; set; }
///
/// Initializes a new instance of the class.
///
/// id.
/// shipcallId.
- /// notificationType.
+ /// participantId.
+ /// type.
/// message.
/// Readonly field set by the database when notification was created.
/// Readonly field set by the database when notification was last modified.
- public Notification(int id = default(int), int shipcallId = default(int), NotificationType? notificationType = default(NotificationType?), string message = default(string), DateTime created = default(DateTime), DateTime? modified = default(DateTime?))
+ public Notification(int id = default(int), int shipcallId = default(int), int? participantId = default(int?), NotificationType? type = default(NotificationType?), string message = default(string), DateTime created = default(DateTime), DateTime? modified = default(DateTime?))
{
this.Id = id;
this.ShipcallId = shipcallId;
- this.NotificationType = notificationType;
+ this.ParticipantId = participantId;
+ this.Type = type;
this.Message = message;
this.Created = created;
this.Modified = modified;
@@ -7136,6 +7138,14 @@ namespace BreCalClient.misc.Model
[DataMember(Name = "shipcall_id", EmitDefaultValue = true)]
public int ShipcallId { get; set; }
///
+ /// Gets or Sets ParticipantId
+ ///
+ /*
+ 9
+ */
+ [DataMember(Name = "participant_id", EmitDefaultValue = true)]
+ public int? ParticipantId { get; set; }
+ ///
/// Gets or Sets Message
///
/*
@@ -7171,7 +7181,8 @@ namespace BreCalClient.misc.Model
sb.Append("class Notification {\n");
sb.Append(" Id: ").Append(Id).Append("\n");
sb.Append(" ShipcallId: ").Append(ShipcallId).Append("\n");
- sb.Append(" NotificationType: ").Append(NotificationType).Append("\n");
+ sb.Append(" ParticipantId: ").Append(ParticipantId).Append("\n");
+ sb.Append(" Type: ").Append(Type).Append("\n");
sb.Append(" Message: ").Append(Message).Append("\n");
sb.Append(" Created: ").Append(Created).Append("\n");
sb.Append(" Modified: ").Append(Modified).Append("\n");
diff --git a/misc/BreCalApi.yaml b/misc/BreCalApi.yaml
index a51bd29..da638ee 100644
--- a/misc/BreCalApi.yaml
+++ b/misc/BreCalApi.yaml
@@ -1550,7 +1550,11 @@ components:
type: integer
example: 5
nullable: false
- notification_type:
+ participant_id:
+ type: integer
+ example: 9
+ nullable: true
+ type:
$ref: '#/components/schemas/NotificationType'
message:
type: string
@@ -1569,7 +1573,8 @@ components:
example:
id: 42
shipcall_id: 5
- notification_type: next24h
+ participant_id: 9
+ type: next24h
message: Shipcall may be relevant to you in the next 24 hours
created: '2023-08-21T08:23:35Z'
modified: '2023-08-21T08:23:35Z'
@@ -1581,13 +1586,14 @@ components:
example:
- id: 42
shipcall_id: 5
- notification_type: time_conflict
+ participant_id: 9
+ type: time_conflict
message: Entry XY violates rule Z
created: '2023-08-21T08:23:35Z'
modified: '2023-08-21T08:23:35Z'
- id: 43
shipcall_id: 7
- notification_type: time_conflict
+ type: time_conflict
message: Entry AB violates rule C
created: '2023-08-21T08:23:35Z'
modified: '2023-08-21T08:23:35Z'
diff --git a/src/BreCalClient/App.xaml b/src/BreCalClient/App.xaml
index 9b54893..292becc 100644
--- a/src/BreCalClient/App.xaml
+++ b/src/BreCalClient/App.xaml
@@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BreCalClient"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ xmlns:options="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
StartupUri="MainWindow.xaml" Exit="Application_Exit" Startup="Application_Startup" >
@@ -14,6 +15,95 @@
10
10
+ #147ec9
+
+
+ #11ad45
+
+
+ #e60914
+
+
+ #f5a300
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BreCalClient/AppNotification.cs b/src/BreCalClient/AppNotification.cs
new file mode 100644
index 0000000..7a0f075
--- /dev/null
+++ b/src/BreCalClient/AppNotification.cs
@@ -0,0 +1,121 @@
+// Copyright (c) 2024- schick Informatik
+// Description: Helper (static) class to handle polled API notifications
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ToastNotifications.Core;
+
+namespace BreCalClient
+{
+ internal class AppNotification
+ {
+ private static Dictionary _notifications = new ();
+ private readonly int _id;
+
+
+ public AppNotification(int id)
+ {
+ _id = id;
+ }
+
+ public int Id { get { return _id; } }
+
+ #region internal statics
+
+ internal static void LoadFromSettings()
+ {
+ _notifications.Clear();
+
+ // preload notifications that have been processed
+ foreach (string? notification_id in Properties.Settings.Default.Notifications)
+ {
+ if(Int32.TryParse(notification_id, out int result))
+ _notifications.Add(result, new AppNotification(result));
+ }
+ }
+
+ internal static void Clear()
+ {
+ _notifications.Clear();
+ SaveNotifications();
+ }
+
+ internal static bool UpdateNotifications(List notifications, System.Collections.Concurrent.ConcurrentDictionary currentShipcalls, ToastViewModel vm)
+ {
+ bool result = false;
+ foreach (BreCalClient.misc.Model.Notification notification in notifications)
+ {
+ if(!_notifications.ContainsKey(notification.Id))
+ {
+ _notifications.Add(notification.Id, new AppNotification(notification.Id));
+
+ // filter if the notification concerns us
+ if(notification.ParticipantId != null)
+ {
+ if(App.Participant.Id == notification.ParticipantId)
+ {
+ result = true;
+ }
+ }
+ else
+ {
+ // find out if this notification concerns us
+ if(currentShipcalls.ContainsKey(notification.ShipcallId))
+ {
+ result = true;
+ }
+ }
+
+ if(result)
+ {
+ System.Diagnostics.Trace.WriteLine($"Notification {notification.Id} Type {notification.Type}");
+ MessageOptions options = new MessageOptions();
+ options.FontSize = 14;
+ options.ShowCloseButton = true;
+ switch(notification.Type)
+ {
+ case misc.Model.NotificationType.TimeConflict:
+
+ break;
+ case misc.Model.NotificationType.TimeConflictResolved:
+
+ break;
+ case misc.Model.NotificationType.Assignment:
+
+ break;
+ case misc.Model.NotificationType.Next24h:
+
+ break;
+ case misc.Model.NotificationType.Unassigned:
+
+ break;
+ }
+
+ string toastText = $"{currentShipcalls[notification.ShipcallId]?.Ship?.Name} ({currentShipcalls[notification.ShipcallId]?.Shipcall?.Type}) - {currentShipcalls[notification.ShipcallId]?.GetETAETD(true)} - {currentShipcalls[notification.ShipcallId]?.GetBerthText(null)}";
+ App.Current.Dispatcher.Invoke(() =>
+ {
+ vm.ShowInformation(toastText, options);
+ });
+ }
+
+ }
+ }
+ return result;
+ }
+
+ internal static void SaveNotifications()
+ {
+ Properties.Settings.Default.Notifications.Clear();
+ foreach (int notification_id in _notifications.Keys)
+ {
+ Properties.Settings.Default.Notifications.Add(notification_id.ToString());
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/BreCalClient/MainWindow.xaml.cs b/src/BreCalClient/MainWindow.xaml.cs
index cb0056b..23e109a 100644
--- a/src/BreCalClient/MainWindow.xaml.cs
+++ b/src/BreCalClient/MainWindow.xaml.cs
@@ -36,8 +36,11 @@ namespace BreCalClient
public partial class MainWindow : Window
{
private readonly ILog _log = LogManager.GetLogger(typeof(MainWindow));
+ private readonly ToastViewModel _vm;
+
private const int SHIPCALL_UPDATE_INTERVAL_SECONDS = 30;
private const int SHIPS_UPDATE_INTERVAL_SECONDS = 120;
+ private const int CHECK_NOTIFICATIONS_INTERVAL_SECONDS = 5;
private const int PROGRESS_STEPS = 50;
#region Fields
@@ -122,6 +125,13 @@ namespace BreCalClient
RetryConfiguration.AsyncRetryPolicy = retryPolicy;
this.generalProgressStatus.Maximum = PROGRESS_STEPS;
+ _vm = new ToastViewModel();
+ this.Unloaded += MainWindow_Unloaded;
+ }
+
+ private void MainWindow_Unloaded(object sender, RoutedEventArgs e)
+ {
+ _vm.OnUnloaded();
}
#endregion
@@ -510,6 +520,7 @@ namespace BreCalClient
_ = Task.Run(() => RefreshShipcalls());
_ = Task.Run(() => RefreshShips());
+ _ = Task.Run(() => CheckNotifications());
}
@@ -633,6 +644,16 @@ namespace BreCalClient
}
}
+ public async Task CheckNotifications()
+ {
+ while (true)
+ {
+ Thread.Sleep(CHECK_NOTIFICATIONS_INTERVAL_SECONDS * 1000);
+ List notifications = await _staticApi.NotificationsGetAsync();
+ AppNotification.UpdateNotifications(notifications, _allShipcallsDict, _vm);
+ }
+ }
+
#endregion
#region basic operations
diff --git a/src/BreCalClient/Properties/Settings.Designer.cs b/src/BreCalClient/Properties/Settings.Designer.cs
index ece7fc6..f24308d 100644
--- a/src/BreCalClient/Properties/Settings.Designer.cs
+++ b/src/BreCalClient/Properties/Settings.Designer.cs
@@ -9,20 +9,20 @@
//------------------------------------------------------------------------------
namespace BreCalClient.Properties {
-
-
+
+
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
-
+
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
+
public static Settings Default {
get {
return defaultInstance;
}
}
-
+
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("#1D751F")]
@@ -31,7 +31,7 @@ namespace BreCalClient.Properties {
return ((string)(this["BG_COLOR"]));
}
}
-
+
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("!!Bremen calling Testversion!!")]
@@ -40,7 +40,7 @@ namespace BreCalClient.Properties {
return ((string)(this["APP_TITLE"]));
}
}
-
+
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("https://www.textbausteine.net/")]
@@ -49,7 +49,7 @@ namespace BreCalClient.Properties {
return ((string)(this["LOGO_IMAGE_URL"]));
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
@@ -61,7 +61,7 @@ namespace BreCalClient.Properties {
this["FilterCriteria"] = value;
}
}
-
+
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("https://brecaldevel.bsmd-emswe.eu")]
@@ -70,7 +70,7 @@ namespace BreCalClient.Properties {
return ((string)(this["API_URL"]));
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("800")]
@@ -82,7 +82,7 @@ namespace BreCalClient.Properties {
this["Width"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("450")]
@@ -94,7 +94,7 @@ namespace BreCalClient.Properties {
this["Height"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -106,7 +106,7 @@ namespace BreCalClient.Properties {
this["Left"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -118,7 +118,7 @@ namespace BreCalClient.Properties {
this["Top"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -130,7 +130,7 @@ namespace BreCalClient.Properties {
this["W1Left"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -142,7 +142,7 @@ namespace BreCalClient.Properties {
this["W1Top"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -154,7 +154,7 @@ namespace BreCalClient.Properties {
this["W2Left"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -166,7 +166,7 @@ namespace BreCalClient.Properties {
this["W2Top"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -178,7 +178,7 @@ namespace BreCalClient.Properties {
this["W3Left"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -190,7 +190,7 @@ namespace BreCalClient.Properties {
this["W3Top"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -202,7 +202,7 @@ namespace BreCalClient.Properties {
this["W4Left"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -214,7 +214,7 @@ namespace BreCalClient.Properties {
this["W4Top"] = value;
}
}
-
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
@@ -226,5 +226,16 @@ namespace BreCalClient.Properties {
this["FilterCriteriaMap"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Collections.Specialized.StringCollection Notifications {
+ get {
+ return ((global::System.Collections.Specialized.StringCollection)(this["Notifications"]));
+ }
+ set {
+ this["Notifications"] = value;
+ }
+ }
}
}
diff --git a/src/BreCalClient/Properties/Settings.settings b/src/BreCalClient/Properties/Settings.settings
index b10fd5b..9f7c317 100644
--- a/src/BreCalClient/Properties/Settings.settings
+++ b/src/BreCalClient/Properties/Settings.settings
@@ -56,5 +56,8 @@
+
+
+
\ No newline at end of file
diff --git a/src/BreCalClient/ToastViewModel.cs b/src/BreCalClient/ToastViewModel.cs
new file mode 100644
index 0000000..cf47fa3
--- /dev/null
+++ b/src/BreCalClient/ToastViewModel.cs
@@ -0,0 +1,105 @@
+// Copyright (c) 2024- schick Informatik
+// Description:
+//
+
+using System;
+using System.ComponentModel;
+using System.Windows;
+
+using ToastNotifications;
+using ToastNotifications.Core;
+using ToastNotifications.Lifetime;
+using ToastNotifications.Lifetime.Clear;
+using ToastNotifications.Messages;
+using ToastNotifications.Position;
+
+namespace BreCalClient
+{
+ internal class ToastViewModel : INotifyPropertyChanged
+ {
+ private readonly Notifier _notifier;
+
+ public ToastViewModel()
+ {
+ _notifier = new Notifier(cfg =>
+ {
+ cfg.PositionProvider = new WindowPositionProvider(
+ parentWindow: Application.Current.MainWindow,
+ corner: Corner.BottomRight,
+ offsetX: 25,
+ offsetY: 100);
+
+ cfg.LifetimeSupervisor = new TimeAndCountBasedLifetimeSupervisor(
+ notificationLifetime: TimeSpan.FromSeconds(6),
+ maximumNotificationCount: MaximumNotificationCount.FromCount(6));
+
+ cfg.Dispatcher = Application.Current.Dispatcher;
+
+ cfg.DisplayOptions.TopMost = false;
+ cfg.DisplayOptions.Width = 250;
+ });
+
+ _notifier.ClearMessages(new ClearAll());
+ }
+
+ public void OnUnloaded()
+ {
+ _notifier.Dispose();
+ }
+
+ public void ShowInformation(string message)
+ {
+ _notifier.ShowInformation(message);
+ }
+
+ public void ShowInformation(string message, MessageOptions opts)
+ {
+ _notifier.ShowInformation(message, opts);
+ }
+
+ public void ShowSuccess(string message)
+ {
+ _notifier.ShowSuccess(message);
+ }
+
+ public void ShowSuccess(string message, MessageOptions opts)
+ {
+ _notifier.ShowSuccess(message, opts);
+ }
+
+ internal void ClearMessages(string msg)
+ {
+ _notifier.ClearMessages(new ClearByMessage(msg));
+ }
+
+ public void ShowWarning(string message, MessageOptions opts)
+ {
+ _notifier.ShowWarning(message, opts);
+ }
+
+ public void ShowError(string message)
+ {
+ _notifier.ShowError(message);
+ }
+
+ public void ShowError(string message, MessageOptions opts)
+ {
+ _notifier.ShowError(message, opts);
+ }
+
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ protected virtual void OnPropertyChanged(string? propertyName = null)
+ {
+ var handler = PropertyChanged;
+ if (handler != null)
+ handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ public void ClearAll()
+ {
+ _notifier.ClearMessages(new ClearAll());
+ }
+ }
+}