Skip to content

Commit a811f69

Browse files
committed
Improve persistent notification deck UI
1 parent a14a870 commit a811f69

12 files changed

Lines changed: 693 additions & 72 deletions

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ Screenshot placeholders live in `docs/assets/`. Real screenshots will be added a
2828
- Test Lab for sample notifications, bursts, sounds, snooze, and persistence checks.
2929
- Fluent Glass, Minimal, Focus, Developer, High Contrast, and Compact Pill themes.
3030

31+
## Persistent UI Prototype
32+
33+
The current prototype includes a WinUI always-on-top Notification Deck window and a corner unread badge. The deck uses Windows App SDK `AppWindow.Show(false)` so notification updates can show the deck without activating it by default.
34+
35+
Current controls include:
36+
37+
- Position: top-right, top-left, bottom-right, bottom-left.
38+
- Monitor selection from available display work areas.
39+
- Card width.
40+
- Maximum visible cards.
41+
- Opacity.
42+
- Animation mode.
43+
- Light, dark, and system theme.
44+
- Compact/collapsed deck mode.
45+
- Corner unread badge toggle.
46+
3147
## Installation
3248

3349
ToastDeck is not released yet.

src/ToastDeck.App/MainWindow.xaml

Lines changed: 98 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,84 +5,130 @@
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
77
mc:Ignorable="d"
8-
Title="ToastDeck">
8+
Title="ToastDeck Settings">
99
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
1010
<Grid.ColumnDefinitions>
11-
<ColumnDefinition Width="300" />
11+
<ColumnDefinition Width="340" />
1212
<ColumnDefinition Width="*" />
1313
</Grid.ColumnDefinitions>
1414

1515
<ScrollViewer>
1616
<StackPanel Padding="24" Spacing="18">
17-
<TextBlock Text="ToastDeck" FontSize="28" FontWeight="SemiBold" />
18-
<TextBlock Text="Persistent, beautiful, actionable notifications for Windows 11." TextWrapping="Wrap" />
17+
<StackPanel Spacing="4">
18+
<TextBlock Text="ToastDeck" FontSize="30" FontWeight="SemiBold" />
19+
<TextBlock Text="Persistent, beautiful, actionable notifications for Windows 11." TextWrapping="Wrap" Opacity="0.72" />
20+
</StackPanel>
1921

20-
<Border CornerRadius="10" Padding="14" BorderThickness="1" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
22+
<Border CornerRadius="12" Padding="16" BorderThickness="1" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
2123
<StackPanel Spacing="10">
2224
<TextBlock Text="First-run onboarding" FontWeight="SemiBold" />
2325
<TextBlock Text="ToastDeck needs permission to read your Windows notifications so it can show them in a persistent deck. Your notifications stay on this device." TextWrapping="Wrap" />
2426
<Button Content="Request notification permission" Click="RequestPermission_Click" />
2527
</StackPanel>
2628
</Border>
2729

28-
<Border CornerRadius="10" Padding="14" BorderThickness="1" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
29-
<StackPanel Spacing="8">
30-
<TextBlock Text="Settings" FontWeight="SemiBold" />
31-
<TextBlock Text="Listener access status" />
30+
<Border CornerRadius="12" Padding="16" BorderThickness="1" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
31+
<StackPanel Spacing="10">
32+
<TextBlock Text="Listener access status" FontWeight="SemiBold" />
3233
<TextBlock x:Name="ListenerStatusText" Text="Checking..." FontSize="20" FontWeight="SemiBold" />
3334
<Button Content="Sync current notifications" Click="SyncNotifications_Click" />
3435
</StackPanel>
3536
</Border>
3637

