Skip to content

Commit

Permalink
notification redesign and action
Browse files Browse the repository at this point in the history
  • Loading branch information
kikipoulet committed May 25, 2024
1 parent 9a06c7f commit 2a6d31e
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 36 deletions.
7 changes: 7 additions & 0 deletions SukiUI.Demo/Features/ControlsLibrary/Toasts/ToastsView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@
Content="Show Toast" />
</controls:GroupBox>
</controls:GlassCard>
<controls:GlassCard>
<controls:GroupBox Header="Action Toast">
<Button Margin="15,10,15,0"
Command="{Binding ShowActionToastCommand}"
Content="Show Toast" />
</controls:GroupBox>
</controls:GlassCard>
<controls:GlassCard>
<controls:GroupBox Header="Separate Toast Window">
<Button Margin="15,10,15,0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using SukiUI.Controls;
using SukiUI.Demo.Utilities;
using SukiUI.Enums;
using SukiUI.Models;

namespace SukiUI.Demo.Features.ControlsLibrary.Toasts;

Expand All @@ -23,6 +24,11 @@ private static Task ShowSingleStandardToast() =>
[RelayCommand]
private static Task ShowInfoToast() =>
SukiHost.ShowToast("A Simple Toast", "This is the content of an info toast.", ToastType.Info);

[RelayCommand]
private static Task ShowActionToast() =>
SukiHost.ShowToast(new ToastModel("Update Available", "A new version is available for you.", ToastType.Info, TimeSpan.FromSeconds(5), null, "Update Now",
() => { SukiHost.ShowToast("Update", "Update done !");}));

[RelayCommand]
private static Task ShowSuccessToast() =>
Expand Down
1 change: 1 addition & 0 deletions SukiUI/ColorTheme/Dark.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

<BoxShadows x:Key="SukiLowShadow">0 0 3 0 #353535</BoxShadows>
<BoxShadows x:Key="SukiSwitchShadow">0 1 5 0 #555555</BoxShadows>
<BoxShadows x:Key="SukiSmallPopupShadow">0 0 5 1 #101010</BoxShadows>
<BoxShadows x:Key="SukiPopupShadow">1 1 14 1 #101010</BoxShadows>
<BoxShadows x:Key="SukiBigPopupShadow">1 1 15 0 #606060</BoxShadows>

Expand Down
1 change: 1 addition & 0 deletions SukiUI/ColorTheme/Light.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

<BoxShadows x:Key="SukiLowShadow">0 0 3 0 #eaeaea</BoxShadows>
<BoxShadows x:Key="SukiSwitchShadow">0 1 5 0 #aaaaaa</BoxShadows>
<BoxShadows x:Key="SukiSmallPopupShadow">0 0 6 0 Gray</BoxShadows>
<BoxShadows x:Key="SukiPopupShadow">1 1 8 0 LightGray</BoxShadows>
<BoxShadows x:Key="SukiBigPopupShadow">1 1 15 0 #dedede</BoxShadows>

Expand Down
4 changes: 2 additions & 2 deletions SukiUI/Content/Icons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ public static class Icons
public static readonly StreamGeometry Star = Parse("M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z");

// Material Icons
public static readonly StreamGeometry InformationOutline = Parse("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");
public static readonly StreamGeometry InformationOutline = Parse("M11 9H13V7H11V9M11 17H13V11H11V17Z");

// Material Icons
public static readonly StreamGeometry AlertOutline = Parse("M12,2L1,21H23M12,6L19.53,19H4.47M11,10V14H13V10M11,16V18H13V16");
public static readonly StreamGeometry AlertOutline = Parse("M 11,4L 13,4L 13,15L 11,15L 11,4 Z M 13,18L 13,20L 11,20L 11,18L 13,18 Z");

private static StreamGeometry Parse(string path) => StreamGeometry.Parse(path);
}
81 changes: 53 additions & 28 deletions SukiUI/Controls/SukiToast.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,80 @@
<ControlTheme x:Key="SukiToastTheme" TargetType="suki:SukiToast">
<Setter Property="Template">
<ControlTemplate>
<Border Name="PART_ToastCard"
Width="300"
Margin="30,5,30,10"
Padding="0" BorderThickness="1" BorderBrush="{DynamicResource SukiBorderBrush}"
BoxShadow="{DynamicResource SukiPopupShadow}"
Background="{DynamicResource SukiCardBackground}"
CornerRadius="15">
<Panel>

