-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainPage.xaml
More file actions
312 lines (285 loc) · 19.5 KB
/
Copy pathMainPage.xaml
File metadata and controls
312 lines (285 loc) · 19.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:NotesApp.Client.ViewModels"
xmlns:models="clr-namespace:NotesApp.Core.Models;assembly=NotesApp.Core"
xmlns:ai="clr-namespace:NotesApp.Client.Ai"
x:Class="NotesApp.Client.MainPage"
x:DataType="viewmodels:NotesViewModel"
Shell.NavBarIsVisible="False"
BackgroundColor="{DynamicResource Bg}"
Title="Notes">
<ContentPage.Resources>
<!-- Colors come from ThemeManager (Application.Resources) via DynamicResource,
so switching themes at runtime repaints everything below. -->
<!-- Implicit styles so we don't repeat colors on every control. -->
<Style TargetType="Label">
<Setter Property="TextColor" Value="{DynamicResource TextPrimary}" />
</Style>
<Style TargetType="Entry">
<Setter Property="TextColor" Value="{DynamicResource TextPrimary}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="PlaceholderColor" Value="{DynamicResource TextMuted}" />
</Style>
<Style TargetType="Editor">
<Setter Property="TextColor" Value="{DynamicResource TextPrimary}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="PlaceholderColor" Value="{DynamicResource TextMuted}" />
</Style>
<Style TargetType="Button">
<Setter Property="TextColor" Value="{DynamicResource TextPrimary}" />
<Setter Property="BackgroundColor" Value="{DynamicResource RowSelected}" />
<Setter Property="FontSize" Value="13" />
<Setter Property="CornerRadius" Value="6" />
<Setter Property="Padding" Value="14,8" />
<Setter Property="BorderWidth" Value="0" />
</Style>
</ContentPage.Resources>
<!-- Root overlay grid: the 3-pane workspace, the floating AI panel, and the FAB
all share one cell and stack by z-order (later children draw on top). -->
<Grid>
<!-- ============ Workspace: sidebar / list / editor ============ -->
<Grid>
<Grid.ColumnDefinitions>
<!-- Named so code-behind can collapse it to zero width (Notion-style). -->
<ColumnDefinition x:Name="SidebarColumn" Width="210" />
<ColumnDefinition Width="270" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Column 0: Folder sidebar -->
<Grid x:Name="SidebarPane" Grid.Column="0" BackgroundColor="{DynamicResource BgSidebar}"
RowDefinitions="Auto,*,Auto" Padding="12" RowSpacing="10">
<Label Grid.Row="0" Text="NotesApp" FontSize="16" FontAttributes="Bold" Margin="4,4,0,4" />
<CollectionView Grid.Row="1"
ItemsSource="{Binding Folders}"
SelectionMode="Single"
SelectedItem="{Binding SelectedFolder}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Folder">
<Grid Padding="10,9">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Transparent" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{DynamicResource RowSelected}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- TextColor set explicitly: WinUI doesn't apply the page-level
implicit Label style inside CollectionView DataTemplates,
so without this the folder name renders invisible on dark themes. -->
<Label Text="{Binding Name}" FontSize="14" VerticalOptions="Center"
TextColor="{DynamicResource TextPrimary}"
LineBreakMode="TailTruncation" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<VerticalStackLayout Grid.Row="2" Spacing="8">
<Entry Text="{Binding NewFolderName}" Placeholder="New folder name" FontSize="13" />
<Grid ColumnDefinitions="*,*" ColumnSpacing="8">
<Button Grid.Column="0" Text="Add" Command="{Binding AddFolderCommand}" />
<Button Grid.Column="1" Text="Delete" Command="{Binding DeleteFolderCommand}" />
</Grid>
<BoxView HeightRequest="1" Color="{DynamicResource Divider}" Margin="0,4" />
<Label Text="THEME" FontSize="10" FontAttributes="Bold"
TextColor="{DynamicResource TextMuted}" />
<Picker ItemsSource="{Binding Themes}" SelectedItem="{Binding SelectedTheme}"
TextColor="{DynamicResource TextPrimary}"
TitleColor="{DynamicResource TextMuted}" FontSize="13" />
</VerticalStackLayout>
</Grid>
<!-- Column 1: Note list -->
<Grid Grid.Column="1" BackgroundColor="{DynamicResource BgList}"
RowDefinitions="Auto,*" Padding="10" RowSpacing="8">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*" ColumnSpacing="8">
<!-- ☰ collapses/expands the folder sidebar. -->
<Button Grid.Column="0" Text="☰" Command="{Binding ToggleSidebarCommand}"
Padding="10,8" FontSize="14" />
<Button Grid.Column="1" Text="+ New Note" Command="{Binding NewNoteCommand}"
HorizontalOptions="Fill" />
</Grid>
<CollectionView Grid.Row="1"
ItemsSource="{Binding Notes}"
SelectionMode="Single"
SelectedItem="{Binding SelectedNote}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Note">
<Grid Padding="12,10" RowDefinitions="Auto,Auto" RowSpacing="3">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Transparent" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{DynamicResource RowSelected}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- Explicit TextColor for the same reason as the folder label above:
the implicit Label style isn't inherited into this DataTemplate on WinUI.
TitleDisplay falls back to "Untitled" (auto-save allows empty titles). -->
<Label Grid.Row="0" Text="{Binding TitleDisplay}" FontAttributes="Bold"
FontSize="14" TextColor="{DynamicResource TextPrimary}"
LineBreakMode="TailTruncation" />
<Label Grid.Row="1" Text="{Binding Tags}" FontSize="11"
TextColor="{DynamicResource TextMuted}" LineBreakMode="TailTruncation" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
<!-- Column 2: Editor. Tabs on top, then title/tags, the rich WebView
editor fills the middle, actions pinned at the bottom. -->
<Grid Grid.Column="2" BackgroundColor="{DynamicResource Bg}"
RowDefinitions="Auto,Auto,Auto,Auto,*,Auto" Padding="28,16,28,24" RowSpacing="12">
<!-- Open-note tabs (session-only, like browser tabs). -->
<ScrollView Grid.Row="0" Orientation="Horizontal"
HorizontalScrollBarVisibility="Never">
<HorizontalStackLayout BindableLayout.ItemsSource="{Binding OpenTabs}" Spacing="4">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:Note">
<Border StrokeThickness="0" StrokeShape="RoundRectangle 7"
BackgroundColor="Transparent" Padding="0">
<Border.Triggers>
<DataTrigger TargetType="Border" Binding="{Binding IsActiveTab}" Value="True">
<Setter Property="BackgroundColor" Value="{DynamicResource RowSelected}" />
</DataTrigger>
</Border.Triggers>
<HorizontalStackLayout Spacing="0">
<Button Text="{Binding TitleDisplay}" FontSize="12.5"
BackgroundColor="Transparent"
TextColor="{DynamicResource TextPrimary}"
Padding="12,6" CornerRadius="7"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:NotesViewModel}}, Path=SelectTabCommand}"
CommandParameter="{Binding .}" />
<Button Text="✕" FontSize="11"
BackgroundColor="Transparent"
TextColor="{DynamicResource TextMuted}"
Padding="4,6,10,6" CornerRadius="7"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:NotesViewModel}}, Path=CloseTabCommand}"
CommandParameter="{Binding .}" />
</HorizontalStackLayout>
</Border>
</DataTemplate>
</BindableLayout.ItemTemplate>
</HorizontalStackLayout>
</ScrollView>
<Grid Grid.Row="1" ColumnDefinitions="*,Auto" ColumnSpacing="8">
<Entry Grid.Column="0" Text="{Binding EditTitle}" Placeholder="Untitled"
FontSize="28" FontAttributes="Bold" />
<!-- Star toggles Favorites membership for the open note.
☆/★ are text glyphs, so they tint with the theme. -->
<Button Grid.Column="1" Text="☆" FontSize="20" Padding="8,4"
BackgroundColor="Transparent"
TextColor="{DynamicResource TextMuted}"
Command="{Binding ToggleFavoriteCommand}">
<Button.Triggers>
<DataTrigger TargetType="Button" Binding="{Binding SelectedNote.IsFavorite}" Value="True">
<Setter Property="Text" Value="★" />
<Setter Property="TextColor" Value="{DynamicResource Accent}" />
</DataTrigger>
</Button.Triggers>
</Button>
</Grid>
<Entry Grid.Row="2" Text="{Binding EditTags}" Placeholder="tags, comma, separated"
FontSize="13" TextColor="{DynamicResource TextMuted}" />
<BoxView Grid.Row="3" HeightRequest="1" Color="{DynamicResource Divider}" Margin="0,2" />
<!-- No border: the editor blends into the page like Notion's canvas.
Notes auto-save while typing, so there's no Save button. -->
<HybridWebView Grid.Row="4" x:Name="EditorWebView" HybridRoot="editor" Margin="0,4" />
<!-- Right margin keeps the status labels clear of the floating ✦ button. -->
<Grid Grid.Row="5" ColumnDefinitions="Auto,Auto,*,Auto" ColumnSpacing="12"
Margin="0,0,72,0">
<Button Grid.Column="0" Text="Delete" Command="{Binding DeleteNoteCommand}" />
<Button Grid.Column="1" Text="Sync" Command="{Binding SyncCommand}" />
<Label Grid.Column="2" Text="{Binding SyncStatus}" FontSize="12"
TextColor="{DynamicResource TextMuted}" VerticalOptions="Center" HorizontalOptions="End" />
<Label Grid.Column="3" Text="{Binding SaveStatus}" FontSize="12"
TextColor="{DynamicResource TextMuted}" VerticalOptions="Center" />
</Grid>
</Grid>
</Grid>
<!-- ============ Floating AI panel (hidden until toggled) ============ -->
<Border WidthRequest="380" HeightRequest="520"
HorizontalOptions="End" VerticalOptions="End"
Margin="0,0,20,88"
IsVisible="{Binding IsAiOpen}"
BackgroundColor="{DynamicResource BgSidebar}"
Stroke="{DynamicResource Divider}" StrokeThickness="1"
StrokeShape="RoundRectangle 14" Padding="16">
<Grid RowDefinitions="Auto,*" RowSpacing="10">
<Grid Grid.Row="0" ColumnDefinitions="*,Auto">
<Label Grid.Column="0" Text="AI ASSISTANT" FontAttributes="Bold" FontSize="12"
TextColor="{DynamicResource Accent}" VerticalOptions="Center" />
<Button Grid.Column="1" Text="✕" Command="{Binding ToggleAiCommand}"
BackgroundColor="Transparent" Padding="6,0" FontSize="16" />
</Grid>
<ScrollView Grid.Row="1">
<VerticalStackLayout Spacing="12">
<Entry Text="{Binding AiPrompt}"
Placeholder="Ask AI to write or edit... (e.g. 'draft a meeting agenda' or 'make this more concise')"
FontSize="13" />
<FlexLayout Wrap="Wrap" JustifyContent="Start" AlignItems="Center">
<Button Text="Draft New" Command="{Binding DraftCommand}" Margin="0,0,8,8" />
<Button Text="Apply to Note" Command="{Binding ApplyAiCommand}" Margin="0,0,8,8" />
<Button Text="Make Table" Command="{Binding MakeTableCommand}" Margin="0,0,8,8" />
<Button Text="Summarize" Command="{Binding SummarizeCommand}" Margin="0,0,8,8" />
<Button Text="Find Related" Command="{Binding FindRelatedCommand}" Margin="0,0,8,8" />
</FlexLayout>
<Label Text="{Binding AiStatus}" FontSize="12"
TextColor="{DynamicResource TextMuted}" />
<!-- Related notes found via semantic similarity; tap one to open it. -->
<Border Padding="12" StrokeThickness="1" Stroke="{DynamicResource Divider}"
BackgroundColor="{DynamicResource BgList}" StrokeShape="RoundRectangle 8"
IsVisible="{Binding HasRelated}">
<VerticalStackLayout Spacing="8">
<Label Text="RELATED NOTES" FontAttributes="Bold" FontSize="11"
TextColor="{DynamicResource Accent}" />
<VerticalStackLayout BindableLayout.ItemsSource="{Binding RelatedNotes}" Spacing="4">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="ai:RelatedNote">
<Button Text="{Binding Title}" FontSize="13"
HorizontalOptions="Start" BackgroundColor="Transparent"
TextColor="{DynamicResource Accent}" Padding="0"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:NotesViewModel}}, Path=OpenRelatedCommand}"
CommandParameter="{Binding .}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</VerticalStackLayout>
</VerticalStackLayout>
</Border>
<Border Padding="12" StrokeThickness="1" Stroke="{DynamicResource Divider}"
BackgroundColor="{DynamicResource BgList}" StrokeShape="RoundRectangle 8"
IsVisible="{Binding HasAiSummary}">
<VerticalStackLayout Spacing="6">
<Label Text="AI SUMMARY" FontAttributes="Bold" FontSize="11"
TextColor="{DynamicResource Accent}" />
<Label Text="{Binding AiSummary}" FontSize="14" />
</VerticalStackLayout>
</Border>
</VerticalStackLayout>
</ScrollView>
</Grid>
</Border>
<!-- ============ Floating action button toggles the AI panel ============
✦ is a plain text glyph (not an emoji), so unlike ✨ it takes
TextColor and follows the theme instead of rendering yellow. -->
<Button Text="✦" FontSize="24"
WidthRequest="56" HeightRequest="56" CornerRadius="28"
HorizontalOptions="End" VerticalOptions="End" Margin="0,0,20,20"
BackgroundColor="{DynamicResource Accent}"
TextColor="{DynamicResource Bg}"
Command="{Binding ToggleAiCommand}" />
</Grid>
</ContentPage>