Merge branch 'feature/toast_notifications' into develop
This commit is contained in:
commit
0c6c3a048d
@ -1,8 +1,8 @@
|
||||
|
||||
//----------------------
|
||||
// <auto-generated>
|
||||
// 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
|
||||
// </auto-generated>
|
||||
//----------------------
|
||||
|
||||
@ -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<T> DeserializeRestResponseFromPolicy<T>(RestClient client, RestRequest request, PolicyResult<RestResponse> policyResult)
|
||||
private async Task<RestResponse<T>> DeserializeRestResponseFromPolicyAsync<T>(RestClient client, RestRequest request, PolicyResult<RestResponse> policyResult, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (policyResult.Outcome == OutcomeType.Successful)
|
||||
{
|
||||
return client.Deserialize<T>(policyResult.Result);
|
||||
return await client.Deserialize<T>(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<T>(client, request, policyResult));
|
||||
return DeserializeRestResponseFromPolicyAsync<T>(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<T>(client, request, policyResult);
|
||||
return await DeserializeRestResponseFromPolicyAsync<T>(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);
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Configuration" /> class
|
||||
@ -5072,9 +5072,9 @@ namespace BreCalClient.misc.Client
|
||||
/// </summary>
|
||||
public virtual IDictionary<string, string> DefaultHeaders { get; set; }
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public virtual int Timeout { get; set; }
|
||||
public virtual TimeSpan Timeout { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the proxy
|
||||
/// </summary>
|
||||
@ -5713,10 +5713,10 @@ namespace BreCalClient.misc.Client
|
||||
/// <value>Temp folder path.</value>
|
||||
string TempFolderPath { get; }
|
||||
/// <summary>
|
||||
/// Gets the HTTP connection timeout (in milliseconds)
|
||||
/// Gets the HTTP connection timeout.
|
||||
/// </summary>
|
||||
/// <value>HTTP connection timeout.</value>
|
||||
int Timeout { get; }
|
||||
TimeSpan Timeout { get; }
|
||||
/// <summary>
|
||||
/// Gets the proxy.
|
||||
/// </summary>
|
||||
@ -7097,24 +7097,26 @@ namespace BreCalClient.misc.Model
|
||||
public partial class Notification : IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or Sets NotificationType
|
||||
/// Gets or Sets Type
|
||||
/// </summary>
|
||||
[DataMember(Name = "notification_type", EmitDefaultValue = true)]
|
||||
public NotificationType? NotificationType { get; set; }
|
||||
[DataMember(Name = "type", EmitDefaultValue = true)]
|
||||
public NotificationType? Type { get; set; }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Notification" /> class.
|
||||
/// </summary>
|
||||
/// <param name="id">id.</param>
|
||||
/// <param name="shipcallId">shipcallId.</param>
|
||||
/// <param name="notificationType">notificationType.</param>
|
||||
/// <param name="participantId">participantId.</param>
|
||||
/// <param name="type">type.</param>
|
||||
/// <param name="message">message.</param>
|
||||
/// <param name="created">Readonly field set by the database when notification was created.</param>
|
||||
/// <param name="modified">Readonly field set by the database when notification was last modified.</param>
|
||||
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; }
|
||||
/// <summary>
|
||||
/// Gets or Sets ParticipantId
|
||||
/// </summary>
|
||||
/*
|
||||
<example>9</example>
|
||||
*/
|
||||
[DataMember(Name = "participant_id", EmitDefaultValue = true)]
|
||||
public int? ParticipantId { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or Sets Message
|
||||
/// </summary>
|
||||
/*
|
||||
@ -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");
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -1 +1 @@
|
||||
1.7.0.0
|
||||
1.7.0.3
|
||||
@ -30,6 +30,7 @@
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
|
||||
@ -47,7 +48,7 @@
|
||||
Informatikbüro Daniel Schick
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
|
||||
<Border BorderThickness="0 0 0 2" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" BorderBrush="Gray" />
|
||||
<Label FontWeight="DemiBold" Grid.Row="3" Grid.Column="0" Content="{x:Static p:Resources.textChangeContactInfo}" HorizontalContentAlignment="Right"/>
|
||||
<Label Grid.Row="4" Grid.Column="0" Content="{x:Static p:Resources.textEmail}" HorizontalContentAlignment="Right" />
|
||||
<Label Grid.Row="5" Grid.Column="0" Content="{x:Static p:Resources.textPhone}" HorizontalContentAlignment="Right" />
|
||||
@ -68,10 +69,10 @@
|
||||
<xctk:WatermarkPasswordBox Watermark="{x:Static p:Resources.textNewPassword}" Grid.Column="1" Grid.Row="13" Margin="2" x:Name="wpBoxNewPassword" TextChanged="wpBoxOldPassword_TextChanged"/>
|
||||
<xctk:WatermarkPasswordBox Watermark="{x:Static p:Resources.textRepeatNewPassword}" Grid.Column="1" Grid.Row="14" Margin="2" x:Name="wpBoxNewPasswordRepeat" TextChanged="wpBoxOldPassword_TextChanged"/>
|
||||
<Button x:Name="buttonChangePassword" Click="buttonChangePassword_Click" Grid.Column="1" Grid.Row="15" Margin="2" Content="{x:Static p:Resources.textChangePassword}" Width="120" HorizontalAlignment="Left" IsEnabled="False" />
|
||||
<Border BorderThickness="0 0 0 2" Grid.Row="16" Grid.Column="0" Grid.ColumnSpan="2" BorderBrush="Gray" />
|
||||
|
||||
|
||||
|
||||
<Button x:Name="buttonClose" Click="buttonClose_Click" Content="{x:Static p:Resources.textClose}" Width="80" Margin="2" Grid.Column="1" Grid.Row="17" HorizontalAlignment="Right" />
|
||||
<Button x:Name="buttonClose" Click="buttonClose_Click" Content="{x:Static p:Resources.textClose}" Width="80" Margin="2" Grid.Column="1" Grid.Row="18" HorizontalAlignment="Right" />
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@ -86,6 +86,12 @@
|
||||
<setting name="FilterCriteriaMap" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="W5Top" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="W5Left" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
</BreCalClient.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
||||
@ -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" >
|
||||
<Application.Resources>
|
||||
|
||||
@ -14,6 +15,95 @@
|
||||
<sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">10</sys:Double>
|
||||
<sys:Double x:Key="{x:Static SystemParameters.HorizontalScrollBarHeightKey}">10</sys:Double>
|
||||
|
||||
<Color x:Key="InformationColor">#147ec9</Color>
|
||||
<SolidColorBrush x:Key="InformationColorBrush" Color="{StaticResource InformationColor}" options:Freeze="True" />
|
||||
|
||||
<Color x:Key="SuccessColor">#11ad45</Color>
|
||||
<SolidColorBrush x:Key="SuccessColorBrush" Color="{StaticResource SuccessColor}" options:Freeze="True" />
|
||||
|
||||
<Color x:Key="ErrorColor">#e60914</Color>
|
||||
<SolidColorBrush x:Key="ErrorColorBrush" Color="{StaticResource ErrorColor}" options:Freeze="True" />
|
||||
|
||||
<Color x:Key="WarningColor">#f5a300</Color>
|
||||
<SolidColorBrush x:Key="WarningColorBrush" Color="{StaticResource WarningColor}" options:Freeze="True" />
|
||||
|
||||
<Canvas x:Key="InformationIcon" Width="24" Height="24">
|
||||
<Path Data="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z" Fill="White" />
|
||||
</Canvas>
|
||||
|
||||
<Canvas x:Key="SuccessIcon" Width="24" Height="24">
|
||||
<Path Data="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" Fill="White" />
|
||||
</Canvas>
|
||||
|
||||
<Canvas x:Key="ErrorIcon" Width="24" Height="24">
|
||||
<Path Data="M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z" Fill="White" />
|
||||
</Canvas>
|
||||
|
||||
<Canvas x:Key="WarningIcon" Width="24" Height="24">
|
||||
<Path Data="M12,2L1,21H23M12,6L19.53,19H4.47M11,10V14H13V10M11,16V18H13V16" Fill="White" />
|
||||
</Canvas>
|
||||
|
||||
<Canvas x:Key="CloseIcon" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
|
||||
<Path Width="31.6666" Height="31.6667" Canvas.Left="22.1666" Canvas.Top="22.1667" Stretch="Fill" Fill="#FF000000" Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z "/>
|
||||
</Canvas>
|
||||
|
||||
<Style TargetType="Border" x:Key="NotificationBorder">
|
||||
<Setter Property="Padding" Value="5" />
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect Opacity="0.5" ShadowDepth="1" BlurRadius="2" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Rectangle" x:Key="NotificationIcon">
|
||||
<Setter Property="Width" Value="24"/>
|
||||
<Setter Property="Height" Value="24"/>
|
||||
<Setter Property="Margin" Value="0,5,5,5" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Fill" Value="White"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TextBlock" x:Key="NotificationText">
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
<Setter Property="Margin" Value="5,0,0,0" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type Button}" x:Key="NotificationCloseButton">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Foreground" Value="#FFF" />
|
||||
<Setter Property="FontSize" Value="15" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="VerticalAlignment" Value="Top" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Border Background="{TemplateBinding Background}">
|
||||
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#33000000" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Background" Value="#77000000" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Rectangle" x:Key="CloseButtonIcon">
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Height" Value="10"/>
|
||||
<Setter Property="Fill" Value="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
</Application.Resources>
|
||||
|
||||
181
src/BreCalClient/AppNotification.cs
Normal file
181
src/BreCalClient/AppNotification.cs
Normal file
@ -0,0 +1,181 @@
|
||||
// Copyright (c) 2024- schick Informatik
|
||||
// Description: Helper (static) class to handle polled API notifications
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using ToastNotifications.Core;
|
||||
using BreCalClient.misc.Model;
|
||||
|
||||
namespace BreCalClient
|
||||
{
|
||||
internal class AppNotification
|
||||
{
|
||||
private static readonly Dictionary<int, AppNotification> _notifications = new();
|
||||
private readonly int _id;
|
||||
private static readonly ObservableCollection<AppNotification> _notificationsCollection = new();
|
||||
|
||||
public AppNotification(int id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
public int Id { get { return _id; } }
|
||||
|
||||
public string? NotificationType
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? NotificationDisplay
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? NotificationDate
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? Ship
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? ShipcallType
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? Berth
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? ETA
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public string? Message
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
|
||||
public static ObservableCollection<AppNotification> AppNotifications { get { return _notificationsCollection; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal statics
|
||||
|
||||
internal static void LoadFromSettings()
|
||||
{
|
||||
_notifications.Clear();
|
||||
|
||||
// load notification ids 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<BreCalClient.misc.Model.Notification> notifications, System.Collections.Concurrent.ConcurrentDictionary<int, ShipcallControlModel> currentShipcalls, ToastViewModel vm)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
foreach (BreCalClient.misc.Model.Notification notification in notifications)
|
||||
{
|
||||
if (notification.ParticipantId.HasValue && notification.ParticipantId.Value != App.Participant.Id) // not meant for us
|
||||
continue;
|
||||
|
||||
if (!currentShipcalls.ContainsKey(notification.ShipcallId)) // not one of our shipcalls (maybe for another port or filtered)
|
||||
continue;
|
||||
|
||||
if (!_notificationsCollection.Where(x => x.Id == notification.Id).Any())
|
||||
{
|
||||
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()
|
||||
{
|
||||
FontSize = 14,
|
||||
ShowCloseButton = true,
|
||||
Tag = ap
|
||||
};
|
||||
|
||||
newList.Add(ap);
|
||||
newList.Sort((a, b) => (a.NotificationDate ?? "").CompareTo(b.NotificationDate));
|
||||
_notificationsCollection.Clear();
|
||||
foreach(AppNotification newAp in newList)
|
||||
_notificationsCollection.Add(newAp);
|
||||
|
||||
ap.NotificationDisplay = string.Empty;
|
||||
switch(notification.Type)
|
||||
{
|
||||
case misc.Model.NotificationType.Assignment:
|
||||
ap.NotificationDisplay = Resources.Resources.textAssignment; break;
|
||||
case misc.Model.NotificationType.Next24h:
|
||||
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:
|
||||
ap.NotificationDisplay = Resources.Resources.textUnassigned; break;
|
||||
}
|
||||
|
||||
string toastText = ap.NotificationDisplay + "\n";
|
||||
|
||||
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.ShowAppNotification(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
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -8,8 +8,8 @@
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<StartupObject>BreCalClient.App</StartupObject>
|
||||
<AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile>
|
||||
<AssemblyVersion>1.7.0.0</AssemblyVersion>
|
||||
<FileVersion>1.7.0.0</FileVersion>
|
||||
<AssemblyVersion>1.7.0.3</AssemblyVersion>
|
||||
<FileVersion>1.7.0.3</FileVersion>
|
||||
<Title>Bremen calling client</Title>
|
||||
<Description>A Windows WPF client for the Bremen calling API.</Description>
|
||||
<ApplicationIcon>containership.ico</ApplicationIcon>
|
||||
@ -26,6 +26,7 @@
|
||||
<None Remove="Resources\arrow_up_blue.png" />
|
||||
<None Remove="Resources\arrow_up_green.png" />
|
||||
<None Remove="Resources\arrow_up_red.png" />
|
||||
<None Remove="Resources\bell3.png" />
|
||||
<None Remove="Resources\check.png" />
|
||||
<None Remove="Resources\clipboard.png" />
|
||||
<None Remove="Resources\clock.png" />
|
||||
@ -84,6 +85,7 @@
|
||||
<Resource Include="Resources\arrow_up_blue.png" />
|
||||
<Resource Include="Resources\arrow_up_green.png" />
|
||||
<Resource Include="Resources\arrow_up_red.png" />
|
||||
<Resource Include="Resources\bell3.png" />
|
||||
<Resource Include="Resources\check.png" />
|
||||
<Resource Include="Resources\clipboard.png" />
|
||||
<Resource Include="Resources\clock.png" />
|
||||
@ -118,10 +120,12 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.6.1" />
|
||||
<PackageReference Include="JsonSubTypes" Version="2.0.1" />
|
||||
<PackageReference Include="log4net" Version="2.0.17" />
|
||||
<PackageReference Include="log4net" Version="3.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Polly" Version="8.4.1" />
|
||||
<PackageReference Include="RestSharp" Version="112.0.0" />
|
||||
<PackageReference Include="Polly" Version="8.5.0" />
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
<PackageReference Include="ToastNotifications" Version="2.5.1" />
|
||||
<PackageReference Include="ToastNotifications.Messages" Version="2.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2024- schick Informatik
|
||||
// Description: Window to show (complete) list of current shipcall histories
|
||||
// Description:
|
||||
//
|
||||
|
||||
using BreCalClient.misc.Api;
|
||||
|
||||
@ -124,6 +124,8 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="26" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="26" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="26" />
|
||||
@ -157,19 +159,25 @@
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="9"/>
|
||||
<StatusBarItem Grid.Column="10">
|
||||
<Button x:Name="buttonNotifications" Click="buttonNotifications_Click" Width="20" ToolTip="{x:Static p:Resources.textShowNotifications}">
|
||||
<Image Source="./Resources/bell3.png"/>
|
||||
</Button>
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="9"/>
|
||||
<StatusBarItem Grid.Column="12">
|
||||
<TextBlock Name="labelStatusBar"></TextBlock>
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="11"/>
|
||||
<StatusBarItem Grid.Column="12">
|
||||
<Separator Grid.Column="13"/>
|
||||
<StatusBarItem Grid.Column="14">
|
||||
<Button x:Name="buttonManualRefresh" Width="20" Click="buttonManualRefresh_Click" ToolTip="{x:Static p:Resources.textTriggerManualRefresh}">
|
||||
<Image Source="./Resources/nav_refresh_green.png"/>
|
||||
</Button>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem Grid.Column="13">
|
||||
<StatusBarItem Grid.Column="15">
|
||||
<TextBlock x:Name="labelLatestUpdate" />
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="14"/>
|
||||
<StatusBarItem Grid.Column="15">
|
||||
<Separator Grid.Column="16"/>
|
||||
<StatusBarItem Grid.Column="17">
|
||||
<ProgressBar Name="generalProgressStatus" Width="90" Height="16" Foreground="LightGray"/>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
|
||||
@ -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
|
||||
@ -68,6 +71,7 @@ namespace BreCalClient
|
||||
// private bool _filterChanged = false;
|
||||
// private bool _sequenceChanged = false;
|
||||
private HistoryDialog? _historyDialog;
|
||||
private NotificationDialog? _notificationDialog;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -122,6 +126,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
|
||||
@ -443,6 +454,21 @@ namespace BreCalClient
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonNotifications_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_notificationDialog == null)
|
||||
{
|
||||
_notificationDialog = new NotificationDialog();
|
||||
_notificationDialog.AppNotifications = AppNotification.AppNotifications;
|
||||
_notificationDialog.Closed += (sender, e) => { this._notificationDialog = null; };
|
||||
_notificationDialog.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
_notificationDialog.Activate();
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonManualRefresh_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_refreshImmediately = true; // set flag to avoid timer loop termination
|
||||
@ -510,6 +536,7 @@ namespace BreCalClient
|
||||
|
||||
_ = Task.Run(() => RefreshShipcalls());
|
||||
_ = Task.Run(() => RefreshShips());
|
||||
_ = Task.Run(() => CheckNotifications());
|
||||
|
||||
}
|
||||
|
||||
@ -633,6 +660,19 @@ namespace BreCalClient
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CheckNotifications()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Thread.Sleep(CHECK_NOTIFICATIONS_INTERVAL_SECONDS * 1000);
|
||||
if (_loginResult?.NotifyPopup ?? false)
|
||||
{
|
||||
List<Notification> notifications = await _staticApi.NotificationsGetAsync();
|
||||
AppNotification.UpdateNotifications(notifications, _allShipcallsDict, _vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region basic operations
|
||||
|
||||
61
src/BreCalClient/NotificationDialog.xaml
Normal file
61
src/BreCalClient/NotificationDialog.xaml
Normal file
@ -0,0 +1,61 @@
|
||||
<Window x:Class="BreCalClient.NotificationDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:BreCalClient"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
xmlns:p = "clr-namespace:BreCalClient.Resources"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W5Left}" Top="{local:SettingBinding W5Top}"
|
||||
Title="{x:Static p:Resources.textNotifications}" Height="450" Width="800" Loaded="Window_Loaded">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
<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">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding NotificationType}" Value="Assignment">
|
||||
<Setter Property="Foreground" Value="Blue"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding NotificationType}" Value="Next24h">
|
||||
<Setter Property="Foreground" Value="DarkOrange"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding NotificationType}" Value="TimeConflict">
|
||||
<Setter Property="Foreground" Value="Red"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding NotificationType}" Value="TimeConflictResolved">
|
||||
<Setter Property="Foreground" Value="Green"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding NotificationType}" Value="Unassigned">
|
||||
<Setter Property="Foreground" Value="DarkGray"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</local:ENIDataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Id" Binding="{Binding Path=Id}" 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"/>
|
||||
<DataGridTextColumn Header="ETA/ETD" Binding="{Binding Path=ETA}" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="{x:Static p:Resources.textBerth}" Binding="{Binding Path=Berth}" IsReadOnly="True"/>
|
||||
</DataGrid.Columns>
|
||||
</local:ENIDataGrid>
|
||||
<Grid Grid.Row="1" Grid.Column="0" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="22" />
|
||||
<ColumnDefinition Width="80" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width=".2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button x:Name="buttonClose" Click="buttonClose_Click" Content="{x:Static p:Resources.textClose}" Width="80" Margin="2" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Right" />
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
44
src/BreCalClient/NotificationDialog.xaml.cs
Normal file
44
src/BreCalClient/NotificationDialog.xaml.cs
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2024- schick Informatik
|
||||
// Description:
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace BreCalClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for NotificationDialog.xaml
|
||||
/// </summary>
|
||||
public partial class NotificationDialog : Window
|
||||
{
|
||||
public NotificationDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
internal ObservableCollection<AppNotification>? AppNotifications { get; set; }
|
||||
|
||||
private void buttonClose_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.dataGridNotifications.ItemsSource = AppNotifications;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ApplicationRevision>2</ApplicationRevision>
|
||||
<ApplicationVersion>1.7.0.0</ApplicationVersion>
|
||||
<ApplicationRevision>1</ApplicationRevision>
|
||||
<ApplicationVersion>1.7.0.3</ApplicationVersion>
|
||||
<BootstrapperEnabled>True</BootstrapperEnabled>
|
||||
<Configuration>Debug</Configuration>
|
||||
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
||||
@ -38,7 +38,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateRequired>True</UpdateRequired>
|
||||
<WebPageFileName>Publish.html</WebPageFileName>
|
||||
<MinimumRequiredVersion>1.7.0.0</MinimumRequiredVersion>
|
||||
<MinimumRequiredVersion>1.7.0.3</MinimumRequiredVersion>
|
||||
<SkipPublishVerification>false</SkipPublishVerification>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
||||
35
src/BreCalClient/Properties/Settings.Designer.cs
generated
35
src/BreCalClient/Properties/Settings.Designer.cs
generated
@ -226,5 +226,40 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public double W5Top {
|
||||
get {
|
||||
return ((double)(this["W5Top"]));
|
||||
}
|
||||
set {
|
||||
this["W5Top"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public double W5Left {
|
||||
get {
|
||||
return ((double)(this["W5Left"]));
|
||||
}
|
||||
set {
|
||||
this["W5Left"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,5 +56,14 @@
|
||||
<Setting Name="FilterCriteriaMap" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="Notifications" Type="System.Collections.Specialized.StringCollection" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="W5Top" Type="System.Double" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="W5Left" Type="System.Double" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
82
src/BreCalClient/Resources/Resources.Designer.cs
generated
82
src/BreCalClient/Resources/Resources.Designer.cs
generated
@ -167,6 +167,16 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
public static byte[] bell3 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("bell3", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
@ -380,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>
|
||||
@ -560,6 +579,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Date.
|
||||
/// </summary>
|
||||
public static string textDate {
|
||||
get {
|
||||
return ResourceManager.GetString("textDate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Delete.
|
||||
/// </summary>
|
||||
@ -884,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>
|
||||
@ -1208,6 +1245,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Shipcall.
|
||||
/// </summary>
|
||||
public static string textShipcall {
|
||||
get {
|
||||
return ResourceManager.GetString("textShipcall", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Ship length.
|
||||
/// </summary>
|
||||
@ -1244,6 +1290,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Show notificiations.
|
||||
/// </summary>
|
||||
public static string textShowNotifications {
|
||||
get {
|
||||
return ResourceManager.GetString("textShowNotifications", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Sort order.
|
||||
/// </summary>
|
||||
@ -1307,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>
|
||||
@ -1397,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>
|
||||
|
||||
@ -565,4 +565,28 @@
|
||||
<data name="textNotifyPush" xml:space="preserve">
|
||||
<value>Banner / Push Benachrichtigung in App</value>
|
||||
</data>
|
||||
<data name="textDate" xml:space="preserve">
|
||||
<value>Datum</value>
|
||||
</data>
|
||||
<data name="textShipcall" xml:space="preserve">
|
||||
<value>Anlauf</value>
|
||||
</data>
|
||||
<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>
|
||||
@ -613,4 +613,31 @@
|
||||
<data name="textNotifyPush" xml:space="preserve">
|
||||
<value>Notify by push notification in app</value>
|
||||
</data>
|
||||
<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>
|
||||
BIN
src/BreCalClient/Resources/bell3.png
Normal file
BIN
src/BreCalClient/Resources/bell3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@ -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()
|
||||
{
|
||||
|
||||
73
src/BreCalClient/ToastViewModel.cs
Normal file
73
src/BreCalClient/ToastViewModel.cs
Normal file
@ -0,0 +1,73 @@
|
||||
// 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(30),
|
||||
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 ShowAppNotification(string message, MessageOptions options)
|
||||
{
|
||||
_notifier?.ShowAppNotification(message, options);
|
||||
}
|
||||
|
||||
public void ShowAppNotification(string message)
|
||||
{
|
||||
_notifier?.ShowAppNotification(message);
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged(string? propertyName = null)
|
||||
{
|
||||
var handler = PropertyChanged;
|
||||
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public void ClearAll()
|
||||
{
|
||||
_notifier.ClearMessages(new ClearAll());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,8 +6,8 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>Resources\lock_preferences.ico</ApplicationIcon>
|
||||
<FileVersion>1.7.0.0</FileVersion>
|
||||
<AssemblyVersion>1.7.0.0</AssemblyVersion>
|
||||
<FileVersion>1.7.0.3</FileVersion>
|
||||
<AssemblyVersion>1.7.0.3</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user