Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions samples/Avalonia.Labs.Catalog/Avalonia.Labs.Catalog.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@
</AvaloniaResource>
</ItemGroup>

<ItemGroup>
<Compile Update="Views\NotificationsView.axaml.cs">
<DependentUpon>NotificationView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>

</Project>
117 changes: 117 additions & 0 deletions samples/Avalonia.Labs.Catalog/ViewModels/NotificationsViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System.Threading.Tasks;
using System;
using System.Reactive;
using Avalonia.Controls.Notifications;
using Avalonia.Labs.Catalog.Views;
using Avalonia.Labs.Controls;
using ReactiveUI;

namespace Avalonia.Labs.Catalog.ViewModels;

internal class NotificationsViewModel : ViewModelBase
{
static NotificationsViewModel()
{
ViewLocator.Register(typeof(NotificationsViewModel), () => new NotificationsView());
}

public NotificationsViewModel()
{
Title = "Notification";
ShowNotificationCommand = ReactiveCommand.CreateFromTask(ShowNotificationAsync);
}

private string? _notificationText = null;
public string? NotificationText
{
get => _notificationText;
set => this.RaiseAndSetIfChanged(ref _notificationText, value);
}
private string? _actionButtonText = "action";
public string? ActionButtonText
{
get => _actionButtonText;
set => this.RaiseAndSetIfChanged(ref _actionButtonText, value);
}

private int _notificationDurationSeconds = 3;
public int NotificationDurationSeconds
{
get => _notificationDurationSeconds;
set => this.RaiseAndSetIfChanged(ref _notificationDurationSeconds, value);
}
private NotificationType _notificationType = Avalonia.Controls.Notifications.NotificationType.Information;
public NotificationType NotificationType
{
get => _notificationType;
set => this.RaiseAndSetIfChanged(ref _notificationType, value);
}
private NotificationPosition _notificationPosition = NotificationPosition.TopLeft;
public NotificationPosition NotificationPosition
{
get => _notificationPosition;
set => this.RaiseAndSetIfChanged(ref _notificationPosition, value);
}

public ReactiveCommand<Unit,Unit> ShowNotificationCommand { get; private set; }

private Task ShowNotificationAsync()
{
if (NotificationPosition == NotificationPosition.TopCenter)
{
NotificationManager.Default.ShowNotification(new NotificationOptions()
{
Type=NotificationType.Error,
Content="NotificationPosition.BottomCenter is not yet supported by Avalonia.Labs.Controls since it targets avalonia 11.0.0"
});
return Task.CompletedTask;
}

if (NotificationPosition == NotificationPosition.BottomCenter)
{
NotificationManager.Default.ShowNotification(new NotificationOptions()
{
Type=NotificationType.Error,
Content="NotificationPosition.BottomCenter is not yet supported by Avalonia.Labs.Controls since it targets avalonia 11.0.0"
});
return Task.CompletedTask;
}

var o = new NotificationOptions()
{
Content = NotificationText ?? $"Hello {_notificationCount:00}",
Type = NotificationType,
Duration = NotificationDurationSeconds == 0 ?
TimeSpan.FromDays(30) // "infinitely open"
:
TimeSpan.FromSeconds(NotificationDurationSeconds),
Position = NotificationPosition,
ClickActionText = ActionButtonText ?? string.Empty,
DismissAction = () =>
{
NotificationManager.Default.ShowNotification(new NotificationOptions
{
Content = $"Notification dismissed: '{NotificationText}'", Type = NotificationType.Success,
});
return Task.CompletedTask;
}
};
if (!string.IsNullOrEmpty(o.ClickActionText))
o.ClickAction = () =>
{
NotificationManager.Default.ShowNotification(new NotificationOptions
{
Content = $"Action '{ActionButtonText}' clicked",
});
return Task.CompletedTask;
};

NotificationManager.Default.ShowNotification(o);

_notificationCount++;

return Task.CompletedTask;
}

private int _notificationCount = 1;
}
110 changes: 110 additions & 0 deletions samples/Avalonia.Labs.Catalog/Views/NotificationsView.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<UserControl xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:vm="clr-namespace:Avalonia.Labs.Catalog.ViewModels"
x:Class="Avalonia.Labs.Catalog.Views.NotificationsView"
x:DataType="vm:NotificationsViewModel">
<UserControl.Resources>
<StreamGeometry x:Key="SwapThemeIcon">M 23.935547,4.0019531 C 23.275047,4.0354318 22.748047,4.5831669 22.748047,5.2519531 V 7.7519531 C 22.748047,8.4423031 23.307647,9.0019531 23.998047,9.0019531 24.688347,9.0019531 25.248047,8.4423031 25.248047,7.7519531 V 5.2519531 C 25.248047,4.5615931 24.688347,4.0019531 23.998047,4.0019531 23.976472,4.0019531 23.956853,4.0008732 23.935547,4.0019531 Z M 10.25,9 C 9.9300987,9 9.6093094,9.1231125 9.3652344,9.3671875 8.8770744,9.8553475 8.8770744,10.646666 9.3652344,11.134766 L 11.865234,13.634766 C 12.353334,14.122966 13.146666,14.122966 13.634766,13.634766 14.122966,13.146666 14.122966,12.355287 13.634766,11.867188 L 11.134766,9.3671875 C 10.890716,9.1231125 10.569901,9 10.25,9 Z M 37.75,9 C 37.430087,9 37.111288,9.1231125 36.867188,9.3671875 L 34.367188,11.867188 C 33.879088,12.355287 33.879087,13.146666 34.367188,13.634766 34.855388,14.122966 35.646666,14.122966 36.134766,13.634766 L 38.634766,11.134766 C 39.122966,10.646666 39.122966,9.8553475 38.634766,9.3671875 38.390716,9.1231125 38.069913,9 37.75,9 Z M 24,14 C 18.47715,14 14,18.47715 14,24 14,29.5228 18.47715,34 24,34 29.5228,34 34,29.5228 34,24 34,18.47715 29.5228,14 24,14 Z M 24,15.5 C 28.6944,15.5 32.5,19.30558 32.5,24 32.5,28.6944 28.6944,32.5 24,32.5 Z M 5.25,22.75 C 4.55965,22.75 4,23.3097 4,24 4,24.6904 4.55965,25.25 5.25,25.25 H 7.75 C 8.44035,25.25 9,24.6904 9,24 9,23.3097 8.44035,22.75 7.75,22.75 Z M 40.25,22.75 C 39.5596,22.75 39,23.3097 39,24 39,24.6904 39.5596,25.25 40.25,25.25 H 42.75 C 43.4403,25.25 44,24.6904 44,24 44,23.3097 43.4403,22.75 42.75,22.75 Z M 12.75,34 C 12.4301,34 12.109284,34.123087 11.865234,34.367188 L 9.3652344,36.867188 C 8.8770744,37.355287 8.8770744,38.146666 9.3652344,38.634766 9.8533844,39.122966 10.646666,39.122966 11.134766,38.634766 L 13.634766,36.134766 C 14.122966,35.646666 14.122966,34.855288 13.634766,34.367188 13.390716,34.123087 13.0699,34 12.75,34 Z M 35.25,34 C 34.930087,34 34.611288,34.123087 34.367188,34.367188 33.879088,34.855288 33.879087,35.646666 34.367188,36.134766 L 36.867188,38.634766 C 37.355388,39.122966 38.146666,39.122966 38.634766,38.634766 39.122966,38.146666 39.122966,37.355287 38.634766,36.867188 L 36.134766,34.367188 C 35.890716,34.123087 35.569913,34 35.25,34 Z M 23.998047,39 C 23.307647,39 22.748047,39.5597 22.748047,40.25 V 42.75 C 22.748047,43.4404 23.307647,44 23.998047,44 24.688347,44 25.248047,43.4404 25.248047,42.75 V 40.25 C 25.248047,39.5597 24.688347,39 23.998047,39 Z</StreamGeometry>
<StreamGeometry x:Key="HamburgerIcon">M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z</StreamGeometry>
</UserControl.Resources>

