Event compose implementation.

This commit is contained in:
Burak Kaan Köse
2026-03-07 01:46:07 +01:00
parent 6608baed69
commit e94cce451f
26 changed files with 1285 additions and 674 deletions
@@ -35,9 +35,6 @@ public partial class CalendarAccountSettingsPageViewModel : CalendarBaseViewMode
[ObservableProperty]
public partial bool IsSyncEnabled { get; set; }
[ObservableProperty]
public partial bool IsPrimaryCalendar { get; set; }
public ObservableCollection<ShowAsOption> ShowAsOptions { get; } = new ObservableCollection<ShowAsOption>();
[ObservableProperty]
@@ -82,7 +79,6 @@ public partial class CalendarAccountSettingsPageViewModel : CalendarBaseViewMode
// Initialize properties from AccountCalendar
AccountColorHex = AccountCalendar.BackgroundColorHex ?? "#0078D4";
IsSyncEnabled = AccountCalendar.IsSynchronizationEnabled;
IsPrimaryCalendar = AccountCalendar.IsPrimary;
SelectedDefaultShowAsOption = ShowAsOptions.FirstOrDefault(o => o.ShowAs == AccountCalendar.DefaultShowAs) ?? ShowAsOptions[2];
}
@@ -104,15 +100,6 @@ public partial class CalendarAccountSettingsPageViewModel : CalendarBaseViewMode
}
}
partial void OnIsPrimaryCalendarChanged(bool value)
{
if (AccountCalendar != null)
{
AccountCalendar.IsPrimary = value;
SaveChangesAsync();
}
}
partial void OnSelectedDefaultShowAsOptionChanged(ShowAsOption value)
{
if (AccountCalendar != null && value != null)
@@ -9,6 +9,7 @@ using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Serilog;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain.Entities.Calendar;
using Wino.Calendar.ViewModels.Interfaces;
using Wino.Core.Domain;
using Wino.Core.Domain.Collections;
@@ -122,12 +123,14 @@ public partial class CalendarAppShellViewModel : CalendarBaseViewModel,
if (mode == NavigationMode.Back)
{
await InitializeAccountCalendarsAsync();
ValidateConfiguredNewEventCalendar();
return;
}
UpdateDateNavigationHeaderItems();
await InitializeAccountCalendarsAsync();
ValidateConfiguredNewEventCalendar();
await ShowWhatIsNewIfNeededAsync();
@@ -311,25 +314,31 @@ public partial class CalendarAppShellViewModel : CalendarBaseViewModel,
[RelayCommand]
private async Task NewEventAsync()
{
var availableGroups = AccountCalendarStateService.GroupedAccountCalendars
.Where(group => group.AccountCalendars.Count > 0)
.Select(group => new CalendarPickerAccountGroup
{
Account = group.Account,
Calendars = group.AccountCalendars.Select(calendar => calendar.AccountCalendar).ToList()
})
.ToList();
var pickedCalendar = TryResolveConfiguredNewEventCalendar();
if (availableGroups.Count == 0)
if (pickedCalendar == null)
{
_dialogService.InfoBarMessage(
Translator.CalendarEventCompose_NoCalendarsTitle,
Translator.CalendarEventCompose_NoCalendarsMessage,
InfoBarMessageType.Warning);
return;
var availableGroups = AccountCalendarStateService.GroupedAccountCalendars
.Where(group => group.AccountCalendars.Count > 0)
.Select(group => new CalendarPickerAccountGroup
{
Account = group.Account,
Calendars = group.AccountCalendars.Select(calendar => calendar.AccountCalendar).ToList()
})
.ToList();
if (availableGroups.Count == 0)
{
_dialogService.InfoBarMessage(
Translator.CalendarEventCompose_NoCalendarsTitle,
Translator.CalendarEventCompose_NoCalendarsMessage,
InfoBarMessageType.Warning);
return;
}
pickedCalendar = await _dialogService.ShowSingleCalendarPickerDialogAsync(availableGroups);
}
var pickedCalendar = await _dialogService.ShowSingleCalendarPickerDialogAsync(availableGroups);
if (pickedCalendar == null)
return;
@@ -472,7 +481,43 @@ public partial class CalendarAppShellViewModel : CalendarBaseViewModel,
}
public async void Receive(AccountRemovedMessage message)
=> await InitializeAccountCalendarsAsync();
{
await InitializeAccountCalendarsAsync();
ValidateConfiguredNewEventCalendar();
}
private AccountCalendar TryResolveConfiguredNewEventCalendar()
{
ValidateConfiguredNewEventCalendar();
if (PreferencesService.NewEventButtonBehavior != NewEventButtonBehavior.AlwaysUseSpecificCalendar
|| !PreferencesService.DefaultNewEventCalendarId.HasValue)
{
return null;
}
return AccountCalendarStateService.AllCalendars
.FirstOrDefault(calendar => calendar.Id == PreferencesService.DefaultNewEventCalendarId.Value)?
.AccountCalendar;
}
private void ValidateConfiguredNewEventCalendar()
{
if (PreferencesService.NewEventButtonBehavior != NewEventButtonBehavior.AlwaysUseSpecificCalendar
|| !PreferencesService.DefaultNewEventCalendarId.HasValue)
{
return;
}
var exists = AccountCalendarStateService.AllCalendars
.Any(calendar => calendar.Id == PreferencesService.DefaultNewEventCalendarId.Value);
if (exists)
return;
PreferencesService.NewEventButtonBehavior = NewEventButtonBehavior.AskEachTime;
PreferencesService.DefaultNewEventCalendarId = null;
}
private static (DateTime StartDate, DateTime EndDate) GetDefaultComposeDateRange()
{
@@ -6,18 +6,20 @@ using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using EmailValidation;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Exceptions;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Calendar;
using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Validation;
using Wino.Core.ViewModels;
namespace Wino.Calendar.ViewModels;
@@ -31,10 +33,12 @@ public partial class CalendarEventComposePageViewModel : CalendarBaseViewModel
private readonly IContactService _contactService;
private readonly IPreferencesService _preferencesService;
private readonly IUnderlyingThemeService _underlyingThemeService;
private readonly CalendarEventComposeResultValidator _composeResultValidator = new();
public Func<Task<string>> GetHtmlNotesAsync { get; set; }
public ObservableCollection<AccountCalendarViewModel> AvailableCalendars { get; } = [];
public ObservableCollection<GroupedAccountCalendarViewModel> AvailableCalendarGroups { get; } = [];
public ObservableCollection<CalendarComposeAttendeeViewModel> Attendees { get; } = [];
public ObservableCollection<CalendarComposeAttachmentViewModel> Attachments { get; } = [];
public ObservableCollection<ShowAsOption> ShowAsOptions { get; } = [];
@@ -97,6 +101,8 @@ public partial class CalendarEventComposePageViewModel : CalendarBaseViewModel
public CalendarSettings CurrentSettings { get; }
public string TimePickerClockIdentifier => CurrentSettings.DayHeaderDisplayType == DayHeaderDisplayType.TwentyFourHour ? "24HourClock" : "12HourClock";
public bool HasAttachments => Attachments.Count > 0;
public string SelectedCalendarDisplayText => SelectedCalendar?.Name ?? Translator.CalendarEventCompose_SelectCalendar;
public string SelectedCalendarAccountText => SelectedCalendar?.Account?.Address ?? string.Empty;
public CalendarEventComposePageViewModel(IAccountService accountService,
ICalendarService calendarService,
@@ -169,11 +175,13 @@ public partial class CalendarEventComposePageViewModel : CalendarBaseViewModel
partial void OnSelectedCalendarChanged(AccountCalendarViewModel value)
{
if (value == null || SelectedShowAsOption != null)
if (value == null)
return;
SelectedShowAsOption = ShowAsOptions.FirstOrDefault(option => option.ShowAs == value.DefaultShowAs)
?? ShowAsOptions.FirstOrDefault();
OnPropertyChanged(nameof(SelectedCalendarDisplayText));
OnPropertyChanged(nameof(SelectedCalendarAccountText));
}
partial void OnIsAllDayChanged(bool value)
@@ -263,36 +271,24 @@ public partial class CalendarEventComposePageViewModel : CalendarBaseViewModel
[RelayCommand]
private async Task CreateAsync()
{
if (!await ValidateAsync())
return;
var uniqueAttendees = Attendees
.GroupBy(attendee => attendee.Email, StringComparer.OrdinalIgnoreCase)
.Select(group => group.First())
.ToList();
var htmlNotes = GetHtmlNotesAsync == null ? string.Empty : await GetHtmlNotesAsync();
var effectiveStart = GetEffectiveStartDateTime();
var effectiveEnd = GetEffectiveEndDateTime();
var createdResult = await BuildResultAsync(uniqueAttendees);
LastCreatedResult = new CalendarEventComposeResult
try
{
CalendarId = SelectedCalendar!.Id,
AccountId = SelectedCalendar.Account.Id,
Title = Title.Trim(),
Location = Location?.Trim() ?? string.Empty,
HtmlNotes = htmlNotes,
StartDate = effectiveStart,
EndDate = effectiveEnd,
IsAllDay = IsAllDay,
TimeZoneId = TimeZoneInfo.Local.Id,
ShowAs = SelectedShowAsOption?.ShowAs ?? SelectedCalendar.DefaultShowAs,
SelectedReminders = BuildSelectedReminders(),
Attendees = BuildAttendees(uniqueAttendees),
Attachments = Attachments.Select(attachment => attachment.ToDraftModel()).ToList(),
Recurrence = BuildRecurrenceRule(),
RecurrenceSummary = RecurrenceSummary
};
_composeResultValidator.Validate(createdResult);
}
catch (CalendarEventComposeValidationException ex)
{
ShowValidationMessage(ex.Message);
return;
}
LastCreatedResult = createdResult;
_navigationService.GoBack();
}
@@ -307,7 +303,7 @@ public partial class CalendarEventComposePageViewModel : CalendarBaseViewModel
public async Task<CalendarComposeAttendeeViewModel> GetAttendeeAsync(string tokenText)
{
if (!IsValidEmailAddress(tokenText))
if (!EmailValidator.Validate(tokenText))
return null;
var existing = Attendees.Any(attendee => attendee.Email.Equals(tokenText, StringComparison.OrdinalIgnoreCase));
@@ -359,26 +355,38 @@ public partial class CalendarEventComposePageViewModel : CalendarBaseViewModel
private async Task LoadAvailableCalendarsAsync()
{
var accountCalendars = new List<AccountCalendarViewModel>();
var groupedCalendars = new List<GroupedAccountCalendarViewModel>();
var accounts = await _accountService.GetAccountsAsync().ConfigureAwait(false);
foreach (var account in accounts)
{
var calendars = await _calendarService.GetAccountCalendarsAsync(account.Id).ConfigureAwait(false);
var viewModels = calendars
.Select(calendar => new AccountCalendarViewModel(account, calendar))
.ToList();
foreach (var calendar in calendars)
accountCalendars.AddRange(viewModels);
if (viewModels.Count > 0)
{
accountCalendars.Add(new AccountCalendarViewModel(account, calendar));
groupedCalendars.Add(new GroupedAccountCalendarViewModel(account, viewModels));
}
}
await ExecuteUIThread(() =>
{
AvailableCalendars.Clear();
AvailableCalendarGroups.Clear();
foreach (var calendar in accountCalendars.OrderBy(calendar => calendar.Account.Name).ThenBy(calendar => calendar.Name))
{
AvailableCalendars.Add(calendar);
}
foreach (var group in groupedCalendars.OrderBy(group => group.Account.Name))
{
AvailableCalendarGroups.Add(group);
}
});
}
@@ -424,68 +432,35 @@ public partial class CalendarEventComposePageViewModel : CalendarBaseViewModel
AllDayEndDate = new DateTimeOffset((isAllDay ? endDate.Date : startDate.Date.AddDays(1)));
}
private async Task<bool> ValidateAsync()
private async Task<CalendarEventComposeResult> BuildResultAsync(List<CalendarComposeAttendeeViewModel> uniqueAttendees)
{
if (SelectedCalendar == null)
{
ShowValidationMessage(Translator.CalendarEventCompose_ValidationMissingCalendar);
return false;
}
if (string.IsNullOrWhiteSpace(Title))
{
ShowValidationMessage(Translator.CalendarEventCompose_ValidationMissingTitle);
return false;
}
if (IsAllDay)
{
if (AllDayEndDate.Date <= StartDate.Date)
{
ShowValidationMessage(Translator.CalendarEventCompose_ValidationInvalidAllDayRange);
return false;
}
}
else if (GetEffectiveEndDateTime() <= GetEffectiveStartDateTime())
{
ShowValidationMessage(Translator.CalendarEventCompose_ValidationInvalidTimeRange);
return false;
}
if (RecurrenceEndDate.HasValue && RecurrenceEndDate.Value.Date < StartDate.Date)
{
ShowValidationMessage(Translator.CalendarEventCompose_ValidationInvalidRecurrenceEnd);
return false;
throw new CalendarEventComposeValidationException(Translator.CalendarEventCompose_ValidationInvalidRecurrenceEnd);
}
var missingAttachments = Attachments
.Where(attachment => !File.Exists(attachment.FilePath))
.Select(attachment => attachment.FileName)
.ToList();
var htmlNotes = GetHtmlNotesAsync == null ? string.Empty : await GetHtmlNotesAsync();
var effectiveStart = GetEffectiveStartDateTime();
var effectiveEnd = GetEffectiveEndDateTime();
if (missingAttachments.Count > 0)
return new CalendarEventComposeResult
{
ShowValidationMessage(string.Format(Translator.CalendarEventCompose_ValidationMissingAttachment, string.Join(", ", missingAttachments)));
return false;
}
var normalizedAttendees = Attendees
.Where(attendee => !string.IsNullOrWhiteSpace(attendee.Email))
.Select(attendee => attendee.Email.Trim())
.ToList();
if (normalizedAttendees.Any(address => !IsValidEmailAddress(address)))
{
ShowValidationMessage(Translator.CalendarEventCompose_ValidationInvalidAttendee);
return false;
}
if (GetHtmlNotesAsync != null)
{
await GetHtmlNotesAsync();
}
return true;
CalendarId = SelectedCalendar?.Id ?? Guid.Empty,
AccountId = SelectedCalendar?.Account.Id ?? Guid.Empty,
Title = Title.Trim(),
Location = Location?.Trim() ?? string.Empty,
HtmlNotes = htmlNotes,
StartDate = effectiveStart,
EndDate = effectiveEnd,
IsAllDay = IsAllDay,
TimeZoneId = TimeZoneInfo.Local.Id,
ShowAs = SelectedShowAsOption?.ShowAs ?? SelectedCalendar?.DefaultShowAs ?? CalendarItemShowAs.Busy,
SelectedReminders = BuildSelectedReminders(),
Attendees = BuildAttendees(uniqueAttendees),
Attachments = Attachments.Select(attachment => attachment.ToDraftModel()).ToList(),
Recurrence = BuildRecurrenceRule(),
RecurrenceSummary = RecurrenceSummary
};
}
private List<Reminder> BuildSelectedReminders()
@@ -676,18 +651,6 @@ public partial class CalendarEventComposePageViewModel : CalendarBaseViewModel
OnPropertyChanged(nameof(HasAttachments));
}
private static bool IsValidEmailAddress(string address)
{
try
{
var parsedAddress = new MailAddress(address);
return parsedAddress.Address.Equals(address, StringComparison.OrdinalIgnoreCase);
}
catch
{
return false;
}
}
}
public partial class CalendarComposeFrequencyOption : ObservableObject
@@ -1,20 +1,17 @@
using System;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Translations;
using Wino.Core.ViewModels;
using Wino.Messaging.Client.Calendar;
using Wino.Messaging.Client.Navigation;
namespace Wino.Calendar.ViewModels;
@@ -56,12 +53,21 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
[ObservableProperty]
public partial int SelectedDefaultSnoozeIndex { get; set; }
public ObservableCollection<MailAccount> Accounts { get; } = [];
public ObservableCollection<CalendarNewEventBehaviorOption> NewEventBehaviorOptions { get; } = [];
public ObservableCollection<AccountCalendarViewModel> AvailableNewEventCalendars { get; } = [];
[ObservableProperty]
public partial CalendarNewEventBehaviorOption SelectedNewEventBehaviorOption { get; set; }
[ObservableProperty]
public partial AccountCalendarViewModel SelectedNewEventCalendar { get; set; }
public bool ShouldShowSpecificNewEventCalendar => SelectedNewEventBehaviorOption?.Behavior == NewEventButtonBehavior.AlwaysUseSpecificCalendar;
public IPreferencesService PreferencesService { get; }
private readonly ICalendarService _calendarService;
private readonly IAccountService _accountService;
public ObservableCollection<MailAccount> Accounts { get; } = new ObservableCollection<MailAccount>();
private readonly bool _isLoaded = false;
public CalendarSettingsPageViewModel(IPreferencesService preferencesService, ICalendarService calendarService, IAccountService accountService)
@@ -71,10 +77,8 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
_accountService = accountService;
var currentLanguageLanguageCode = WinoTranslationDictionary.GetLanguageFileNameRelativePath(preferencesService.CurrentLanguage);
var cultureInfo = new CultureInfo(currentLanguageLanguageCode);
// Populate the day names list
for (var i = 0; i < 7; i++)
{
DayNames.Add(cultureInfo.DateTimeFormat.DayNames[i]);
@@ -89,7 +93,6 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
WorkingDayStartIndex = DayNames.IndexOf(cultureInfo.DateTimeFormat.GetDayName(preferencesService.WorkingDayStart));
WorkingDayEndIndex = DayNames.IndexOf(cultureInfo.DateTimeFormat.GetDayName(preferencesService.WorkingDayEnd));
// Initialize reminder options
var predefinedMinutes = _calendarService.GetPredefinedReminderMinutes();
ReminderOptions.Add("None");
foreach (var minutes in predefinedMinutes)
@@ -102,10 +105,9 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
ReminderOptions.Add(displayText);
}
// Set selected index based on current default reminder setting
if (preferencesService.DefaultReminderDurationInSeconds == 0)
{
SelectedDefaultReminderIndex = 0; // None
SelectedDefaultReminderIndex = 0;
}
else
{
@@ -123,35 +125,47 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
var selectedSnoozeIndex = Array.IndexOf(supportedSnoozeMinutes, preferencesService.DefaultSnoozeDurationInMinutes);
SelectedDefaultSnoozeIndex = selectedSnoozeIndex >= 0 ? selectedSnoozeIndex : 0;
NewEventBehaviorOptions.Add(new CalendarNewEventBehaviorOption(NewEventButtonBehavior.AskEachTime, Translator.CalendarSettings_NewEventBehavior_AskEachTime));
NewEventBehaviorOptions.Add(new CalendarNewEventBehaviorOption(NewEventButtonBehavior.AlwaysUseSpecificCalendar, Translator.CalendarSettings_NewEventBehavior_AlwaysUseSpecificCalendar));
SelectedNewEventBehaviorOption = NewEventBehaviorOptions.FirstOrDefault(option => option.Behavior == preferencesService.NewEventButtonBehavior)
?? NewEventBehaviorOptions.First();
_isLoaded = true;
// Load accounts with calendar support
LoadAccountsAsync();
}
private async void LoadAccountsAsync()
{
var accounts = await _accountService.GetAccountsAsync();
var accounts = await _accountService.GetAccountsAsync().ConfigureAwait(false);
var calendarsByAccount = new List<(MailAccount Account, List<AccountCalendarViewModel> Calendars)>();
foreach (var account in accounts)
{
var calendars = await _calendarService.GetAccountCalendarsAsync(account.Id).ConfigureAwait(false);
calendarsByAccount.Add((account, calendars.Select(calendar => new AccountCalendarViewModel(account, calendar)).ToList()));
}
await Dispatcher.ExecuteOnUIThread(() =>
{
Accounts.Clear();
AvailableNewEventCalendars.Clear();
foreach (var account in accounts)
{
Accounts.Add(account);
}
});
}
[RelayCommand]
private void NavigateToAccountSettings(MailAccount account)
{
if (account == null) return;
Messenger.Send(new BreadcrumbNavigationRequested(
string.Format(Translator.CalendarAccountSettings_Description, account.Name),
WinoPage.CalendarAccountSettingsPage,
account.Id));
foreach (var accountCalendars in calendarsByAccount)
{
foreach (var calendar in accountCalendars.Calendars)
{
AvailableNewEventCalendars.Add(calendar);
}
}
ApplyStoredNewEventCalendarPreference();
});
}
partial void OnCellHourHeightChanged(double oldValue, double newValue) => SaveSettings();
@@ -163,10 +177,17 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
partial void OnWorkingDayEndIndexChanged(int value) => SaveSettings();
partial void OnSelectedDefaultReminderIndexChanged(int value) => SaveSettings();
partial void OnSelectedDefaultSnoozeIndexChanged(int value) => SaveSettings();
partial void OnSelectedNewEventBehaviorOptionChanged(CalendarNewEventBehaviorOption value)
{
OnPropertyChanged(nameof(ShouldShowSpecificNewEventCalendar));
SaveSettings();
}
partial void OnSelectedNewEventCalendarChanged(AccountCalendarViewModel value) => SaveSettings();
public void SaveSettings()
{
if (!_isLoaded) return;
if (!_isLoaded)
return;
PreferencesService.FirstDayOfWeek = SelectedFirstDayOfWeekIndex switch
{
@@ -209,10 +230,9 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
PreferencesService.WorkingHourEnd = WorkingHourEnd;
PreferencesService.HourHeight = CellHourHeight;
// Save default reminder setting
if (SelectedDefaultReminderIndex == 0)
{
PreferencesService.DefaultReminderDurationInSeconds = 0; // None
PreferencesService.DefaultReminderDurationInSeconds = 0;
}
else
{
@@ -228,6 +248,47 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
PreferencesService.DefaultSnoozeDurationInMinutes = supportedSnoozeMinutes[selectedIndex];
}
Messenger.Send(new CalendarSettingsUpdatedMessage());
var newEventBehavior = SelectedNewEventBehaviorOption?.Behavior ?? NewEventButtonBehavior.AskEachTime;
if (newEventBehavior == NewEventButtonBehavior.AlwaysUseSpecificCalendar && SelectedNewEventCalendar != null)
{
PreferencesService.NewEventButtonBehavior = NewEventButtonBehavior.AlwaysUseSpecificCalendar;
PreferencesService.DefaultNewEventCalendarId = SelectedNewEventCalendar.Id;
}
else
{
PreferencesService.NewEventButtonBehavior = NewEventButtonBehavior.AskEachTime;
PreferencesService.DefaultNewEventCalendarId = null;
}
}
private void ApplyStoredNewEventCalendarPreference()
{
var configuredCalendarId = PreferencesService.DefaultNewEventCalendarId;
var configuredCalendar = configuredCalendarId.HasValue
? AvailableNewEventCalendars.FirstOrDefault(calendar => calendar.Id == configuredCalendarId.Value)
: null;
if (PreferencesService.NewEventButtonBehavior == NewEventButtonBehavior.AlwaysUseSpecificCalendar && configuredCalendar == null)
{
SelectedNewEventBehaviorOption = NewEventBehaviorOptions.First(option => option.Behavior == NewEventButtonBehavior.AskEachTime);
SelectedNewEventCalendar = null;
return;
}
SelectedNewEventCalendar = configuredCalendar
?? AvailableNewEventCalendars.FirstOrDefault(calendar => calendar.IsPrimary)
?? AvailableNewEventCalendars.FirstOrDefault();
}
}
public sealed class CalendarNewEventBehaviorOption
{
public NewEventButtonBehavior Behavior { get; }
public string DisplayText { get; }
public CalendarNewEventBehaviorOption(NewEventButtonBehavior behavior, string displayText)
{
Behavior = behavior;
DisplayText = displayText;
}
}
@@ -10,7 +10,8 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TimePeriodLibrary.NET" />
<PackageReference Include="TimePeriodLibrary.NET" />
<PackageReference Include="EmailValidation" />
</ItemGroup>
<ItemGroup>