Initial integration.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
using Wino.Calendar.ViewModels;
|
||||
using Wino.Mail.WinUI;
|
||||
|
||||
namespace Wino.Mail.Views.Abstract;
|
||||
|
||||
public abstract class CalendarAppShellAbstract : BasePage<CalendarAppShellViewModel> { }
|
||||
@@ -0,0 +1,6 @@
|
||||
using Wino.Calendar.ViewModels;
|
||||
using Wino.Mail.WinUI;
|
||||
|
||||
namespace Wino.Calendar.Views.Abstract;
|
||||
|
||||
public abstract class CalendarPageAbstract : BasePage<CalendarPageViewModel> { }
|
||||
@@ -0,0 +1,5 @@
|
||||
using Wino.Calendar.ViewModels;
|
||||
|
||||
namespace Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
public abstract class EventDetailsPageAbstract : BasePage<EventDetailsPageViewModel> { }
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
using Wino.Mail.WinUI;
|
||||
using Wino.Mail.ViewModels;
|
||||
using Wino.Mail.WinUI;
|
||||
|
||||
namespace Wino.Views.Abstract;
|
||||
|
||||
public abstract class AppShellAbstract : BasePage<AppShellViewModel>
|
||||
public abstract class MailAppShellAbstract : BasePage<MailAppShellViewModel>
|
||||
{
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,66 @@
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Wino.Mail.Views.Abstract;
|
||||
using Wino.Messaging.Client.Calendar;
|
||||
|
||||
namespace Wino.Mail.WinUI.Views.Calendar;
|
||||
|
||||
public sealed partial class CalendarAppShell : CalendarAppShellAbstract,
|
||||
IRecipient<CalendarDisplayTypeChangedMessage>
|
||||
{
|
||||
private const string STATE_HorizontalCalendar = "HorizontalCalendar";
|
||||
private const string STATE_VerticalCalendar = "VerticalCalendar";
|
||||
|
||||
public Frame GetShellFrame() => InnerShellFrame;
|
||||
|
||||
public CalendarAppShell()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Window.Current.SetTitleBar(DragArea);
|
||||
ManageCalendarDisplayType();
|
||||
}
|
||||
|
||||
private void ManageCalendarDisplayType()
|
||||
{
|
||||
// Go to different states based on the display type.
|
||||
if (ViewModel.IsVerticalCalendar)
|
||||
{
|
||||
VisualStateManager.GoToState(this, STATE_VerticalCalendar, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager.GoToState(this, STATE_HorizontalCalendar, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void PreviousDateClicked(object sender, RoutedEventArgs e) => WeakReferenceMessenger.Default.Send(new GoPreviousDateRequestedMessage());
|
||||
|
||||
private void NextDateClicked(object sender, RoutedEventArgs e) => WeakReferenceMessenger.Default.Send(new GoNextDateRequestedMessage());
|
||||
|
||||
public void Receive(CalendarDisplayTypeChangedMessage message)
|
||||
{
|
||||
ManageCalendarDisplayType();
|
||||
}
|
||||
|
||||
//private void ShellFrameContentNavigated(object sender, Microsoft.UI.Xaml.Navigation.NavigationEventArgs e)
|
||||
// => RealAppBar.ShellFrameContent = (e.Content as BasePage).ShellContent;
|
||||
|
||||
//private void AppBarBackButtonClicked(Core.UWP.Controls.WinoAppTitleBar sender, RoutedEventArgs args)
|
||||
// => ViewModel.NavigationService.GoBack();
|
||||
|
||||
protected override void RegisterRecipients()
|
||||
{
|
||||
base.RegisterRecipients();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<CalendarDisplayTypeChangedMessage>(this);
|
||||
}
|
||||
|
||||
protected override void UnregisterRecipients()
|
||||
{
|
||||
base.UnregisterRecipients();
|
||||
|
||||
WeakReferenceMessenger.Default.Unregister<CalendarDisplayTypeChangedMessage>(this);
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using Wino.Calendar.Args;
|
||||
using Wino.Calendar.Views.Abstract;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Messaging.Client.Calendar;
|
||||
|
||||
namespace Wino.Calendar.Views;
|
||||
|
||||
public sealed partial class CalendarPage : CalendarPageAbstract,
|
||||
IRecipient<ScrollToDateMessage>,
|
||||
IRecipient<ScrollToHourMessage>,
|
||||
IRecipient<GoNextDateRequestedMessage>,
|
||||
IRecipient<GoPreviousDateRequestedMessage>
|
||||
{
|
||||
private const int PopupDialogOffset = 12;
|
||||
|
||||
public CalendarPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
NavigationCacheMode = NavigationCacheMode.Enabled;
|
||||
|
||||
ViewModel.DetailsShowCalendarItemChanged += CalendarItemDetailContextChanged;
|
||||
}
|
||||
|
||||
private void CalendarItemDetailContextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (ViewModel.DisplayDetailsCalendarItemViewModel != null)
|
||||
{
|
||||
var control = CalendarControl.GetCalendarItemControl(ViewModel.DisplayDetailsCalendarItemViewModel);
|
||||
|
||||
if (control != null)
|
||||
{
|
||||
EventDetailsPopup.PlacementTarget = control;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(ScrollToHourMessage message) => CalendarControl.NavigateToHour(message.TimeSpan);
|
||||
public void Receive(ScrollToDateMessage message) => CalendarControl.NavigateToDay(message.Date);
|
||||
public void Receive(GoNextDateRequestedMessage message) => CalendarControl.GoNextRange();
|
||||
public void Receive(GoPreviousDateRequestedMessage message) => CalendarControl.GoPreviousRange();
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
base.OnNavigatedTo(e);
|
||||
|
||||
if (e.NavigationMode == NavigationMode.Back) return;
|
||||
|
||||
if (e.Parameter is CalendarPageNavigationArgs args)
|
||||
{
|
||||
if (args.RequestDefaultNavigation)
|
||||
{
|
||||
// Go today.
|
||||
WeakReferenceMessenger.Default.Send(new LoadCalendarMessage(DateTime.Now.Date, CalendarInitInitiative.App));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Go specified date.
|
||||
WeakReferenceMessenger.Default.Send(new LoadCalendarMessage(args.NavigationDate, CalendarInitInitiative.User));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CellSelected(object sender, TimelineCellSelectedArgs e)
|
||||
{
|
||||
// Dismiss event details if exists and cancel the selection.
|
||||
// This is to prevent the event details from being displayed when the user clicks somewhere else.
|
||||
|
||||
if (EventDetailsPopup.IsOpen)
|
||||
{
|
||||
CalendarControl.UnselectActiveTimelineCell();
|
||||
ViewModel.DisplayDetailsCalendarItemViewModel = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ViewModel.SelectedQuickEventDate = e.ClickedDate;
|
||||
|
||||
TeachingTipPositionerGrid.Width = e.CellSize.Width;
|
||||
TeachingTipPositionerGrid.Height = e.CellSize.Height;
|
||||
|
||||
Canvas.SetLeft(TeachingTipPositionerGrid, e.PositionerPoint.X);
|
||||
Canvas.SetTop(TeachingTipPositionerGrid, e.PositionerPoint.Y);
|
||||
|
||||
// Adjust the start and end time in the flyout.
|
||||
var startTime = ViewModel.SelectedQuickEventDate.Value.TimeOfDay;
|
||||
var endTime = startTime.Add(TimeSpan.FromMinutes(30));
|
||||
|
||||
ViewModel.SelectQuickEventTimeRange(startTime, endTime);
|
||||
|
||||
QuickEventPopupDialog.IsOpen = true;
|
||||
}
|
||||
|
||||
private void CellUnselected(object sender, TimelineCellUnselectedArgs e)
|
||||
{
|
||||
QuickEventPopupDialog.IsOpen = false;
|
||||
}
|
||||
|
||||
private void QuickEventAccountSelectorSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
QuickEventAccountSelectorFlyout.Hide();
|
||||
}
|
||||
|
||||
private void QuickEventPopupClosed(object sender, object e)
|
||||
{
|
||||
// Reset the timeline selection when the tip is closed.
|
||||
CalendarControl.ResetTimelineSelection();
|
||||
}
|
||||
|
||||
private void PopupPlacementChanged(object sender, object e)
|
||||
{
|
||||
if (sender is Popup senderPopup)
|
||||
{
|
||||
// When the quick event Popup is positioned for different calendar types,
|
||||
// we must adjust the offset to make sure the tip is not hidden and has nice
|
||||
// spacing from the cell.
|
||||
|
||||
switch (senderPopup.ActualPlacement)
|
||||
{
|
||||
case PopupPlacementMode.Top:
|
||||
senderPopup.VerticalOffset = PopupDialogOffset * -1;
|
||||
break;
|
||||
case PopupPlacementMode.Bottom:
|
||||
senderPopup.VerticalOffset = PopupDialogOffset;
|
||||
break;
|
||||
case PopupPlacementMode.Left:
|
||||
senderPopup.HorizontalOffset = PopupDialogOffset * -1;
|
||||
break;
|
||||
case PopupPlacementMode.Right:
|
||||
senderPopup.HorizontalOffset = PopupDialogOffset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void StartTimeDurationSubmitted(ComboBox sender, ComboBoxTextSubmittedEventArgs args)
|
||||
=> ViewModel.SelectedStartTimeString = args.Text;
|
||||
|
||||
private void EndTimeDurationSubmitted(ComboBox sender, ComboBoxTextSubmittedEventArgs args)
|
||||
=> ViewModel.SelectedEndTimeString = args.Text;
|
||||
|
||||
private void EventDetailsPopupClosed(object sender, object e)
|
||||
{
|
||||
ViewModel.DisplayDetailsCalendarItemViewModel = null;
|
||||
}
|
||||
|
||||
private void CalendarScrolling(object sender, EventArgs e)
|
||||
{
|
||||
// In case of scrolling, we must dismiss the event details dialog.
|
||||
ViewModel.DisplayDetailsCalendarItemViewModel = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<abstract:EventDetailsPageAbstract
|
||||
x:Class="Wino.Calendar.Views.EventDetailsPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Mail.WinUI.Views.Abstract"
|
||||
xmlns:calendar="using:Wino.Core.Domain.Entities.Calendar"
|
||||
xmlns:calendarHelpers="using:Wino.Calendar.Helpers"
|
||||
xmlns:coreControls="using:Wino.Mail.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:domain="using:Wino.Core.Domain"
|
||||
xmlns:helpers="using:Wino.Helpers"
|
||||
xmlns:local="using:Wino.Calendar.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Style="{StaticResource PageStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<Style x:Key="ActionBarElementContainerStackStyle" TargetType="StackPanel">
|
||||
<Setter Property="Spacing" Value="6" />
|
||||
<Setter Property="Padding" Value="10,0,4,0" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Orientation" Value="Horizontal" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="AppBarElementContainer">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="EventDetailsPanelGridStyle" TargetType="Grid">
|
||||
<Setter Property="Padding" Value="0,12" />
|
||||
<Setter Property="Margin" Value="12,0" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="EventDetailsPanelTitleStyle"
|
||||
BasedOn="{StaticResource SubtitleTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="Margin" Value="0,0,0,20" />
|
||||
</Style>
|
||||
</Page.Resources>
|
||||
<Grid Padding="20">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Action Bar -->
|
||||
<Border
|
||||
VerticalAlignment="Top"
|
||||
Background="{ThemeResource WinoContentZoneBackgroud}"
|
||||
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="7">
|
||||
<CommandBar
|
||||
HorizontalAlignment="Left"
|
||||
Background="Transparent"
|
||||
DefaultLabelPosition="Right"
|
||||
IsSticky="True"
|
||||
OverflowButtonVisibility="Auto">
|
||||
<AppBarToggleButton
|
||||
x:Name="ReadOnlyToggle"
|
||||
Content="Read-only event"
|
||||
IsChecked="True" />
|
||||
<AppBarButton Label="{x:Bind domain:Translator.Buttons_Save}">
|
||||
<AppBarButton.Icon>
|
||||
<coreControls:WinoFontIcon Icon="Save" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<AppBarButton Label="{x:Bind domain:Translator.Buttons_Delete}">
|
||||
<AppBarButton.Icon>
|
||||
<coreControls:WinoFontIcon Icon="Delete" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
|
||||
<AppBarSeparator />
|
||||
|
||||
<!-- Join Online -->
|
||||
<AppBarButton Label="Join Online">
|
||||
<AppBarButton.Icon>
|
||||
<coreControls:WinoFontIcon Icon="EventJoinOnline" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
|
||||
<AppBarSeparator />
|
||||
|
||||
<!-- Join Options -->
|
||||
<AppBarButton Label="Accept">
|
||||
<AppBarButton.Icon>
|
||||
<coreControls:WinoFontIcon Foreground="#527257" Icon="EventAccept" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
|
||||
<AppBarButton Label="Tentative">
|
||||
<AppBarButton.Icon>
|
||||
<coreControls:WinoFontIcon Foreground="#805682" Icon="EventTentative" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
|
||||
<AppBarButton Label="Decline">
|
||||
<AppBarButton.Icon>
|
||||
<PathIcon Data="F1 M 10.253906 9.375 L 16.064453 15.185547 C 16.18815 15.309245 16.25 15.455729 16.25 15.625 C 16.25 15.794271 16.18815 15.940756 16.064453 16.064453 C 15.940754 16.188152 15.79427 16.25 15.625 16.25 C 15.455729 16.25 15.309244 16.188152 15.185547 16.064453 L 9.375 10.253906 L 3.564453 16.064453 C 3.440755 16.188152 3.294271 16.25 3.125 16.25 C 2.955729 16.25 2.809245 16.188152 2.685547 16.064453 C 2.561849 15.940756 2.5 15.794271 2.5 15.625 C 2.5 15.455729 2.561849 15.309245 2.685547 15.185547 L 8.496094 9.375 L 2.685547 3.564453 C 2.561849 3.440756 2.5 3.294271 2.5 3.125 C 2.5 2.95573 2.561849 2.809246 2.685547 2.685547 C 2.809245 2.56185 2.955729 2.5 3.125 2.5 C 3.294271 2.5 3.440755 2.56185 3.564453 2.685547 L 9.375 8.496094 L 15.185547 2.685547 C 15.309244 2.56185 15.455729 2.5 15.625 2.5 C 15.79427 2.5 15.940754 2.56185 16.064453 2.685547 C 16.18815 2.809246 16.25 2.95573 16.25 3.125 C 16.25 3.294271 16.18815 3.440756 16.064453 3.564453 Z " Foreground="#d94b4e" />
|
||||
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
|
||||
<AppBarButton Label="Respond">
|
||||
<AppBarButton.Icon>
|
||||
<coreControls:WinoFontIcon Foreground="#805682" Icon="EventRespond" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
|
||||
<AppBarSeparator />
|
||||
|
||||
<!-- Show as -->
|
||||
<AppBarElementContainer>
|
||||
<StackPanel Style="{StaticResource ActionBarElementContainerStackStyle}">
|
||||
<TextBlock VerticalAlignment="Center" Text="Show as" />
|
||||
<ComboBox Width="150" />
|
||||
</StackPanel>
|
||||
</AppBarElementContainer>
|
||||
|
||||
<!-- Reminder -->
|
||||
<AppBarElementContainer>
|
||||
<StackPanel Style="{StaticResource ActionBarElementContainerStackStyle}">
|
||||
<coreControls:WinoFontIcon FontSize="16" Icon="Reminder" />
|
||||
<TextBlock VerticalAlignment="Center" Text="Reminder" />
|
||||
<ComboBox Width="150" />
|
||||
</StackPanel>
|
||||
</AppBarElementContainer>
|
||||
|
||||
<AppBarSeparator />
|
||||
|
||||
<!-- Edit Series -->
|
||||
<AppBarButton Label="Edit Series">
|
||||
<AppBarButton.Icon>
|
||||
<coreControls:WinoFontIcon Icon="EventEditSeries" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
</CommandBar>
|
||||
</Border>
|
||||
|
||||
<!-- Event details -->
|
||||
<ScrollViewer Grid.Row="1">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Details -->
|
||||
<Grid x:Name="DetailsGrid" Style="{StaticResource EventDetailsPanelGridStyle}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Style="{StaticResource EventDetailsPanelTitleStyle}" Text="Details" />
|
||||
|
||||
<Grid Grid.Row="1">
|
||||
<!-- Read-Only Event -->
|
||||
<Grid
|
||||
x:Name="ReadOnlyDetailsGrid"
|
||||
RowSpacing="6"
|
||||
Visibility="{x:Bind ReadOnlyToggle.IsChecked, Mode=OneWay}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="16" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Title -->
|
||||
<TextBlock
|
||||
Style="{StaticResource SubheaderTextBlockStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentEvent.Title, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- Date and Duration -->
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Text="{x:Bind calendarHelpers:CalendarXamlHelpers.GetEventDetailsDateString(ViewModel.CurrentEvent, ViewModel.CurrentSettings), Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- Recurrence Info -->
|
||||
<Grid
|
||||
Grid.Row="3"
|
||||
ColumnSpacing="6"
|
||||
Visibility="{x:Bind ViewModel.CurrentEvent.IsRecurringEvent}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<coreControls:WinoFontIcon FontSize="14" Icon="CalendarEventRepeat" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind calendarHelpers:CalendarXamlHelpers.GetRecurrenceString(ViewModel.CurrentEvent), Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
<!-- Editable Event -->
|
||||
<Grid Visibility="{x:Bind helpers:XamlHelpers.ReverseVisibilityConverter(ReadOnlyDetailsGrid.Visibility), Mode=OneWay}">
|
||||
<TextBlock Text="editing" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- People -->
|
||||
<Grid
|
||||
x:Name="PeopleGrid"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource EventDetailsPanelGridStyle}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Style="{StaticResource EventDetailsPanelTitleStyle}" Text="People" />
|
||||
|
||||
<Grid Grid.Row="1" RowSpacing="12">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<AutoSuggestBox
|
||||
Margin="6,0"
|
||||
BorderThickness="0"
|
||||
PlaceholderText="Invite someone" />
|
||||
|
||||
<ListView
|
||||
Grid.Row="1"
|
||||
IsItemClickEnabled="True"
|
||||
ItemsSource="{x:Bind ViewModel.CurrentEvent.Attendees, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="calendar:CalendarEventAttendee">
|
||||
<Grid Margin="0,6" ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<PersonPicture
|
||||
Width="40"
|
||||
Height="40"
|
||||
DisplayName="{x:Bind Name}" />
|
||||
|
||||
<!-- TODO: Organizer -->
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind Name}" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
FontSize="13"
|
||||
Text="{x:Bind Email}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- Attachments -->
|
||||
<Grid
|
||||
x:Name="AttachmentsGrid"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource EventDetailsPanelGridStyle}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Style="{StaticResource EventDetailsPanelTitleStyle}" Text="Attachments" />
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</abstract:EventDetailsPageAbstract>
|
||||
@@ -0,0 +1,11 @@
|
||||
using Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
namespace Wino.Calendar.Views;
|
||||
|
||||
public sealed partial class EventDetailsPage : EventDetailsPageAbstract
|
||||
{
|
||||
public EventDetailsPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
+30
-24
@@ -1,5 +1,5 @@
|
||||
<abstract:ComposePageAbstract
|
||||
x:Class="Wino.Views.ComposePage"
|
||||
x:Class="Wino.Views.Mail.ComposePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Views.Abstract"
|
||||
@@ -439,31 +439,34 @@
|
||||
</ToggleSplitButton>
|
||||
</AppBarElementContainer>
|
||||
<AppBarElementContainer>
|
||||
<muxc:ToggleSplitButton x:Name="SignatureToggleButton"
|
||||
Margin="8,0,0,0"
|
||||
IsChecked="{x:Bind ViewModel.IsSmimeSignatureEnabled, Mode=TwoWay}"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_EnableSmimeSignature}"
|
||||
IsEnabled="{x:Bind ViewModel.AreCertificatesAvailable, Mode=OneWay}">
|
||||
<muxc:ToggleSplitButton
|
||||
x:Name="SignatureToggleButton"
|
||||
Margin="8,0,0,0"
|
||||
IsChecked="{x:Bind ViewModel.IsSmimeSignatureEnabled, Mode=TwoWay}"
|
||||
IsEnabled="{x:Bind ViewModel.AreCertificatesAvailable, Mode=OneWay}"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_EnableSmimeSignature}">
|
||||
<muxc:ToggleSplitButton.Content>
|
||||
<Viewbox Width="16" Height="16" Margin="0,0,4,0">
|
||||
<PathIcon
|
||||
Data="M15 18c.835.629 1.875 1.001 3 1.001a4.978 4.978 0 0 0 3-.999v3.246a.75.75 0 0 1-1.09.67l-.09-.055L18 20.591l-1.82 1.272a.75.75 0 0 1-1.172-.51l-.007-.105L15 18.001Zm4.25-14.996a2.75 2.75 0 0 1 2.745 2.582l.005.168.001 5.246a5.027 5.027 0 0 0-1.5-1.331L20.5 5.754a1.25 1.25 0 0 0-1.122-1.244l-.128-.006H4.75a1.25 1.25 0 0 0-1.244 1.122l-.006.128v9.5c0 .647.492 1.18 1.122 1.243l.128.007h8.92c.1.172.21.338.33.496v1.004H4.75a2.75 2.75 0 0 1-2.745-2.583L2 15.254v-9.5a2.75 2.75 0 0 1 2.582-2.745l.168-.005h14.5ZM18 10A4 4 0 1 1 18 18 4 4 0 0 1 18 10Zm-6.75 2.5a.75.75 0 0 1 .102 1.493L11.25 14h-4.5a.75.75 0 0 1-.102-1.493l.102-.007h4.5Zm6-5.5a.75.75 0 0 1 .102 1.493l-.102.007H6.75a.75.75 0 0 1-.102-1.493L6.75 7h10.5Z" />
|
||||
<Viewbox
|
||||
Width="16"
|
||||
Height="16"
|
||||
Margin="0,0,4,0">
|
||||
<PathIcon Data="M15 18c.835.629 1.875 1.001 3 1.001a4.978 4.978 0 0 0 3-.999v3.246a.75.75 0 0 1-1.09.67l-.09-.055L18 20.591l-1.82 1.272a.75.75 0 0 1-1.172-.51l-.007-.105L15 18.001Zm4.25-14.996a2.75 2.75 0 0 1 2.745 2.582l.005.168.001 5.246a5.027 5.027 0 0 0-1.5-1.331L20.5 5.754a1.25 1.25 0 0 0-1.122-1.244l-.128-.006H4.75a1.25 1.25 0 0 0-1.244 1.122l-.006.128v9.5c0 .647.492 1.18 1.122 1.243l.128.007h8.92c.1.172.21.338.33.496v1.004H4.75a2.75 2.75 0 0 1-2.745-2.583L2 15.254v-9.5a2.75 2.75 0 0 1 2.582-2.745l.168-.005h14.5ZM18 10A4 4 0 1 1 18 18 4 4 0 0 1 18 10Zm-6.75 2.5a.75.75 0 0 1 .102 1.493L11.25 14h-4.5a.75.75 0 0 1-.102-1.493l.102-.007h4.5Zm6-5.5a.75.75 0 0 1 .102 1.493l-.102.007H6.75a.75.75 0 0 1-.102-1.493L6.75 7h10.5Z" />
|
||||
</Viewbox>
|
||||
</muxc:ToggleSplitButton.Content>
|
||||
<muxc:ToggleSplitButton.Flyout>
|
||||
<Flyout Placement="Bottom">
|
||||
<ListView
|
||||
Width="320"
|
||||
ItemsSource="{x:Bind ViewModel.AvailableCertificates, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.SelectedSigningCertificate, Mode=TwoWay}"
|
||||
Width="320">
|
||||
SelectedItem="{x:Bind ViewModel.SelectedSigningCertificate, Mode=TwoWay}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="x509:X509Certificate2" xmlns:x509="using:System.Security.Cryptography.X509Certificates">
|
||||
<StackPanel Orientation="Vertical" Padding="8,4">
|
||||
<TextBlock Text="{x:Bind Subject}" FontWeight="SemiBold" />
|
||||
<TextBlock Text="{x:Bind Issuer}" FontSize="12" />
|
||||
<DataTemplate xmlns:x509="using:System.Security.Cryptography.X509Certificates" x:DataType="x509:X509Certificate2">
|
||||
<StackPanel Padding="8,4" Orientation="Vertical">
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind Subject}" />
|
||||
<TextBlock FontSize="12" Text="{x:Bind Issuer}" />
|
||||
<TextBlock>
|
||||
<Run Text="{x:Bind domain:Translator.Composer_CertificateExpires}"/>
|
||||
<Run Text="{x:Bind NotAfter, Mode=OneWay}"/>
|
||||
<Run Text="{x:Bind domain:Translator.Composer_CertificateExpires}" />
|
||||
<Run Text="{x:Bind NotAfter, Mode=OneWay}" />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
@@ -474,14 +477,17 @@
|
||||
</muxc:ToggleSplitButton>
|
||||
</AppBarElementContainer>
|
||||
<AppBarElementContainer>
|
||||
<ToggleButton x:Name="EncryptionToggleButton"
|
||||
Margin="8,0,0,0"
|
||||
IsChecked="{x:Bind ViewModel.IsSmimeEncryptionEnabled, Mode=TwoWay}"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_EnableSmimeEncryption}">
|
||||
<ToggleButton
|
||||
x:Name="EncryptionToggleButton"
|
||||
Margin="8,0,0,0"
|
||||
IsChecked="{x:Bind ViewModel.IsSmimeEncryptionEnabled, Mode=TwoWay}"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_EnableSmimeEncryption}">
|
||||
<ToggleButton.Content>
|
||||
<Viewbox Width="16" Height="16" Margin="0,0,4,0">
|
||||
<PathIcon
|
||||
Data="M12 2a4 4 0 0 1 4 4v2h1.75A2.25 2.25 0 0 1 20 10.25v9.5A2.25 2.25 0 0 1 17.75 22H6.25A2.25 2.25 0 0 1 4 19.75v-9.5A2.25 2.25 0 0 1 6.25 8H8V6a4 4 0 0 1 4-4Zm5.75 7.5H6.25a.75.75 0 0 0-.75.75v9.5c0 .414.336.75.75.75h11.5a.75.75 0 0 0 .75-.75v-9.5a.75.75 0 0 0-.75-.75Zm-5.75 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Zm0-10A2.5 2.5 0 0 0 9.5 6v2h5V6A2.5 2.5 0 0 0 12 3.5Z" />
|
||||
<Viewbox
|
||||
Width="16"
|
||||
Height="16"
|
||||
Margin="0,0,4,0">
|
||||
<PathIcon Data="M12 2a4 4 0 0 1 4 4v2h1.75A2.25 2.25 0 0 1 20 10.25v9.5A2.25 2.25 0 0 1 17.75 22H6.25A2.25 2.25 0 0 1 4 19.75v-9.5A2.25 2.25 0 0 1 6.25 8H8V6a4 4 0 0 1 4-4Zm5.75 7.5H6.25a.75.75 0 0 0-.75.75v9.5c0 .414.336.75.75.75h11.5a.75.75 0 0 0 .75-.75v-9.5a.75.75 0 0 0-.75-.75Zm-5.75 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Zm0-10A2.5 2.5 0 0 0 9.5 6v2h5V6A2.5 2.5 0 0 0 12 3.5Z" />
|
||||
</Viewbox>
|
||||
</ToggleButton.Content>
|
||||
</ToggleButton>
|
||||
+4
-4
@@ -20,13 +20,13 @@ using Windows.UI.Core.Preview;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Models.Reader;
|
||||
using Wino.Mail.WinUI.Extensions;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Mail.WinUI.Extensions;
|
||||
using Wino.Messaging.Client.Mails;
|
||||
using Wino.Messaging.Client.Shell;
|
||||
using Wino.Views.Abstract;
|
||||
|
||||
namespace Wino.Views;
|
||||
namespace Wino.Views.Mail;
|
||||
|
||||
public sealed partial class ComposePage : ComposePageAbstract,
|
||||
IRecipient<CreateNewComposeMailRequested>,
|
||||
@@ -308,8 +308,8 @@ public sealed partial class ComposePage : ComposePageAbstract,
|
||||
if (sender is Button senderButton && senderButton.Tag is MessageImportance importance)
|
||||
{
|
||||
ViewModel.SelectedMessageImportance = importance;
|
||||
if (ImportanceSplitButton.Content is Viewbox viewbox &&
|
||||
viewbox.Child is SymbolIcon symbolIcon &&
|
||||
if (ImportanceSplitButton.Content is Viewbox viewbox &&
|
||||
viewbox.Child is SymbolIcon symbolIcon &&
|
||||
senderButton.Content is SymbolIcon contentIcon)
|
||||
{
|
||||
symbolIcon.Symbol = contentIcon.Symbol;
|
||||
@@ -1,5 +1,5 @@
|
||||
<abstract:IdlePageAbstract
|
||||
x:Class="Wino.Views.IdlePage"
|
||||
x:Class="Wino.Views.Mail.IdlePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Views.Abstract"
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using Wino.Views.Abstract;
|
||||
|
||||
namespace Wino.Views;
|
||||
namespace Wino.Views.Mail;
|
||||
|
||||
public sealed partial class IdlePage : IdlePageAbstract
|
||||
{
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<abstract:MailListPageAbstract
|
||||
x:Class="Wino.Views.MailListPage"
|
||||
x:Class="Wino.Views.Mail.MailListPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Views.Abstract"
|
||||
+1
-1
@@ -30,7 +30,7 @@ using Wino.MenuFlyouts.Context;
|
||||
using Wino.Messaging.Client.Mails;
|
||||
using Wino.Views.Abstract;
|
||||
|
||||
namespace Wino.Views;
|
||||
namespace Wino.Views.Mail;
|
||||
|
||||
public sealed partial class MailListPage : MailListPageAbstract,
|
||||
IRecipient<ClearMailSelectionsRequested>,
|
||||
+30
-23
@@ -1,5 +1,5 @@
|
||||
<abstract:MailRenderingPageAbstract
|
||||
x:Class="Wino.Views.MailRenderingPage"
|
||||
x:Class="Wino.Views.Mail.MailRenderingPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Views.Abstract"
|
||||
@@ -209,46 +209,53 @@
|
||||
</HyperlinkButton>
|
||||
|
||||
|
||||
<!-- S/MIME Signed Email Indicator -->
|
||||
<!-- S/MIME Signed Email Indicator -->
|
||||
<HyperlinkButton
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,4"
|
||||
VerticalAlignment="Center"
|
||||
Command="{x:Bind ViewModel.ShowSmimeSigningCertificateInfoCommand}"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.SmimeSignedTooltip}"
|
||||
Visibility="{x:Bind ViewModel.IsSmimeSigned, Mode=OneWay}"
|
||||
Command="{x:Bind ViewModel.ShowSmimeSigningCertificateInfoCommand}">
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto">
|
||||
<Viewbox Width="16" Height="16" Margin="0,0,4,0">
|
||||
<PathIcon
|
||||
Data="M15 18c.835.629 1.875 1.001 3 1.001a4.978 4.978 0 0 0 3-.999v3.246a.75.75 0 0 1-1.09.67l-.09-.055L18 20.591l-1.82 1.272a.75.75 0 0 1-1.172-.51l-.007-.105L15 18.001Zm4.25-14.996a2.75 2.75 0 0 1 2.745 2.582l.005.168.001 5.246a5.027 5.027 0 0 0-1.5-1.331L20.5 5.754a1.25 1.25 0 0 0-1.122-1.244l-.128-.006H4.75a1.25 1.25 0 0 0-1.244 1.122l-.006.128v9.5c0 .647.492 1.18 1.122 1.243l.128.007h8.92c.1.172.21.338.33.496v1.004H4.75a2.75 2.75 0 0 1-2.745-2.583L2 15.254v-9.5a2.75 2.75 0 0 1 2.582-2.745l.168-.005h14.5ZM18 10A4 4 0 1 1 18 18 4 4 0 0 1 18 10Zm-6.75 2.5a.75.75 0 0 1 .102 1.493L11.25 14h-4.5a.75.75 0 0 1-.102-1.493l.102-.007h4.5Zm6-5.5a.75.75 0 0 1 .102 1.493l-.102.007H6.75a.75.75 0 0 1-.102-1.493L6.75 7h10.5Z" />
|
||||
Visibility="{x:Bind ViewModel.IsSmimeSigned, Mode=OneWay}">
|
||||
<Grid
|
||||
Width="Auto"
|
||||
Height="Auto"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Viewbox
|
||||
Width="16"
|
||||
Height="16"
|
||||
Margin="0,0,4,0">
|
||||
<PathIcon Data="M15 18c.835.629 1.875 1.001 3 1.001a4.978 4.978 0 0 0 3-.999v3.246a.75.75 0 0 1-1.09.67l-.09-.055L18 20.591l-1.82 1.272a.75.75 0 0 1-1.172-.51l-.007-.105L15 18.001Zm4.25-14.996a2.75 2.75 0 0 1 2.745 2.582l.005.168.001 5.246a5.027 5.027 0 0 0-1.5-1.331L20.5 5.754a1.25 1.25 0 0 0-1.122-1.244l-.128-.006H4.75a1.25 1.25 0 0 0-1.244 1.122l-.006.128v9.5c0 .647.492 1.18 1.122 1.243l.128.007h8.92c.1.172.21.338.33.496v1.004H4.75a2.75 2.75 0 0 1-2.745-2.583L2 15.254v-9.5a2.75 2.75 0 0 1 2.582-2.745l.168-.005h14.5ZM18 10A4 4 0 1 1 18 18 4 4 0 0 1 18 10Zm-6.75 2.5a.75.75 0 0 1 .102 1.493L11.25 14h-4.5a.75.75 0 0 1-.102-1.493l.102-.007h4.5Zm6-5.5a.75.75 0 0 1 .102 1.493l-.102.007H6.75a.75.75 0 0 1-.102-1.493L6.75 7h10.5Z" />
|
||||
</Viewbox>
|
||||
<muxc:InfoBadge
|
||||
Visibility="{x:Bind ViewModel.SmimeSignaturesInvalid, Mode=OneWay}"
|
||||
Width="8"
|
||||
Height="8"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Style="{ThemeResource CautionIconInfoBadgeStyle}"/>
|
||||
Style="{ThemeResource CautionIconInfoBadgeStyle}"
|
||||
Visibility="{x:Bind ViewModel.SmimeSignaturesInvalid, Mode=OneWay}" />
|
||||
<muxc:InfoBadge
|
||||
Visibility="{x:Bind ViewModel.SmimeSignaturesValid, Mode=OneWay}"
|
||||
Width="8"
|
||||
Height="8"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Style="{ThemeResource SuccessIconInfoBadgeStyle}"/>
|
||||
Style="{ThemeResource SuccessIconInfoBadgeStyle}"
|
||||
Visibility="{x:Bind ViewModel.SmimeSignaturesValid, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</HyperlinkButton>
|
||||
|
||||
<!-- S/MIME Encrypted Email Indicator -->
|
||||
<Viewbox Width="16" Height="16"
|
||||
Grid.Column="3"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,4"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.SmimeEncryptedTooltip}"
|
||||
Visibility="{x:Bind ViewModel.IsSmimeEncrypted, Mode=OneWay}">
|
||||
<PathIcon
|
||||
Data="M12 2a4 4 0 0 1 4 4v2h1.75A2.25 2.25 0 0 1 20 10.25v9.5A2.25 2.25 0 0 1 17.75 22H6.25A2.25 2.25 0 0 1 4 19.75v-9.5A2.25 2.25 0 0 1 6.25 8H8V6a4 4 0 0 1 4-4Zm5.75 7.5H6.25a.75.75 0 0 0-.75.75v9.5c0 .414.336.75.75.75h11.5a.75.75 0 0 0 .75-.75v-9.5a.75.75 0 0 0-.75-.75Zm-5.75 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Zm0-10A2.5 2.5 0 0 0 9.5 6v2h5V6A2.5 2.5 0 0 0 12 3.5Z" />
|
||||
</Viewbox>
|
||||
<!-- S/MIME Encrypted Email Indicator -->
|
||||
<Viewbox
|
||||
Grid.Column="3"
|
||||
Width="16"
|
||||
Height="16"
|
||||
Margin="0,0,0,4"
|
||||
VerticalAlignment="Center"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.SmimeEncryptedTooltip}"
|
||||
Visibility="{x:Bind ViewModel.IsSmimeEncrypted, Mode=OneWay}">
|
||||
<PathIcon Data="M12 2a4 4 0 0 1 4 4v2h1.75A2.25 2.25 0 0 1 20 10.25v9.5A2.25 2.25 0 0 1 17.75 22H6.25A2.25 2.25 0 0 1 4 19.75v-9.5A2.25 2.25 0 0 1 6.25 8H8V6a4 4 0 0 1 4-4Zm5.75 7.5H6.25a.75.75 0 0 0-.75.75v9.5c0 .414.336.75.75.75h11.5a.75.75 0 0 0 .75-.75v-9.5a.75.75 0 0 0-.75-.75Zm-5.75 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Zm0-10A2.5 2.5 0 0 0 9.5 6v2h5V6A2.5 2.5 0 0 0 12 3.5Z" />
|
||||
</Viewbox>
|
||||
</Grid>
|
||||
<CommandBar
|
||||
x:Name="RendererBar"
|
||||
+1
-1
@@ -21,7 +21,7 @@ using Wino.Messaging.Client.Mails;
|
||||
using Wino.Messaging.Client.Shell;
|
||||
using Wino.Views.Abstract;
|
||||
|
||||
namespace Wino.Views;
|
||||
namespace Wino.Views.Mail;
|
||||
|
||||
public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
|
||||
IRecipient<HtmlRenderingRequested>,
|
||||
Reference in New Issue
Block a user