Skip to content

Commit

Permalink
Add Platform-Specific Option to Enable Snackbar on Windows (#1780)
Browse files Browse the repository at this point in the history
* Add `Options.SetShouldEnableSnackbarOnWindows(bool)`

* Update Options.cs

* Update src/CommunityToolkit.Maui/Options.cs

Co-authored-by: Shaun Lawrence <[email protected]>

* Update src/CommunityToolkit.Maui/Options.cs

* Throw `InvalidOperationException` whenf `SetShouldEnableSnackbarOnWindows` is invoked incorrectly

* Add Runtime Validation of Snackbar on Windows

* Fix typo

* Add `HelpLink`

* Update Snackbar.shared.cs

* Update Snackbar.shared.cs

* Only throw `InvalidOperationException` on net8.0-windows TFM

---------

Co-authored-by: Shaun Lawrence <[email protected]>
  • Loading branch information
TheCodeTraveler and bijington authored Mar 29, 2024
1 parent d32fb23 commit 51dc63a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 31 deletions.
6 changes: 5 additions & 1 deletion samples/CommunityToolkit.Maui.Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,14 @@ public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder()
#if DEBUG
.UseMauiCommunityToolkit()
.UseMauiCommunityToolkit(options =>
{
options.SetShouldEnableSnackbarOnWindows(true);
})
#else
.UseMauiCommunityToolkit(options =>
{
options.SetShouldEnableSnackbarOnWindows(true);
options.SetShouldSuppressExceptionsInConverters(true);
options.SetShouldSuppressExceptionsInBehaviors(true);
options.SetShouldSuppressExceptionsInAnimations(true);
Expand Down
10 changes: 10 additions & 0 deletions src/CommunityToolkit.Maui/Alerts/Snackbar/Snackbar.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ public partial class Snackbar : ISnackbar
/// </summary>
public Snackbar()
{
#if WINDOWS
if (!Options.ShouldEnableSnackbarOnWindows)
{
throw new InvalidOperationException($"Additional setup is required in the Package.appxmanifest file to enable {nameof(Snackbar)} on Windows. Additonally, `{nameof(AppBuilderExtensions.UseMauiCommunityToolkit)}(options => options.{nameof(Options.SetShouldEnableSnackbarOnWindows)}({bool.TrueString.ToLower()});` must be called to enable Snackbar on Windows. See the Platform Specific Initialization section of the {nameof(Snackbar)} documentaion for more information: https://learn.microsoft.com/dotnet/communitytoolkit/maui/alerts/snackbar")
{
HelpLink = "https://learn.microsoft.com/dotnet/communitytoolkit/maui/alerts/snackbar"
};
}
#endif

Duration = GetDefaultTimeSpan();
VisualOptions = new SnackbarOptions();
}
Expand Down
27 changes: 1 addition & 26 deletions src/CommunityToolkit.Maui/AppBuilderExtensions.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,10 @@ public static MauiAppBuilder UseMauiCommunityToolkit(this MauiAppBuilder builder
// Pass `null` because `options?.Invoke()` will set options on both `CommunityToolkit.Maui` and `CommunityToolkit.Maui.Core`
builder.UseMauiCommunityToolkitCore(null);

#if WINDOWS
builder.ConfigureLifecycleEvents(events =>
{
events.AddWindows(windows => windows
.OnLaunched((_, _) =>
{
Microsoft.Windows.AppNotifications.AppNotificationManager.Default.NotificationInvoked += OnSnackbarNotificationInvoked;
Microsoft.Windows.AppNotifications.AppNotificationManager.Default.Register();
})
.OnClosed((_, _) =>
{
Microsoft.Windows.AppNotifications.AppNotificationManager.Default.NotificationInvoked -= OnSnackbarNotificationInvoked;
Microsoft.Windows.AppNotifications.AppNotificationManager.Default.Unregister();
}));
});
#endif

builder.Services.AddSingleton<IPopupService, PopupService>();

// Invokes options for both `CommunityToolkit.Maui` and `CommunityToolkit.Maui.Core`
options?.Invoke(new Options());
options?.Invoke(new Options(builder));

builder.ConfigureMauiHandlers(h =>
{
Expand All @@ -56,12 +39,4 @@ public static MauiAppBuilder UseMauiCommunityToolkit(this MauiAppBuilder builder
NavigationBar.RemapForControls();
return builder;
}
#if WINDOWS
static void OnSnackbarNotificationInvoked(
Microsoft.Windows.AppNotifications.AppNotificationManager sender,
Microsoft.Windows.AppNotifications.AppNotificationActivatedEventArgs args)
{
Snackbar.HandleSnackbarAction(args);
}
#endif
}
67 changes: 63 additions & 4 deletions src/CommunityToolkit.Maui/Options.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,91 @@
using CommunityToolkit.Maui.Behaviors;
using CommunityToolkit.Maui.Converters;
using Microsoft.Maui.LifecycleEvents;

namespace CommunityToolkit.Maui;

/// <summary>
/// .NET MAUI Community Toolkit Options.
/// </summary>
public class Options : Core.Options
public class Options() : Core.Options
{
readonly MauiAppBuilder? builder;

internal Options(in MauiAppBuilder builder) : this()
{
this.builder = builder;
}

internal static bool ShouldSuppressExceptionsInAnimations { get; private set; }
internal static bool ShouldSuppressExceptionsInConverters { get; private set; }
internal static bool ShouldSuppressExceptionsInBehaviors { get; private set; }
internal static bool ShouldEnableSnackbarOnWindows { get; private set; }

/// <summary>
/// Allows to return default value instead of throwing an exception when using <see cref="BaseConverter{TFrom,TTo}"/>.
/// Default value is false.
/// </summary>
/// <remarks>
/// Default value is false.
/// </remarks>
public void SetShouldSuppressExceptionsInConverters(bool value) => ShouldSuppressExceptionsInConverters = value;

/// <summary>
/// Allows to return default value instead of throwing an exception when using <see cref="AnimationBehavior"/>.
/// Default value is false.
/// </summary>
/// <remarks>
/// Default value is false.
/// </remarks>
public void SetShouldSuppressExceptionsInAnimations(bool value) => ShouldSuppressExceptionsInAnimations = value;

/// <summary>
/// Allows to return default value instead of throwing an exception when using <see cref="BaseBehavior{TView}"/>.
/// Default value is false.
/// </summary>
/// <remarks>
/// Default value is false.
/// </remarks>
public void SetShouldSuppressExceptionsInBehaviors(bool value) => ShouldSuppressExceptionsInBehaviors = value;

/// <summary>
/// Enables <see cref="Alerts.Snackbar"/> for Windows
/// </summary>
/// <remarks>
/// Additional setup is required in the Package.appxmanifest file to enable <see cref="Alerts.Snackbar"/> on Windows. See the <a href="https://learn.microsoft.com/dotnet/communitytoolkit/maui/alerts/snackbar">Snackbar Platform Specific Initialization Documentation</a> for more information. Default value is false.
/// </remarks>
public void SetShouldEnableSnackbarOnWindows(bool value)
{
#if WINDOWS
if (value is true && builder is null)
{
throw new InvalidOperationException($"{nameof(SetShouldEnableSnackbarOnWindows)} must be called using the {nameof(AppBuilderExtensions.UseMauiCommunityToolkit)} extension method. See the Platform Specific Initialization section of the {nameof(Alerts.Snackbar)} documentaion for more inforamtion: https://learn.microsoft.com/dotnet/communitytoolkit/maui/alerts/snackbar)")
{
HelpLink = "https://learn.microsoft.com/dotnet/communitytoolkit/maui/alerts/snackbar"
};
}
else if (value is true && builder is not null)
{
builder.ConfigureLifecycleEvents(events =>
{
events.AddWindows(windows => windows
.OnLaunched((_, _) =>
{
Microsoft.Windows.AppNotifications.AppNotificationManager.Default.NotificationInvoked += OnSnackbarNotificationInvoked;
Microsoft.Windows.AppNotifications.AppNotificationManager.Default.Register();
})
.OnClosed((_, _) =>
{
Microsoft.Windows.AppNotifications.AppNotificationManager.Default.NotificationInvoked -= OnSnackbarNotificationInvoked;
Microsoft.Windows.AppNotifications.AppNotificationManager.Default.Unregister();
}));
});

static void OnSnackbarNotificationInvoked(Microsoft.Windows.AppNotifications.AppNotificationManager sender,
Microsoft.Windows.AppNotifications.AppNotificationActivatedEventArgs args)
{
Alerts.Snackbar.HandleSnackbarAction(args);
}
}
#endif

ShouldEnableSnackbarOnWindows = value;
}
}

0 comments on commit 51dc63a

Please sign in to comment.