<SplitView x:Name="MainSplitView"
IsPaneOpen="True"
DisplayMode="Inline"
OpenPaneLength="300"
PanePlacement="Left">
<SplitView.Pane>
<!-- Left column with inputs -->
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
Margin="0,0,10,0"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Vertical" Spacing="5">
<Expander Header="Notification Settings"
IsExpanded="True"
HorizontalAlignment="Stretch">
<StackPanel Spacing="5">
<Grid ColumnDefinitions="Auto, *"
RowDefinitions="Auto,Auto,Auto,Auto,Auto"
Margin="0,5">

<TextBlock Grid.Row="0" Grid.Column="0"
VerticalAlignment="Center"
Margin="0,0,10,0"
Text="Duration:"/>
<TextBox Grid.Row="0" Grid.Column="1" Watermark="Notification text"
AcceptsReturn="true"
Text="{Binding NotificationText}" />

<TextBlock Grid.Row="1" Grid.Column="0"
VerticalAlignment="Center"
Margin="0,0,10,0"
Text="Duration:"/>
<NumericUpDown Grid.Row="1" Grid.Column="1"
Value="{Binding NotificationDurationSeconds}"
Minimum="0"
Maximum="30"
FormatString="0 seconds"/>

<TextBlock Grid.Row="2" Grid.Column="0"
VerticalAlignment="Center"
Margin="0,0,10,0"
Text="Type:"/>
<ComboBox Grid.Row="2" Grid.Column="1"
SelectedItem="{Binding NotificationType}"
HorizontalAlignment="Stretch">
<NotificationType>Information</NotificationType>
<NotificationType>Success</NotificationType>
<NotificationType>Warning</NotificationType>
<NotificationType>Error</NotificationType>
</ComboBox>

