Some UI shit.

This commit is contained in:
Burak Kaan Köse
2025-12-27 19:16:24 +01:00
parent 014b5aa671
commit a5227abd40
17 changed files with 218 additions and 126 deletions
@@ -111,6 +111,8 @@ public partial class CalendarAppShellViewModel : CalendarBaseViewModel,
{
base.OnNavigatedTo(mode, parameters);
if (mode == NavigationMode.Back) return;
UpdateDateNavigationHeaderItems();
await InitializeAccountCalendarsAsync();
@@ -161,6 +161,29 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel,
AccountCalendarStateService.CollectiveAccountGroupSelectionStateChanged += AccountCalendarStateCollectivelyChanged;
}
protected override void RegisterRecipients()
{
base.RegisterRecipients();
Messenger.Register<LoadCalendarMessage>(this);
Messenger.Register<CalendarItemDeleted>(this);
Messenger.Register<CalendarSettingsUpdatedMessage>(this);
Messenger.Register<CalendarItemTappedMessage>(this);
Messenger.Register<CalendarItemDoubleTappedMessage>(this);
Messenger.Register<CalendarItemRightTappedMessage>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
Messenger.Unregister<LoadCalendarMessage>(this);
Messenger.Unregister<CalendarItemDeleted>(this);
Messenger.Unregister<CalendarSettingsUpdatedMessage>(this);
Messenger.Unregister<CalendarItemTappedMessage>(this);
Messenger.Unregister<CalendarItemDoubleTappedMessage>(this);
Messenger.Unregister<CalendarItemRightTappedMessage>(this);
}
private void AccountCalendarStateCollectivelyChanged(object sender, GroupedAccountCalendarViewModel e)
=> FilterActiveCalendars(DayRanges);
@@ -255,7 +255,7 @@ public partial class WinoCalendarControl : Control
// Total height of the FlipViewItem is the same as vertical ScrollViewer to position day headers.
await Task.Yield();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
await DispatcherQueue.EnqueueAsync(() =>
{
double hourHeght = 60;
double totalHeight = ActiveScrollViewer.ScrollableHeight;
@@ -104,7 +104,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
{
var flipViewItem = task.Result;
_ = Dispatcher.TryRunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
_ = DispatcherQueue.TryEnqueue(() =>
{
ActiveVerticalScrollViewer = flipViewItem.FindDescendant<ScrollViewer>();
});
@@ -125,7 +125,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
{
var flipViewItem = task.Result;
_ = Dispatcher.TryRunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
_ = DispatcherQueue.TryEnqueue(() =>
{
ActiveCanvas = flipViewItem.FindDescendant<WinoDayTimelineCanvas>();
});
@@ -142,7 +142,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
{
await Task.Yield();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
await DispatcherQueue.EnqueueAsync(() =>
{
// Find the day range that contains the date.
var dayRange = GetItemsSource()?.FirstOrDefault(a => a.CalendarDays.Any(b => b.RepresentingDate.Date == dateTime.Date));
@@ -29,6 +29,7 @@ public class CoreBaseViewModel : ObservableRecipient, INavigationAware
public virtual void OnNavigatedTo(NavigationMode mode, object parameters)
{
UnregisterRecipients();
RegisterRecipients();
}
@@ -220,6 +220,9 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
{
base.OnNavigatedTo(mode, parameters);
if (mode == NavigationMode.Back) return;
await CreateFooterItemsAsync();
await RecreateMenuItemsAsync();
+1 -1
View File
@@ -341,7 +341,7 @@ public partial class App : WinoApplication,
/// Creates the main window without activating it.
/// Used for both normal launch and startup task launch (tray only).
/// </summary>
private void CreateWindow(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
private void CreateWindow(LaunchActivatedEventArgs args)
{
LogActivation("Creating main window.");
@@ -2,6 +2,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Wino.Calendar.Args;
@@ -255,7 +256,7 @@ public partial class WinoCalendarControl : Control
// Total height of the FlipViewItem is the same as vertical ScrollViewer to position day headers.
await Task.Yield();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
await DispatcherQueue.EnqueueAsync(() =>
{
double hourHeght = 60;
double totalHeight = ActiveScrollViewer.ScrollableHeight;
@@ -88,8 +88,6 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
}
return ContainerFromIndex(SelectedIndex) as FlipViewItem;
}
private void UpdateActiveScrollViewer()
@@ -104,7 +102,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
{
var flipViewItem = task.Result;
_ = Dispatcher.TryRunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
_ = DispatcherQueue.TryEnqueue(() =>
{
ActiveVerticalScrollViewer = flipViewItem.FindDescendant<ScrollViewer>();
});
@@ -125,7 +123,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
{
var flipViewItem = task.Result;
_ = Dispatcher.TryRunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
_ = DispatcherQueue.TryEnqueue(() =>
{
ActiveCanvas = flipViewItem.FindDescendant<WinoDayTimelineCanvas>();
});
@@ -142,7 +140,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
{
await Task.Yield();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
await DispatcherQueue.EnqueueAsync(() =>
{
// Find the day range that contains the date.
var dayRange = GetItemsSource()?.FirstOrDefault(a => a.CalendarDays.Any(b => b.RepresentingDate.Date == dateTime.Date));
+8
View File
@@ -9,6 +9,7 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
@@ -45,6 +46,13 @@ public sealed partial class MailAppShell : MailAppShellAbstract,
InitializeComponent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Bindings.StopTracking();
}
private async void ItemDroppedOnFolder(object sender, DragEventArgs e)
{
// Validate package content.
@@ -73,9 +73,9 @@ public partial class AccountCalendarStateService : ObservableObject, IAccountCal
public void ClearGroupedAccountCalendar()
{
foreach (var groupedAccountCalendar in _internalGroupedAccountCalendars)
while (_internalGroupedAccountCalendars.Any())
{
RemoveGroupedAccountCalendar(groupedAccountCalendar);
RemoveGroupedAccountCalendar(_internalGroupedAccountCalendars[0]);
}
}
+33 -6
View File
@@ -87,15 +87,38 @@ public class NavigationService : NavigationServiceBase, INavigationService
if (coreFrame == null) return false;
if (mode == WinoApplicationMode.Mail)
var targetPageType = mode == WinoApplicationMode.Mail ? typeof(MailAppShell) : typeof(CalendarAppShell);
var currentPageType = coreFrame.Content?.GetType();
var transitionInfo = GetNavigationTransitionInfo(NavigationTransitionType.DrillIn);
// If already on the target page, do nothing
if (currentPageType == targetPageType)
return true;
// Check if we can go back to the target page
if (coreFrame.CanGoBack && coreFrame.BackStack.Count > 0)
{
coreFrame.Navigate(typeof(MailAppShell), null);
var previousPage = coreFrame.BackStack[coreFrame.BackStack.Count - 1];
if (previousPage.SourcePageType == targetPageType)
{
coreFrame.GoBack(transitionInfo);
return true;
}
else
{
coreFrame.Navigate(typeof(CalendarAppShell), null);
}
// Check if we can go forward to the target page
if (coreFrame.CanGoForward && coreFrame.ForwardStack.Count > 0)
{
var nextPage = coreFrame.ForwardStack[coreFrame.ForwardStack.Count - 1];
if (nextPage.SourcePageType == targetPageType)
{
coreFrame.GoForward();
return true;
}
}
// Navigate to the target page only if it's not in the navigation stack
coreFrame.Navigate(targetPageType, null, transitionInfo);
return true;
}
@@ -112,7 +135,11 @@ public class NavigationService : NavigationServiceBase, INavigationService
if (shellFrame != null)
{
var currentFrameType = GetCurrentFrameType(ref shellFrame);
bool isCalendarShellActive = shellFrame.Content != null && shellFrame.Content.GetType() == typeof(CalendarAppShell);
if (isCalendarShellActive)
{
return shellFrame.Navigate(pageType, parameter);
}
bool isMailListingPageActive = currentFrameType != null && currentFrameType == typeof(MailListPage);
// Active page is mail list page and we are refreshing the folder.
+3 -2
View File
@@ -25,7 +25,7 @@
<TitleBar
x:Name="ShellTitleBar"
Title="{x:Bind StatePersistanceService.CoreWindowTitle, Mode=OneWay}"
MinHeight="48"
Margin="-2"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
BackRequested="BackButtonClicked"
@@ -35,7 +35,7 @@
PaneToggleRequested="PaneButtonClicked">
<TitleBar.RightHeader>
<Grid>
<controls:Segmented SelectionChanged="SegmentedChanged">
<controls:Segmented x:Name="AppModeSegmentedControl" SelectionChanged="SegmentedChanged">
<controls:SegmentedItem>
<controls:SegmentedItem.Icon>
<PathIcon
@@ -60,6 +60,7 @@
<Frame
x:Name="MainShellFrame"
Grid.Row="1"
CacheSize="2"
Navigated="MainFrameNavigated" />
<notifyicon:TaskbarIcon
+40 -3
View File
@@ -69,9 +69,41 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient
public void HandleAppActivation(LaunchActivatedEventArgs args)
{
// TODO: Handle protocol activations.
// Parse launch arguments to determine the application mode
var launchArguments = args?.Arguments?.ToLower() ?? string.Empty;
MainShellFrame.Navigate(typeof(MailAppShell));
Core.Domain.Enums.WinoApplicationMode targetMode;
if (launchArguments.Contains("wino-calendar"))
{
targetMode = Core.Domain.Enums.WinoApplicationMode.Calendar;
}
else if (launchArguments.Contains("wino-mail"))
{
targetMode = Core.Domain.Enums.WinoApplicationMode.Mail;
}
else if (!string.IsNullOrEmpty(launchArguments))
{
// TODO: Handle other protocol activations (e.g., .eml files)
// For now, default to Mail mode for unknown protocols
targetMode = Core.Domain.Enums.WinoApplicationMode.Mail;
}
else
{
// Default to Mail mode when no arguments provided
targetMode = Core.Domain.Enums.WinoApplicationMode.Mail;
}
// Use NavigationService to change application mode with proper navigation
if (targetMode == Core.Domain.Enums.WinoApplicationMode.Mail)
{
AppModeSegmentedControl.SelectedIndex = 0;
}
else
{
AppModeSegmentedControl.SelectedIndex = 1;
}
}
public Microsoft.UI.Xaml.Controls.TitleBar GetTitleBar() => ShellTitleBar;
@@ -88,7 +120,12 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient
private void MainFrameNavigated(object sender, Microsoft.UI.Xaml.Navigation.NavigationEventArgs e)
{
if (e.Content is BasePage basePage)
// Mail shell has shell content only for mail list page
// Thus, we check if the current content is MailAppShell
if (sender is Frame mainFrame && mainFrame.Content is MailAppShell mailAppShellPage)
ShellTitleBar.Content = mailAppShellPage.TopShellContent;
else if (e.Content is BasePage basePage)
ShellTitleBar.Content = basePage.ShellContent;
}
@@ -3,4 +3,10 @@ using Wino.Mail.WinUI;
namespace Wino.Mail.Views.Abstract;
public abstract class CalendarAppShellAbstract : BasePage<CalendarAppShellViewModel> { }
public abstract class CalendarAppShellAbstract : BasePage<CalendarAppShellViewModel>
{
protected CalendarAppShellAbstract()
{
NavigationCacheMode = Microsoft.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
}
}
@@ -5,4 +5,8 @@ namespace Wino.Views.Abstract;
public abstract class MailAppShellAbstract : BasePage<MailAppShellViewModel>
{
protected MailAppShellAbstract()
{
NavigationCacheMode = Microsoft.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
}
}
@@ -37,60 +37,26 @@
</Style>
</Page.Resources>
<abstract:CalendarAppShellAbstract.ShellContent>
<Grid
x:Name="RootGrid"
Padding="0"
ColumnSpacing="0"
RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="48" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- CoreWindowText="{x:Bind ViewModel.StatePersistenceService.CoreWindowTitle, Mode=OneWay}" -->
<!--<coreControls:WinoAppTitleBar
x:Name="RealAppBar"
Grid.ColumnSpan="2"
BackButtonClicked="AppBarBackButtonClicked"
Canvas.ZIndex="150"
CoreWindowText="Wino Calendar"
IsBackButtonVisible="{x:Bind ViewModel.StatePersistenceService.IsBackButtonVisible, Mode=OneWay}"
IsNavigationPaneOpen="{x:Bind MainSplitView.IsPaneOpen, Mode=TwoWay}"
NavigationViewDisplayMode="{x:Bind helpers:XamlHelpers.NavigationViewDisplayModeConverter(MainSplitView.DisplayMode), Mode=OneWay}"
OpenPaneLength="{x:Bind ViewModel.StatePersistenceService.OpenPaneLength, Mode=OneWay}"
ShrinkShellContentOnExpansion="False"
SystemReserved="180">
<coreControls:WinoAppTitleBar.ShellFrameContent>
<Grid Margin="4,0,0,0" ColumnSpacing="12">
Margin="4,0,0,0"
Background="Transparent"
ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
x:Name="DragArea"
Grid.ColumnSpan="3"
Background="Transparent" />
<Grid x:Name="ShellContentArea" ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="7*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<AutoSuggestBox
x:Name="SearchBox"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
BorderBrush="Transparent"
PlaceholderText="Search" />
<StackPanel
x:Name="NavigationTitleStack"
Grid.Column="1"
Grid.Column="0"
Margin="0,0,12,4"
Orientation="Horizontal"
Spacing="6">
@@ -132,6 +98,14 @@
</FlipView.ItemTemplate>
</calendarControls:CustomCalendarFlipView>
</StackPanel>
<AutoSuggestBox
x:Name="SearchBox"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
BorderBrush="Transparent"
PlaceholderText="Search" />
</Grid>
<calendarControls:WinoCalendarTypeSelectorControl
@@ -142,11 +116,19 @@
SelectedType="{x:Bind ViewModel.StatePersistenceService.CalendarDisplayType, Mode=TwoWay}"
TodayClickedCommand="{x:Bind ViewModel.TodayClickedCommand}" />
</Grid>
</coreControls:WinoAppTitleBar.ShellFrameContent>
</coreControls:WinoAppTitleBar>-->
</abstract:CalendarAppShellAbstract.ShellContent>
<Grid
x:Name="RootGrid"
Padding="0"
ColumnSpacing="0"
RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
Grid.RowSpan="2"
Grid.ColumnSpan="2"
Background="{ThemeResource WinoApplicationBackgroundColor}"
IsHitTestVisible="False">
@@ -164,9 +146,8 @@
IsPaneOpen="{x:Bind ViewModel.PreferencesService.IsNavigationPaneOpened, Mode=TwoWay}"
PaneBackground="Transparent">
<SplitView.Pane>
<Grid Padding="0,20,0,6">
<Grid Padding="0,0,0,6">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />