Files
Wino-Mail/Wino.Calendar.ViewModels/CalendarSettingsPageViewModel.cs
T

295 lines
12 KiB
C#
Raw Normal View History

2026-03-07 01:46:07 +01:00
using System;
2024-11-10 23:28:25 +01:00
using System.Collections.Generic;
using System.Collections.ObjectModel;
2024-11-10 23:28:25 +01:00
using System.Globalization;
2026-01-01 15:02:40 +01:00
using System.Linq;
using System.Threading.Tasks;
2024-11-10 23:28:25 +01:00
using CommunityToolkit.Mvvm.ComponentModel;
2026-03-07 01:46:07 +01:00
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
2024-11-10 23:28:25 +01:00
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Translations;
using Wino.Core.ViewModels;
2025-05-18 14:06:25 +02:00
namespace Wino.Calendar.ViewModels;
public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
2024-11-10 23:28:25 +01:00
{
2025-05-18 14:06:25 +02:00
[ObservableProperty]
2025-12-31 13:28:53 +01:00
public partial double CellHourHeight { get; set; }
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
[ObservableProperty]
2025-12-31 13:28:53 +01:00
public partial int SelectedFirstDayOfWeekIndex { get; set; }
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
[ObservableProperty]
2025-12-31 13:28:53 +01:00
public partial bool Is24HourHeaders { get; set; }
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
[ObservableProperty]
2025-12-31 13:28:53 +01:00
public partial TimeSpan WorkingHourStart { get; set; }
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
[ObservableProperty]
2025-12-31 13:28:53 +01:00
public partial TimeSpan WorkingHourEnd { get; set; }
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
[ObservableProperty]
2025-12-31 13:28:53 +01:00
public partial List<string> DayNames { get; set; } = [];
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
[ObservableProperty]
2025-12-31 13:28:53 +01:00
public partial int WorkingDayStartIndex { get; set; }
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
[ObservableProperty]
2025-12-31 13:28:53 +01:00
public partial int WorkingDayEndIndex { get; set; }
2026-01-01 15:02:40 +01:00
[ObservableProperty]
public partial List<string> ReminderOptions { get; set; } = [];
[ObservableProperty]
public partial int SelectedDefaultReminderIndex { get; set; }
[ObservableProperty]
public partial List<string> SnoozeOptions { get; set; } = [];
[ObservableProperty]
public partial int SelectedDefaultSnoozeIndex { get; set; }
2026-03-07 01:46:07 +01:00
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;
2025-05-18 14:06:25 +02:00
public IPreferencesService PreferencesService { get; }
2026-01-01 15:02:40 +01:00
private readonly ICalendarService _calendarService;
private readonly IAccountService _accountService;
2025-05-18 14:06:25 +02:00
private readonly bool _isLoaded = false;
2024-11-10 23:28:25 +01:00
public CalendarSettingsPageViewModel(IPreferencesService preferencesService, ICalendarService calendarService, IAccountService accountService)
2025-05-18 14:06:25 +02:00
{
PreferencesService = preferencesService;
2026-01-01 15:02:40 +01:00
_calendarService = calendarService;
_accountService = accountService;
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
var currentLanguageLanguageCode = WinoTranslationDictionary.GetLanguageFileNameRelativePath(preferencesService.CurrentLanguage);
var cultureInfo = new CultureInfo(currentLanguageLanguageCode);
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
for (var i = 0; i < 7; i++)
{
2025-12-31 13:28:53 +01:00
DayNames.Add(cultureInfo.DateTimeFormat.DayNames[i]);
2025-05-18 14:06:25 +02:00
}
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
var cultureFirstDayName = cultureInfo.DateTimeFormat.GetDayName(preferencesService.FirstDayOfWeek);
2025-12-31 13:28:53 +01:00
SelectedFirstDayOfWeekIndex = DayNames.IndexOf(cultureFirstDayName);
Is24HourHeaders = preferencesService.Prefer24HourTimeFormat;
WorkingHourStart = preferencesService.WorkingHourStart;
WorkingHourEnd = preferencesService.WorkingHourEnd;
CellHourHeight = preferencesService.HourHeight;
WorkingDayStartIndex = DayNames.IndexOf(cultureInfo.DateTimeFormat.GetDayName(preferencesService.WorkingDayStart));
WorkingDayEndIndex = DayNames.IndexOf(cultureInfo.DateTimeFormat.GetDayName(preferencesService.WorkingDayEnd));
2024-11-10 23:28:25 +01:00
2026-01-01 15:02:40 +01:00
var predefinedMinutes = _calendarService.GetPredefinedReminderMinutes();
ReminderOptions.Add("None");
foreach (var minutes in predefinedMinutes)
{
var displayText = minutes switch
{
>= 60 => $"{minutes / 60} Hour{(minutes / 60 > 1 ? "s" : "")}",
_ => $"{minutes} Minute{(minutes > 1 ? "s" : "")}"
};
ReminderOptions.Add(displayText);
}
if (preferencesService.DefaultReminderDurationInSeconds == 0)
{
2026-03-07 01:46:07 +01:00
SelectedDefaultReminderIndex = 0;
2026-01-01 15:02:40 +01:00
}
else
{
var minutes = (int)(preferencesService.DefaultReminderDurationInSeconds / 60);
var index = Array.IndexOf(predefinedMinutes, minutes);
SelectedDefaultReminderIndex = index >= 0 ? index + 1 : 0;
}
var supportedSnoozeMinutes = CalendarReminderSnoozeOptions.GetSupportedSnoozeMinutes().ToArray();
foreach (var snoozeMinutes in supportedSnoozeMinutes)
{
SnoozeOptions.Add(string.Format(Translator.CalendarReminder_SnoozeMinutesOption, snoozeMinutes));
}
var selectedSnoozeIndex = Array.IndexOf(supportedSnoozeMinutes, preferencesService.DefaultSnoozeDurationInMinutes);
SelectedDefaultSnoozeIndex = selectedSnoozeIndex >= 0 ? selectedSnoozeIndex : 0;
2026-03-07 01:46:07 +01:00
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();
2025-05-18 14:06:25 +02:00
_isLoaded = true;
LoadAccountsAsync();
}
private async void LoadAccountsAsync()
{
2026-03-07 01:46:07 +01:00
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();
2026-03-07 01:46:07 +01:00
AvailableNewEventCalendars.Clear();
foreach (var account in accounts)
{
Accounts.Add(account);
}
2026-03-07 01:46:07 +01:00
foreach (var accountCalendars in calendarsByAccount)
{
foreach (var calendar in accountCalendars.Calendars)
{
AvailableNewEventCalendars.Add(calendar);
}
}
ApplyStoredNewEventCalendarPreference();
});
2025-05-18 14:06:25 +02:00
}
partial void OnCellHourHeightChanged(double oldValue, double newValue) => SaveSettings();
partial void OnIs24HourHeadersChanged(bool value) => SaveSettings();
partial void OnSelectedFirstDayOfWeekIndexChanged(int value) => SaveSettings();
partial void OnWorkingHourStartChanged(TimeSpan value) => SaveSettings();
partial void OnWorkingHourEndChanged(TimeSpan value) => SaveSettings();
partial void OnWorkingDayStartIndexChanged(int value) => SaveSettings();
partial void OnWorkingDayEndIndexChanged(int value) => SaveSettings();
2026-01-01 15:02:40 +01:00
partial void OnSelectedDefaultReminderIndexChanged(int value) => SaveSettings();
partial void OnSelectedDefaultSnoozeIndexChanged(int value) => SaveSettings();
2026-03-07 01:46:07 +01:00
partial void OnSelectedNewEventBehaviorOptionChanged(CalendarNewEventBehaviorOption value)
{
OnPropertyChanged(nameof(ShouldShowSpecificNewEventCalendar));
SaveSettings();
}
partial void OnSelectedNewEventCalendarChanged(AccountCalendarViewModel value) => SaveSettings();
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
public void SaveSettings()
{
2026-03-07 01:46:07 +01:00
if (!_isLoaded)
return;
2024-11-10 23:28:25 +01:00
2025-05-18 14:06:25 +02:00
PreferencesService.FirstDayOfWeek = SelectedFirstDayOfWeekIndex switch
2024-11-10 23:28:25 +01:00
{
2025-05-18 14:06:25 +02:00
0 => DayOfWeek.Sunday,
1 => DayOfWeek.Monday,
2 => DayOfWeek.Tuesday,
3 => DayOfWeek.Wednesday,
4 => DayOfWeek.Thursday,
5 => DayOfWeek.Friday,
6 => DayOfWeek.Saturday,
_ => throw new ArgumentOutOfRangeException()
};
PreferencesService.WorkingDayStart = WorkingDayStartIndex switch
{
0 => DayOfWeek.Sunday,
1 => DayOfWeek.Monday,
2 => DayOfWeek.Tuesday,
3 => DayOfWeek.Wednesday,
4 => DayOfWeek.Thursday,
5 => DayOfWeek.Friday,
6 => DayOfWeek.Saturday,
_ => throw new ArgumentOutOfRangeException()
};
PreferencesService.WorkingDayEnd = WorkingDayEndIndex switch
{
0 => DayOfWeek.Sunday,
1 => DayOfWeek.Monday,
2 => DayOfWeek.Tuesday,
3 => DayOfWeek.Wednesday,
4 => DayOfWeek.Thursday,
5 => DayOfWeek.Friday,
6 => DayOfWeek.Saturday,
_ => throw new ArgumentOutOfRangeException()
};
PreferencesService.Prefer24HourTimeFormat = Is24HourHeaders;
PreferencesService.WorkingHourStart = WorkingHourStart;
PreferencesService.WorkingHourEnd = WorkingHourEnd;
PreferencesService.HourHeight = CellHourHeight;
2026-01-01 15:02:40 +01:00
if (SelectedDefaultReminderIndex == 0)
{
2026-03-07 01:46:07 +01:00
PreferencesService.DefaultReminderDurationInSeconds = 0;
2026-01-01 15:02:40 +01:00
}
else
{
var predefinedMinutes = _calendarService.GetPredefinedReminderMinutes();
var minutes = predefinedMinutes[SelectedDefaultReminderIndex - 1];
PreferencesService.DefaultReminderDurationInSeconds = minutes * 60;
}
var supportedSnoozeMinutes = CalendarReminderSnoozeOptions.GetSupportedSnoozeMinutes();
if (supportedSnoozeMinutes.Count > 0)
{
var selectedIndex = Math.Clamp(SelectedDefaultSnoozeIndex, 0, supportedSnoozeMinutes.Count - 1);
PreferencesService.DefaultSnoozeDurationInMinutes = supportedSnoozeMinutes[selectedIndex];
}
2026-03-07 01:46:07 +01:00
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;
2024-11-10 23:28:25 +01:00
}
}