Target .Netstandard 2.0 (#8)

* Fix build on non-windows platform

* Update to netstandard 2.0
Fix build on OSX

* Fix netstandard UWP API usage

* Update README.md

* Fix build

* Fix build

* Fix build on *Nix

* Remove Win stuff on nonwindows

* fix compilation

* Fixes

* Fix
This commit is contained in:
Luis v.d.Eltz
2022-03-06 19:13:33 +01:00
committed by GitHub
parent 2d78b282fc
commit 68d4c265a5
14 changed files with 329 additions and 121 deletions
@@ -20,22 +20,22 @@ namespace DesktopNotifications.Apple
public string? LaunchActionId { get; }
public ValueTask Initialize()
public Task Initialize()
{
return default;
return Task.CompletedTask;
}
public ValueTask ShowNotification(Notification notification, DateTimeOffset? expirationTime = null)
public Task ShowNotification(Notification notification, DateTimeOffset? expirationTime = null)
{
ShowNotification();
return default;
return Task.CompletedTask;
}
public ValueTask ScheduleNotification(Notification notification, DateTimeOffset deliveryTime,
public Task ScheduleNotification(Notification notification, DateTimeOffset deliveryTime,
DateTimeOffset? expirationTime = null)
{
return default;
return Task.CompletedTask;
}
}
}
@@ -1,8 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--Note: Dotnet currently does not allow to build on non-windows platforms when a windows TFM is specified-->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0-windows10.0.17763.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net5.0-windows10.0.17763.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>A cross-platform C# library for native desktop "toast" notifications.</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
@@ -1,7 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--Note: Dotnet currently does not allow to build on non-windows platforms when a windows TFM is specified-->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0-windows10.0.17763.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net5.0-windows10.0.17763.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
<Description>A cross-platform C# library for native desktop "toast" notifications.</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
@@ -9,7 +18,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.0" />
<PackageReference Include="Avalonia" Version="0.10.11" />
</ItemGroup>
<ItemGroup>
@@ -1,8 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--Note: Dotnet currently does not allow to build on non-windows platforms when a windows TFM is specified-->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0-windows10.0.17763.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net5.0-windows10.0.17763.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
<Description>A cross-platform C# library for native desktop "toast" notifications.</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Tmds.DBus;
@@ -41,7 +40,7 @@ namespace DesktopNotifications.FreeDesktop
public string? LaunchActionId { get; }
public async ValueTask Initialize()
public async Task Initialize()
{
_connection = Connection.Session;
@@ -62,7 +61,7 @@ namespace DesktopNotifications.FreeDesktop
);
}
public async ValueTask ShowNotification(Notification notification, DateTimeOffset? expirationTime = null)
public async Task ShowNotification(Notification notification, DateTimeOffset? expirationTime = null)
{
if (_connection == null || _proxy == null)
{
@@ -91,7 +90,7 @@ namespace DesktopNotifications.FreeDesktop
_activeNotifications[id] = notification;
}
public async ValueTask ScheduleNotification(
public async Task ScheduleNotification(
Notification notification,
DateTimeOffset deliveryTime,
DateTimeOffset? expirationTime = null)
@@ -135,7 +134,9 @@ namespace DesktopNotifications.FreeDesktop
private void OnNotificationClosed((uint id, uint reason) @event)
{
_activeNotifications.Remove(@event.id, out var notification);
var notification = _activeNotifications[@event.id];
_activeNotifications.Remove(@event.id);
//TODO: Not sure why but it calls this event twice sometimes
//In this case the notification has already been removed from the dict.
@@ -1,7 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--Note: Dotnet currently does not allow to build on non-windows platforms when a windows TFM is specified-->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0-windows10.0.17763.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net5.0-windows10.0.17763.0</TargetFrameworks>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>A cross-platform C# library for native desktop "toast" notifications.</Description>
@@ -9,9 +17,20 @@
<PackageProjectUrl>https://github.com/pr8x/DesktopNotifications</PackageProjectUrl>
</PropertyGroup>
<ItemGroup Condition="'$(OS)' == 'Windows_NT'">
<Compile Remove="NullImpl_WindowsNotificationManager.cs" />
</ItemGroup>
<ItemGroup Condition="'$(OS)' != 'Windows_NT'">
<Compile Remove="ShellLink.cs" />
<Compile Remove="WindowsNotificationManager.cs" />
<Compile Remove="WindowsApplicationContext.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DesktopNotifications\DesktopNotifications.csproj" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.0.2" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Condition="'$(TargetFramework)' != 'netstandard2.0'" Version="7.0.2" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Condition="'$(TargetFramework)' == 'netstandard2.0'" Version="10.0.22000.196" />
</ItemGroup>
</Project>
@@ -0,0 +1,57 @@
using System;
using System.Threading.Tasks;
#pragma warning disable CS0067
namespace DesktopNotifications.Windows
{
public class WindowsApplicationContext : ApplicationContext
{
public static WindowsApplicationContext FromCurrentProcess(
string? customName = null,
string? appUserModelId = null)
{
throw new PlatformNotSupportedException();
}
public WindowsApplicationContext(string name) : base(name)
{
throw new PlatformNotSupportedException();
}
}
public class WindowsNotificationManager : INotificationManager
{
public WindowsNotificationManager(WindowsApplicationContext? context = null)
{
throw new PlatformNotSupportedException();
}
public void Dispose()
{
throw new PlatformNotSupportedException();
}
public string? LaunchActionId { get; }
public event EventHandler<NotificationActivatedEventArgs>? NotificationActivated;
public event EventHandler<NotificationDismissedEventArgs>? NotificationDismissed;
public Task Initialize()
{
throw new PlatformNotSupportedException();
}
public Task ShowNotification(Notification notification, DateTimeOffset? expirationTime = null)
{
throw new PlatformNotSupportedException();
}
public Task ScheduleNotification(Notification notification, DateTimeOffset deliveryTime,
DateTimeOffset? expirationTime = null)
{
throw new PlatformNotSupportedException();
}
}
}
@@ -1,10 +1,16 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using XmlDocument = Windows.Data.Xml.Dom.XmlDocument;
#if NETSTANDARD
using System.IO;
using System.Xml;
#else
using System.Diagnostics;
using Microsoft.Toolkit.Uwp.Notifications;
#endif
namespace DesktopNotifications.Windows
{
@@ -14,7 +20,12 @@ namespace DesktopNotifications.Windows
private readonly WindowsApplicationContext _applicationContext;
private readonly TaskCompletionSource<string>? _launchActionPromise;
private readonly Dictionary<ToastNotification, Notification> _notifications;
#if NETSTANDARD
private readonly ToastNotifier _toastNotifier;
#else
private readonly ToastNotifierCompat _toastNotifier;
#endif
/// <summary>
/// </summary>
@@ -24,6 +35,7 @@ namespace DesktopNotifications.Windows
_applicationContext = applicationContext ?? WindowsApplicationContext.FromCurrentProcess();
_launchActionPromise = new TaskCompletionSource<string>();
#if !NETSTANDARD
if (ToastNotificationManagerCompat.WasCurrentProcessToastActivated())
{
ToastNotificationManagerCompat.OnActivated += OnAppActivated;
@@ -33,8 +45,14 @@ namespace DesktopNotifications.Windows
LaunchActionId = _launchActionPromise.Task.Result;
}
}
#endif
#if NETSTANDARD
_toastNotifier = ToastNotificationManager.CreateToastNotifier(_applicationContext.AppUserModelId);
#else
_toastNotifier = ToastNotificationManagerCompat.CreateToastNotifier();
#endif
_notifications = new Dictionary<ToastNotification, Notification>();
}
@@ -44,12 +62,12 @@ namespace DesktopNotifications.Windows
public string? LaunchActionId { get; }
public ValueTask Initialize()
public Task Initialize()
{
return default;
return Task.CompletedTask;
}
public ValueTask ShowNotification(Notification notification, DateTimeOffset? expirationTime)
public Task ShowNotification(Notification notification, DateTimeOffset? expirationTime)
{
if (expirationTime < DateTimeOffset.Now)
{
@@ -69,10 +87,10 @@ namespace DesktopNotifications.Windows
_toastNotifier.Show(toastNotification);
_notifications[toastNotification] = notification;
return default;
return Task.CompletedTask;
}
public ValueTask ScheduleNotification(
public Task ScheduleNotification(
Notification notification,
DateTimeOffset deliveryTime,
DateTimeOffset? expirationTime = null)
@@ -90,7 +108,7 @@ namespace DesktopNotifications.Windows
_toastNotifier.AddToSchedule(toastNotification);
return default;
return Task.CompletedTask;
}
public void Dispose()
@@ -99,6 +117,57 @@ namespace DesktopNotifications.Windows
private static XmlDocument GenerateXml(Notification notification)
{
#if NETSTANDARD
var sw = new StringWriter();
var xw = XmlWriter.Create(sw, new XmlWriterSettings
{
OmitXmlDeclaration = true,
Indent = true
});
xw.WriteStartElement("toast");
xw.WriteStartElement("visual");
xw.WriteStartElement("binding");
xw.WriteAttributeString("template", "ToastGeneric");
xw.WriteStartElement("text");
xw.WriteString(notification.Title ?? string.Empty);
xw.WriteEndElement();
xw.WriteStartElement("text");
xw.WriteString(notification.Body ?? string.Empty);
xw.WriteEndElement();
xw.WriteEndElement();
xw.WriteEndElement();
xw.WriteStartElement("actions");
foreach (var (title, actionId) in notification.Buttons)
{
xw.WriteStartElement("action");
xw.WriteAttributeString("content", title);
xw.WriteAttributeString("activationType", "foreground");
xw.WriteAttributeString("arguments", actionId);
xw.WriteEndElement();
}
xw.WriteEndElement();
xw.WriteEndElement();
xw.Flush();
var xmlStr = sw.ToString();
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlStr);
return xmlDoc;
#else
var builder = new ToastContentBuilder();
builder.AddText(notification.Title);
@@ -110,8 +179,11 @@ namespace DesktopNotifications.Windows
}
return builder.GetXml();
#endif
}
#if !NETSTANDARD
private void OnAppActivated(ToastNotificationActivatedEventArgsCompat e)
{
Debug.Assert(_launchActionPromise != null);
@@ -119,6 +191,7 @@ namespace DesktopNotifications.Windows
var actionId = GetActionId(e.Argument);
_launchActionPromise.SetResult(actionId);
}
#endif
private static void ToastNotificationOnFailed(ToastNotification sender, ToastFailedEventArgs args)
{
@@ -127,11 +200,13 @@ namespace DesktopNotifications.Windows
private void ToastNotificationOnDismissed(ToastNotification sender, ToastDismissedEventArgs args)
{
if (!_notifications.Remove(sender, out var notification))
if (!_notifications.TryGetValue(sender, out var notification))
{
return;
}
_notifications.Remove(sender);
var reason = args.Reason switch
{
ToastDismissalReason.UserCanceled => NotificationDismissReason.User,
@@ -1,8 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--Note: Dotnet currently does not allow to build on non-windows platforms when a windows TFM is specified-->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0-windows10.0.17763.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net5.0-windows10.0.17763.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>A cross-platform C# library for native desktop "toast" notifications.</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
+3 -3
View File
@@ -32,14 +32,14 @@ namespace DesktopNotifications
/// Initialized the notification manager.
/// </summary>
/// <returns></returns>
ValueTask Initialize();
Task Initialize();
/// <summary>
/// Schedules a notification for presentation.
/// </summary>
/// <param name="notification">The notification to present.</param>
/// <param name="expirationTime">The expiration time marking the point when the notification gets removed.</param>
ValueTask ShowNotification(Notification notification, DateTimeOffset? expirationTime = null);
Task ShowNotification(Notification notification, DateTimeOffset? expirationTime = null);
/// <summary>
/// </summary>
@@ -47,7 +47,7 @@ namespace DesktopNotifications
/// <param name="deliveryTime"></param>
/// <param name="expirationTime"></param>
/// <returns></returns>
ValueTask ScheduleNotification(
Task ScheduleNotification(
Notification notification,
DateTimeOffset deliveryTime,
DateTimeOffset? expirationTime = null);
+14 -5
View File
@@ -1,13 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<!--Note: Dotnet currently does not allow to build on non-windows platforms when a windows TFM is specified-->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
<TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<TargetFrameworks>netcoreapp3.1;net5.0-windows10.0.17763.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<LangVersion>8.0</LangVersion>
<OutputType>WinExe</OutputType>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.0" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.0" />
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.0" />
<PackageReference Include="Avalonia" Version="0.10.11" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.11" />
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.11" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DesktopNotifications.Avalonia\DesktopNotifications.Avalonia.csproj" />
+7 -2
View File
@@ -29,7 +29,8 @@ namespace Example.Avalonia
_eventsListBox = this.FindControl<ListBox>("EventsListBox");
_eventsListBox.Items = new ObservableCollection<string>();
_notificationManager = AvaloniaLocator.Current.GetService<INotificationManager>();
_notificationManager = AvaloniaLocator.Current.GetService<INotificationManager>() ??
throw new InvalidOperationException("Missing notification manager");
_notificationManager.NotificationActivated += OnNotificationActivated;
_notificationManager.NotificationDismissed += OnNotificationDismissed;
@@ -61,7 +62,11 @@ namespace Example.Avalonia
_notificationManager.ShowNotification(new Notification
{
Title = _titleTextBox.Text ?? _titleTextBox.Watermark,
Body = _bodyTextBox.Text ?? _bodyTextBox.Watermark
Body = _bodyTextBox.Text ?? _bodyTextBox.Watermark,
Buttons =
{
("This is awesome!", "awesome")
}
});
}
+9 -1
View File
@@ -1,9 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--Note: Dotnet currently does not allow to build on non-windows platforms when a windows TFM is specified-->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net5.0-windows10.0.17763.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net5.0-windows10.0.17763.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
+2 -1
View File
@@ -16,13 +16,14 @@ A cross-platform C# library for native desktop "toast" notifications.
|--------------------------|---------|---------------------|-----|
| Show notifications | ✓ | ✓ | ✕ |
| Schedule notifications | ✓ | ✓* | ✕ |
| Launch actions** | ✓ | ✕ | ✕ |
| Launch actions** | ✓*** | ✕ | ✕ |
| Replacing notifications | ✕ | ✕ | ✕ |
| Buttons | ✓ | ✓ | ✕ |
| Advanced content (Audio, Images, etc) | ✕ | ✕ | ✕ |
<sub> * Scheduled notifications will only be delivered while the application is running. </sub>
<sub> ** Some platforms support launching your application when the user clicked a notification. The associated action identifier is passed as a command-line argument. </sub>
<sub> *** This is currently not supported when targeting .netstandard
# Application Context