37-
<Border CornerRadius="10" Padding="14" BorderThickness="1" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
38-
<StackPanel Spacing="8">
39-
<TextBlock Text="Test Lab" FontWeight="SemiBold" />
40-
<TextBlock Text="Test Lab scenarios are available in the core catalog. Full generation UI lands after listener mode." TextWrapping="Wrap" />
38+
<Border CornerRadius="12" Padding="16" BorderThickness="1" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
39+
<StackPanel Spacing="12">
40+
<TextBlock Text="Deck controls" FontWeight="SemiBold" />
41+
<Button Content="Show deck" Click="ShowDeck_Click" />
42+
<Button Content="Collapse deck" Click="CollapseDeck_Click" />
4143
</StackPanel>
4244
</Border>
4345
</StackPanel>
4446
</ScrollViewer>
4547

46-
<Grid Grid.Column="1" Padding="24">
47-
<Grid.RowDefinitions>
48-
<RowDefinition Height="Auto" />
49-
<RowDefinition Height="*" />
50-
</Grid.RowDefinitions>
48+
<ScrollViewer Grid.Column="1">
49+
<StackPanel Padding="24" Spacing="18">
50+
<StackPanel Spacing="4">
51+
<TextBlock Text="Persistent UI Settings" FontSize="24" FontWeight="SemiBold" />
52+
<TextBlock x:Name="DeckSummaryText" Text="Syncing Windows notifications..." TextWrapping="Wrap" Opacity="0.72" />
53+
</StackPanel>
5154

52-
<StackPanel Spacing="8" Margin="0,0,0,18">
53-
<TextBlock Text="Notification Deck" FontSize="24" FontWeight="SemiBold" />
54-
<TextBlock x:Name="DeckSummaryText" Text="Syncing Windows notifications..." TextWrapping="Wrap" />
55-
</StackPanel>
55+
<Grid ColumnSpacing="16" RowSpacing="14">
56+
<Grid.ColumnDefinitions>
57+
<ColumnDefinition Width="220" />
58+
<ColumnDefinition Width="220" />
59+
</Grid.ColumnDefinitions>
60+
<Grid.RowDefinitions>
61+
<RowDefinition Height="Auto" />
62+
<RowDefinition Height="Auto" />
63+
<RowDefinition Height="Auto" />
64+
<RowDefinition Height="Auto" />
65+
<RowDefinition Height="Auto" />
66+
<RowDefinition Height="Auto" />
67+
<RowDefinition Height="Auto" />
68+
</Grid.RowDefinitions>
69+
70+
<StackPanel Spacing="6">
71+
<TextBlock Text="Position" FontWeight="SemiBold" />
72+
<ComboBox x:Name="AnchorComboBox" SelectionChanged="Setting_SelectionChanged" />
73+
</StackPanel>
74+
75+
<StackPanel Grid.Column="1" Spacing="6">
76+
<TextBlock Text="Monitor" FontWeight="SemiBold" />
77+
<ComboBox x:Name="MonitorComboBox" DisplayMemberPath="DisplayName" SelectionChanged="Setting_SelectionChanged" />
78+
</StackPanel>
79+
80+
<StackPanel Grid.Row="1" Spacing="6">
81+
<TextBlock Text="Theme" FontWeight="SemiBold" />
82+
<ComboBox x:Name="ThemeComboBox" SelectionChanged="Setting_SelectionChanged" />
83+
</StackPanel>
5684

