Custom toast control, colored by type
This commit is contained in:
parent
a648cc2e71
commit
1fd87edd6e
@ -13,9 +13,9 @@ namespace BreCalClient
|
||||
{
|
||||
internal class AppNotification
|
||||
{
|
||||
private static Dictionary<int, AppNotification> _notifications = new();
|
||||
private static readonly Dictionary<int, AppNotification> _notifications = new();
|
||||
private readonly int _id;
|
||||
private static ObservableCollection<AppNotification> _notificationsCollection = new();
|
||||
private static readonly ObservableCollection<AppNotification> _notificationsCollection = new();
|
||||
|
||||
public AppNotification(int id)
|
||||
{
|
||||
@ -31,6 +31,11 @@ namespace BreCalClient
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? NotificationDisplay
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? NotificationDate
|
||||
{
|
||||
get; private set;
|
||||
@ -50,12 +55,18 @@ namespace BreCalClient
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
|
||||
public string? ETA
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? Message
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
|
||||
public static ObservableCollection<AppNotification> AppNotifications { get { return _notificationsCollection; } }
|
||||
|
||||
#endregion
|
||||
@ -94,48 +105,61 @@ namespace BreCalClient
|
||||
|
||||
if (!_notificationsCollection.Where(x => x.Id == notification.Id).Any())
|
||||
{
|
||||
AppNotification ap = new(notification.Id);
|
||||
ap.NotificationType = notification.Type.ToString();
|
||||
ap.Ship = currentShipcalls[notification.ShipcallId]?.Ship?.Name;
|
||||
ap.ShipcallType = currentShipcalls[notification.ShipcallId]?.Shipcall?.Type.ToString();
|
||||
ap.ETA = currentShipcalls[notification.ShipcallId]?.GetETAETD(true);
|
||||
List<AppNotification> newList = new(_notificationsCollection);
|
||||
|
||||
AppNotification ap = new(notification.Id)
|
||||
{
|
||||
NotificationType = notification.Type.ToString(),
|
||||
NotificationDate = notification.Created.ToString(),
|
||||
Ship = currentShipcalls[notification.ShipcallId]?.Ship?.Name,
|
||||
ShipcallType = currentShipcalls[notification.ShipcallId]?.Shipcall?.Type.ToString(),
|
||||
ETA = currentShipcalls[notification.ShipcallId]?.GetETAETD(true)
|
||||
};
|
||||
Times? agencyTimes = currentShipcalls[notification.ShipcallId]?.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
|
||||
ap.Berth = currentShipcalls[notification.ShipcallId]?.GetBerthText(agencyTimes);
|
||||
ap.Message = notification.Message;
|
||||
|
||||
System.Diagnostics.Trace.WriteLine($"Notification {notification.Id} Type {notification.Type}");
|
||||
MessageOptions options = new();
|
||||
options.FontSize = 14;
|
||||
options.ShowCloseButton = true;
|
||||
|
||||
switch(notification.Type) // TODO: Set toast color and icon
|
||||
MessageOptions options = new()
|
||||
{
|
||||
case misc.Model.NotificationType.TimeConflict:
|
||||
FontSize = 14,
|
||||
ShowCloseButton = true,
|
||||
Tag = ap
|
||||
};
|
||||
|
||||
break;
|
||||
case misc.Model.NotificationType.TimeConflictResolved:
|
||||
newList.Add(ap);
|
||||
newList.Sort((a, b) => (a.NotificationDate ?? "").CompareTo(b.NotificationDate));
|
||||
_notificationsCollection.Clear();
|
||||
foreach(AppNotification newAp in newList)
|
||||
_notificationsCollection.Add(newAp);
|
||||
|
||||
break;
|
||||
ap.NotificationDisplay = string.Empty;
|
||||
switch(notification.Type)
|
||||
{
|
||||
case misc.Model.NotificationType.Assignment:
|
||||
|
||||
break;
|
||||
ap.NotificationDisplay = Resources.Resources.textAssignment; break;
|
||||
case misc.Model.NotificationType.Next24h:
|
||||
|
||||
break;
|
||||
ap.NotificationDisplay = Resources.Resources.textNext24h; break;
|
||||
case misc.Model.NotificationType.TimeConflict:
|
||||
ap.NotificationDisplay = Resources.Resources.textTimeConflict; break;
|
||||
case misc.Model.NotificationType.TimeConflictResolved:
|
||||
ap.NotificationDisplay = Resources.Resources.textTimeConflictResolved; break;
|
||||
case misc.Model.NotificationType.Unassigned:
|
||||
|
||||
break;
|
||||
ap.NotificationDisplay = Resources.Resources.textUnassigned; break;
|
||||
}
|
||||
|
||||
_notificationsCollection.Add(ap);
|
||||
string toastText = ap.NotificationDisplay + "\n";
|
||||
|
||||
string toastText = $"{ap.Ship} ({ap.ShipcallType}) - {ap.ETA} - {ap.Berth}";
|
||||
toastText += $"{ap.Ship} ({ap.ShipcallType}) - {ap.ETA} - {ap.Berth}";
|
||||
if (!string.IsNullOrEmpty(ap.Message))
|
||||
toastText += $" \n{ap.Message}";
|
||||
|
||||
if (!_notifications.ContainsKey(notification.Id))
|
||||
{
|
||||
_notifications.Add(notification.Id, ap);
|
||||
App.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
vm.ShowInformation(toastText, options);
|
||||
vm.ShowAppNotification(toastText, options);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
23
src/BreCalClient/AppNotificationExtension.cs
Normal file
23
src/BreCalClient/AppNotificationExtension.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2024- schick Informatik
|
||||
// Description:
|
||||
//
|
||||
|
||||
using ToastNotifications;
|
||||
using ToastNotifications.Core;
|
||||
|
||||
namespace BreCalClient
|
||||
{
|
||||
public static class AppNotificationExtension
|
||||
{
|
||||
public static void ShowAppNotification(this Notifier notifier, string message)
|
||||
{
|
||||
notifier.Notify(() => new AppNotificationMessage(message));
|
||||
}
|
||||
|
||||
public static void ShowAppNotification(this Notifier notifier, string message, MessageOptions displayOptions)
|
||||
{
|
||||
notifier.Notify(() => new AppNotificationMessage(message, displayOptions));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
30
src/BreCalClient/AppNotificationMessage.cs
Normal file
30
src/BreCalClient/AppNotificationMessage.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Windows;
|
||||
using ToastNotifications.Core;
|
||||
using ToastNotifications.Messages.Core;
|
||||
|
||||
namespace BreCalClient
|
||||
{
|
||||
public class AppNotificationMessage : MessageBase<AppNotificationPart>
|
||||
{
|
||||
public AppNotificationMessage(string message) : this(message, new MessageOptions())
|
||||
{
|
||||
}
|
||||
|
||||
public AppNotificationMessage(string message, MessageOptions options) : base(message, options)
|
||||
{
|
||||
}
|
||||
|
||||
protected override AppNotificationPart CreateDisplayPart()
|
||||
{
|
||||
return new AppNotificationPart(this);
|
||||
}
|
||||
|
||||
protected override void UpdateDisplayOptions(AppNotificationPart displayPart, MessageOptions options)
|
||||
{
|
||||
// if (options.FontSize != null)
|
||||
// displayPart.Text.FontSize = options.FontSize.Value;
|
||||
|
||||
// displayPart.CloseButton.Visibility = options.ShowCloseButton ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/BreCalClient/AppNotificationPart.xaml
Normal file
31
src/BreCalClient/AppNotificationPart.xaml
Normal file
@ -0,0 +1,31 @@
|
||||
<core:NotificationDisplayPart x:Class="BreCalClient.AppNotificationPart"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:core="clr-namespace:ToastNotifications.Core;assembly=ToastNotifications"
|
||||
mc:Ignorable="d" d:DesignWidth="250" >
|
||||
<Border x:Name="ContentWrapper" Style="{DynamicResource NotificationBorder}" Background="{DynamicResource ErrorColorBrush}">
|
||||
<Grid x:Name="ContentContainer">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="25" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle x:Name="Icon" Width="24" Height="24">
|
||||
<Rectangle.Fill>
|
||||
<VisualBrush Visual="{StaticResource ErrorIcon}" />
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
|
||||
<TextBlock x:Name="Text" Text="{Binding Message, Mode=OneTime}" Style="{StaticResource NotificationText}" Grid.Column="1" />
|
||||
<Button x:Name="CloseButton" Style="{StaticResource NotificationCloseButton}" Padding="1" Grid.Column="2" Click="OnClose" Visibility="Hidden">
|
||||
<Rectangle Style="{StaticResource CloseButtonIcon}" Margin="2">
|
||||
<Rectangle.OpacityMask>
|
||||
<VisualBrush Stretch="Fill" Visual="{StaticResource CloseIcon}" />
|
||||
</Rectangle.OpacityMask>
|
||||
</Rectangle>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</core:NotificationDisplayPart>
|
||||
51
src/BreCalClient/AppNotificationPart.xaml.cs
Normal file
51
src/BreCalClient/AppNotificationPart.xaml.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using BreCalClient.misc.Model;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using ToastNotifications.Core;
|
||||
|
||||
namespace BreCalClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for NotificationPart.xaml
|
||||
/// </summary>
|
||||
public partial class AppNotificationPart : NotificationDisplayPart
|
||||
{
|
||||
public AppNotificationPart(AppNotificationMessage appNotification)
|
||||
{
|
||||
InitializeComponent();
|
||||
Bind(appNotification);
|
||||
|
||||
if (appNotification.Options.Tag is AppNotification ap)
|
||||
{
|
||||
switch (ap.NotificationType)
|
||||
{
|
||||
case "TimeConflict":
|
||||
this.ContentWrapper.Background = Brushes.Red;
|
||||
break;
|
||||
case "TimeConflictResolved":
|
||||
this.ContentWrapper.Background = Brushes.Green;
|
||||
break;
|
||||
case "Assignment":
|
||||
this.ContentWrapper.Background = Brushes.Blue;
|
||||
break;
|
||||
case "Next24h":
|
||||
this.ContentWrapper.Background = Brushes.DarkOrange;
|
||||
break;
|
||||
case "Unassigned":
|
||||
this.ContentWrapper.Background = Brushes.Gray;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void OnClose(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Notification.Close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,7 @@
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
<local:ENIDataGrid x:Name="dataGridNotifications" Grid.Row="0" SelectionMode="Single" IsReadOnly="True" AlternatingRowBackground="LightBlue" AutoGenerateColumns="False"
|
||||
<local:ENIDataGrid x:Name="dataGridNotifications" Grid.Row="0" SelectionMode="Single" IsReadOnly="True" AutoGenerateColumns="False"
|
||||
CanUserAddRows="False" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
|
||||
<local:ENIDataGrid.RowStyle>
|
||||
<Style TargetType="DataGridRow">
|
||||
@ -38,7 +38,7 @@
|
||||
</local:ENIDataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Id" Binding="{Binding Path=Id}" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="{x:Static p:Resources.textType}" Binding="{Binding Path=NotificationType}" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="{x:Static p:Resources.textType}" Binding="{Binding Path=NotificationDisplay}" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="{x:Static p:Resources.textDate}" Binding="{Binding Path=NotificationDate}" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="{x:Static p:Resources.textShip}" Binding="{Binding Path=Ship}" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="{x:Static p:Resources.textShipcall}" Binding="{Binding Path=ShipcallType}" IsReadOnly="True"/>
|
||||
|
||||
45
src/BreCalClient/Resources/Resources.Designer.cs
generated
45
src/BreCalClient/Resources/Resources.Designer.cs
generated
@ -390,6 +390,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Participant assigned to shipcall.
|
||||
/// </summary>
|
||||
public static string textAssignment {
|
||||
get {
|
||||
return ResourceManager.GetString("textAssignment", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Berth.
|
||||
/// </summary>
|
||||
@ -903,6 +912,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Relevant next 24hrs.
|
||||
/// </summary>
|
||||
public static string textNext24h {
|
||||
get {
|
||||
return ResourceManager.GetString("textNext24h", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Notifications.
|
||||
/// </summary>
|
||||
@ -1344,6 +1362,24 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Participants disagree on times.
|
||||
/// </summary>
|
||||
public static string textTimeConflict {
|
||||
get {
|
||||
return ResourceManager.GetString("textTimeConflict", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Times conflict resolved.
|
||||
/// </summary>
|
||||
public static string textTimeConflictResolved {
|
||||
get {
|
||||
return ResourceManager.GetString("textTimeConflictResolved", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Timestamp.
|
||||
/// </summary>
|
||||
@ -1434,6 +1470,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Participant unassigned from shipcall.
|
||||
/// </summary>
|
||||
public static string textUnassigned {
|
||||
get {
|
||||
return ResourceManager.GetString("textUnassigned", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to User login.
|
||||
/// </summary>
|
||||
|
||||
@ -574,4 +574,19 @@
|
||||
<data name="textShowNotifications" xml:space="preserve">
|
||||
<value>Benachrichtigungen anzeigen</value>
|
||||
</data>
|
||||
<data name="textAssignment" xml:space="preserve">
|
||||
<value>Teilnehmer wurde nominiert</value>
|
||||
</data>
|
||||
<data name="textNext24h" xml:space="preserve">
|
||||
<value>Relevant für Morgenrunde (24hrs)</value>
|
||||
</data>
|
||||
<data name="textTimeConflict" xml:space="preserve">
|
||||
<value>"Ampel"-Regel(n) wurde verletzt</value>
|
||||
</data>
|
||||
<data name="textTimeConflictResolved" xml:space="preserve">
|
||||
<value>Zeitliche Konflikte aufgelöst</value>
|
||||
</data>
|
||||
<data name="textUnassigned" xml:space="preserve">
|
||||
<value>Nominierung des Teilnehmer entfernt</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -616,13 +616,28 @@
|
||||
<data name="bell3" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>bell3.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="textAssignment" xml:space="preserve">
|
||||
<value>Participant assigned to shipcall</value>
|
||||
</data>
|
||||
<data name="textDate" xml:space="preserve">
|
||||
<value>Date</value>
|
||||
</data>
|
||||
<data name="textNext24h" xml:space="preserve">
|
||||
<value>Relevant next 24hrs</value>
|
||||
</data>
|
||||
<data name="textShipcall" xml:space="preserve">
|
||||
<value>Shipcall</value>
|
||||
</data>
|
||||
<data name="textShowNotifications" xml:space="preserve">
|
||||
<value>Show notificiations</value>
|
||||
</data>
|
||||
<data name="textTimeConflict" xml:space="preserve">
|
||||
<value>Participants disagree on times</value>
|
||||
</data>
|
||||
<data name="textTimeConflictResolved" xml:space="preserve">
|
||||
<value>Times conflict resolved</value>
|
||||
</data>
|
||||
<data name="textUnassigned" xml:space="preserve">
|
||||
<value>Participant unassigned from shipcall</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -98,7 +98,7 @@ namespace BreCalClient
|
||||
private async void DataGridShips_CreateRequested()
|
||||
{
|
||||
|
||||
ShipModel shipModel = new((ShipModel.LastEditShip != null) ? ShipModel.LastEditShip : new Ship());
|
||||
ShipModel shipModel = new(ShipModel.LastEditShip ?? new Ship());
|
||||
|
||||
EditShipDialog esd = new()
|
||||
{
|
||||
|
||||
@ -30,7 +30,7 @@ namespace BreCalClient
|
||||
offsetY: 100);
|
||||
|
||||
cfg.LifetimeSupervisor = new TimeAndCountBasedLifetimeSupervisor(
|
||||
notificationLifetime: TimeSpan.FromSeconds(6),
|
||||
notificationLifetime: TimeSpan.FromSeconds(30),
|
||||
maximumNotificationCount: MaximumNotificationCount.FromCount(6));
|
||||
|
||||
cfg.Dispatcher = Application.Current.Dispatcher;
|
||||
@ -47,54 +47,22 @@ namespace BreCalClient
|
||||
_notifier.Dispose();
|
||||
}
|
||||
|
||||
public void ShowInformation(string message)
|
||||
public void ShowAppNotification(string message, MessageOptions options)
|
||||
{
|
||||
_notifier.ShowInformation(message);
|
||||
_notifier?.ShowAppNotification(message, options);
|
||||
}
|
||||
|
||||
public void ShowInformation(string message, MessageOptions opts)
|
||||
public void ShowAppNotification(string message)
|
||||
{
|
||||
_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);
|
||||
}
|
||||
|
||||
_notifier?.ShowAppNotification(message);
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged(string? propertyName = null)
|
||||
{
|
||||
var handler = PropertyChanged;
|
||||
if (handler != null)
|
||||
handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public void ClearAll()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user