<TextBlock Grid.Row="3" Grid.Column="0"
VerticalAlignment="Center"
Margin="0,0,10,0"
Text="Position:"/>
<ComboBox Grid.Row="3" Grid.Column="1"
SelectedItem="{Binding NotificationPosition}"
HorizontalAlignment="Stretch">
<NotificationPosition>TopLeft</NotificationPosition>
<NotificationPosition>TopCenter</NotificationPosition>
<NotificationPosition>TopRight</NotificationPosition>
<NotificationPosition>BottomLeft</NotificationPosition>
<NotificationPosition>BottomCenter</NotificationPosition>
<NotificationPosition>BottomRight</NotificationPosition>
</ComboBox>

<TextBlock Grid.Row="4" Grid.Column="0"
VerticalAlignment="Center"
Margin="0,0,10,0"
Text="Button text:"/>
<TextBox Grid.Row="4" Grid.Column="1" Watermark="Action button text"
Text="{Binding ActionButtonText}" />
</Grid>
</StackPanel>
</Expander>
</StackPanel>
</ScrollViewer>
</SplitView.Pane>

<!-- Right column with buttons -->
<ScrollViewer HorizontalScrollBarVisibility="Disabled">
<StackPanel Spacing="5" MinWidth="200">
<Button x:Name="HamburgerButton"
Grid.Column="0"
Click="OnHamburgerButtonClick"
IsVisible="False"
Background="Transparent">
<PathIcon Data="{StaticResource HamburgerIcon}"/>
</Button>


<Button Content="Show Notification"
Command="{Binding ShowNotificationCommand}"
HorizontalAlignment="Stretch"/>
</StackPanel>
</ScrollViewer>
</SplitView>
</UserControl>
56 changes: 56 additions & 0 deletions samples/Avalonia.Labs.Catalog/Views/NotificationsView.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using Avalonia.Controls;
using Avalonia.Interactivity;

namespace Avalonia.Labs.Catalog.Views;

public partial class NotificationsView : UserControl
{
private const double MOBILE_WIDTH_THRESHOLD = 600;
private SplitView? _mainSplitView;
private Button? _hamburgerButton;
private bool _isNarrowLayout;

public NotificationsView()
{
InitializeComponent();
_mainSplitView = this.FindControl<SplitView>("MainSplitView");
_hamburgerButton = this.FindControl<Button>("HamburgerButton");
if (_mainSplitView != null)
{
this.LayoutUpdated += OnLayoutUpdated;
}
}

private void OnLayoutUpdated(object? sender, EventArgs e)
{
if (_mainSplitView == null || _hamburgerButton == null) return;

var isNarrowNow = this.Bounds.Width <= MOBILE_WIDTH_THRESHOLD;
if (_isNarrowLayout == isNarrowNow) return;

_isNarrowLayout = isNarrowNow;

if (_isNarrowLayout)
{
_mainSplitView.DisplayMode = SplitViewDisplayMode.CompactOverlay;
_mainSplitView.IsPaneOpen = false;
_mainSplitView.CompactPaneLength = 0;
_hamburgerButton.IsVisible = true;
}
else
{
_mainSplitView.DisplayMode = SplitViewDisplayMode.Inline;
_mainSplitView.IsPaneOpen = true;
_hamburgerButton.IsVisible = false;
}
}

private void OnHamburgerButtonClick(object? sender, RoutedEventArgs e)
{
if (_mainSplitView != null)
{
_mainSplitView.IsPaneOpen = !_mainSplitView.IsPaneOpen;
}
}
}
11 changes: 11 additions & 0 deletions samples/Avalonia.Labs.Catalog/Views/WelcomeView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@
<Label FontSize="18"
VerticalAlignment="Center">Qr Generator</Label>
</Button>
<Button HorizontalAlignment="Stretch"
Height="60"
Command="{Binding NavigateTo}"
CornerRadius="10"
Margin="0,5">
<Button.CommandParameter>
<viewModels:NotificationsViewModel/>
</Button.CommandParameter>
<Label FontSize="18"
VerticalAlignment="Center">In-App Notifications</Label>
</Button>
<Button HorizontalAlignment="Stretch"
Height="60"
Command="{Binding NavigateTo}"
Expand Down
12 changes: 12 additions & 0 deletions src/Avalonia.Labs.Controls/Notification/INotificationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using Avalonia.Controls.Notifications;

namespace Avalonia.Labs.Controls;

// INotificationManager.cs
public interface INotificationManager
{
void ShowNotification(NotificationOptions options);
NotificationPosition DefaultNotificationPosition { get; set; }
TimeSpan DefaultDuration { get; set; }
}
Loading