<Border Name="PART_ToastCard"
Width="300"
Margin="40,5,30,10"
Padding="0" BorderThickness="1" BorderBrush="{DynamicResource SukiBorderBrush}"
BoxShadow="{DynamicResource SukiPopupShadow}"
Background="{DynamicResource SukiCardBackground}"
CornerRadius="15">
<Border CornerRadius="15" ClipToBounds="True">
<Panel>

<Panel Margin="0">
<Panel.Background>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<GradientStop Color="{DynamicResource SukiPrimaryColor7}" Offset="1"></GradientStop>
<GradientStop Color="Transparent" Offset="0"></GradientStop>
</LinearGradientBrush>
</Panel.Background>
<Panel IsVisible="{DynamicResource IsDark}">
<Panel Margin="0">
<Panel.Background>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<GradientStop Color="{DynamicResource SukiAccentColor5}" Offset="0"></GradientStop>
<GradientStop Color="{DynamicResource SukiPrimaryColor10}" Offset="1"></GradientStop>

</LinearGradientBrush>
</Panel.Background>
</Panel>
</Panel>
<Panel Margin="0">
<Panel.Background>
<LinearGradientBrush StartPoint="0%,50%" EndPoint="100%,50%">
<GradientStop Color="{DynamicResource SukiAccentColor7}" Offset="0"></GradientStop>
<GradientStop Color="Transparent" Offset="1"></GradientStop>
</LinearGradientBrush>
</Panel.Background>

<Panel IsVisible="{DynamicResource IsLight}">
<Panel Margin="0">
<Panel.Background>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<GradientStop Color="{DynamicResource SukiAccentColor3}" Offset="0"></GradientStop>
<GradientStop Color="{DynamicResource SukiPrimaryColor3}" Offset="1"></GradientStop>

</LinearGradientBrush>
</Panel.Background>
</Panel>

</Panel>


<Panel Margin="20, 22">

<DockPanel Margin="0,-7" LastChildFill="True">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<PathIcon Width="16" Margin="-6,0,0,0"
Height="16"
Data="{TemplateBinding Icon}"
Foreground="{TemplateBinding Foreground}" />
<TextBlock Margin="12,0,0,0"
<TextBlock Margin="12,0,0,0"
FontSize="15"
FontWeight="DemiBold"
Foreground="{DynamicResource SukiText}"
Text="{TemplateBinding Title}" />
</StackPanel>
<ContentPresenter Margin="22,10,0,0"
<Button Name="ButtonAction" FontSize="14" Padding="14,6" DockPanel.Dock="Bottom" IsVisible="{TemplateBinding ShowActionButton}" HorizontalAlignment="Right" Margin="0,14,0,0" Content="{TemplateBinding ActionButtonContent}">
</Button>
<ContentPresenter Margin="12,10,0,0"
Content="{TemplateBinding Content}"
Foreground="{DynamicResource SukiText}"
TextWrapping="Wrap" />

</DockPanel>
</Panel>
</Panel>
</Border>
</Border>
<Border BoxShadow="{DynamicResource SukiSmallPopupShadow}"
Margin="20,0,0,0" Background="{DynamicResource SukiCardBackground}" Width="40" Height="40" CornerRadius="40" VerticalAlignment="Center" HorizontalAlignment="Left">
<Border CornerRadius="40" ClipToBounds="True">
<Panel>
<Panel IsVisible="{DynamicResource IsDark}" Opacity="0.3" Background="{TemplateBinding Foreground}"></Panel>
<Panel IsVisible="{DynamicResource IsLight}" Opacity="0.1" Background="{TemplateBinding Foreground}"></Panel>
<PathIcon Width="16" Margin="0,0,0,0"
Height="16" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="{TemplateBinding Icon}"
Foreground="{TemplateBinding Foreground}" />

</Panel>
</Border>
</Border>
</Panel>
</ControlTemplate>
</Setter>
</ControlTheme>
Expand Down
47 changes: 43 additions & 4 deletions SukiUI/Controls/SukiToast.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using SukiUI.Models;
using System;
using System.Timers;
using Avalonia.Interactivity;
using Avalonia.Media;
using SukiUI.Content;
using SukiUI.Enums;
Expand All @@ -20,6 +21,7 @@ public class SukiToast : ContentControl
private readonly Timer _timer = new();

private Action? _onClickedCallback;
private Action? _onActionCallback;

public SukiToast()

Check warning on line 26 in SukiUI/Controls/SukiToast.axaml.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Host' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
{
Expand Down Expand Up @@ -49,12 +51,36 @@ public string Title
get => GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}

public static readonly StyledProperty<bool> ShowActionButtonProperty =
AvaloniaProperty.Register<SukiToast, bool>(nameof(ShowActionButton));

