Calendar item context flyout implementation
This commit is contained in:
@@ -1,11 +1,23 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using System.Collections.Generic;
|
||||
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.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
|
||||
@@ -14,6 +26,11 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
||||
set { SetValue(ItemProperty, value); }
|
||||
}
|
||||
|
||||
public CalendarItemCommandBarFlyout()
|
||||
{
|
||||
_contextMenuItemService = WinoApplication.Current.Services.GetRequiredService<ICalendarContextMenuItemService>();
|
||||
Opening += FlyoutOpening;
|
||||
}
|
||||
|
||||
private static void OnItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
@@ -23,8 +40,148 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
foreach (var menuItem in menuItems)
|
||||
{
|
||||
var appBarButton = BuildAppBarButton(menuItem);
|
||||
|
||||
if (menuItem.IsPrimary)
|
||||
PrimaryCommands.Add(appBarButton);
|
||||
else
|
||||
SecondaryCommands.Add(appBarButton);
|
||||
}
|
||||
}
|
||||
|
||||
private AppBarButton BuildAppBarButton(CalendarContextMenuItem menuItem)
|
||||
{
|
||||
var button = new AppBarButton
|
||||
{
|
||||
Label = GetActionLabel(menuItem.Action),
|
||||
IsEnabled = menuItem.IsEnabled,
|
||||
Icon = new WinoFontIcon
|
||||
{
|
||||
Icon = GetActionIcon(menuItem.Action),
|
||||
FontSize = 16
|
||||
}
|
||||
};
|
||||
|
||||
if (menuItem.HasChildren)
|
||||
{
|
||||
var flyout = new MenuFlyout();
|
||||
PopulateMenuFlyoutItems(flyout.Items, menuItem.Children);
|
||||
button.Flyout = flyout;
|
||||
}
|
||||
else
|
||||
{
|
||||
button.Click += (_, _) => ExecuteAction(menuItem.Action);
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private void PopulateMenuFlyoutItems(IList<MenuFlyoutItemBase> items, IReadOnlyList<CalendarContextMenuItem> menuItems)
|
||||
{
|
||||
foreach (var menuItem in menuItems)
|
||||
{
|
||||
if (menuItem.HasChildren)
|
||||
{
|
||||
var subItem = new MenuFlyoutSubItem
|
||||
{
|
||||
Text = GetActionLabel(menuItem.Action),
|
||||
IsEnabled = menuItem.IsEnabled
|
||||
};
|
||||
|
||||
PopulateMenuFlyoutItems(subItem.Items, menuItem.Children);
|
||||
items.Add(subItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
var flyoutItem = new MenuFlyoutItem
|
||||
{
|
||||
Text = GetActionLabel(menuItem.Action),
|
||||
IsEnabled = menuItem.IsEnabled
|
||||
};
|
||||
|
||||
flyoutItem.Click += (_, _) => ExecuteAction(menuItem.Action);
|
||||
items.Add(flyoutItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteAction(CalendarContextMenuAction action)
|
||||
{
|
||||
if (Item == null)
|
||||
return;
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new CalendarItemContextActionRequestedMessage(Item, action));
|
||||
Hide();
|
||||
}
|
||||
|
||||
private static string GetActionLabel(CalendarContextMenuAction action)
|
||||
{
|
||||
if (action.ShowAs.HasValue)
|
||||
{
|
||||
return action.ShowAs.Value switch
|
||||
{
|
||||
CalendarItemShowAs.Free => Translator.CalendarShowAs_Free,
|
||||
CalendarItemShowAs.Tentative => Translator.CalendarShowAs_Tentative,
|
||||
CalendarItemShowAs.Busy => Translator.CalendarShowAs_Busy,
|
||||
CalendarItemShowAs.OutOfOffice => Translator.CalendarShowAs_OutOfOffice,
|
||||
CalendarItemShowAs.WorkingElsewhere => Translator.CalendarShowAs_WorkingElsewhere,
|
||||
_ => Translator.CalendarShowAs_Busy
|
||||
};
|
||||
}
|
||||
|
||||
if (action.ResponseStatus.HasValue)
|
||||
{
|
||||
return action.ResponseStatus.Value switch
|
||||
{
|
||||
CalendarItemStatus.Accepted => Translator.CalendarEventResponse_Accept,
|
||||
CalendarItemStatus.Tentative => Translator.CalendarEventResponse_Tentative,
|
||||
CalendarItemStatus.Cancelled => Translator.CalendarEventResponse_Decline,
|
||||
_ => Translator.CalendarEventResponse_Accept
|
||||
};
|
||||
}
|
||||
|
||||
if (action.TargetType.HasValue && action.ActionType is CalendarContextMenuActionType.Delete or CalendarContextMenuActionType.ShowAs or CalendarContextMenuActionType.Respond)
|
||||
{
|
||||
return action.TargetType == CalendarEventTargetType.Single
|
||||
? Translator.CalendarContextMenu_ThisEventOnly
|
||||
: Translator.CalendarContextMenu_AllEventsInSeries;
|
||||
}
|
||||
|
||||
return action.ActionType switch
|
||||
{
|
||||
CalendarContextMenuActionType.Open when action.TargetType == CalendarEventTargetType.Series => Translator.CalendarItem_DetailsPopup_ViewSeriesButton,
|
||||
CalendarContextMenuActionType.Open => Translator.Buttons_Open,
|
||||
CalendarContextMenuActionType.JoinOnline => Translator.CalendarItem_DetailsPopup_JoinOnline,
|
||||
CalendarContextMenuActionType.Delete => Translator.Buttons_Delete,
|
||||
CalendarContextMenuActionType.ShowAs => Translator.CalendarEventDetails_ShowAs,
|
||||
CalendarContextMenuActionType.Respond => Translator.CalendarContextMenu_Respond,
|
||||
_ => Translator.Buttons_Open
|
||||
};
|
||||
}
|
||||
|
||||
private static WinoIconGlyph GetActionIcon(CalendarContextMenuAction action)
|
||||
=> action.ActionType switch
|
||||
{
|
||||
CalendarContextMenuActionType.Open when action.TargetType == CalendarEventTargetType.Series => WinoIconGlyph.EventEditSeries,
|
||||
CalendarContextMenuActionType.Open => WinoIconGlyph.OpenInNewWindow,
|
||||
CalendarContextMenuActionType.JoinOnline => WinoIconGlyph.EventJoinOnline,
|
||||
CalendarContextMenuActionType.Delete => WinoIconGlyph.Delete,
|
||||
CalendarContextMenuActionType.ShowAs => WinoIconGlyph.CalendarShowAs,
|
||||
CalendarContextMenuActionType.Respond => WinoIconGlyph.EventRespond,
|
||||
_ => WinoIconGlyph.More
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,12 +29,9 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.ContextFlyout>
|
||||
<local:CalendarItemCommandBarFlyout Placement="Top">
|
||||
<local:CalendarItemCommandBarFlyout.PrimaryCommands>
|
||||
<AppBarButton Icon="Save" Label="save" />
|
||||
<AppBarButton Icon="Delete" Label="Delet" />
|
||||
</local:CalendarItemCommandBarFlyout.PrimaryCommands>
|
||||
</local:CalendarItemCommandBarFlyout>
|
||||
<local:CalendarItemCommandBarFlyout
|
||||
Item="{x:Bind CalendarItem, Mode=OneWay}"
|
||||
Placement="Top" />
|
||||
</Grid.ContextFlyout>
|
||||
|
||||
|
||||
|
||||
@@ -130,7 +130,14 @@ public sealed partial class CalendarItemControl : UserControl
|
||||
|
||||
private void ControlRightTapped(object sender, RightTappedRoutedEventArgs e)
|
||||
{
|
||||
if (CalendarItem == null) return;
|
||||
if (CalendarItem == null)
|
||||
return;
|
||||
|
||||
if (CalendarItem.IsBusy)
|
||||
{
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new CalendarItemRightTappedMessage(CalendarItem));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user