57-
<ListView x:Name="NotificationList" Grid.Row="1" SelectionMode="None">
58-
<ListView.ItemTemplate>
59-
<DataTemplate>
60-
<Border CornerRadius="12" Padding="16" Margin="0,0,0,12" BorderThickness="1" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
61-
<StackPanel Spacing="8">
62-
<Grid ColumnSpacing="12">
63-
<Grid.ColumnDefinitions>
64-
<ColumnDefinition Width="Auto" />
65-
<ColumnDefinition Width="*" />
66-
<ColumnDefinition Width="Auto" />
67-
</Grid.ColumnDefinitions>
68-
<Image Width="32" Height="32" Source="{Binding SourceAppLogoPath}" />
69-
<StackPanel Grid.Column="1">
70-
<TextBlock Text="{Binding SourceAppName}" FontWeight="SemiBold" />
71-
<TextBlock Text="{Binding ReceivedAt}" FontSize="12" Opacity="0.72" />
72-
</StackPanel>
73-
<TextBlock Grid.Column="2" Text="{Binding Severity}" FontWeight="SemiBold" />
74-
</Grid>
75-
<TextBlock Text="{Binding Title}" FontSize="18" FontWeight="SemiBold" TextWrapping="Wrap" />
76-
<TextBlock Text="{Binding BodyPreview}" TextWrapping="Wrap" />
77-
<StackPanel Orientation="Horizontal" Spacing="8">
78-
<Button Content="Dismiss locally" Tag="{Binding}" Click="DismissLocally_Click" />
79-
<Button Content="Dismiss + remove from Windows" Tag="{Binding}" Click="DismissAndRemove_Click" />
80-
</StackPanel>
81-
</StackPanel>
82-
</Border>
83-
</DataTemplate>
84-
</ListView.ItemTemplate>
85-
</ListView>
86-
</Grid>
85+
<StackPanel Grid.Row="1" Grid.Column="1" Spacing="6">
86+
<TextBlock Text="Animation" FontWeight="SemiBold" />
87+
<ComboBox x:Name="AnimationComboBox" SelectionChanged="Setting_SelectionChanged" />
88+
</StackPanel>
89+
90+
<StackPanel Grid.Row="2" Spacing="6">
91+
<TextBlock Text="Card width" FontWeight="SemiBold" />
92+
<NumberBox x:Name="CardWidthBox" Minimum="320" Maximum="560" SmallChange="20" LargeChange="40" ValueChanged="Setting_NumberChanged" />
93+
</StackPanel>
94+
95+
<StackPanel Grid.Row="2" Grid.Column="1" Spacing="6">
96+
<TextBlock Text="Max visible cards" FontWeight="SemiBold" />
97+
<NumberBox x:Name="MaxVisibleCardsBox" Minimum="1" Maximum="10" SmallChange="1" LargeChange="2" ValueChanged="Setting_NumberChanged" />
98+
</StackPanel>
99+
100+
<StackPanel Grid.Row="3" Spacing="6">
101+
<TextBlock Text="Opacity" FontWeight="SemiBold" />
102+
<Slider x:Name="OpacitySlider" Minimum="0.35" Maximum="1" StepFrequency="0.05" ValueChanged="Setting_SliderChanged" />
103+
</StackPanel>
104+
105+
<CheckBox Grid.Row="3" Grid.Column="1" x:Name="CornerBadgeCheckBox" Content="Show corner unread badge" Checked="Setting_CheckChanged" Unchecked="Setting_CheckChanged" />
106+
</Grid>
107+
108+
<Border CornerRadius="12" Padding="16" BorderThickness="1" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
109+
<StackPanel Spacing="10">
110+
<TextBlock Text="Current active notifications" FontWeight="SemiBold" />
111+
<ListView x:Name="NotificationList" SelectionMode="None" MaxHeight="440">
112+
<ListView.ItemTemplate>
113+
<DataTemplate>
114+
<Grid ColumnSpacing="12" Padding="8">
115+
<Grid.ColumnDefinitions>
116+
<ColumnDefinition Width="*" />
117+
<ColumnDefinition Width="Auto" />
118+
</Grid.ColumnDefinitions>
119+
<StackPanel>
120+
<TextBlock Text="{Binding SourceAppName}" FontWeight="SemiBold" />
121+
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" />
122+
<TextBlock Text="{Binding BodyPreview}" TextWrapping="Wrap" Opacity="0.72" MaxLines="2" />
123+
</StackPanel>
124+
<TextBlock Grid.Column="1" Text="{Binding State}" FontWeight="SemiBold" />
125+
</Grid>
126+
</DataTemplate>
127+
</ListView.ItemTemplate>
128+
</ListView>
129+
</StackPanel>
130+
</Border>
131+
</StackPanel>
132+
</ScrollViewer>
87133
</Grid>
88134
</Window>

0 commit comments

Comments
 (0)