public bool ShowActionButton
{
get => GetValue(ShowActionButtonProperty);
set => SetValue(ShowActionButtonProperty, value);
}

public static readonly StyledProperty<string> ActionButtonContentProperty =
AvaloniaProperty.Register<SukiToast, string>(nameof(ActionButtonContent));

public string ActionButtonContent
{
get => GetValue(ActionButtonContentProperty);
set => SetValue(ActionButtonContentProperty, value);
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);

e.NameScope.Get<Border>("PART_ToastCard").PointerPressed += ToastCardClickedHandler;
e.NameScope.Get<Button>("ButtonAction").Click += ButtonActionClicked;
}

private void ButtonActionClicked(object sender, RoutedEventArgs e)
{
_onActionCallback?.Invoke();
}

private async void ToastCardClickedHandler(object o, PointerPressedEventArgs pointerPressedEventArgs)
Expand All @@ -66,7 +92,7 @@ private async void ToastCardClickedHandler(object o, PointerPressedEventArgs poi

// Icon Foreground Brushes
// Note: it would be better to place them into a resource dictionary, but findResource performs slightly slower
private readonly SolidColorBrush _infoIconForeground = new(Color.FromRgb(47,84,235));
private readonly SolidColorBrush _infoIconForeground = new(Color.FromRgb(89,126,255));
private readonly SolidColorBrush _successIconForeground = new(Color.FromRgb(35,143,35));
private readonly SolidColorBrush _warningIconForeground = new(Color.FromRgb(177,113,20));
private readonly SolidColorBrush _errorIconForeground = new(Color.FromRgb(216,63,48));
Expand All @@ -76,12 +102,24 @@ public void Initialize(ToastModel model, SukiHost host)
Host = host;
Title = model.Title;
Content = model.Content;
if (model.ActionButtonContent != null || model.ActionButton != null)
{
ShowActionButton = true;
ActionButtonContent = model.ActionButtonContent;
_onActionCallback = model.OnActionButtonClicked;
}
else
{
ShowActionButton = false;
ActionButtonContent = "";
_onActionCallback = null;
}
Icon = model.Type switch
{
ToastType.Info => Icons.InformationOutline,
ToastType.Success => Icons.CircleOutlineCheck,
ToastType.Success => Icons.Check,
ToastType.Warning => Icons.AlertOutline,
ToastType.Error => Icons.CircleOutlineMinus,
ToastType.Error => Icons.AlertOutline,
_ => Icons.InformationOutline
};
Foreground = model.Type switch
Expand All @@ -93,7 +131,8 @@ public void Initialize(ToastModel model, SukiHost host)
_ => _infoIconForeground
};
_onClickedCallback = model.OnClicked;
_timer.Interval = model.Lifetime.TotalMilliseconds;

_timer.Interval = model.Lifetime?.TotalMilliseconds ?? TimeSpan.FromSeconds(6).TotalMilliseconds;
_timer.Start();
DockPanel.SetDock(this, Dock.Bottom);
}
Expand Down
7 changes: 5 additions & 2 deletions SukiUI/Models/ToastModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

namespace SukiUI.Models;

public readonly record struct ToastModel(string Title, object Content, ToastType Type, TimeSpan Lifetime, Action? OnClicked)
public readonly record struct ToastModel(string Title, object Content, ToastType Type = ToastType.Info, TimeSpan? Lifetime = null, Action? OnClicked = null, string? ActionButtonContent = null,Action? ActionButton= null)
{
public string Title { get; } = Title;
public object Content { get; } = Content;
public ToastType Type { get; } = Type;
public TimeSpan Lifetime { get; } = Lifetime;
public TimeSpan? Lifetime { get; } = Lifetime ;
public Action? OnClicked { get; } = OnClicked;

public string? ActionButtonContent { get; } = ActionButtonContent;
public Action? OnActionButtonClicked { get; } = ActionButton;
}
1 change: 1 addition & 0 deletions SukiUI/Theme/Index.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ private void SetColorWithOpacities(string baseName, Color baseColor)
SetResource($"{baseName}10", baseColor.WithAlpha(0.10));
SetResource($"{baseName}7", baseColor.WithAlpha(0.07));
SetResource($"{baseName}5", baseColor.WithAlpha(0.05));
SetResource($"{baseName}3", baseColor.WithAlpha(0.03));
SetResource($"{baseName}0", baseColor.WithAlpha(0.00));
}

Expand Down

0 comments on commit 2a6d31e

Please sign in to comment.