Resolving warnings and treating warnings as errors in WinUI project. (#824)

This commit is contained in:
Burak Kaan Köse
2026-02-27 20:12:43 +01:00
committed by GitHub
parent d2fce5eee1
commit 0e742c7a8f
55 changed files with 336 additions and 269 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
<PackageVersion Include="ColorHashSharp" Version="1.1.0" /> <PackageVersion Include="ColorHashSharp" Version="1.1.0" />
<PackageVersion Include="CommunityToolkit.Common" Version="8.4.0" /> <PackageVersion Include="CommunityToolkit.Common" Version="8.4.0" />
<PackageVersion Include="CommunityToolkit.Diagnostics" Version="8.4.0" /> <PackageVersion Include="CommunityToolkit.Diagnostics" Version="8.4.0" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.1-build.4" />
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.2.251219" /> <PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.251219" /> <PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.251219" /> <PackageVersion Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.251219" />
@@ -89,7 +89,7 @@ public class ImapSynchronizerCalDavConfigurationTests
private static ImapSynchronizer CreateSynchronizer(string appDataFolder, private static ImapSynchronizer CreateSynchronizer(string appDataFolder,
CustomServerInformation serverInformation, CustomServerInformation serverInformation,
IAutoDiscoveryService autoDiscoveryService = null) IAutoDiscoveryService? autoDiscoveryService = null)
{ {
var account = new MailAccount var account = new MailAccount
{ {
@@ -18,13 +18,16 @@ public abstract class ActivationHandler<T> : ActivationHandler
public override async Task HandleAsync(object args) public override async Task HandleAsync(object args)
{ {
await HandleInternalAsync(args as T); if (args is T typedArgs)
{
await HandleInternalAsync(typedArgs);
}
} }
public override bool CanHandle(object args) public override bool CanHandle(object args)
{ {
// CanHandle checks the args is of type you have configured // CanHandle checks the args is of type you have configured
return args is T && CanHandleInternal(args as T); return args is T typedArgs && CanHandleInternal(typedArgs);
} }
// You can override this method to add extra validation on activation args // You can override this method to add extra validation on activation args
+5 -5
View File
@@ -181,7 +181,7 @@ public partial class App : WinoApplication,
else else
{ {
// Normal launch - show and activate the window. // Normal launch - show and activate the window.
MainWindow.Activate(); MainWindow?.Activate();
LogActivation("Window created and activated."); LogActivation("Window created and activated.");
} }
} }
@@ -259,8 +259,8 @@ public partial class App : WinoApplication,
} }
else else
{ {
MainWindow.BringToFront(); MainWindow?.BringToFront();
MainWindow.Activate(); MainWindow?.Activate();
} }
navigationService.ChangeApplicationMode(Core.Domain.Enums.WinoApplicationMode.Calendar); navigationService.ChangeApplicationMode(Core.Domain.Enums.WinoApplicationMode.Calendar);
@@ -300,7 +300,7 @@ public partial class App : WinoApplication,
// App is already running - send message and bring window to front. // App is already running - send message and bring window to front.
navigationService.ChangeApplicationMode(Core.Domain.Enums.WinoApplicationMode.Mail); navigationService.ChangeApplicationMode(Core.Domain.Enums.WinoApplicationMode.Mail);
WeakReferenceMessenger.Default.Send(message); WeakReferenceMessenger.Default.Send(message);
MainWindow.BringToFront(); MainWindow?.BringToFront();
} }
} }
@@ -405,7 +405,7 @@ public partial class App : WinoApplication,
// Initialize theme service after window is created. // Initialize theme service after window is created.
await NewThemeService.InitializeAsync(); await NewThemeService.InitializeAsync();
MainWindow.Activate(); MainWindow?.Activate();
LogActivation("Window created and activated."); LogActivation("Window created and activated.");
} }
@@ -14,9 +14,9 @@ namespace Wino.Mail.WinUI.Controls;
public sealed partial class AccountCreationDialogControl : UserControl, IRecipient<CopyAuthURLRequested> public sealed partial class AccountCreationDialogControl : UserControl, IRecipient<CopyAuthURLRequested>
{ {
private string copyClipboardURL; private string copyClipboardURL = string.Empty;
public event EventHandler CancelClicked; public event EventHandler? CancelClicked;
public AccountCreationDialogState State public AccountCreationDialogState State
{ {
@@ -67,10 +67,10 @@ public sealed partial class AccountCreationDialogControl : UserControl, IRecipie
{ {
if (string.IsNullOrEmpty(copyClipboardURL)) return; if (string.IsNullOrEmpty(copyClipboardURL)) return;
var clipboardService = WinoApplication.Current.Services.GetService<IClipboardService>(); var clipboardService = WinoApplication.Current.Services.GetRequiredService<IClipboardService>();
await clipboardService.CopyClipboardAsync(copyClipboardURL); await clipboardService.CopyClipboardAsync(copyClipboardURL);
} }
private void CancelButtonClicked(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) => CancelClicked?.Invoke(this, null); private void CancelButtonClicked(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) => CancelClicked?.Invoke(this, EventArgs.Empty);
} }
@@ -63,7 +63,7 @@ public partial class CustomCalendarFlipView : FlipView
private void FlipViewSelectionChanged(object sender, SelectionChangedEventArgs e) private void FlipViewSelectionChanged(object sender, SelectionChangedEventArgs e)
=> OnSelectedItemChanged(e.RemovedItems.FirstOrDefault(), e.AddedItems.FirstOrDefault()); => OnSelectedItemChanged(e.RemovedItems.FirstOrDefault(), e.AddedItems.FirstOrDefault());
protected virtual void OnSelectedItemChanged(object oldValue, object newValue) { } protected virtual void OnSelectedItemChanged(object? oldValue, object? newValue) { }
protected override void PrepareContainerForItemOverride(DependencyObject element, object item) protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{ {
@@ -18,11 +18,11 @@ public partial class DayColumnControl : Control
private const string TodayState = nameof(TodayState); private const string TodayState = nameof(TodayState);
private const string NotTodayState = nameof(NotTodayState); private const string NotTodayState = nameof(NotTodayState);
private TextBlock HeaderDateDayText; private TextBlock? HeaderDateDayText;
private TextBlock ColumnHeaderText; private TextBlock? ColumnHeaderText;
private Border IsTodayBorder; private Border? IsTodayBorder;
private ItemsControl AllDayItemsControl; private ItemsControl? AllDayItemsControl;
private CalendarEventCollection _boundEventsCollection; private CalendarEventCollection? _boundEventsCollection;
public CalendarDayModel DayModel public CalendarDayModel DayModel
{ {
@@ -97,7 +97,7 @@ public partial class DayColumnControl : Control
_boundEventsCollection = null; _boundEventsCollection = null;
} }
private void EventsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) private void EventsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{ {
UpdateEventItemsSource(); UpdateEventItemsSource();
} }
@@ -8,7 +8,7 @@ namespace Wino.Calendar.Controls;
public partial class DayHeaderControl : Control public partial class DayHeaderControl : Control
{ {
private const string PART_DayHeaderTextBlock = nameof(PART_DayHeaderTextBlock); private const string PART_DayHeaderTextBlock = nameof(PART_DayHeaderTextBlock);
private TextBlock HeaderTextblock; private TextBlock? HeaderTextblock;
public DayHeaderDisplayType DisplayType public DayHeaderDisplayType DisplayType
{ {
@@ -18,10 +18,10 @@ public partial class WinoCalendarControl : Control
private const string PART_WinoFlipView = nameof(PART_WinoFlipView); private const string PART_WinoFlipView = nameof(PART_WinoFlipView);
private const string PART_IdleGrid = nameof(PART_IdleGrid); private const string PART_IdleGrid = nameof(PART_IdleGrid);
public event EventHandler<TimelineCellSelectedArgs> TimelineCellSelected; public event EventHandler<TimelineCellSelectedArgs>? TimelineCellSelected;
public event EventHandler<TimelineCellUnselectedArgs> TimelineCellUnselected; public event EventHandler<TimelineCellUnselectedArgs>? TimelineCellUnselected;
public event EventHandler ScrollPositionChanging; public event EventHandler? ScrollPositionChanging;
#region Dependency Properties #region Dependency Properties
@@ -66,8 +66,8 @@ public partial class WinoCalendarControl : Control
#endregion #endregion
private WinoCalendarFlipView InternalFlipView; private WinoCalendarFlipView? InternalFlipView;
private Grid IdleGrid; private Grid? IdleGrid;
private ScrollViewer? _previousScrollViewer; private ScrollViewer? _previousScrollViewer;
private WinoDayTimelineCanvas? _previousCanvas; private WinoDayTimelineCanvas? _previousCanvas;
@@ -183,7 +183,7 @@ public partial class WinoCalendarControl : Control
scrollViewer.ViewChanging -= ScrollViewChanging; scrollViewer.ViewChanging -= ScrollViewChanging;
} }
private void ScrollViewChanging(object sender, ScrollViewerViewChangingEventArgs e) private void ScrollViewChanging(object? sender, ScrollViewerViewChangingEventArgs e)
=> ScrollPositionChanging?.Invoke(this, EventArgs.Empty); => ScrollPositionChanging?.Invoke(this, EventArgs.Empty);
private void CalendarSizeChanged(object sender, SizeChangedEventArgs e) private void CalendarSizeChanged(object sender, SizeChangedEventArgs e)
@@ -233,10 +233,10 @@ public partial class WinoCalendarControl : Control
} }
} }
private void ActiveTimelineCellUnselected(object sender, TimelineCellUnselectedArgs e) private void ActiveTimelineCellUnselected(object? sender, TimelineCellUnselectedArgs e)
=> TimelineCellUnselected?.Invoke(this, e); => TimelineCellUnselected?.Invoke(this, e);
private void ActiveTimelineCellSelected(object sender, TimelineCellSelectedArgs e) private void ActiveTimelineCellSelected(object? sender, TimelineCellSelectedArgs e)
=> TimelineCellSelected?.Invoke(this, e); => TimelineCellSelected?.Invoke(this, e);
public void NavigateToDay(DateTime dateTime) => InternalFlipView?.NavigateToDay(dateTime); public void NavigateToDay(DateTime dateTime) => InternalFlipView?.NavigateToDay(dateTime);
@@ -289,6 +289,6 @@ public partial class WinoCalendarControl : Control
public CalendarItemControl GetCalendarItemControl(CalendarItemViewModel calendarItemViewModel) public CalendarItemControl GetCalendarItemControl(CalendarItemViewModel calendarItemViewModel)
{ {
return this.FindDescendants<CalendarItemControl>().FirstOrDefault(a => a.CalendarItem == calendarItemViewModel); return this.FindDescendants<CalendarItemControl>().FirstOrDefault(a => a.CalendarItem == calendarItemViewModel)!;
} }
} }
@@ -81,7 +81,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
UpdateIdleState(); UpdateIdleState();
} }
protected override void OnSelectedItemChanged(object oldValue, object newValue) protected override void OnSelectedItemChanged(object? oldValue, object? newValue)
{ {
base.OnSelectedItemChanged(oldValue, newValue); base.OnSelectedItemChanged(oldValue, newValue);
@@ -101,7 +101,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
} }
} }
private void ItemsSourceUpdated(object sender, NotifyCollectionChangedEventArgs e) private void ItemsSourceUpdated(object? sender, NotifyCollectionChangedEventArgs e)
{ {
UpdateIdleState(); UpdateIdleState();
} }
@@ -205,7 +205,7 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
}); });
} }
private ObservableRangeCollection<DayRangeRenderModel> GetItemsSource() private ObservableRangeCollection<DayRangeRenderModel>? GetItemsSource()
=> ItemsSource as ObservableRangeCollection<DayRangeRenderModel>; => ItemsSource as ObservableRangeCollection<DayRangeRenderModel>;
} }
@@ -120,7 +120,7 @@ public partial class WinoCalendarPanel : Panel
if (!calendarControls.Any()) return base.ArrangeOverride(finalSize); if (!calendarControls.Any()) return base.ArrangeOverride(finalSize);
var events = calendarControls.Select(a => a.Content as CalendarItemViewModel); var events = calendarControls.Select(a => a.Content as CalendarItemViewModel).OfType<ICalendarItem>();
LayoutEvents(events); LayoutEvents(events);
@@ -21,9 +21,9 @@ public partial class WinoCalendarTypeSelectorControl : Control
public static readonly DependencyProperty DisplayDayCountProperty = DependencyProperty.Register(nameof(DisplayDayCount), typeof(int), typeof(WinoCalendarTypeSelectorControl), new PropertyMetadata(0)); public static readonly DependencyProperty DisplayDayCountProperty = DependencyProperty.Register(nameof(DisplayDayCount), typeof(int), typeof(WinoCalendarTypeSelectorControl), new PropertyMetadata(0));
public static readonly DependencyProperty TodayClickedCommandProperty = DependencyProperty.Register(nameof(TodayClickedCommand), typeof(ICommand), typeof(WinoCalendarTypeSelectorControl), new PropertyMetadata(null)); public static readonly DependencyProperty TodayClickedCommandProperty = DependencyProperty.Register(nameof(TodayClickedCommand), typeof(ICommand), typeof(WinoCalendarTypeSelectorControl), new PropertyMetadata(null));
public ICommand TodayClickedCommand public ICommand? TodayClickedCommand
{ {
get { return (ICommand)GetValue(TodayClickedCommandProperty); } get { return (ICommand?)GetValue(TodayClickedCommandProperty); }
set { SetValue(TodayClickedCommandProperty, value); } set { SetValue(TodayClickedCommandProperty, value); }
} }
@@ -39,10 +39,10 @@ public partial class WinoCalendarTypeSelectorControl : Control
set { SetValue(DisplayDayCountProperty, value); } set { SetValue(DisplayDayCountProperty, value); }
} }
private AppBarButton _todayButton; private AppBarButton? _todayButton;
private AppBarToggleButton _dayToggle; private AppBarToggleButton? _dayToggle;
private AppBarToggleButton _weekToggle; private AppBarToggleButton? _weekToggle;
private AppBarToggleButton _monthToggle; private AppBarToggleButton? _monthToggle;
public WinoCalendarTypeSelectorControl() public WinoCalendarTypeSelectorControl()
{ {
@@ -65,16 +65,16 @@ public partial class WinoCalendarTypeSelectorControl : Control
Guard.IsNotNull(_weekToggle, nameof(_weekToggle)); Guard.IsNotNull(_weekToggle, nameof(_weekToggle));
Guard.IsNotNull(_monthToggle, nameof(_monthToggle)); Guard.IsNotNull(_monthToggle, nameof(_monthToggle));
_todayButton.Click += TodayClicked; _todayButton!.Click += TodayClicked;
_dayToggle.Click += (s, e) => { SetSelectedType(CalendarDisplayType.Day); }; _dayToggle!.Click += (s, e) => { SetSelectedType(CalendarDisplayType.Day); };
_weekToggle.Click += (s, e) => { SetSelectedType(CalendarDisplayType.Week); }; _weekToggle!.Click += (s, e) => { SetSelectedType(CalendarDisplayType.Week); };
_monthToggle.Click += (s, e) => { SetSelectedType(CalendarDisplayType.Month); }; _monthToggle!.Click += (s, e) => { SetSelectedType(CalendarDisplayType.Month); };
UpdateToggleButtonStates(); UpdateToggleButtonStates();
} }
private void TodayClicked(object sender, RoutedEventArgs e) => TodayClickedCommand?.Execute(null); private void TodayClicked(object? sender, RoutedEventArgs e) => TodayClickedCommand?.Execute(null);
private void SetSelectedType(CalendarDisplayType type) private void SetSelectedType(CalendarDisplayType type)
{ {
@@ -18,7 +18,7 @@ public partial class WinoCalendarView : Control
public static readonly DependencyProperty HighlightedDateRangeProperty = DependencyProperty.Register(nameof(HighlightedDateRange), typeof(DateRange), typeof(WinoCalendarView), new PropertyMetadata(null, new PropertyChangedCallback(OnHighlightedDateRangeChanged))); public static readonly DependencyProperty HighlightedDateRangeProperty = DependencyProperty.Register(nameof(HighlightedDateRange), typeof(DateRange), typeof(WinoCalendarView), new PropertyMetadata(null, new PropertyChangedCallback(OnHighlightedDateRangeChanged)));
public static readonly DependencyProperty VisibleDateBackgroundProperty = DependencyProperty.Register(nameof(VisibleDateBackground), typeof(Brush), typeof(WinoCalendarView), new PropertyMetadata(null, new PropertyChangedCallback(OnPropertiesChanged))); public static readonly DependencyProperty VisibleDateBackgroundProperty = DependencyProperty.Register(nameof(VisibleDateBackground), typeof(Brush), typeof(WinoCalendarView), new PropertyMetadata(null, new PropertyChangedCallback(OnPropertiesChanged)));
public static readonly DependencyProperty DateClickedCommandProperty = DependencyProperty.Register(nameof(DateClickedCommand), typeof(ICommand), typeof(WinoCalendarView), new PropertyMetadata(null)); public static readonly DependencyProperty DateClickedCommandProperty = DependencyProperty.Register(nameof(DateClickedCommand), typeof(ICommand), typeof(WinoCalendarView), new PropertyMetadata(null));
public static readonly DependencyProperty TodayBackgroundColorProperty = DependencyProperty.Register(nameof(TodayBackgroundColor), typeof(Color), typeof(WinoCalendarView), new PropertyMetadata(null)); public static readonly DependencyProperty TodayBackgroundColorProperty = DependencyProperty.Register(nameof(TodayBackgroundColor), typeof(Color), typeof(WinoCalendarView), new PropertyMetadata(new Color()));
public Color TodayBackgroundColor public Color TodayBackgroundColor
{ {
@@ -30,30 +30,30 @@ public partial class WinoCalendarView : Control
/// Gets or sets the command to execute when a date is picked. /// Gets or sets the command to execute when a date is picked.
/// Unused. /// Unused.
/// </summary> /// </summary>
public ICommand DateClickedCommand public ICommand? DateClickedCommand
{ {
get { return (ICommand)GetValue(DateClickedCommandProperty); } get { return (ICommand?)GetValue(DateClickedCommandProperty); }
set { SetValue(DateClickedCommandProperty, value); } set { SetValue(DateClickedCommandProperty, value); }
} }
/// <summary> /// <summary>
/// Gets or sets the highlighted range of dates. /// Gets or sets the highlighted range of dates.
/// </summary> /// </summary>
public DateRange HighlightedDateRange public DateRange? HighlightedDateRange
{ {
get { return (DateRange)GetValue(HighlightedDateRangeProperty); } get { return (DateRange?)GetValue(HighlightedDateRangeProperty); }
set { SetValue(HighlightedDateRangeProperty, value); } set { SetValue(HighlightedDateRangeProperty, value); }
} }
public Brush VisibleDateBackground public Brush? VisibleDateBackground
{ {
get { return (Brush)GetValue(VisibleDateBackgroundProperty); } get { return (Brush?)GetValue(VisibleDateBackgroundProperty); }
set { SetValue(VisibleDateBackgroundProperty, value); } set { SetValue(VisibleDateBackgroundProperty, value); }
} }
private CalendarView CalendarView; private CalendarView? CalendarView;
public WinoCalendarView() public WinoCalendarView()
{ {
@@ -67,6 +67,7 @@ public partial class WinoCalendarView : Control
CalendarView = GetTemplateChild(PART_CalendarView) as CalendarView; CalendarView = GetTemplateChild(PART_CalendarView) as CalendarView;
Guard.IsNotNull(CalendarView, nameof(CalendarView)); Guard.IsNotNull(CalendarView, nameof(CalendarView));
if (CalendarView == null) return;
CalendarView.SelectedDatesChanged -= InternalCalendarViewSelectionChanged; CalendarView.SelectedDatesChanged -= InternalCalendarViewSelectionChanged;
CalendarView.SelectedDatesChanged += InternalCalendarViewSelectionChanged; CalendarView.SelectedDatesChanged += InternalCalendarViewSelectionChanged;
@@ -92,7 +93,7 @@ public partial class WinoCalendarView : Control
} }
// Reset selection, we don't show selected dates but react to them. // Reset selection, we don't show selected dates but react to them.
CalendarView.SelectedDates.Clear(); CalendarView?.SelectedDates.Clear();
} }
private static void OnPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) private static void OnPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -107,7 +108,7 @@ public partial class WinoCalendarView : Control
// Changing selected dates will trigger the selection changed event. // Changing selected dates will trigger the selection changed event.
// It will behave like user clicked the date. // It will behave like user clicked the date.
public void GoToDay(DateTime dateTime) => CalendarView.SelectedDates.Add(dateTime); public void GoToDay(DateTime dateTime) => CalendarView?.SelectedDates.Add(dateTime);
private static void OnHighlightedDateRangeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) private static void OnHighlightedDateRangeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ {
@@ -17,11 +17,11 @@ namespace Wino.Calendar.Controls;
public partial class WinoDayTimelineCanvas : Control, IDisposable public partial class WinoDayTimelineCanvas : Control, IDisposable
{ {
public event EventHandler<TimelineCellSelectedArgs> TimelineCellSelected; public event EventHandler<TimelineCellSelectedArgs>? TimelineCellSelected;
public event EventHandler<TimelineCellUnselectedArgs> TimelineCellUnselected; public event EventHandler<TimelineCellUnselectedArgs>? TimelineCellUnselected;
private const string PART_InternalCanvas = nameof(PART_InternalCanvas); private const string PART_InternalCanvas = nameof(PART_InternalCanvas);
private SKXamlCanvas Canvas; private SKXamlCanvas? Canvas;
public static readonly DependencyProperty RenderOptionsProperty = DependencyProperty.Register(nameof(RenderOptions), typeof(CalendarRenderOptions), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null, new PropertyChangedCallback(OnRenderingPropertiesChanged))); public static readonly DependencyProperty RenderOptionsProperty = DependencyProperty.Register(nameof(RenderOptions), typeof(CalendarRenderOptions), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null, new PropertyChangedCallback(OnRenderingPropertiesChanged)));
public static readonly DependencyProperty SeperatorColorProperty = DependencyProperty.Register(nameof(SeperatorColor), typeof(SolidColorBrush), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null, new PropertyChangedCallback(OnRenderingPropertiesChanged))); public static readonly DependencyProperty SeperatorColorProperty = DependencyProperty.Register(nameof(SeperatorColor), typeof(SolidColorBrush), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null, new PropertyChangedCallback(OnRenderingPropertiesChanged)));
@@ -31,39 +31,39 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable
public static readonly DependencyProperty SelectedDateTimeProperty = DependencyProperty.Register(nameof(SelectedDateTime), typeof(DateTime?), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedDateTimeChanged))); public static readonly DependencyProperty SelectedDateTimeProperty = DependencyProperty.Register(nameof(SelectedDateTime), typeof(DateTime?), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedDateTimeChanged)));
public static readonly DependencyProperty PositionerUIElementProperty = DependencyProperty.Register(nameof(PositionerUIElement), typeof(UIElement), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null)); public static readonly DependencyProperty PositionerUIElementProperty = DependencyProperty.Register(nameof(PositionerUIElement), typeof(UIElement), typeof(WinoDayTimelineCanvas), new PropertyMetadata(null));
public UIElement PositionerUIElement public UIElement? PositionerUIElement
{ {
get { return (UIElement)GetValue(PositionerUIElementProperty); } get { return (UIElement?)GetValue(PositionerUIElementProperty); }
set { SetValue(PositionerUIElementProperty, value); } set { SetValue(PositionerUIElementProperty, value); }
} }
public CalendarRenderOptions RenderOptions public CalendarRenderOptions? RenderOptions
{ {
get { return (CalendarRenderOptions)GetValue(RenderOptionsProperty); } get { return (CalendarRenderOptions?)GetValue(RenderOptionsProperty); }
set { SetValue(RenderOptionsProperty, value); } set { SetValue(RenderOptionsProperty, value); }
} }
public SolidColorBrush HalfHourSeperatorColor public SolidColorBrush? HalfHourSeperatorColor
{ {
get { return (SolidColorBrush)GetValue(HalfHourSeperatorColorProperty); } get { return (SolidColorBrush?)GetValue(HalfHourSeperatorColorProperty); }
set { SetValue(HalfHourSeperatorColorProperty, value); } set { SetValue(HalfHourSeperatorColorProperty, value); }
} }
public SolidColorBrush SeperatorColor public SolidColorBrush? SeperatorColor
{ {
get { return (SolidColorBrush)GetValue(SeperatorColorProperty); } get { return (SolidColorBrush?)GetValue(SeperatorColorProperty); }
set { SetValue(SeperatorColorProperty, value); } set { SetValue(SeperatorColorProperty, value); }
} }
public SolidColorBrush WorkingHourCellBackgroundColor public SolidColorBrush? WorkingHourCellBackgroundColor
{ {
get { return (SolidColorBrush)GetValue(WorkingHourCellBackgroundColorProperty); } get { return (SolidColorBrush?)GetValue(WorkingHourCellBackgroundColorProperty); }
set { SetValue(WorkingHourCellBackgroundColorProperty, value); } set { SetValue(WorkingHourCellBackgroundColorProperty, value); }
} }
public SolidColorBrush SelectedCellBackgroundBrush public SolidColorBrush? SelectedCellBackgroundBrush
{ {
get { return (SolidColorBrush)GetValue(SelectedCellBackgroundBrushProperty); } get { return (SolidColorBrush?)GetValue(SelectedCellBackgroundBrushProperty); }
set { SetValue(SelectedCellBackgroundBrushProperty, value); } set { SetValue(SelectedCellBackgroundBrushProperty, value); }
} }
@@ -106,9 +106,11 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable
TimelineCellUnselected?.Invoke(this, new TimelineCellUnselectedArgs()); TimelineCellUnselected?.Invoke(this, new TimelineCellUnselectedArgs());
} }
private void OnCanvasPointerPressed(object sender, PointerRoutedEventArgs e) private void OnCanvasPointerPressed(object? sender, PointerRoutedEventArgs e)
{ {
if (RenderOptions == null) return; if (RenderOptions == null) return;
var canvas = Canvas;
if (canvas == null) return;
var hourHeight = RenderOptions.CalendarSettings.HourHeight; var hourHeight = RenderOptions.CalendarSettings.HourHeight;
@@ -119,12 +121,15 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable
PositionerUIElement = this.FindParents().LastOrDefault(a => a is Grid); PositionerUIElement = this.FindParents().LastOrDefault(a => a is Grid);
} }
if (PositionerUIElement == null)
return;
PointerPoint positionerRootPoint = e.GetCurrentPoint(PositionerUIElement); PointerPoint positionerRootPoint = e.GetCurrentPoint(PositionerUIElement);
PointerPoint canvasPointerPoint = e.GetCurrentPoint(Canvas); PointerPoint canvasPointerPoint = e.GetCurrentPoint(canvas);
Point touchPoint = canvasPointerPoint.Position; Point touchPoint = canvasPointerPoint.Position;
var singleDayWidth = (Canvas.ActualWidth / RenderOptions.TotalDayCount); var singleDayWidth = (canvas.ActualWidth / RenderOptions.TotalDayCount);
int day = (int)(touchPoint.X / singleDayWidth); int day = (int)(touchPoint.X / singleDayWidth);
int hour = (int)(touchPoint.Y / hourHeight); int hour = (int)(touchPoint.Y / hourHeight);
@@ -187,9 +192,14 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable
&& SelectedCellBackgroundBrush != null; && SelectedCellBackgroundBrush != null;
} }
private void OnCanvasPaintSurface(object sender, SKPaintSurfaceEventArgs e) private void OnCanvasPaintSurface(object? sender, SKPaintSurfaceEventArgs e)
{ {
if (!CanDrawTimeline()) return; if (!CanDrawTimeline()) return;
var renderOptions = RenderOptions!;
var workingHourCellBackgroundColor = WorkingHourCellBackgroundColor!;
var seperatorColor = SeperatorColor!;
var halfHourSeperatorColor = HalfHourSeperatorColor!;
var selectedCellBackgroundBrush = SelectedCellBackgroundBrush!;
var canvas = e.Surface.Canvas; var canvas = e.Surface.Canvas;
canvas.Clear(SKColors.Transparent); canvas.Clear(SKColors.Transparent);
@@ -203,13 +213,13 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable
// Calculate the width of each rectangle (1 day column) // Calculate the width of each rectangle (1 day column)
// Equal distribution of the whole width. // Equal distribution of the whole width.
double rectWidth = canvasWidth / RenderOptions.TotalDayCount; double rectWidth = canvasWidth / renderOptions.TotalDayCount;
// Calculate the height of each rectangle (1 hour row) // Calculate the height of each rectangle (1 hour row)
double rectHeight = RenderOptions.CalendarSettings.HourHeight; double rectHeight = renderOptions.CalendarSettings.HourHeight;
// Define stroke and fill colors // Define stroke and fill colors
var strokeColor = ToSKColor(SeperatorColor.Color); var strokeColor = ToSKColor(seperatorColor.Color);
float strokeThickness = 0.5f; float strokeThickness = 0.5f;
// Create paints for drawing // Create paints for drawing
@@ -229,18 +239,18 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable
using var dashedPaint = new SKPaint using var dashedPaint = new SKPaint
{ {
Color = ToSKColor(HalfHourSeperatorColor.Color), Color = ToSKColor(halfHourSeperatorColor.Color),
StrokeWidth = strokeThickness, StrokeWidth = strokeThickness,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
PathEffect = SKPathEffect.CreateDash([2f, 2f], 0), PathEffect = SKPathEffect.CreateDash([2f, 2f], 0),
IsAntialias = true IsAntialias = true
}; };
for (int day = 0; day < RenderOptions.TotalDayCount; day++) for (int day = 0; day < renderOptions.TotalDayCount; day++)
{ {
var currentDay = RenderOptions.DateRange.StartDate.AddDays(day); var currentDay = renderOptions.DateRange.StartDate.AddDays(day);
bool isWorkingDay = RenderOptions.CalendarSettings.WorkingDays.Contains(currentDay.DayOfWeek); bool isWorkingDay = renderOptions.CalendarSettings.WorkingDays.Contains(currentDay.DayOfWeek);
// Loop through each hour (rows) // Loop through each hour (rows)
for (int hour = 0; hour < hours; hour++) for (int hour = 0; hour < hours; hour++)
@@ -263,12 +273,12 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable
// Fill another rectangle with the working hour background color // Fill another rectangle with the working hour background color
// This rectangle must be placed with -1 margin to prevent invisible borders of the main rectangle. // This rectangle must be placed with -1 margin to prevent invisible borders of the main rectangle.
if (isWorkingDay && renderTime >= RenderOptions.CalendarSettings.WorkingHourStart && renderTime <= RenderOptions.CalendarSettings.WorkingHourEnd) if (isWorkingDay && renderTime >= renderOptions.CalendarSettings.WorkingHourStart && renderTime <= renderOptions.CalendarSettings.WorkingHourEnd)
{ {
var backgroundRectangle = new SKRect(x + 1, y + 1, x + width - 1, y + height - 1); var backgroundRectangle = new SKRect(x + 1, y + 1, x + width - 1, y + height - 1);
canvas.DrawRect(backgroundRectangle, strokePaint); canvas.DrawRect(backgroundRectangle, strokePaint);
fillPaint.Color = ToSKColor(WorkingHourCellBackgroundColor.Color); fillPaint.Color = ToSKColor(workingHourCellBackgroundColor.Color);
canvas.DrawRect(backgroundRectangle, fillPaint); canvas.DrawRect(backgroundRectangle, fillPaint);
} }
@@ -298,7 +308,7 @@ public partial class WinoDayTimelineCanvas : Control, IDisposable
(float)(day * rectWidth + rectWidth), (float)(day * rectWidth + rectWidth),
(float)(selectedY + selectionRectHeight)); (float)(selectedY + selectionRectHeight));
fillPaint.Color = ToSKColor(SelectedCellBackgroundBrush.Color); fillPaint.Color = ToSKColor(selectedCellBackgroundBrush.Color);
canvas.DrawRect(selectedRectangle, fillPaint); canvas.DrawRect(selectedRectangle, fillPaint);
} }
} }
+1 -1
View File
@@ -71,7 +71,7 @@ public partial class WinoInfoBar : InfoBar
} }
} }
private async void TimerTick(object sender, object e) private async void TimerTick(object? sender, object e)
{ {
_dispatcherTimer.Stop(); _dispatcherTimer.Stop();
_dispatcherTimer.Tick -= TimerTick; _dispatcherTimer.Tick -= TimerTick;
@@ -10,7 +10,7 @@ namespace Wino.Dialogs;
public sealed partial class AccountCreationDialog : ContentDialog, IAccountCreationDialog public sealed partial class AccountCreationDialog : ContentDialog, IAccountCreationDialog
{ {
private TaskCompletionSource<bool> dialogOpened = new TaskCompletionSource<bool>(); private TaskCompletionSource<bool> dialogOpened = new TaskCompletionSource<bool>();
public CancellationTokenSource CancellationTokenSource { get; private set; } public CancellationTokenSource? CancellationTokenSource { get; private set; }
public AccountCreationDialogState State public AccountCreationDialogState State
{ {
@@ -41,7 +41,7 @@ public sealed partial class AccountCreationDialog : ContentDialog, IAccountCreat
// Unregister from closing event. // Unregister from closing event.
Closing -= DialogClosing; Closing -= DialogClosing;
if (cancel && !CancellationTokenSource.IsCancellationRequested) if (cancel && CancellationTokenSource != null && !CancellationTokenSource.IsCancellationRequested)
{ {
CancellationTokenSource.Cancel(); CancellationTokenSource.Cancel();
} }
@@ -6,9 +6,9 @@ namespace Wino.Dialogs;
public sealed partial class AccountPickerDialog : ContentDialog public sealed partial class AccountPickerDialog : ContentDialog
{ {
public MailAccount PickedAccount { get; set; } public MailAccount? PickedAccount { get; set; }
public List<MailAccount> AvailableAccounts { get; set; } public List<MailAccount> AvailableAccounts { get; set; } = [];
public AccountPickerDialog(List<MailAccount> availableAccounts) public AccountPickerDialog(List<MailAccount> availableAccounts)
{ {
@@ -10,21 +10,21 @@ namespace Wino.Dialogs;
public sealed partial class CustomThemeBuilderDialog : ContentDialog public sealed partial class CustomThemeBuilderDialog : ContentDialog
{ {
public byte[] WallpaperData { get; private set; } public byte[] WallpaperData { get; private set; } = Array.Empty<byte>();
public string AccentColor { get; private set; } public string AccentColor { get; private set; } = string.Empty;
private INewThemeService _themeService; private readonly INewThemeService _themeService;
public CustomThemeBuilderDialog() public CustomThemeBuilderDialog()
{ {
InitializeComponent(); InitializeComponent();
_themeService = WinoApplication.Current.Services.GetService<INewThemeService>(); _themeService = WinoApplication.Current.Services.GetRequiredService<INewThemeService>();
} }
private async void ApplyClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) private async void ApplyClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{ {
if (Array.Empty<byte>() == WallpaperData) if (WallpaperData.Length == 0)
return; return;
var deferal = args.GetDeferral(); var deferal = args.GetDeferral();
@@ -45,11 +45,11 @@ public sealed partial class CustomThemeBuilderDialog : ContentDialog
private async void BrowseWallpaperClicked(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) private async void BrowseWallpaperClicked(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{ {
var dialogService = WinoApplication.Current.Services.GetService<IMailDialogService>(); var dialogService = WinoApplication.Current.Services.GetRequiredService<IMailDialogService>();
var pickedFileData = await dialogService.PickWindowsFileContentAsync(".jpg", ".png"); var pickedFileData = await dialogService.PickWindowsFileContentAsync(".jpg", ".png");
if (pickedFileData == Array.Empty<byte>()) return; if (pickedFileData.Length == 0) return;
IsPrimaryButtonEnabled = true; IsPrimaryButtonEnabled = true;
@@ -15,7 +15,7 @@ namespace Wino.Mail.WinUI.Dialogs;
public sealed partial class NewAccountDialog : ContentDialog public sealed partial class NewAccountDialog : ContentDialog
{ {
private Dictionary<SpecialImapProvider, string> helpingLinks = new Dictionary<SpecialImapProvider, string>() private readonly Dictionary<SpecialImapProvider, string> helpingLinks = new Dictionary<SpecialImapProvider, string>()
{ {
{ SpecialImapProvider.iCloud, "https://support.apple.com/en-us/102654" }, { SpecialImapProvider.iCloud, "https://support.apple.com/en-us/102654" },
{ SpecialImapProvider.Yahoo, "http://help.yahoo.com/kb/SLN15241.html" }, { SpecialImapProvider.Yahoo, "http://help.yahoo.com/kb/SLN15241.html" },
@@ -28,9 +28,9 @@ public sealed partial class NewAccountDialog : ContentDialog
public static readonly DependencyProperty SelectedCalendarModeIndexProperty = DependencyProperty.Register(nameof(SelectedCalendarModeIndex), typeof(int), typeof(NewAccountDialog), new PropertyMetadata(0)); public static readonly DependencyProperty SelectedCalendarModeIndexProperty = DependencyProperty.Register(nameof(SelectedCalendarModeIndex), typeof(int), typeof(NewAccountDialog), new PropertyMetadata(0));
public AppColorViewModel SelectedColor public AppColorViewModel? SelectedColor
{ {
get { return (AppColorViewModel)GetValue(SelectedColorProperty); } get { return (AppColorViewModel?)GetValue(SelectedColorProperty); }
set { SetValue(SelectedColorProperty, value); } set { SetValue(SelectedColorProperty, value); }
} }
@@ -43,9 +43,9 @@ public sealed partial class NewAccountDialog : ContentDialog
/// <summary> /// <summary>
/// Gets or sets current selected mail provider in the dialog. /// Gets or sets current selected mail provider in the dialog.
/// </summary> /// </summary>
public ProviderDetail SelectedMailProvider public ProviderDetail? SelectedMailProvider
{ {
get { return (ProviderDetail)GetValue(SelectedMailProviderProperty); } get { return (ProviderDetail?)GetValue(SelectedMailProviderProperty); }
set { SetValue(SelectedMailProviderProperty, value); } set { SetValue(SelectedMailProviderProperty, value); }
} }
@@ -64,9 +64,9 @@ public sealed partial class NewAccountDialog : ContentDialog
// List of available mail providers for now. // List of available mail providers for now.
public List<IProviderDetail> Providers { get; set; } public List<IProviderDetail> Providers { get; set; } = [];
public List<AppColorViewModel> AvailableColors { get; set; } public List<AppColorViewModel> AvailableColors { get; set; } = [];
public List<string> CalendarModeOptions { get; } = public List<string> CalendarModeOptions { get; } =
[ [
Translator.ImapCalDavSettingsPage_CalendarModeCalDav, Translator.ImapCalDavSettingsPage_CalendarModeCalDav,
@@ -75,7 +75,7 @@ public sealed partial class NewAccountDialog : ContentDialog
]; ];
public AccountCreationDialogResult Result = null; public AccountCreationDialogResult? Result = null;
public NewAccountDialog() public NewAccountDialog()
{ {
@@ -113,6 +113,9 @@ public sealed partial class NewAccountDialog : ContentDialog
private void CreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) private void CreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{ {
if (SelectedMailProvider == null)
return;
if (IsSpecialImapServerPartVisible) if (IsSpecialImapServerPartVisible)
{ {
// Special imap detail input. // Special imap detail input.
@@ -198,7 +201,11 @@ public sealed partial class NewAccountDialog : ContentDialog
private async void AppSpecificHelpButtonClicked(object sender, RoutedEventArgs e) private async void AppSpecificHelpButtonClicked(object sender, RoutedEventArgs e)
{ {
var helpUrl = helpingLinks[SelectedMailProvider.SpecialImapProvider]; if (SelectedMailProvider == null ||
!helpingLinks.TryGetValue(SelectedMailProvider.SpecialImapProvider, out var helpUrl))
{
return;
}
await Launcher.LaunchUriAsync(new Uri(helpUrl)); await Launcher.LaunchUriAsync(new Uri(helpUrl));
} }
+1 -1
View File
@@ -25,7 +25,7 @@ public sealed partial class PrintDialog : ContentDialog
/// Initializes the dialog with existing print settings. /// Initializes the dialog with existing print settings.
/// </summary> /// </summary>
/// <param name="printSettings">The initial print settings to load.</param> /// <param name="printSettings">The initial print settings to load.</param>
public PrintDialog(WebView2PrintSettingsModel printSettings = null) public PrintDialog(WebView2PrintSettingsModel printSettings = default!)
{ {
if (printSettings != null) PrintSettings = printSettings; if (printSettings != null) PrintSettings = printSettings;
@@ -76,7 +76,7 @@ public static class AnimationExtensions
public static void Animate(this DependencyObject target, double? from, double to, public static void Animate(this DependencyObject target, double? from, double to,
string propertyPath, int duration = 400, int startTime = 0, string propertyPath, int duration = 400, int startTime = 0,
EasingFunctionBase easing = null, Action completed = null, bool enableDependentAnimation = false) EasingFunctionBase? easing = null, Action? completed = null, bool enableDependentAnimation = false)
{ {
if (easing == null) if (easing == null)
{ {
@@ -17,12 +17,12 @@ public static partial class CompositionExtensions
var compositor = elementVisual.Compositor; var compositor = elementVisual.Compositor;
ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.SetIsTranslationEnabled(element, true);
ScalarKeyFrameAnimation hideOpacityAnimation = null; ScalarKeyFrameAnimation? hideOpacityAnimation = null;
ScalarKeyFrameAnimation showOpacityAnimation = null; ScalarKeyFrameAnimation? showOpacityAnimation = null;
ScalarKeyFrameAnimation hideOffsetAnimation = null; ScalarKeyFrameAnimation? hideOffsetAnimation = null;
ScalarKeyFrameAnimation showOffsetAnimation = null; ScalarKeyFrameAnimation? showOffsetAnimation = null;
Vector2KeyFrameAnimation hideScaleAnimation = null; Vector2KeyFrameAnimation? hideScaleAnimation = null;
Vector2KeyFrameAnimation showeScaleAnimation = null; Vector2KeyFrameAnimation? showeScaleAnimation = null;
if (animateOpacity) if (animateOpacity)
{ {
@@ -119,7 +119,7 @@ public static partial class CompositionExtensions
} }
public static void EnableImplicitAnimation(this UIElement element, VisualPropertyType typeToAnimate, public static void EnableImplicitAnimation(this UIElement element, VisualPropertyType typeToAnimate,
double duration = 800, double delay = 0, CompositionEasingFunction easing = null) double duration = 800, double delay = 0, CompositionEasingFunction? easing = null)
{ {
var visual = element.Visual(); var visual = element.Visual();
var compositor = visual.Compositor; var compositor = visual.Compositor;
@@ -142,7 +142,7 @@ public static partial class CompositionExtensions
} }
public static void EnableImplicitAnimation(this Visual visual, VisualPropertyType typeToAnimate, public static void EnableImplicitAnimation(this Visual visual, VisualPropertyType typeToAnimate,
double duration = 800, double delay = 0, CompositionEasingFunction easing = null) double duration = 800, double delay = 0, CompositionEasingFunction? easing = null)
{ {
var compositor = visual.Compositor; var compositor = visual.Compositor;
@@ -163,8 +163,8 @@ public static partial class CompositionExtensions
visual.ImplicitAnimations = animationCollection; visual.ImplicitAnimations = animationCollection;
} }
private static KeyFrameAnimation CreateAnimationByType(Compositor compositor, VisualPropertyType type, private static KeyFrameAnimation? CreateAnimationByType(Compositor compositor, VisualPropertyType type,
double duration = 800, double delay = 0, CompositionEasingFunction easing = null) double duration = 800, double delay = 0, CompositionEasingFunction? easing = null)
{ {
KeyFrameAnimation animation; KeyFrameAnimation animation;
+4 -11
View File
@@ -22,9 +22,9 @@ public static class UtilExtensions
{ {
var child = VisualTreeHelper.GetChild(parent, i); var child = VisualTreeHelper.GetChild(parent, i);
if (child is FrameworkElement) if (child is FrameworkElement frameworkElement)
{ {
list.Add(child as FrameworkElement); list.Add(frameworkElement);
} }
list.AddRange(Children(child)); list.AddRange(Children(child));
@@ -33,20 +33,13 @@ public static class UtilExtensions
return list; return list;
} }
public static T GetChildByName<T>(this DependencyObject parent, string name) public static T? GetChildByName<T>(this DependencyObject parent, string name) where T : class
{ {
var childControls = Children(parent); var childControls = Children(parent);
var controls = childControls.OfType<FrameworkElement>(); var controls = childControls.OfType<FrameworkElement>();
if (controls == null)
{
return default(T);
}
var control = controls var control = controls
.Where(x => x.Name.Equals(name)) .FirstOrDefault(x => x.Name.Equals(name)) as T;
.Cast<T>()
.First();
return control; return control;
} }
@@ -15,7 +15,7 @@ namespace Wino.Calendar.Helpers;
public static class CalendarXamlHelpers public static class CalendarXamlHelpers
{ {
public static CalendarItemViewModel GetFirstAllDayEvent(CalendarEventCollection collection) public static CalendarItemViewModel GetFirstAllDayEvent(CalendarEventCollection collection)
=> (CalendarItemViewModel)collection.AllDayEvents.FirstOrDefault(); => collection.AllDayEvents.OfType<CalendarItemViewModel>().FirstOrDefault()!;
/// <summary> /// <summary>
/// Returns full date + duration info in Event Details page details title. /// Returns full date + duration info in Event Details page details title.
@@ -6,18 +6,20 @@ namespace Wino.Helpers;
public static class WinoVisualTreeHelper public static class WinoVisualTreeHelper
{ {
public static T GetChildObject<T>(DependencyObject obj, string name) where T : FrameworkElement public static T? GetChildObject<T>(DependencyObject? obj, string name) where T : FrameworkElement
{ {
DependencyObject child = null; if (obj == null) return null;
T grandChild = null;
DependencyObject? child = null;
T? grandChild = null;
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++) for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
{ {
child = VisualTreeHelper.GetChild(obj, i); child = VisualTreeHelper.GetChild(obj, i);
if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name))) if (child is T typedChild && (typedChild.Name == name || string.IsNullOrEmpty(name)))
{ {
return (T)child; return typedChild;
} }
else else
{ {
@@ -31,7 +33,7 @@ public static class WinoVisualTreeHelper
return null; return null;
} }
public static IEnumerable<T> FindDescendants<T>(this DependencyObject depObj) where T : DependencyObject public static IEnumerable<T> FindDescendants<T>(this DependencyObject? depObj) where T : DependencyObject
{ {
if (depObj != null) if (depObj != null)
{ {
+7 -3
View File
@@ -51,7 +51,7 @@ public static class XamlHelpers
public static ListViewSelectionMode BoolToSelectionMode(bool isSelectionMode) => isSelectionMode ? ListViewSelectionMode.Multiple : ListViewSelectionMode.None; public static ListViewSelectionMode BoolToSelectionMode(bool isSelectionMode) => isSelectionMode ? ListViewSelectionMode.Multiple : ListViewSelectionMode.None;
public static string BoolToSelectionModeText(bool isSelectionMode) => isSelectionMode ? Translator.Buttons_Cancel : Translator.Buttons_Multiselect; public static string BoolToSelectionModeText(bool isSelectionMode) => isSelectionMode ? Translator.Buttons_Cancel : Translator.Buttons_Multiselect;
public static Microsoft.UI.Xaml.Media.Imaging.BitmapImage Base64ToBitmapImage(string base64String) public static Microsoft.UI.Xaml.Media.Imaging.BitmapImage? Base64ToBitmapImage(string base64String)
{ {
if (string.IsNullOrEmpty(base64String)) if (string.IsNullOrEmpty(base64String))
return null; return null;
@@ -154,7 +154,7 @@ public static class XamlHelpers
if (groupObject is string stringObject) if (groupObject is string stringObject)
return stringObject; return stringObject;
object dateObject = null; object? dateObject = null;
// From regular mail header template // From regular mail header template
if (groupObject is DateTime groupedDate) if (groupObject is DateTime groupedDate)
@@ -180,7 +180,7 @@ public static class XamlHelpers
} }
else else
return dateObject.ToString(); return dateObject.ToString() ?? string.Empty;
} }
return Translator.UnknownDateHeader; return Translator.UnknownDateHeader;
@@ -321,6 +321,10 @@ public static class XamlHelpers
"xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" + "xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" +
"<Path.Data>" + pathMarkup + "</Path.Data></Path>"; "<Path.Data>" + pathMarkup + "</Path.Data></Path>";
var path = XamlReader.Load(xaml) as Microsoft.UI.Xaml.Shapes.Path; var path = XamlReader.Load(xaml) as Microsoft.UI.Xaml.Shapes.Path;
if (path?.Data == null)
{
return new PathGeometry();
}
Geometry geometry = path.Data; Geometry geometry = path.Data;
path.Data = null; path.Data = null;
@@ -17,7 +17,7 @@ public class PrintDialogViewModel : INotifyPropertyChanged
private bool _isCustomPageRange = false; private bool _isCustomPageRange = false;
private WebView2PrintSettingsModel _printSettings = new(); private WebView2PrintSettingsModel _printSettings = new();
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
public PrintDialogViewModel() public PrintDialogViewModel()
{ {
@@ -208,7 +208,7 @@ public class PrintDialogViewModel : INotifyPropertyChanged
/// Initializes the dialog with the provided print settings. /// Initializes the dialog with the provided print settings.
/// </summary> /// </summary>
/// <param name="printSettings">The initial print settings.</param> /// <param name="printSettings">The initial print settings.</param>
public void Initialize(WebView2PrintSettingsModel printSettings = null) public void Initialize(WebView2PrintSettingsModel printSettings = default!)
{ {
if (printSettings != null) if (printSettings != null)
{ {
@@ -237,7 +237,7 @@ public class PrintDialogViewModel : INotifyPropertyChanged
} }
} }
private void OnPrintSettingsChanged(object sender, PropertyChangedEventArgs e) private void OnPrintSettingsChanged(object? sender, PropertyChangedEventArgs e)
{ {
if (e.PropertyName == nameof(WebView2PrintSettingsModel.ScaleFactor)) if (e.PropertyName == nameof(WebView2PrintSettingsModel.ScaleFactor))
{ {
@@ -6,9 +6,9 @@ namespace Wino.Mail.WinUI.Selectors;
public partial class AppThemePreviewTemplateSelector : DataTemplateSelector public partial class AppThemePreviewTemplateSelector : DataTemplateSelector
{ {
public DataTemplate SystemThemeTemplate { get; set; } public DataTemplate SystemThemeTemplate { get; set; } = null!;
public DataTemplate PreDefinedThemeTemplate { get; set; } public DataTemplate PreDefinedThemeTemplate { get; set; } = null!;
public DataTemplate CustomAppTemplate { get; set; } public DataTemplate CustomAppTemplate { get; set; } = null!;
protected override DataTemplate SelectTemplateCore(object item) protected override DataTemplate SelectTemplateCore(object item)
{ {
@@ -19,6 +19,6 @@ public partial class AppThemePreviewTemplateSelector : DataTemplateSelector
else if (item is CustomAppTheme) else if (item is CustomAppTheme)
return CustomAppTemplate; return CustomAppTemplate;
return base.SelectTemplateCore(item); return base.SelectTemplateCore(item) ?? SystemThemeTemplate;
} }
} }
@@ -10,11 +10,11 @@ namespace Wino.Selectors;
/// </summary> /// </summary>
public partial class CalendarItemShowAsStripeTemplateSelector : DataTemplateSelector public partial class CalendarItemShowAsStripeTemplateSelector : DataTemplateSelector
{ {
public DataTemplate FreeTemplate { get; set; } public DataTemplate FreeTemplate { get; set; } = null!;
public DataTemplate TentativeTemplate { get; set; } public DataTemplate TentativeTemplate { get; set; } = null!;
public DataTemplate BusyTemplate { get; set; } public DataTemplate BusyTemplate { get; set; } = null!;
public DataTemplate OutOfOfficeTemplate { get; set; } public DataTemplate OutOfOfficeTemplate { get; set; } = null!;
public DataTemplate WorkingElsewhereTemplate { get; set; } public DataTemplate WorkingElsewhereTemplate { get; set; } = null!;
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{ {
@@ -31,6 +31,6 @@ public partial class CalendarItemShowAsStripeTemplateSelector : DataTemplateSele
}; };
} }
return base.SelectTemplateCore(item, container); return base.SelectTemplateCore(item, container) ?? BusyTemplate;
} }
} }
@@ -7,14 +7,14 @@ namespace Wino.Mail.WinUI.Selectors;
public partial class CustomWinoMessageDialogIconSelector : DataTemplateSelector public partial class CustomWinoMessageDialogIconSelector : DataTemplateSelector
{ {
public DataTemplate InfoIconTemplate { get; set; } public DataTemplate InfoIconTemplate { get; set; } = null!;
public DataTemplate WarningIconTemplate { get; set; } public DataTemplate WarningIconTemplate { get; set; } = null!;
public DataTemplate QuestionIconTemplate { get; set; } public DataTemplate QuestionIconTemplate { get; set; } = null!;
public DataTemplate ErrorIconTemplate { get; set; } public DataTemplate ErrorIconTemplate { get; set; } = null!;
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{ {
if (item == null) return null; if (item == null) return InfoIconTemplate;
if (item is WinoCustomMessageDialogIcon icon) if (item is WinoCustomMessageDialogIcon icon)
{ {
@@ -32,6 +32,6 @@ public partial class CustomWinoMessageDialogIconSelector : DataTemplateSelector
throw new Exception("Unknown custom message dialog icon."); throw new Exception("Unknown custom message dialog icon.");
} }
} }
return base.SelectTemplateCore(item, container); return base.SelectTemplateCore(item, container) ?? InfoIconTemplate;
} }
} }
@@ -6,16 +6,16 @@ namespace Wino.Mail.WinUI.Selectors;
public partial class FileAttachmentTypeSelector : DataTemplateSelector public partial class FileAttachmentTypeSelector : DataTemplateSelector
{ {
public DataTemplate None { get; set; } public DataTemplate None { get; set; } = null!;
public DataTemplate Executable { get; set; } public DataTemplate Executable { get; set; } = null!;
public DataTemplate Image { get; set; } public DataTemplate Image { get; set; } = null!;
public DataTemplate Audio { get; set; } public DataTemplate Audio { get; set; } = null!;
public DataTemplate Video { get; set; } public DataTemplate Video { get; set; } = null!;
public DataTemplate PDF { get; set; } public DataTemplate PDF { get; set; } = null!;
public DataTemplate HTML { get; set; } public DataTemplate HTML { get; set; } = null!;
public DataTemplate RarArchive { get; set; } public DataTemplate RarArchive { get; set; } = null!;
public DataTemplate Archive { get; set; } public DataTemplate Archive { get; set; } = null!;
public DataTemplate Other { get; set; } public DataTemplate Other { get; set; } = null!;
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{ {
@@ -6,23 +6,23 @@ namespace Wino.Mail.WinUI.Selectors;
public partial class NavigationMenuTemplateSelector : DataTemplateSelector public partial class NavigationMenuTemplateSelector : DataTemplateSelector
{ {
public DataTemplate MenuItemTemplate { get; set; } public DataTemplate MenuItemTemplate { get; set; } = null!;
public DataTemplate ContactsMenuItemTemplate { get; set; } public DataTemplate ContactsMenuItemTemplate { get; set; } = null!;
public DataTemplate AccountManagementTemplate { get; set; } public DataTemplate AccountManagementTemplate { get; set; } = null!;
public DataTemplate ClickableAccountMenuTemplate { get; set; } public DataTemplate ClickableAccountMenuTemplate { get; set; } = null!;
public DataTemplate MergedAccountTemplate { get; set; } public DataTemplate MergedAccountTemplate { get; set; } = null!;
public DataTemplate MergedAccountFolderTemplate { get; set; } public DataTemplate MergedAccountFolderTemplate { get; set; } = null!;
public DataTemplate MergedAccountMoreExpansionItemTemplate { get; set; } public DataTemplate MergedAccountMoreExpansionItemTemplate { get; set; } = null!;
public DataTemplate FolderMenuTemplate { get; set; } public DataTemplate FolderMenuTemplate { get; set; } = null!;
public DataTemplate SettingsItemTemplate { get; set; } public DataTemplate SettingsItemTemplate { get; set; } = null!;
public DataTemplate MoreItemsFolderTemplate { get; set; } public DataTemplate MoreItemsFolderTemplate { get; set; } = null!;
public DataTemplate RatingItemTemplate { get; set; } public DataTemplate RatingItemTemplate { get; set; } = null!;
public DataTemplate CreateNewFolderTemplate { get; set; } public DataTemplate CreateNewFolderTemplate { get; set; } = null!;
public DataTemplate SeperatorTemplate { get; set; } public DataTemplate SeperatorTemplate { get; set; } = null!;
public DataTemplate NewMailTemplate { get; set; } public DataTemplate NewMailTemplate { get; set; } = null!;
public DataTemplate CategoryItemsTemplate { get; set; } public DataTemplate CategoryItemsTemplate { get; set; } = null!;
public DataTemplate FixAuthenticationIssueTemplate { get; set; } public DataTemplate FixAuthenticationIssueTemplate { get; set; } = null!;
public DataTemplate FixMissingFolderConfigTemplate { get; set; } public DataTemplate FixMissingFolderConfigTemplate { get; set; } = null!;
protected override DataTemplate SelectTemplateCore(object item) protected override DataTemplate SelectTemplateCore(object item)
{ {
@@ -34,7 +34,7 @@ public partial class NavigationMenuTemplateSelector : DataTemplateSelector
return SettingsItemTemplate; return SettingsItemTemplate;
else if (item is SeperatorItem) else if (item is SeperatorItem)
return SeperatorTemplate; return SeperatorTemplate;
else if (item is AccountMenuItem accountMenuItem) else if (item is AccountMenuItem)
// Merged inbox account menu items must be nested. // Merged inbox account menu items must be nested.
return ClickableAccountMenuTemplate; return ClickableAccountMenuTemplate;
else if (item is ManageAccountsMenuItem) else if (item is ManageAccountsMenuItem)
@@ -52,10 +52,6 @@ public partial class NavigationMenuTemplateSelector : DataTemplateSelector
else if (item is FixAccountIssuesMenuItem fixAccountIssuesMenuItem) else if (item is FixAccountIssuesMenuItem fixAccountIssuesMenuItem)
return fixAccountIssuesMenuItem.Account.AttentionReason == Wino.Core.Domain.Enums.AccountAttentionReason.MissingSystemFolderConfiguration return fixAccountIssuesMenuItem.Account.AttentionReason == Wino.Core.Domain.Enums.AccountAttentionReason.MissingSystemFolderConfiguration
? FixMissingFolderConfigTemplate : FixAuthenticationIssueTemplate; ? FixMissingFolderConfigTemplate : FixAuthenticationIssueTemplate;
else return MenuItemTemplate;
{
var type = item.GetType();
return null;
}
} }
} }
@@ -6,10 +6,10 @@ namespace Wino.Mail.WinUI.Selectors;
public partial class RsvpStatusIconTemplateSelector : DataTemplateSelector public partial class RsvpStatusIconTemplateSelector : DataTemplateSelector
{ {
public DataTemplate NotRespondedTemplate { get; set; } public DataTemplate NotRespondedTemplate { get; set; } = null!;
public DataTemplate ConfirmedTemplate { get; set; } public DataTemplate ConfirmedTemplate { get; set; } = null!;
public DataTemplate TentativeTemplate { get; set; } public DataTemplate TentativeTemplate { get; set; } = null!;
public DataTemplate CancelledTemplate { get; set; } public DataTemplate CancelledTemplate { get; set; } = null!;
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{ {
@@ -25,6 +25,6 @@ public partial class RsvpStatusIconTemplateSelector : DataTemplateSelector
}; };
} }
return base.SelectTemplateCore(item, container); return base.SelectTemplateCore(item, container) ?? NotRespondedTemplate;
} }
} }
@@ -8,8 +8,8 @@ public partial class WinoCalendarItemTemplateSelector : DataTemplateSelector
{ {
public CalendarDisplayType DisplayType { get; set; } public CalendarDisplayType DisplayType { get; set; }
public DataTemplate DayWeekWorkWeekTemplate { get; set; } public DataTemplate DayWeekWorkWeekTemplate { get; set; } = null!;
public DataTemplate MonthlyTemplate { get; set; } public DataTemplate MonthlyTemplate { get; set; } = null!;
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
@@ -26,6 +26,6 @@ public partial class WinoCalendarItemTemplateSelector : DataTemplateSelector
break; break;
} }
return base.SelectTemplateCore(item, container); return base.SelectTemplateCore(item, container) ?? DayWeekWorkWeekTemplate;
} }
} }
@@ -16,7 +16,7 @@ public class ApplicationResourceManager : IApplicationResourceManager<ResourceDi
=> WinoApplication.Current.Resources.ContainsKey(resourceKey); => WinoApplication.Current.Resources.ContainsKey(resourceKey);
public ResourceDictionary GetLastResource() public ResourceDictionary GetLastResource()
=> WinoApplication.Current.Resources.MergedDictionaries.LastOrDefault(); => WinoApplication.Current.Resources.MergedDictionaries.LastOrDefault()!;
public void ReplaceResource(string resourceKey, object resource) public void ReplaceResource(string resourceKey, object resource)
=> WinoApplication.Current.Resources[resourceKey] = resource; => WinoApplication.Current.Resources[resourceKey] = resource;
@@ -9,10 +9,10 @@ namespace Wino.Mail.WinUI.Services;
public class ConfigurationService : IConfigurationService public class ConfigurationService : IConfigurationService
{ {
public T Get<T>(string key, T defaultValue = default) public T Get<T>(string key, T defaultValue = default!)
=> GetInternal(key, ApplicationData.Current.LocalSettings.Values, defaultValue); => GetInternal(key, ApplicationData.Current.LocalSettings.Values, defaultValue);
public T GetRoaming<T>(string key, T defaultValue = default) public T GetRoaming<T>(string key, T defaultValue = default!)
=> GetInternal(key, ApplicationData.Current.RoamingSettings.Values, defaultValue); => GetInternal(key, ApplicationData.Current.RoamingSettings.Values, defaultValue);
public void Set(string key, object value) public void Set(string key, object value)
@@ -21,11 +21,13 @@ public class ConfigurationService : IConfigurationService
public void SetRoaming(string key, object value) public void SetRoaming(string key, object value)
=> SetInternal(key, value, ApplicationData.Current.RoamingSettings.Values); => SetInternal(key, value, ApplicationData.Current.RoamingSettings.Values);
private static T GetInternal<T>(string key, IPropertySet collection, T defaultValue = default) private static T GetInternal<T>(string key, IPropertySet collection, T defaultValue = default!)
{ {
if (collection.TryGetValue(key, out object value)) if (collection.TryGetValue(key, out object? value))
{ {
var stringValue = value?.ToString(); var stringValue = value?.ToString();
if (string.IsNullOrWhiteSpace(stringValue))
return defaultValue;
if (typeof(T).IsEnum) if (typeof(T).IsEnum)
return (T)Enum.Parse(typeof(T), stringValue); return (T)Enum.Parse(typeof(T), stringValue);
@@ -40,7 +42,8 @@ public class ConfigurationService : IConfigurationService
return (T)(object)TimeSpan.Parse(stringValue); return (T)(object)TimeSpan.Parse(stringValue);
} }
return (T)Convert.ChangeType(stringValue, typeof(T)); var converted = Convert.ChangeType(stringValue, typeof(T));
return converted is T typed ? typed : defaultValue;
} }
return defaultValue; return defaultValue;
+1 -1
View File
@@ -119,7 +119,7 @@ public class DialogService : DialogServiceBase, IMailDialogService
await HandleDialogPresentationAsync(accountPicker); await HandleDialogPresentationAsync(accountPicker);
return accountPicker.PickedAccount; return accountPicker.PickedAccount ?? null!;
} }
public async Task<AccountSignature> ShowSignatureEditorDialog(AccountSignature? signatureModel = null) public async Task<AccountSignature> ShowSignatureEditorDialog(AccountSignature? signatureModel = null)
+23 -11
View File
@@ -40,7 +40,7 @@ public class DialogServiceBase : IDialogServiceBase
ApplicationResourceManager = applicationResourceManager; ApplicationResourceManager = applicationResourceManager;
} }
protected XamlRoot GetXamlRoot() protected XamlRoot? GetXamlRoot()
{ {
return WinoApplication.MainWindow?.Content?.XamlRoot; return WinoApplication.MainWindow?.Content?.XamlRoot;
} }
@@ -54,7 +54,10 @@ public class DialogServiceBase : IDialogServiceBase
picker.FileTypeFilter.Add("*"); picker.FileTypeFilter.Add("*");
nint windowHandle = WindowNative.GetWindowHandle(WinoApplication.MainWindow); var mainWindow = WinoApplication.MainWindow;
if (mainWindow == null) return string.Empty;
nint windowHandle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, windowHandle); InitializeWithWindow.Initialize(picker, windowHandle);
var folder = await picker.PickSingleFolderAsync(); var folder = await picker.PickSingleFolderAsync();
@@ -94,7 +97,10 @@ public class DialogServiceBase : IDialogServiceBase
picker.FileTypeFilter.Add(filter.ToString()); picker.FileTypeFilter.Add(filter.ToString());
} }
nint windowHandle = WindowNative.GetWindowHandle(WinoApplication.MainWindow); var mainWindow = WinoApplication.MainWindow;
if (mainWindow == null) return returnList;
nint windowHandle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, windowHandle); InitializeWithWindow.Initialize(picker, windowHandle);
var files = await picker.PickMultipleFilesAsync(); var files = await picker.PickMultipleFilesAsync();
@@ -111,7 +117,7 @@ public class DialogServiceBase : IDialogServiceBase
return returnList; return returnList;
} }
private async Task<StorageFile> PickFileAsync(params object[] typeFilters) private async Task<StorageFile?> PickFileAsync(params object[] typeFilters)
{ {
var picker = new FileOpenPicker var picker = new FileOpenPicker
{ {
@@ -123,7 +129,10 @@ public class DialogServiceBase : IDialogServiceBase
picker.FileTypeFilter.Add(filter.ToString()); picker.FileTypeFilter.Add(filter.ToString());
} }
nint windowHandle = WindowNative.GetWindowHandle(WinoApplication.MainWindow); var mainWindow = WinoApplication.MainWindow;
if (mainWindow == null) return null;
nint windowHandle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, windowHandle); InitializeWithWindow.Initialize(picker, windowHandle);
var file = await picker.PickSingleFileAsync(); var file = await picker.PickSingleFileAsync();
@@ -174,7 +183,7 @@ public class DialogServiceBase : IDialogServiceBase
if (isDontAskEnabled && ConfigurationService.Get(dontAskAgainConfigurationKey, false)) return false; if (isDontAskEnabled && ConfigurationService.Get(dontAskAgainConfigurationKey, false)) return false;
var informationContainer = new CustomMessageDialogInformationContainer(title, description, icon.Value, isDontAskEnabled); var informationContainer = new CustomMessageDialogInformationContainer(title, description, icon ?? WinoCustomMessageDialogIcon.Information, isDontAskEnabled);
var dialog = new ContentDialog var dialog = new ContentDialog
{ {
@@ -270,7 +279,10 @@ public class DialogServiceBase : IDialogServiceBase
picker.FileTypeFilter.Add("*"); picker.FileTypeFilter.Add("*");
nint windowHandle = WindowNative.GetWindowHandle(WinoApplication.MainWindow); var mainWindow = WinoApplication.MainWindow;
if (mainWindow == null) return string.Empty;
nint windowHandle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, windowHandle); InitializeWithWindow.Initialize(picker, windowHandle);
var pickedFolder = await picker.PickSingleFolderAsync(); var pickedFolder = await picker.PickSingleFolderAsync();
@@ -307,10 +319,10 @@ public class DialogServiceBase : IDialogServiceBase
await HandleDialogPresentationAsync(dialog); await HandleDialogPresentationAsync(dialog);
return dialog.Result; return dialog.Result ?? null!;
} }
public async Task<WebView2PrintSettingsModel> ShowPrintDialogAsync(WebView2PrintSettingsModel initialSettings = null) public async Task<WebView2PrintSettingsModel> ShowPrintDialogAsync(WebView2PrintSettingsModel initialSettings = default!)
{ {
try try
{ {
@@ -334,13 +346,13 @@ public class DialogServiceBase : IDialogServiceBase
// Return the settings if user clicked Print, otherwise null // Return the settings if user clicked Print, otherwise null
return result == ContentDialogResult.Primary return result == ContentDialogResult.Primary
? dialog.PrintSettings ? dialog.PrintSettings
: null; : null!;
} }
catch (Exception ex) catch (Exception ex)
{ {
// Log the exception if logging is available // Log the exception if logging is available
Log.Error(ex, "Error showing print dialog"); Log.Error(ex, "Error showing print dialog");
return null; return null!;
} }
} }
} }
+3 -3
View File
@@ -16,10 +16,10 @@ namespace Wino.Services;
public class NativeAppService : INativeAppService public class NativeAppService : INativeAppService
{ {
private string _mimeMessagesFolder; private string _mimeMessagesFolder = string.Empty;
private string _editorBundlePath; private string _editorBundlePath = string.Empty;
public Func<IntPtr> GetCoreWindowHwnd { get; set; } public Func<IntPtr> GetCoreWindowHwnd { get; set; } = static () => IntPtr.Zero;
public string GetWebAuthenticationBrokerUri() public string GetWebAuthenticationBrokerUri()
{ {
@@ -100,7 +100,10 @@ public class NavigationService : NavigationServiceBase, INavigationService
if (frameType == NavigationReferenceFrame.ShellFrame) return shellWindow.GetMainFrame(); if (frameType == NavigationReferenceFrame.ShellFrame) return shellWindow.GetMainFrame();
return WinoVisualTreeHelper.GetChildObject<Frame>(mainFrame.Content as UIElement, frameType.ToString()); var contentRoot = mainFrame.Content as UIElement;
if (contentRoot == null) return mainFrame;
return WinoVisualTreeHelper.GetChildObject<Frame>(contentRoot, frameType.ToString()) ?? mainFrame;
} }
public bool ChangeApplicationMode(WinoApplicationMode mode) public bool ChangeApplicationMode(WinoApplicationMode mode)
@@ -17,7 +17,7 @@ public class NavigationServiceBase
}; };
} }
public Type GetCurrentFrameType(ref Frame _frame) public Type? GetCurrentFrameType(ref Frame _frame)
{ {
if (_frame != null && _frame.Content != null) if (_frame != null && _frame.Content != null)
return _frame.Content.GetType(); return _frame.Content.GetType();
+19 -9
View File
@@ -45,9 +45,9 @@ public class NewThemeService : INewThemeService
private static string _snowflakeThemeId = "e143ddde-2e28-4846-9d98-dad63d6505f1"; private static string _snowflakeThemeId = "e143ddde-2e28-4846-9d98-dad63d6505f1";
private static string _gardenThemeId = "698e4466-f88c-4799-9c61-f0ea1308ed49"; private static string _gardenThemeId = "698e4466-f88c-4799-9c61-f0ea1308ed49";
public event EventHandler<ApplicationElementTheme> ElementThemeChanged; public event EventHandler<ApplicationElementTheme>? ElementThemeChanged;
public event EventHandler<string> AccentColorChanged; public event EventHandler<string>? AccentColorChanged;
public event EventHandler<WindowBackdropType> BackdropChanged; public event EventHandler<WindowBackdropType>? BackdropChanged;
private const string AccentColorKey = nameof(AccentColorKey); private const string AccentColorKey = nameof(AccentColorKey);
private const string CurrentApplicationThemeKey = nameof(CurrentApplicationThemeKey); private const string CurrentApplicationThemeKey = nameof(CurrentApplicationThemeKey);
@@ -125,7 +125,7 @@ public class NewThemeService : INewThemeService
} }
} }
private string accentColor; private string accentColor = string.Empty;
public string AccentColor public string AccentColor
{ {
@@ -218,7 +218,7 @@ public class NewThemeService : INewThemeService
try try
{ {
Microsoft.UI.Xaml.Media.SystemBackdrop backdrop = backdropType switch Microsoft.UI.Xaml.Media.SystemBackdrop? backdrop = backdropType switch
{ {
WindowBackdropType.Mica => new MicaBackdrop() { Kind = Microsoft.UI.Composition.SystemBackdrops.MicaKind.Base }, WindowBackdropType.Mica => new MicaBackdrop() { Kind = Microsoft.UI.Composition.SystemBackdrops.MicaKind.Base },
WindowBackdropType.MicaAlt => new MicaBackdrop() { Kind = Microsoft.UI.Composition.SystemBackdrops.MicaKind.BaseAlt }, WindowBackdropType.MicaAlt => new MicaBackdrop() { Kind = Microsoft.UI.Composition.SystemBackdrops.MicaKind.BaseAlt },
@@ -385,7 +385,7 @@ public class NewThemeService : INewThemeService
return; return;
} }
AppThemeBase applyingTheme = null; AppThemeBase? applyingTheme = null;
var controlThemeList = new List<AppThemeBase>(preDefinedThemes); var controlThemeList = new List<AppThemeBase>(preDefinedThemes);
@@ -416,13 +416,19 @@ public class NewThemeService : INewThemeService
} }
} }
if (applyingTheme == null)
{
Debug.WriteLine($"Theme with ID {currentApplicationThemeId} not found, skipping theme application");
return;
}
try try
{ {
var existingThemeDictionary = _applicationResourceManager.GetLastResource(); var existingThemeDictionary = _applicationResourceManager.GetLastResource();
if (existingThemeDictionary != null && existingThemeDictionary.TryGetValue("ThemeName", out object themeNameString)) if (existingThemeDictionary != null && existingThemeDictionary.TryGetValue("ThemeName", out object? themeNameString))
{ {
var themeName = themeNameString.ToString(); var themeName = themeNameString?.ToString();
// Applying different theme. // Applying different theme.
if (themeName != applyingTheme.ThemeName) if (themeName != applyingTheme.ThemeName)
@@ -430,6 +436,10 @@ public class NewThemeService : INewThemeService
var resourceDictionaryContent = await applyingTheme.GetThemeResourceDictionaryContentAsync(); var resourceDictionaryContent = await applyingTheme.GetThemeResourceDictionaryContentAsync();
var resourceDictionary = XamlReader.Load(resourceDictionaryContent) as ResourceDictionary; var resourceDictionary = XamlReader.Load(resourceDictionaryContent) as ResourceDictionary;
if (resourceDictionary == null)
{
return;
}
// Custom themes require special attention for background image because // Custom themes require special attention for background image because
// they share the same base theme resource dictionary. // they share the same base theme resource dictionary.
@@ -561,7 +571,7 @@ public class NewThemeService : INewThemeService
return results; return results;
} }
private async Task<CustomThemeMetadata> GetCustomMetadataAsync(IStorageFile file) private async Task<CustomThemeMetadata?> GetCustomMetadataAsync(IStorageFile file)
{ {
var fileContent = await FileIO.ReadTextAsync(file); var fileContent = await FileIO.ReadTextAsync(file);
@@ -215,7 +215,12 @@ public class NotificationBuilder : INotificationBuilder
XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber); XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);
// Set the value of the badge in the XML to our number // Set the value of the badge in the XML to our number
XmlElement badgeElement = badgeXml.SelectSingleNode("/badge") as XmlElement; XmlElement? badgeElement = badgeXml.SelectSingleNode("/badge") as XmlElement;
if (badgeElement == null)
{
badgeUpdater.Clear();
return;
}
badgeElement.SetAttribute("value", totalUnreadCount.ToString()); badgeElement.SetAttribute("value", totalUnreadCount.ToString());
// Create the badge notification // Create the badge notification
@@ -17,20 +17,20 @@ public class PreferencesService(IConfigurationService configurationService) : Ob
{ {
private readonly IConfigurationService _configurationService = configurationService; private readonly IConfigurationService _configurationService = configurationService;
public event EventHandler<string> PreferenceChanged; public event EventHandler<string>? PreferenceChanged;
protected override void OnPropertyChanged(PropertyChangedEventArgs e) protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{ {
base.OnPropertyChanged(e); base.OnPropertyChanged(e);
PreferenceChanged?.Invoke(this, e.PropertyName); PreferenceChanged?.Invoke(this, e.PropertyName ?? string.Empty);
} }
private void SaveProperty(string propertyName, object value) => _configurationService.Set(propertyName, value); private void SaveProperty(string propertyName, object? value) => _configurationService.Set(propertyName, value ?? string.Empty);
private void SetPropertyAndSave(string propertyName, object value) private void SetPropertyAndSave(string propertyName, object? value)
{ {
_configurationService.Set(propertyName, value); _configurationService.Set(propertyName, value ?? string.Empty);
OnPropertyChanged(propertyName); OnPropertyChanged(propertyName);
Debug.WriteLine($"PreferencesService -> {propertyName}:{value?.ToString()}"); Debug.WriteLine($"PreferencesService -> {propertyName}:{value?.ToString()}");
+15 -6
View File
@@ -24,10 +24,10 @@ namespace Wino.Mail.WinUI.Services;
public class PrintService : IPrintService public class PrintService : IPrintService
{ {
private TaskCompletionSource<PrintingResult> _taskCompletionSource; private TaskCompletionSource<PrintingResult>? _taskCompletionSource;
private CanvasPrintDocument printDocument; private CanvasPrintDocument? printDocument;
private PrintTask printTask; private PrintTask? printTask;
private PdfDocument pdfDocument; private PdfDocument? pdfDocument;
private List<CanvasBitmap> bitmaps = new(); private List<CanvasBitmap> bitmaps = new();
private Vector2 largestBitmap; private Vector2 largestBitmap;
@@ -41,7 +41,7 @@ public class PrintService : IPrintService
private int bitmapsPerPage; private int bitmapsPerPage;
private int pageCount = -1; private int pageCount = -1;
private PrintInformation _currentPrintInformation; private PrintInformation? _currentPrintInformation;
public async Task<PrintingResult> PrintPdfFileAsync(string pdfFilePath, string printTitle) public async Task<PrintingResult> PrintPdfFileAsync(string pdfFilePath, string printTitle)
{ {
@@ -125,6 +125,9 @@ public class PrintService : IPrintService
printTask = args.Request.CreatePrintTask(_currentPrintInformation.PDFTitle, (createPrintTaskArgs) => printTask = args.Request.CreatePrintTask(_currentPrintInformation.PDFTitle, (createPrintTaskArgs) =>
{ {
if (printDocument == null)
return;
createPrintTaskArgs.SetSource(printDocument); createPrintTaskArgs.SetSource(printDocument);
}); });
@@ -191,6 +194,9 @@ public class PrintService : IPrintService
private async Task LoadPDFPageBitmapsAsync(CanvasPrintDocument sender) private async Task LoadPDFPageBitmapsAsync(CanvasPrintDocument sender)
{ {
if (pdfDocument == null)
return;
ClearBitmaps(); ClearBitmaps();
bitmaps ??= new List<CanvasBitmap>(); bitmaps ??= new List<CanvasBitmap>();
@@ -226,6 +232,9 @@ public class PrintService : IPrintService
{ {
var detailedOptions = PrintTaskOptionDetails.GetFromPrintTaskOptions(args.PrintTaskOptions); var detailedOptions = PrintTaskOptionDetails.GetFromPrintTaskOptions(args.PrintTaskOptions);
if (pdfDocument == null)
return;
int pageCountToPrint = (int)pdfDocument.PageCount; int pageCountToPrint = (int)pdfDocument.PageCount;
for (uint i = 1; i <= pageCountToPrint; ++i) for (uint i = 1; i <= pageCountToPrint; ++i)
@@ -239,7 +248,7 @@ public class PrintService : IPrintService
private void DrawPdfPage(CanvasPrintDocument sender, CanvasDrawingSession ds, uint pageNumber) private void DrawPdfPage(CanvasPrintDocument sender, CanvasDrawingSession ds, uint pageNumber)
{ {
if (bitmaps?.Count == 0) return; if (bitmaps.Count == 0) return;
var cellAcross = new Vector2(cellSize.X, 0); var cellAcross = new Vector2(cellSize.X, 0);
var cellDown = new Vector2(0, cellSize.Y); var cellDown = new Vector2(0, cellSize.Y);
@@ -17,7 +17,7 @@ public class SmimeCertificateService : ISmimeCertificateService
/// private key and at least one extension. The store is opened in read-only mode.</remarks> /// private key and at least one extension. The store is opened in read-only mode.</remarks>
/// <returns>An enumerable collection of <see cref="X509Certificate2"/> objects representing the personal certificates that /// <returns>An enumerable collection of <see cref="X509Certificate2"/> objects representing the personal certificates that
/// meet the specified criteria. If no matching certificates are found, the collection will be empty.</returns> /// meet the specified criteria. If no matching certificates are found, the collection will be empty.</returns>
public IEnumerable<X509Certificate2> GetCertificates(StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser, string emailAddress = null) public IEnumerable<X509Certificate2> GetCertificates(StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser, string? emailAddress = null)
{ {
using var store = new X509Store(storeName, storeLocation); using var store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.ReadOnly); store.Open(OpenFlags.ReadOnly);
@@ -26,7 +26,7 @@ public class SmimeCertificateService : ISmimeCertificateService
} }
public void ImportCertificate(string fileExtension, byte[] rawData, string password = null, StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser) public void ImportCertificate(string fileExtension, byte[] rawData, string? password = null, StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser)
{ {
X509Certificate2Collection collection = []; X509Certificate2Collection collection = [];
@@ -198,7 +198,13 @@ public class StatePersistenceService : ObservableObject, IStatePersistanceServic
} }
} }
private void UpdateAppCoreWindowTitle() => WinoApplication.MainWindow.Title = CoreWindowTitle; private void UpdateAppCoreWindowTitle()
{
if (WinoApplication.MainWindow != null)
{
WinoApplication.MainWindow.Title = CoreWindowTitle;
}
}
private static CalendarDisplayType EnsureValidCalendarDisplayType(CalendarDisplayType displayType) private static CalendarDisplayType EnsureValidCalendarDisplayType(CalendarDisplayType displayType)
{ {
+7 -7
View File
@@ -21,7 +21,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
private static readonly HttpClient _httpClient = new(); private static readonly HttpClient _httpClient = new();
private bool _isInitialized = false; private bool _isInitialized = false;
private ConcurrentDictionary<string, (string graviton, string favicon)> _cache; private ConcurrentDictionary<string, (string? graviton, string? favicon)> _cache = [];
private readonly ConcurrentDictionary<string, Task> _requests = []; private readonly ConcurrentDictionary<string, Task> _requests = [];
private static readonly List<string> _excludedFaviconDomains = [ private static readonly List<string> _excludedFaviconDomains = [
@@ -43,7 +43,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
"rediffmail.com" "rediffmail.com"
]; ];
public async ValueTask<string> GetThumbnailAsync(string email, bool awaitLoad = false) public async ValueTask<string?> GetThumbnailAsync(string email, bool awaitLoad = false)
{ {
if (string.IsNullOrWhiteSpace(email)) if (string.IsNullOrWhiteSpace(email))
return null; return null;
@@ -55,8 +55,8 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
{ {
var thumbnailsList = await _databaseService.Connection.Table<Thumbnail>().ToListAsync(); var thumbnailsList = await _databaseService.Connection.Table<Thumbnail>().ToListAsync();
_cache = new ConcurrentDictionary<string, (string graviton, string favicon)>( _cache = new ConcurrentDictionary<string, (string? graviton, string? favicon)>(
thumbnailsList.ToDictionary(x => x.Domain, x => (x.Gravatar, x.Favicon))); thumbnailsList.ToDictionary(x => x.Domain, x => ((string?)x.Gravatar, (string?)x.Favicon)));
_isInitialized = true; _isInitialized = true;
} }
@@ -84,7 +84,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
await _databaseService.Connection.DeleteAllAsync<Thumbnail>(); await _databaseService.Connection.DeleteAllAsync<Thumbnail>();
} }
private async ValueTask<(string gravatar, string favicon)> GetThumbnailInternal(string email, bool awaitLoad) private async ValueTask<(string? gravatar, string? favicon)> GetThumbnailInternal(string email, bool awaitLoad)
{ {
if (_cache.TryGetValue(email, out var cached)) if (_cache.TryGetValue(email, out var cached))
return cached; return cached;
@@ -136,7 +136,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
WeakReferenceMessenger.Default.Send(new ThumbnailAdded(email)); WeakReferenceMessenger.Default.Send(new ThumbnailAdded(email));
} }
private static async Task<string> GetGravatarBase64(string email) private static async Task<string?> GetGravatarBase64(string email)
{ {
try try
{ {
@@ -156,7 +156,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
return null; return null;
} }
private static async Task<string> GetFaviconBase64(string email) private static async Task<string?> GetFaviconBase64(string email)
{ {
try try
{ {
@@ -26,7 +26,7 @@ public sealed partial class CalendarPage : CalendarPageAbstract,
ViewModel.DetailsShowCalendarItemChanged += CalendarItemDetailContextChanged; ViewModel.DetailsShowCalendarItemChanged += CalendarItemDetailContextChanged;
} }
private void CalendarItemDetailContextChanged(object sender, EventArgs e) private void CalendarItemDetailContextChanged(object? sender, EventArgs e)
{ {
if (ViewModel.DisplayDetailsCalendarItemViewModel != null) if (ViewModel.DisplayDetailsCalendarItemViewModel != null)
{ {
@@ -37,7 +37,7 @@ public sealed partial class AliasManagementPage : AliasManagementPageAbstract
} }
} }
private static (MailAccountAlias alias, X509Certificate2 cert) GetAliasAndSelectedCertificateForCombobox(object sender) private static (MailAccountAlias? alias, X509Certificate2? cert) GetAliasAndSelectedCertificateForCombobox(object sender)
{ {
var comboBox = sender as ComboBox; var comboBox = sender as ComboBox;
var alias = comboBox?.DataContext as MailAccountAlias; var alias = comboBox?.DataContext as MailAccountAlias;
@@ -89,7 +89,7 @@ public sealed partial class ContactsPage : ContactsPageAbstract
ClearSelection(); ClearSelection();
} }
private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) private void ViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
{ {
if (e.PropertyName == nameof(ContactsPageViewModel.IsSelectionMode) && !ViewModel.IsSelectionMode) if (e.PropertyName == nameof(ContactsPageViewModel.IsSelectionMode) && !ViewModel.IsSelectionMode)
{ {
+3 -1
View File
@@ -5,6 +5,7 @@
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion> <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>Wino.Mail.WinUI</RootNamespace> <RootNamespace>Wino.Mail.WinUI</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
<Platform Condition="'$(Platform)' == '' or '$(Platform)' == 'AnyCPU'">x64</Platform>
<Platforms>x86;x64;ARM64</Platforms> <Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<PublishProfile>win-$(Platform).pubxml</PublishProfile> <PublishProfile>win-$(Platform).pubxml</PublishProfile>
@@ -15,7 +16,8 @@
<!-- AOT / Trimming --> <!-- AOT / Trimming -->
<PublishAot Condition="'$(Configuration)' == 'Debug'">False</PublishAot> <PublishAot Condition="'$(Configuration)' == 'Debug'">False</PublishAot>
<PublishAot Condition="'$(Configuration)' != 'Debug'">True</PublishAot> <PublishAot Condition="'$(Configuration)' != 'Debug'">True</PublishAot>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors> <TreatWarningsAsErrors>True</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);CS8305</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun> <PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun> <PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
+11 -11
View File
@@ -38,7 +38,7 @@ public abstract class WinoApplication : Application, IRecipient<LanguageChanged>
protected IDatabaseService DatabaseService { get; } protected IDatabaseService DatabaseService { get; }
protected ITranslationService TranslationService { get; } protected ITranslationService TranslationService { get; }
public static WindowEx MainWindow { get; set; } public static WindowEx? MainWindow { get; set; }
protected WinoApplication() protected WinoApplication()
{ {
@@ -50,14 +50,14 @@ public abstract class WinoApplication : Application, IRecipient<LanguageChanged>
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException; TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
UnhandledException += OnAppUnhandledException; UnhandledException += OnAppUnhandledException;
LogInitializer = Services.GetService<IWinoLogger>(); LogInitializer = Services.GetRequiredService<IWinoLogger>();
AppConfiguration = Services.GetService<IApplicationConfiguration>(); AppConfiguration = Services.GetRequiredService<IApplicationConfiguration>();
NewThemeService = Services.GetService<INewThemeService>(); NewThemeService = Services.GetRequiredService<INewThemeService>();
DatabaseService = Services.GetService<IDatabaseService>(); DatabaseService = Services.GetRequiredService<IDatabaseService>();
TranslationService = Services.GetService<ITranslationService>(); TranslationService = Services.GetRequiredService<ITranslationService>();
UnderlyingThemeService = Services.GetService<IUnderlyingThemeService>(); UnderlyingThemeService = Services.GetRequiredService<IUnderlyingThemeService>();
ThumbnailService = Services.GetService<IThumbnailService>(); ThumbnailService = Services.GetRequiredService<IThumbnailService>();
// Make sure the paths are setup on app start. // Make sure the paths are setup on app start.
AppConfiguration.ApplicationDataFolderPath = ApplicationData.Current.LocalFolder.Path; AppConfiguration.ApplicationDataFolderPath = ApplicationData.Current.LocalFolder.Path;
@@ -67,10 +67,10 @@ public abstract class WinoApplication : Application, IRecipient<LanguageChanged>
ConfigureLogging(); ConfigureLogging();
} }
private void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e) private void CurrentDomain_UnhandledException(object? sender, System.UnhandledExceptionEventArgs e)
=> Log.Fatal(e.ExceptionObject as Exception, "AppDomain Unhandled Exception"); => Log.Fatal(e.ExceptionObject as Exception, "AppDomain Unhandled Exception");
private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) private void OnUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
=> Log.Error(e.Exception, "Unobserved Task Exception"); => Log.Error(e.Exception, "Unobserved Task Exception");
private void OnAppUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) private void OnAppUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
@@ -83,7 +83,7 @@ public abstract class WinoApplication : Application, IRecipient<LanguageChanged>
{ {
yield return DatabaseService; yield return DatabaseService;
yield return TranslationService; yield return TranslationService;
yield return Services.GetService<SynchronizationManagerInitializer>(); yield return Services.GetRequiredService<SynchronizationManagerInitializer>();
} }
public Task InitializeServicesAsync() => GetActivationServices().Select(a => a.InitializeAsync()).WhenAll(); public Task InitializeServicesAsync() => GetActivationServices().Select(a => a.InitializeAsync()).WhenAll();
@@ -43,7 +43,7 @@ namespace Wino.Core.SourceGeneration.Translator
// Get the JSON schema and track changes // Get the JSON schema and track changes
var jsonSchema = context.AdditionalTextsProvider var jsonSchema = context.AdditionalTextsProvider
.Where(static file => file.Path.EndsWith("en_US\\resources.json")) .Where(static file => file.Path.Replace("\\", "/").EndsWith("en_US/resources.json", StringComparison.OrdinalIgnoreCase))
.Select((text, _) => (text, text.GetText())) .Select((text, _) => (text, text.GetText()))
.Collect() .Collect()
.WithTrackingName("JsonSchema"); .WithTrackingName("JsonSchema");
@@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<IncludeBuildOutput>false</IncludeBuildOutput> <IncludeBuildOutput>false</IncludeBuildOutput>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>