Better creation of context menu items for calendar events.
This commit is contained in:
@@ -1,56 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Wino.Calendar.ViewModels.Messages;
|
||||
using Wino.Calendar.ViewModels.Data;
|
||||
using Wino.Calendar.ViewModels.Messages;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Mail.WinUI;
|
||||
using Wino.Mail.WinUI.Controls;
|
||||
|
||||
namespace Wino.Calendar.Controls;
|
||||
|
||||
public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
||||
{
|
||||
private readonly ICalendarContextMenuItemService _contextMenuItemService;
|
||||
|
||||
public static readonly DependencyProperty ItemProperty = DependencyProperty.Register(nameof(Item), typeof(CalendarItemViewModel), typeof(CalendarItemCommandBarFlyout), new PropertyMetadata(null, new PropertyChangedCallback(OnItemChanged)));
|
||||
|
||||
public CalendarItemViewModel Item
|
||||
{
|
||||
get { return (CalendarItemViewModel)GetValue(ItemProperty); }
|
||||
set { SetValue(ItemProperty, value); }
|
||||
}
|
||||
private readonly RelayCommand<CalendarContextMenuAction> _executeActionCommand;
|
||||
|
||||
public CalendarItemCommandBarFlyout()
|
||||
{
|
||||
_contextMenuItemService = WinoApplication.Current.Services.GetRequiredService<ICalendarContextMenuItemService>();
|
||||
Opening += FlyoutOpening;
|
||||
_executeActionCommand = new RelayCommand<CalendarContextMenuAction>(ExecuteAction);
|
||||
}
|
||||
|
||||
private static void OnItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
public CalendarItemViewModel? Item { get; set; }
|
||||
|
||||
public void SetMenuItems(IReadOnlyList<CalendarContextMenuItem> menuItems)
|
||||
{
|
||||
if (d is CalendarItemCommandBarFlyout flyout)
|
||||
{
|
||||
flyout.UpdateMenuItems();
|
||||
}
|
||||
}
|
||||
|
||||
private void FlyoutOpening(object sender, object e) => UpdateMenuItems();
|
||||
|
||||
private void UpdateMenuItems()
|
||||
{
|
||||
PrimaryCommands.Clear();
|
||||
SecondaryCommands.Clear();
|
||||
|
||||
if (Item?.CalendarItem == null)
|
||||
return;
|
||||
|
||||
var menuItems = _contextMenuItemService.GetContextMenuItems(Item.CalendarItem);
|
||||
ClearMenuItems();
|
||||
|
||||
foreach (var menuItem in menuItems)
|
||||
{
|
||||
@@ -63,12 +37,20 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearMenuItems()
|
||||
{
|
||||
PrimaryCommands.Clear();
|
||||
SecondaryCommands.Clear();
|
||||
}
|
||||
|
||||
private AppBarButton BuildAppBarButton(CalendarContextMenuItem menuItem)
|
||||
{
|
||||
var button = new AppBarButton
|
||||
{
|
||||
Label = GetActionLabel(menuItem.Action),
|
||||
IsEnabled = menuItem.IsEnabled,
|
||||
Command = _executeActionCommand,
|
||||
CommandParameter = menuItem.Action,
|
||||
Icon = new WinoFontIcon
|
||||
{
|
||||
Icon = GetActionIcon(menuItem.Action),
|
||||
@@ -82,10 +64,6 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
||||
PopulateMenuFlyoutItems(flyout.Items, menuItem.Children);
|
||||
button.Flyout = flyout;
|
||||
}
|
||||
else
|
||||
{
|
||||
button.Click += (_, _) => ExecuteAction(menuItem.Action);
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
@@ -110,10 +88,11 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
||||
var flyoutItem = new MenuFlyoutItem
|
||||
{
|
||||
Text = GetActionLabel(menuItem.Action),
|
||||
IsEnabled = menuItem.IsEnabled
|
||||
IsEnabled = menuItem.IsEnabled,
|
||||
Command = _executeActionCommand,
|
||||
CommandParameter = menuItem.Action
|
||||
};
|
||||
|
||||
flyoutItem.Click += (_, _) => ExecuteAction(menuItem.Action);
|
||||
items.Add(flyoutItem);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +100,8 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
||||
|
||||
private void ExecuteAction(CalendarContextMenuAction action)
|
||||
{
|
||||
if (Item == null)
|
||||
// We don't want to trigger any action or hide the flyout if it's a sub menu item.
|
||||
if (Item == null || (action.ShowAs == null && action.ResponseStatus == null && action.TargetType == null))
|
||||
return;
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new CalendarItemContextActionRequestedMessage(Item, action));
|
||||
|
||||
@@ -31,9 +31,10 @@
|
||||
<Grid.ContextFlyout>
|
||||
<local:CalendarItemCommandBarFlyout
|
||||
AlwaysExpanded="True"
|
||||
Item="{x:Bind CalendarItem, Mode=OneWay}"
|
||||
Closed="CalendarItemCommandBarFlyout_Closed"
|
||||
Opening="CalendarItemCommandBarFlyout_Opening"
|
||||
Placement="BottomEdgeAlignedLeft"
|
||||
ShowMode="Transient" />
|
||||
ShowMode="Auto" />
|
||||
</Grid.ContextFlyout>
|
||||
|
||||
|
||||
@@ -80,8 +81,8 @@
|
||||
<muxc:ProgressRing
|
||||
x:Name="BusyRing"
|
||||
Grid.Column="2"
|
||||
Width="14"
|
||||
Height="14"
|
||||
Width="10"
|
||||
Height="10"
|
||||
Margin="0,2,2,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
@@ -111,6 +112,7 @@
|
||||
</StackPanel>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<!-- TODO: Selection of items are disabled temporarily. -->
|
||||
<VisualStateGroup x:Name="SelectionStates">
|
||||
<VisualState x:Name="NonSelected" />
|
||||
<VisualState x:Name="Selected">
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Itenso.TimePeriod;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Wino.Calendar.ViewModels.Data;
|
||||
using Wino.Calendar.ViewModels.Messages;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Mail.WinUI;
|
||||
namespace Wino.Calendar.Controls;
|
||||
|
||||
public sealed partial class CalendarItemControl : UserControl
|
||||
{
|
||||
private readonly ICalendarContextMenuItemService _contextMenuItemService;
|
||||
|
||||
// Single tap has a delay to report double taps properly.
|
||||
private bool isSingleTap = false;
|
||||
|
||||
@@ -44,6 +45,7 @@ public sealed partial class CalendarItemControl : UserControl
|
||||
|
||||
public CalendarItemControl()
|
||||
{
|
||||
_contextMenuItemService = WinoApplication.Current.Services.GetRequiredService<ICalendarContextMenuItemService>();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -141,4 +143,33 @@ public sealed partial class CalendarItemControl : UserControl
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new CalendarItemRightTappedMessage(CalendarItem));
|
||||
}
|
||||
|
||||
private void CalendarItemCommandBarFlyout_Opening(object sender, object e)
|
||||
{
|
||||
if (sender is not CalendarItemCommandBarFlyout flyout)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
flyout.Item = CalendarItem;
|
||||
|
||||
if (CalendarItem?.CalendarItem == null)
|
||||
{
|
||||
flyout.ClearMenuItems();
|
||||
return;
|
||||
}
|
||||
|
||||
flyout.SetMenuItems(_contextMenuItemService.GetContextMenuItems(CalendarItem.CalendarItem));
|
||||
}
|
||||
|
||||
private void CalendarItemCommandBarFlyout_Closed(object sender, object e)
|
||||
{
|
||||
if (sender is not CalendarItemCommandBarFlyout flyout)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
flyout.ClearMenuItems();
|
||||
flyout.Item = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
private CancellationTokenSource? _searchCancellationTokenSource;
|
||||
private long _calendarTypeSelectorChangedToken;
|
||||
private bool _suppressSelectionResetOnPopupClose;
|
||||
private bool _hasAttachedNavigationLifetimeEvents;
|
||||
|
||||
public ObservableCollection<TitleBarSearchSuggestion> SearchSuggestions { get; } = [];
|
||||
|
||||
@@ -42,13 +43,6 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
public CalendarPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
_calendarTypeSelectorChangedToken = CalendarToolbar.RegisterSelectedTypeChanged(CalendarTypeSelectorSelectedTypeChanged);
|
||||
CalendarToolbar.PreviousDateRequested += CalendarToolbarPreviousDateRequested;
|
||||
CalendarToolbar.NextDateRequested += CalendarToolbarNextDateRequested;
|
||||
ViewModel.PropertyChanged += ViewModelPropertyChanged;
|
||||
CalendarShellClient.PropertyChanged += CalendarShellClientPropertyChanged;
|
||||
CalendarShellClient.StatePersistenceService.StatePropertyChanged += CalendarStatePersistenceServiceChanged;
|
||||
Unloaded += CalendarPageUnloaded;
|
||||
RefreshCalendarToolbar();
|
||||
}
|
||||
|
||||
@@ -61,6 +55,8 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
base.OnNavigatedTo(e);
|
||||
Bindings.Update();
|
||||
AttachNavigationLifetimeEvents();
|
||||
RefreshCalendarToolbar();
|
||||
|
||||
if (e.NavigationMode == NavigationMode.Back && ViewModel.RestoreVisibleState())
|
||||
@@ -79,6 +75,12 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
WeakReferenceMessenger.Default.Send(new LoadCalendarMessage(request));
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
base.OnNavigatedFrom(e);
|
||||
DetachNavigationLifetimeEvents();
|
||||
}
|
||||
|
||||
public async Task OnTitleBarSearchTextChangedAsync()
|
||||
{
|
||||
_searchCancellationTokenSource?.Cancel();
|
||||
@@ -272,9 +274,31 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
}
|
||||
}
|
||||
|
||||
private void CalendarPageUnloaded(object sender, RoutedEventArgs e)
|
||||
private void AttachNavigationLifetimeEvents()
|
||||
{
|
||||
if (_hasAttachedNavigationLifetimeEvents)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_calendarTypeSelectorChangedToken = CalendarToolbar.RegisterSelectedTypeChanged(CalendarTypeSelectorSelectedTypeChanged);
|
||||
CalendarToolbar.PreviousDateRequested += CalendarToolbarPreviousDateRequested;
|
||||
CalendarToolbar.NextDateRequested += CalendarToolbarNextDateRequested;
|
||||
ViewModel.PropertyChanged += ViewModelPropertyChanged;
|
||||
CalendarShellClient.PropertyChanged += CalendarShellClientPropertyChanged;
|
||||
CalendarShellClient.StatePersistenceService.StatePropertyChanged += CalendarStatePersistenceServiceChanged;
|
||||
_hasAttachedNavigationLifetimeEvents = true;
|
||||
}
|
||||
|
||||
private void DetachNavigationLifetimeEvents()
|
||||
{
|
||||
if (!_hasAttachedNavigationLifetimeEvents)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CloseQuickEventPopup(clearSelection: true);
|
||||
Bindings.StopTracking();
|
||||
CalendarToolbar.UnregisterSelectedTypeChanged(_calendarTypeSelectorChangedToken);
|
||||
CalendarToolbar.PreviousDateRequested -= CalendarToolbarPreviousDateRequested;
|
||||
CalendarToolbar.NextDateRequested -= CalendarToolbarNextDateRequested;
|
||||
@@ -283,7 +307,8 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
CalendarShellClient.StatePersistenceService.StatePropertyChanged -= CalendarStatePersistenceServiceChanged;
|
||||
_searchCancellationTokenSource?.Cancel();
|
||||
_searchCancellationTokenSource?.Dispose();
|
||||
Unloaded -= CalendarPageUnloaded;
|
||||
_searchCancellationTokenSource = null;
|
||||
_hasAttachedNavigationLifetimeEvents = false;
|
||||
}
|
||||
|
||||
private async void SaveQuickEventClicked(object sender, RoutedEventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user