dotnet format refactorings.
This commit is contained in:
@@ -21,347 +21,346 @@ using Wino.Messaging.Client.Calendar;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
using Wino.Messaging.Server;
|
||||
|
||||
namespace Wino.Calendar.ViewModels
|
||||
namespace Wino.Calendar.ViewModels;
|
||||
|
||||
public partial class AppShellViewModel : CalendarBaseViewModel,
|
||||
IRecipient<VisibleDateRangeChangedMessage>,
|
||||
IRecipient<CalendarEnableStatusChangedMessage>,
|
||||
IRecipient<NavigateManageAccountsRequested>,
|
||||
IRecipient<CalendarDisplayTypeChangedMessage>,
|
||||
IRecipient<DetailsPageStateChangedMessage>
|
||||
{
|
||||
public partial class AppShellViewModel : CalendarBaseViewModel,
|
||||
IRecipient<VisibleDateRangeChangedMessage>,
|
||||
IRecipient<CalendarEnableStatusChangedMessage>,
|
||||
IRecipient<NavigateManageAccountsRequested>,
|
||||
IRecipient<CalendarDisplayTypeChangedMessage>,
|
||||
IRecipient<DetailsPageStateChangedMessage>
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
public IStatePersistanceService StatePersistenceService { get; }
|
||||
public IAccountCalendarStateService AccountCalendarStateService { get; }
|
||||
public INavigationService NavigationService { get; }
|
||||
public IWinoServerConnectionManager ServerConnectionManager { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEventDetailsPageActive;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _selectedMenuItemIndex = -1;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isCalendarEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the active connection status of the Wino server.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private WinoServerConnectionStatus activeConnectionStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display date of the calendar.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private DateTimeOffset _displayDate;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the highlighted range in the CalendarView and displayed date range in FlipView.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private DateRange highlightedDateRange;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableRangeCollection<string> dateNavigationHeaderItems = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private int _selectedDateNavigationHeaderIndex;
|
||||
|
||||
public bool IsVerticalCalendar => StatePersistenceService.CalendarDisplayType == CalendarDisplayType.Month;
|
||||
|
||||
// For updating account calendars asynchronously.
|
||||
private SemaphoreSlim _accountCalendarUpdateSemaphoreSlim = new(1);
|
||||
|
||||
public AppShellViewModel(IPreferencesService preferencesService,
|
||||
IStatePersistanceService statePersistanceService,
|
||||
IAccountService accountService,
|
||||
ICalendarService calendarService,
|
||||
IAccountCalendarStateService accountCalendarStateService,
|
||||
INavigationService navigationService,
|
||||
IWinoServerConnectionManager serverConnectionManager)
|
||||
{
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
public IStatePersistanceService StatePersistenceService { get; }
|
||||
public IAccountCalendarStateService AccountCalendarStateService { get; }
|
||||
public INavigationService NavigationService { get; }
|
||||
public IWinoServerConnectionManager ServerConnectionManager { get; }
|
||||
_accountService = accountService;
|
||||
_calendarService = calendarService;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEventDetailsPageActive;
|
||||
AccountCalendarStateService = accountCalendarStateService;
|
||||
AccountCalendarStateService.AccountCalendarSelectionStateChanged += UpdateAccountCalendarRequested;
|
||||
AccountCalendarStateService.CollectiveAccountGroupSelectionStateChanged += AccountCalendarStateCollectivelyChanged;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _selectedMenuItemIndex = -1;
|
||||
NavigationService = navigationService;
|
||||
ServerConnectionManager = serverConnectionManager;
|
||||
PreferencesService = preferencesService;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isCalendarEnabled;
|
||||
StatePersistenceService = statePersistanceService;
|
||||
StatePersistenceService.StatePropertyChanged += PrefefencesChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the active connection status of the Wino server.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private WinoServerConnectionStatus activeConnectionStatus;
|
||||
private void SelectedCalendarItemsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display date of the calendar.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private DateTimeOffset _displayDate;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the highlighted range in the CalendarView and displayed date range in FlipView.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private DateRange highlightedDateRange;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableRangeCollection<string> dateNavigationHeaderItems = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private int _selectedDateNavigationHeaderIndex;
|
||||
|
||||
public bool IsVerticalCalendar => StatePersistenceService.CalendarDisplayType == CalendarDisplayType.Month;
|
||||
|
||||
// For updating account calendars asynchronously.
|
||||
private SemaphoreSlim _accountCalendarUpdateSemaphoreSlim = new(1);
|
||||
|
||||
public AppShellViewModel(IPreferencesService preferencesService,
|
||||
IStatePersistanceService statePersistanceService,
|
||||
IAccountService accountService,
|
||||
ICalendarService calendarService,
|
||||
IAccountCalendarStateService accountCalendarStateService,
|
||||
INavigationService navigationService,
|
||||
IWinoServerConnectionManager serverConnectionManager)
|
||||
private void PrefefencesChanged(object sender, string e)
|
||||
{
|
||||
if (e == nameof(StatePersistenceService.CalendarDisplayType))
|
||||
{
|
||||
_accountService = accountService;
|
||||
_calendarService = calendarService;
|
||||
Messenger.Send(new CalendarDisplayTypeChangedMessage(StatePersistenceService.CalendarDisplayType));
|
||||
|
||||
AccountCalendarStateService = accountCalendarStateService;
|
||||
AccountCalendarStateService.AccountCalendarSelectionStateChanged += UpdateAccountCalendarRequested;
|
||||
AccountCalendarStateService.CollectiveAccountGroupSelectionStateChanged += AccountCalendarStateCollectivelyChanged;
|
||||
|
||||
NavigationService = navigationService;
|
||||
ServerConnectionManager = serverConnectionManager;
|
||||
PreferencesService = preferencesService;
|
||||
|
||||
StatePersistenceService = statePersistanceService;
|
||||
StatePersistenceService.StatePropertyChanged += PrefefencesChanged;
|
||||
// Change the calendar.
|
||||
DateClicked(new CalendarViewDayClickedEventArgs(GetDisplayTypeSwitchDate()));
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectedCalendarItemsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
|
||||
{
|
||||
base.OnNavigatedTo(mode, parameters);
|
||||
|
||||
private void PrefefencesChanged(object sender, string e)
|
||||
UpdateDateNavigationHeaderItems();
|
||||
|
||||
await InitializeAccountCalendarsAsync();
|
||||
|
||||
TodayClicked();
|
||||
}
|
||||
|
||||
private async void AccountCalendarStateCollectivelyChanged(object sender, GroupedAccountCalendarViewModel e)
|
||||
{
|
||||
// When using three-state checkbox, multiple accounts will be selected/unselected at the same time.
|
||||
// Reporting all these changes one by one to the UI is not efficient and may cause problems in the future.
|
||||
|
||||
// Update all calendar states at once.
|
||||
try
|
||||
{
|
||||
if (e == nameof(StatePersistenceService.CalendarDisplayType))
|
||||
await _accountCalendarUpdateSemaphoreSlim.WaitAsync();
|
||||
|
||||
foreach (var calendar in e.AccountCalendars)
|
||||
{
|
||||
Messenger.Send(new CalendarDisplayTypeChangedMessage(StatePersistenceService.CalendarDisplayType));
|
||||
|
||||
|
||||
// Change the calendar.
|
||||
DateClicked(new CalendarViewDayClickedEventArgs(GetDisplayTypeSwitchDate()));
|
||||
await _calendarService.UpdateAccountCalendarAsync(calendar.AccountCalendar).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
|
||||
catch (Exception ex)
|
||||
{
|
||||
base.OnNavigatedTo(mode, parameters);
|
||||
|
||||
UpdateDateNavigationHeaderItems();
|
||||
|
||||
await InitializeAccountCalendarsAsync();
|
||||
|
||||
TodayClicked();
|
||||
Log.Error(ex, "Error while waiting for account calendar update semaphore.");
|
||||
}
|
||||
|
||||
private async void AccountCalendarStateCollectivelyChanged(object sender, GroupedAccountCalendarViewModel e)
|
||||
finally
|
||||
{
|
||||
// When using three-state checkbox, multiple accounts will be selected/unselected at the same time.
|
||||
// Reporting all these changes one by one to the UI is not efficient and may cause problems in the future.
|
||||
|
||||
// Update all calendar states at once.
|
||||
try
|
||||
{
|
||||
await _accountCalendarUpdateSemaphoreSlim.WaitAsync();
|
||||
|
||||
foreach (var calendar in e.AccountCalendars)
|
||||
{
|
||||
await _calendarService.UpdateAccountCalendarAsync(calendar.AccountCalendar).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error while waiting for account calendar update semaphore.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_accountCalendarUpdateSemaphoreSlim.Release();
|
||||
}
|
||||
_accountCalendarUpdateSemaphoreSlim.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private async void UpdateAccountCalendarRequested(object sender, AccountCalendarViewModel e)
|
||||
=> await _calendarService.UpdateAccountCalendarAsync(e.AccountCalendar).ConfigureAwait(false);
|
||||
private async void UpdateAccountCalendarRequested(object sender, AccountCalendarViewModel e)
|
||||
=> await _calendarService.UpdateAccountCalendarAsync(e.AccountCalendar).ConfigureAwait(false);
|
||||
|
||||
private async Task InitializeAccountCalendarsAsync()
|
||||
private async Task InitializeAccountCalendarsAsync()
|
||||
{
|
||||
await Dispatcher.ExecuteOnUIThread(() => AccountCalendarStateService.ClearGroupedAccountCalendar());
|
||||
|
||||
var accounts = await _accountService.GetAccountsAsync().ConfigureAwait(false);
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
await Dispatcher.ExecuteOnUIThread(() => AccountCalendarStateService.ClearGroupedAccountCalendar());
|
||||
var accountCalendars = await _calendarService.GetAccountCalendarsAsync(account.Id).ConfigureAwait(false);
|
||||
var calendarViewModels = new List<AccountCalendarViewModel>();
|
||||
|
||||
var accounts = await _accountService.GetAccountsAsync().ConfigureAwait(false);
|
||||
|
||||
foreach (var account in accounts)
|
||||
foreach (var calendar in accountCalendars)
|
||||
{
|
||||
var accountCalendars = await _calendarService.GetAccountCalendarsAsync(account.Id).ConfigureAwait(false);
|
||||
var calendarViewModels = new List<AccountCalendarViewModel>();
|
||||
var calendarViewModel = new AccountCalendarViewModel(account, calendar);
|
||||
|
||||
foreach (var calendar in accountCalendars)
|
||||
{
|
||||
var calendarViewModel = new AccountCalendarViewModel(account, calendar);
|
||||
|
||||
calendarViewModels.Add(calendarViewModel);
|
||||
}
|
||||
|
||||
var groupedAccountCalendarViewModel = new GroupedAccountCalendarViewModel(account, calendarViewModels);
|
||||
|
||||
await Dispatcher.ExecuteOnUIThread(() =>
|
||||
{
|
||||
AccountCalendarStateService.AddGroupedAccountCalendar(groupedAccountCalendarViewModel);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void ForceNavigateCalendarDate()
|
||||
{
|
||||
if (SelectedMenuItemIndex == -1)
|
||||
{
|
||||
var args = new CalendarPageNavigationArgs()
|
||||
{
|
||||
NavigationDate = _navigationDate ?? DateTime.Now.Date
|
||||
};
|
||||
|
||||
// Already on calendar. Just navigate.
|
||||
NavigationService.Navigate(WinoPage.CalendarPage, args);
|
||||
|
||||
_navigationDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedMenuItemIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
partial void OnSelectedMenuItemIndexChanged(int oldValue, int newValue)
|
||||
{
|
||||
switch (newValue)
|
||||
{
|
||||
case -1:
|
||||
ForceNavigateCalendarDate();
|
||||
break;
|
||||
case 0:
|
||||
NavigationService.Navigate(WinoPage.ManageAccountsPage);
|
||||
break;
|
||||
case 1:
|
||||
NavigationService.Navigate(WinoPage.SettingsPage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task Sync()
|
||||
{
|
||||
// Sync all calendars.
|
||||
var accounts = await _accountService.GetAccountsAsync().ConfigureAwait(false);
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
var t = new NewCalendarSynchronizationRequested(new CalendarSynchronizationOptions()
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Type = CalendarSynchronizationType.CalendarMetadata
|
||||
}, SynchronizationSource.Client);
|
||||
|
||||
Messenger.Send(t);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When calendar type switches, we need to navigate to the most ideal date.
|
||||
/// This method returns that date.
|
||||
/// </summary>
|
||||
private DateTime GetDisplayTypeSwitchDate()
|
||||
{
|
||||
var settings = PreferencesService.GetCurrentCalendarSettings();
|
||||
switch (StatePersistenceService.CalendarDisplayType)
|
||||
{
|
||||
case CalendarDisplayType.Day:
|
||||
if (HighlightedDateRange.IsInRange(DateTime.Now)) return DateTime.Now.Date;
|
||||
|
||||
return HighlightedDateRange.StartDate;
|
||||
case CalendarDisplayType.Week:
|
||||
if (HighlightedDateRange == null || HighlightedDateRange.IsInRange(DateTime.Now))
|
||||
{
|
||||
return DateTime.Now.Date.GetWeekStartDateForDate(settings.FirstDayOfWeek);
|
||||
}
|
||||
|
||||
return HighlightedDateRange.StartDate.GetWeekStartDateForDate(settings.FirstDayOfWeek);
|
||||
case CalendarDisplayType.WorkWeek:
|
||||
break;
|
||||
case CalendarDisplayType.Month:
|
||||
break;
|
||||
case CalendarDisplayType.Year:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
calendarViewModels.Add(calendarViewModel);
|
||||
}
|
||||
|
||||
return DateTime.Today.Date;
|
||||
}
|
||||
var groupedAccountCalendarViewModel = new GroupedAccountCalendarViewModel(account, calendarViewModels);
|
||||
|
||||
private DateTime? _navigationDate;
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly ICalendarService _calendarService;
|
||||
|
||||
#region Commands
|
||||
|
||||
[RelayCommand]
|
||||
private void TodayClicked()
|
||||
{
|
||||
_navigationDate = DateTime.Now.Date;
|
||||
|
||||
ForceNavigateCalendarDate();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void ManageAccounts() => NavigationService.Navigate(WinoPage.AccountManagementPage);
|
||||
|
||||
[RelayCommand]
|
||||
private Task ReconnectServerAsync() => ServerConnectionManager.ConnectAsync();
|
||||
|
||||
[RelayCommand]
|
||||
private void DateClicked(CalendarViewDayClickedEventArgs clickedDateArgs)
|
||||
{
|
||||
_navigationDate = clickedDateArgs.ClickedDate;
|
||||
|
||||
ForceNavigateCalendarDate();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Receive(VisibleDateRangeChangedMessage message) => HighlightedDateRange = message.DateRange;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the header navigation items based on visible date range and calendar type.
|
||||
/// </summary>
|
||||
private void UpdateDateNavigationHeaderItems()
|
||||
{
|
||||
DateNavigationHeaderItems.Clear();
|
||||
|
||||
// TODO: From settings
|
||||
var testInfo = new CultureInfo("en-US");
|
||||
|
||||
switch (StatePersistenceService.CalendarDisplayType)
|
||||
await Dispatcher.ExecuteOnUIThread(() =>
|
||||
{
|
||||
case CalendarDisplayType.Day:
|
||||
case CalendarDisplayType.Week:
|
||||
case CalendarDisplayType.WorkWeek:
|
||||
case CalendarDisplayType.Month:
|
||||
DateNavigationHeaderItems.ReplaceRange(testInfo.DateTimeFormat.MonthNames);
|
||||
break;
|
||||
case CalendarDisplayType.Year:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SetDateNavigationHeaderItems();
|
||||
}
|
||||
|
||||
partial void OnHighlightedDateRangeChanged(DateRange value) => SetDateNavigationHeaderItems();
|
||||
|
||||
private void SetDateNavigationHeaderItems()
|
||||
{
|
||||
if (HighlightedDateRange == null) return;
|
||||
|
||||
if (DateNavigationHeaderItems.Count == 0)
|
||||
{
|
||||
UpdateDateNavigationHeaderItems();
|
||||
}
|
||||
|
||||
// TODO: Year view
|
||||
var monthIndex = HighlightedDateRange.GetMostVisibleMonthIndex();
|
||||
|
||||
SelectedDateNavigationHeaderIndex = Math.Max(monthIndex - 1, -1);
|
||||
}
|
||||
|
||||
public async void Receive(CalendarEnableStatusChangedMessage message)
|
||||
=> await ExecuteUIThread(() => IsCalendarEnabled = message.IsEnabled);
|
||||
|
||||
public void Receive(NavigateManageAccountsRequested message) => SelectedMenuItemIndex = 1;
|
||||
|
||||
public void Receive(CalendarDisplayTypeChangedMessage message) => OnPropertyChanged(nameof(IsVerticalCalendar));
|
||||
|
||||
public async void Receive(DetailsPageStateChangedMessage message)
|
||||
{
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
IsEventDetailsPageActive = message.IsActivated;
|
||||
|
||||
// TODO: This is for Wino Mail. Generalize this later on.
|
||||
StatePersistenceService.IsReaderNarrowed = message.IsActivated;
|
||||
StatePersistenceService.IsReadingMail = message.IsActivated;
|
||||
AccountCalendarStateService.AddGroupedAccountCalendar(groupedAccountCalendarViewModel);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void ForceNavigateCalendarDate()
|
||||
{
|
||||
if (SelectedMenuItemIndex == -1)
|
||||
{
|
||||
var args = new CalendarPageNavigationArgs()
|
||||
{
|
||||
NavigationDate = _navigationDate ?? DateTime.Now.Date
|
||||
};
|
||||
|
||||
// Already on calendar. Just navigate.
|
||||
NavigationService.Navigate(WinoPage.CalendarPage, args);
|
||||
|
||||
_navigationDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedMenuItemIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
partial void OnSelectedMenuItemIndexChanged(int oldValue, int newValue)
|
||||
{
|
||||
switch (newValue)
|
||||
{
|
||||
case -1:
|
||||
ForceNavigateCalendarDate();
|
||||
break;
|
||||
case 0:
|
||||
NavigationService.Navigate(WinoPage.ManageAccountsPage);
|
||||
break;
|
||||
case 1:
|
||||
NavigationService.Navigate(WinoPage.SettingsPage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task Sync()
|
||||
{
|
||||
// Sync all calendars.
|
||||
var accounts = await _accountService.GetAccountsAsync().ConfigureAwait(false);
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
var t = new NewCalendarSynchronizationRequested(new CalendarSynchronizationOptions()
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Type = CalendarSynchronizationType.CalendarMetadata
|
||||
}, SynchronizationSource.Client);
|
||||
|
||||
Messenger.Send(t);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When calendar type switches, we need to navigate to the most ideal date.
|
||||
/// This method returns that date.
|
||||
/// </summary>
|
||||
private DateTime GetDisplayTypeSwitchDate()
|
||||
{
|
||||
var settings = PreferencesService.GetCurrentCalendarSettings();
|
||||
switch (StatePersistenceService.CalendarDisplayType)
|
||||
{
|
||||
case CalendarDisplayType.Day:
|
||||
if (HighlightedDateRange.IsInRange(DateTime.Now)) return DateTime.Now.Date;
|
||||
|
||||
return HighlightedDateRange.StartDate;
|
||||
case CalendarDisplayType.Week:
|
||||
if (HighlightedDateRange == null || HighlightedDateRange.IsInRange(DateTime.Now))
|
||||
{
|
||||
return DateTime.Now.Date.GetWeekStartDateForDate(settings.FirstDayOfWeek);
|
||||
}
|
||||
|
||||
return HighlightedDateRange.StartDate.GetWeekStartDateForDate(settings.FirstDayOfWeek);
|
||||
case CalendarDisplayType.WorkWeek:
|
||||
break;
|
||||
case CalendarDisplayType.Month:
|
||||
break;
|
||||
case CalendarDisplayType.Year:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DateTime.Today.Date;
|
||||
}
|
||||
|
||||
private DateTime? _navigationDate;
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly ICalendarService _calendarService;
|
||||
|
||||
#region Commands
|
||||
|
||||
[RelayCommand]
|
||||
private void TodayClicked()
|
||||
{
|
||||
_navigationDate = DateTime.Now.Date;
|
||||
|
||||
ForceNavigateCalendarDate();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void ManageAccounts() => NavigationService.Navigate(WinoPage.AccountManagementPage);
|
||||
|
||||
[RelayCommand]
|
||||
private Task ReconnectServerAsync() => ServerConnectionManager.ConnectAsync();
|
||||
|
||||
[RelayCommand]
|
||||
private void DateClicked(CalendarViewDayClickedEventArgs clickedDateArgs)
|
||||
{
|
||||
_navigationDate = clickedDateArgs.ClickedDate;
|
||||
|
||||
ForceNavigateCalendarDate();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Receive(VisibleDateRangeChangedMessage message) => HighlightedDateRange = message.DateRange;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the header navigation items based on visible date range and calendar type.
|
||||
/// </summary>
|
||||
private void UpdateDateNavigationHeaderItems()
|
||||
{
|
||||
DateNavigationHeaderItems.Clear();
|
||||
|
||||
// TODO: From settings
|
||||
var testInfo = new CultureInfo("en-US");
|
||||
|
||||
switch (StatePersistenceService.CalendarDisplayType)
|
||||
{
|
||||
case CalendarDisplayType.Day:
|
||||
case CalendarDisplayType.Week:
|
||||
case CalendarDisplayType.WorkWeek:
|
||||
case CalendarDisplayType.Month:
|
||||
DateNavigationHeaderItems.ReplaceRange(testInfo.DateTimeFormat.MonthNames);
|
||||
break;
|
||||
case CalendarDisplayType.Year:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SetDateNavigationHeaderItems();
|
||||
}
|
||||
|
||||
partial void OnHighlightedDateRangeChanged(DateRange value) => SetDateNavigationHeaderItems();
|
||||
|
||||
private void SetDateNavigationHeaderItems()
|
||||
{
|
||||
if (HighlightedDateRange == null) return;
|
||||
|
||||
if (DateNavigationHeaderItems.Count == 0)
|
||||
{
|
||||
UpdateDateNavigationHeaderItems();
|
||||
}
|
||||
|
||||
// TODO: Year view
|
||||
var monthIndex = HighlightedDateRange.GetMostVisibleMonthIndex();
|
||||
|
||||
SelectedDateNavigationHeaderIndex = Math.Max(monthIndex - 1, -1);
|
||||
}
|
||||
|
||||
public async void Receive(CalendarEnableStatusChangedMessage message)
|
||||
=> await ExecuteUIThread(() => IsCalendarEnabled = message.IsEnabled);
|
||||
|
||||
public void Receive(NavigateManageAccountsRequested message) => SelectedMenuItemIndex = 1;
|
||||
|
||||
public void Receive(CalendarDisplayTypeChangedMessage message) => OnPropertyChanged(nameof(IsVerticalCalendar));
|
||||
|
||||
public async void Receive(DetailsPageStateChangedMessage message)
|
||||
{
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
IsEventDetailsPageActive = message.IsActivated;
|
||||
|
||||
// TODO: This is for Wino Mail. Generalize this later on.
|
||||
StatePersistenceService.IsReaderNarrowed = message.IsActivated;
|
||||
StatePersistenceService.IsReadingMail = message.IsActivated;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,120 +8,119 @@ using Wino.Core.Domain.Translations;
|
||||
using Wino.Core.ViewModels;
|
||||
using Wino.Messaging.Client.Calendar;
|
||||
|
||||
namespace Wino.Calendar.ViewModels
|
||||
namespace Wino.Calendar.ViewModels;
|
||||
|
||||
public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
|
||||
{
|
||||
public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
|
||||
[ObservableProperty]
|
||||
private double _cellHourHeight;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _selectedFirstDayOfWeekIndex;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _is24HourHeaders;
|
||||
|
||||
[ObservableProperty]
|
||||
private TimeSpan _workingHourStart;
|
||||
|
||||
[ObservableProperty]
|
||||
private TimeSpan _workingHourEnd;
|
||||
|
||||
[ObservableProperty]
|
||||
private List<string> _dayNames = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private int _workingDayStartIndex;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _workingDayEndIndex;
|
||||
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
|
||||
private readonly bool _isLoaded = false;
|
||||
|
||||
public CalendarSettingsPageViewModel(IPreferencesService preferencesService)
|
||||
{
|
||||
[ObservableProperty]
|
||||
private double _cellHourHeight;
|
||||
PreferencesService = preferencesService;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _selectedFirstDayOfWeekIndex;
|
||||
var currentLanguageLanguageCode = WinoTranslationDictionary.GetLanguageFileNameRelativePath(preferencesService.CurrentLanguage);
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _is24HourHeaders;
|
||||
var cultureInfo = new CultureInfo(currentLanguageLanguageCode);
|
||||
|
||||
[ObservableProperty]
|
||||
private TimeSpan _workingHourStart;
|
||||
|
||||
[ObservableProperty]
|
||||
private TimeSpan _workingHourEnd;
|
||||
|
||||
[ObservableProperty]
|
||||
private List<string> _dayNames = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private int _workingDayStartIndex;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _workingDayEndIndex;
|
||||
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
|
||||
private readonly bool _isLoaded = false;
|
||||
|
||||
public CalendarSettingsPageViewModel(IPreferencesService preferencesService)
|
||||
// Populate the day names list
|
||||
for (var i = 0; i < 7; i++)
|
||||
{
|
||||
PreferencesService = preferencesService;
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
var cultureFirstDayName = cultureInfo.DateTimeFormat.GetDayName(preferencesService.FirstDayOfWeek);
|
||||
|
||||
_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));
|
||||
|
||||
_isLoaded = true;
|
||||
_dayNames.Add(cultureInfo.DateTimeFormat.DayNames[i]);
|
||||
}
|
||||
|
||||
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();
|
||||
var cultureFirstDayName = cultureInfo.DateTimeFormat.GetDayName(preferencesService.FirstDayOfWeek);
|
||||
|
||||
public void SaveSettings()
|
||||
_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));
|
||||
|
||||
_isLoaded = true;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
public void SaveSettings()
|
||||
{
|
||||
if (!_isLoaded) return;
|
||||
|
||||
PreferencesService.FirstDayOfWeek = SelectedFirstDayOfWeekIndex switch
|
||||
{
|
||||
if (!_isLoaded) return;
|
||||
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.FirstDayOfWeek = SelectedFirstDayOfWeekIndex 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.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.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.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;
|
||||
|
||||
PreferencesService.Prefer24HourTimeFormat = Is24HourHeaders;
|
||||
PreferencesService.WorkingHourStart = WorkingHourStart;
|
||||
PreferencesService.WorkingHourEnd = WorkingHourEnd;
|
||||
PreferencesService.HourHeight = CellHourHeight;
|
||||
|
||||
Messenger.Send(new CalendarSettingsUpdatedMessage());
|
||||
}
|
||||
Messenger.Send(new CalendarSettingsUpdatedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Wino.Core;
|
||||
|
||||
namespace Wino.Calendar.ViewModels
|
||||
namespace Wino.Calendar.ViewModels;
|
||||
|
||||
public static class CalendarViewModelContainerSetup
|
||||
{
|
||||
public static class CalendarViewModelContainerSetup
|
||||
public static void RegisterCalendarViewModelServices(this IServiceCollection services)
|
||||
{
|
||||
public static void RegisterCalendarViewModelServices(this IServiceCollection services)
|
||||
{
|
||||
services.RegisterCoreServices();
|
||||
}
|
||||
services.RegisterCoreServices();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,67 +4,66 @@ using Wino.Core.Domain.Entities.Calendar;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Calendar.ViewModels.Data
|
||||
namespace Wino.Calendar.ViewModels.Data;
|
||||
|
||||
public partial class AccountCalendarViewModel : ObservableObject, IAccountCalendar
|
||||
{
|
||||
public partial class AccountCalendarViewModel : ObservableObject, IAccountCalendar
|
||||
public MailAccount Account { get; }
|
||||
public AccountCalendar AccountCalendar { get; }
|
||||
|
||||
public AccountCalendarViewModel(MailAccount account, AccountCalendar accountCalendar)
|
||||
{
|
||||
public MailAccount Account { get; }
|
||||
public AccountCalendar AccountCalendar { get; }
|
||||
Account = account;
|
||||
AccountCalendar = accountCalendar;
|
||||
|
||||
public AccountCalendarViewModel(MailAccount account, AccountCalendar accountCalendar)
|
||||
{
|
||||
Account = account;
|
||||
AccountCalendar = accountCalendar;
|
||||
|
||||
IsChecked = accountCalendar.IsExtended;
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isChecked;
|
||||
|
||||
partial void OnIsCheckedChanged(bool value) => IsExtended = value;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => AccountCalendar.Name;
|
||||
set => SetProperty(AccountCalendar.Name, value, AccountCalendar, (u, n) => u.Name = n);
|
||||
}
|
||||
|
||||
public string TextColorHex
|
||||
{
|
||||
get => AccountCalendar.TextColorHex;
|
||||
set => SetProperty(AccountCalendar.TextColorHex, value, AccountCalendar, (u, t) => u.TextColorHex = t);
|
||||
}
|
||||
|
||||
public string BackgroundColorHex
|
||||
{
|
||||
get => AccountCalendar.BackgroundColorHex;
|
||||
set => SetProperty(AccountCalendar.BackgroundColorHex, value, AccountCalendar, (u, b) => u.BackgroundColorHex = b);
|
||||
}
|
||||
|
||||
public bool IsExtended
|
||||
{
|
||||
get => AccountCalendar.IsExtended;
|
||||
set => SetProperty(AccountCalendar.IsExtended, value, AccountCalendar, (u, i) => u.IsExtended = i);
|
||||
}
|
||||
|
||||
public bool IsPrimary
|
||||
{
|
||||
get => AccountCalendar.IsPrimary;
|
||||
set => SetProperty(AccountCalendar.IsPrimary, value, AccountCalendar, (u, i) => u.IsPrimary = i);
|
||||
}
|
||||
|
||||
public Guid AccountId
|
||||
{
|
||||
get => AccountCalendar.AccountId;
|
||||
set => SetProperty(AccountCalendar.AccountId, value, AccountCalendar, (u, a) => u.AccountId = a);
|
||||
}
|
||||
|
||||
public string RemoteCalendarId
|
||||
{
|
||||
get => AccountCalendar.RemoteCalendarId;
|
||||
set => SetProperty(AccountCalendar.RemoteCalendarId, value, AccountCalendar, (u, r) => u.RemoteCalendarId = r);
|
||||
}
|
||||
public Guid Id { get => ((IAccountCalendar)AccountCalendar).Id; set => ((IAccountCalendar)AccountCalendar).Id = value; }
|
||||
IsChecked = accountCalendar.IsExtended;
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isChecked;
|
||||
|
||||
partial void OnIsCheckedChanged(bool value) => IsExtended = value;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => AccountCalendar.Name;
|
||||
set => SetProperty(AccountCalendar.Name, value, AccountCalendar, (u, n) => u.Name = n);
|
||||
}
|
||||
|
||||
public string TextColorHex
|
||||
{
|
||||
get => AccountCalendar.TextColorHex;
|
||||
set => SetProperty(AccountCalendar.TextColorHex, value, AccountCalendar, (u, t) => u.TextColorHex = t);
|
||||
}
|
||||
|
||||
public string BackgroundColorHex
|
||||
{
|
||||
get => AccountCalendar.BackgroundColorHex;
|
||||
set => SetProperty(AccountCalendar.BackgroundColorHex, value, AccountCalendar, (u, b) => u.BackgroundColorHex = b);
|
||||
}
|
||||
|
||||
public bool IsExtended
|
||||
{
|
||||
get => AccountCalendar.IsExtended;
|
||||
set => SetProperty(AccountCalendar.IsExtended, value, AccountCalendar, (u, i) => u.IsExtended = i);
|
||||
}
|
||||
|
||||
public bool IsPrimary
|
||||
{
|
||||
get => AccountCalendar.IsPrimary;
|
||||
set => SetProperty(AccountCalendar.IsPrimary, value, AccountCalendar, (u, i) => u.IsPrimary = i);
|
||||
}
|
||||
|
||||
public Guid AccountId
|
||||
{
|
||||
get => AccountCalendar.AccountId;
|
||||
set => SetProperty(AccountCalendar.AccountId, value, AccountCalendar, (u, a) => u.AccountId = a);
|
||||
}
|
||||
|
||||
public string RemoteCalendarId
|
||||
{
|
||||
get => AccountCalendar.RemoteCalendarId;
|
||||
set => SetProperty(AccountCalendar.RemoteCalendarId, value, AccountCalendar, (u, r) => u.RemoteCalendarId = r);
|
||||
}
|
||||
public Guid Id { get => ((IAccountCalendar)AccountCalendar).Id; set => ((IAccountCalendar)AccountCalendar).Id = value; }
|
||||
}
|
||||
|
||||
@@ -5,42 +5,41 @@ using Itenso.TimePeriod;
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Calendar.ViewModels.Data
|
||||
namespace Wino.Calendar.ViewModels.Data;
|
||||
|
||||
public partial class CalendarItemViewModel : ObservableObject, ICalendarItem, ICalendarItemViewModel
|
||||
{
|
||||
public partial class CalendarItemViewModel : ObservableObject, ICalendarItem, ICalendarItemViewModel
|
||||
public CalendarItem CalendarItem { get; }
|
||||
|
||||
public string Title => CalendarItem.Title;
|
||||
|
||||
public Guid Id => CalendarItem.Id;
|
||||
|
||||
public IAccountCalendar AssignedCalendar => CalendarItem.AssignedCalendar;
|
||||
|
||||
public DateTime StartDate { get => CalendarItem.StartDate; set => CalendarItem.StartDate = value; }
|
||||
|
||||
public DateTime EndDate => CalendarItem.EndDate;
|
||||
|
||||
public double DurationInSeconds { get => CalendarItem.DurationInSeconds; set => CalendarItem.DurationInSeconds = value; }
|
||||
|
||||
public ITimePeriod Period => CalendarItem.Period;
|
||||
|
||||
public bool IsAllDayEvent => CalendarItem.IsAllDayEvent;
|
||||
public bool IsMultiDayEvent => CalendarItem.IsMultiDayEvent;
|
||||
public bool IsRecurringEvent => CalendarItem.IsRecurringEvent;
|
||||
public bool IsRecurringChild => CalendarItem.IsRecurringChild;
|
||||
public bool IsRecurringParent => CalendarItem.IsRecurringParent;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isSelected;
|
||||
|
||||
public ObservableCollection<CalendarEventAttendee> Attendees { get; } = new ObservableCollection<CalendarEventAttendee>();
|
||||
|
||||
public CalendarItemViewModel(CalendarItem calendarItem)
|
||||
{
|
||||
public CalendarItem CalendarItem { get; }
|
||||
|
||||
public string Title => CalendarItem.Title;
|
||||
|
||||
public Guid Id => CalendarItem.Id;
|
||||
|
||||
public IAccountCalendar AssignedCalendar => CalendarItem.AssignedCalendar;
|
||||
|
||||
public DateTime StartDate { get => CalendarItem.StartDate; set => CalendarItem.StartDate = value; }
|
||||
|
||||
public DateTime EndDate => CalendarItem.EndDate;
|
||||
|
||||
public double DurationInSeconds { get => CalendarItem.DurationInSeconds; set => CalendarItem.DurationInSeconds = value; }
|
||||
|
||||
public ITimePeriod Period => CalendarItem.Period;
|
||||
|
||||
public bool IsAllDayEvent => CalendarItem.IsAllDayEvent;
|
||||
public bool IsMultiDayEvent => CalendarItem.IsMultiDayEvent;
|
||||
public bool IsRecurringEvent => CalendarItem.IsRecurringEvent;
|
||||
public bool IsRecurringChild => CalendarItem.IsRecurringChild;
|
||||
public bool IsRecurringParent => CalendarItem.IsRecurringParent;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isSelected;
|
||||
|
||||
public ObservableCollection<CalendarEventAttendee> Attendees { get; } = new ObservableCollection<CalendarEventAttendee>();
|
||||
|
||||
public CalendarItemViewModel(CalendarItem calendarItem)
|
||||
{
|
||||
CalendarItem = calendarItem;
|
||||
}
|
||||
|
||||
public override string ToString() => CalendarItem.Title;
|
||||
CalendarItem = calendarItem;
|
||||
}
|
||||
|
||||
public override string ToString() => CalendarItem.Title;
|
||||
}
|
||||
|
||||
@@ -6,141 +6,140 @@ using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
namespace Wino.Calendar.ViewModels.Data
|
||||
namespace Wino.Calendar.ViewModels.Data;
|
||||
|
||||
public partial class GroupedAccountCalendarViewModel : ObservableObject
|
||||
{
|
||||
public partial class GroupedAccountCalendarViewModel : ObservableObject
|
||||
public event EventHandler CollectiveSelectionStateChanged;
|
||||
public event EventHandler<AccountCalendarViewModel> CalendarSelectionStateChanged;
|
||||
|
||||
public MailAccount Account { get; }
|
||||
public ObservableCollection<AccountCalendarViewModel> AccountCalendars { get; }
|
||||
|
||||
public GroupedAccountCalendarViewModel(MailAccount account, IEnumerable<AccountCalendarViewModel> calendarViewModels)
|
||||
{
|
||||
public event EventHandler CollectiveSelectionStateChanged;
|
||||
public event EventHandler<AccountCalendarViewModel> CalendarSelectionStateChanged;
|
||||
Account = account;
|
||||
AccountCalendars = new ObservableCollection<AccountCalendarViewModel>(calendarViewModels);
|
||||
|
||||
public MailAccount Account { get; }
|
||||
public ObservableCollection<AccountCalendarViewModel> AccountCalendars { get; }
|
||||
ManageIsCheckedState();
|
||||
|
||||
public GroupedAccountCalendarViewModel(MailAccount account, IEnumerable<AccountCalendarViewModel> calendarViewModels)
|
||||
foreach (var calendarViewModel in calendarViewModels)
|
||||
{
|
||||
Account = account;
|
||||
AccountCalendars = new ObservableCollection<AccountCalendarViewModel>(calendarViewModels);
|
||||
|
||||
ManageIsCheckedState();
|
||||
|
||||
foreach (var calendarViewModel in calendarViewModels)
|
||||
{
|
||||
calendarViewModel.PropertyChanged += CalendarPropertyChanged;
|
||||
}
|
||||
|
||||
AccountCalendars.CollectionChanged += CalendarListUpdated;
|
||||
calendarViewModel.PropertyChanged += CalendarPropertyChanged;
|
||||
}
|
||||
|
||||
private void CalendarListUpdated(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
AccountCalendars.CollectionChanged += CalendarListUpdated;
|
||||
}
|
||||
|
||||
private void CalendarListUpdated(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.Action == NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
if (e.Action == NotifyCollectionChangedAction.Add)
|
||||
foreach (AccountCalendarViewModel calendar in e.NewItems)
|
||||
{
|
||||
foreach (AccountCalendarViewModel calendar in e.NewItems)
|
||||
{
|
||||
calendar.PropertyChanged += CalendarPropertyChanged;
|
||||
}
|
||||
}
|
||||
else if (e.Action == NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
foreach (AccountCalendarViewModel calendar in e.OldItems)
|
||||
{
|
||||
calendar.PropertyChanged -= CalendarPropertyChanged;
|
||||
}
|
||||
}
|
||||
else if (e.Action == NotifyCollectionChangedAction.Reset)
|
||||
{
|
||||
foreach (AccountCalendarViewModel calendar in e.OldItems)
|
||||
{
|
||||
calendar.PropertyChanged -= CalendarPropertyChanged;
|
||||
}
|
||||
calendar.PropertyChanged += CalendarPropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void CalendarPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
else if (e.Action == NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
if (sender is AccountCalendarViewModel viewModel)
|
||||
foreach (AccountCalendarViewModel calendar in e.OldItems)
|
||||
{
|
||||
if (e.PropertyName == nameof(AccountCalendarViewModel.IsChecked))
|
||||
{
|
||||
ManageIsCheckedState();
|
||||
UpdateCalendarCheckedState(viewModel, viewModel.IsChecked, true);
|
||||
}
|
||||
calendar.PropertyChanged -= CalendarPropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isExpanded = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool? isCheckedState = true;
|
||||
|
||||
private bool _isExternalPropChangeBlocked = false;
|
||||
|
||||
private void ManageIsCheckedState()
|
||||
else if (e.Action == NotifyCollectionChangedAction.Reset)
|
||||
{
|
||||
if (_isExternalPropChangeBlocked) return;
|
||||
|
||||
_isExternalPropChangeBlocked = true;
|
||||
|
||||
if (AccountCalendars.All(c => c.IsChecked))
|
||||
foreach (AccountCalendarViewModel calendar in e.OldItems)
|
||||
{
|
||||
IsCheckedState = true;
|
||||
calendar.PropertyChanged -= CalendarPropertyChanged;
|
||||
}
|
||||
else if (AccountCalendars.All(c => !c.IsChecked))
|
||||
{
|
||||
IsCheckedState = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsCheckedState = null;
|
||||
}
|
||||
|
||||
_isExternalPropChangeBlocked = false;
|
||||
}
|
||||
|
||||
partial void OnIsCheckedStateChanged(bool? newValue)
|
||||
{
|
||||
if (_isExternalPropChangeBlocked) return;
|
||||
|
||||
// Update is triggered by user on the three-state checkbox.
|
||||
// We should not report all changes one by one.
|
||||
|
||||
_isExternalPropChangeBlocked = true;
|
||||
|
||||
if (newValue == null)
|
||||
{
|
||||
// Only primary calendars must be checked.
|
||||
|
||||
foreach (var calendar in AccountCalendars)
|
||||
{
|
||||
UpdateCalendarCheckedState(calendar, calendar.IsPrimary);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var calendar in AccountCalendars)
|
||||
{
|
||||
UpdateCalendarCheckedState(calendar, newValue.GetValueOrDefault());
|
||||
}
|
||||
}
|
||||
|
||||
_isExternalPropChangeBlocked = false;
|
||||
|
||||
CollectiveSelectionStateChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void UpdateCalendarCheckedState(AccountCalendarViewModel accountCalendarViewModel, bool newValue, bool ignoreValueCheck = false)
|
||||
{
|
||||
var currentValue = accountCalendarViewModel.IsChecked;
|
||||
|
||||
if (currentValue == newValue && !ignoreValueCheck) return;
|
||||
|
||||
accountCalendarViewModel.IsChecked = newValue;
|
||||
|
||||
// No need to report.
|
||||
if (_isExternalPropChangeBlocked == true) return;
|
||||
|
||||
CalendarSelectionStateChanged?.Invoke(this, accountCalendarViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
private void CalendarPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (sender is AccountCalendarViewModel viewModel)
|
||||
{
|
||||
if (e.PropertyName == nameof(AccountCalendarViewModel.IsChecked))
|
||||
{
|
||||
ManageIsCheckedState();
|
||||
UpdateCalendarCheckedState(viewModel, viewModel.IsChecked, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isExpanded = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool? isCheckedState = true;
|
||||
|
||||
private bool _isExternalPropChangeBlocked = false;
|
||||
|
||||
private void ManageIsCheckedState()
|
||||
{
|
||||
if (_isExternalPropChangeBlocked) return;
|
||||
|
||||
_isExternalPropChangeBlocked = true;
|
||||
|
||||
if (AccountCalendars.All(c => c.IsChecked))
|
||||
{
|
||||
IsCheckedState = true;
|
||||
}
|
||||
else if (AccountCalendars.All(c => !c.IsChecked))
|
||||
{
|
||||
IsCheckedState = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsCheckedState = null;
|
||||
}
|
||||
|
||||
_isExternalPropChangeBlocked = false;
|
||||
}
|
||||
|
||||
partial void OnIsCheckedStateChanged(bool? newValue)
|
||||
{
|
||||
if (_isExternalPropChangeBlocked) return;
|
||||
|
||||
// Update is triggered by user on the three-state checkbox.
|
||||
// We should not report all changes one by one.
|
||||
|
||||
_isExternalPropChangeBlocked = true;
|
||||
|
||||
if (newValue == null)
|
||||
{
|
||||
// Only primary calendars must be checked.
|
||||
|
||||
foreach (var calendar in AccountCalendars)
|
||||
{
|
||||
UpdateCalendarCheckedState(calendar, calendar.IsPrimary);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var calendar in AccountCalendars)
|
||||
{
|
||||
UpdateCalendarCheckedState(calendar, newValue.GetValueOrDefault());
|
||||
}
|
||||
}
|
||||
|
||||
_isExternalPropChangeBlocked = false;
|
||||
|
||||
CollectiveSelectionStateChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void UpdateCalendarCheckedState(AccountCalendarViewModel accountCalendarViewModel, bool newValue, bool ignoreValueCheck = false)
|
||||
{
|
||||
var currentValue = accountCalendarViewModel.IsChecked;
|
||||
|
||||
if (currentValue == newValue && !ignoreValueCheck) return;
|
||||
|
||||
accountCalendarViewModel.IsChecked = newValue;
|
||||
|
||||
// No need to report.
|
||||
if (_isExternalPropChangeBlocked == true) return;
|
||||
|
||||
CalendarSelectionStateChanged?.Invoke(this, accountCalendarViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,105 +12,104 @@ using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.ViewModels;
|
||||
using Wino.Messaging.Client.Calendar;
|
||||
|
||||
namespace Wino.Calendar.ViewModels
|
||||
namespace Wino.Calendar.ViewModels;
|
||||
|
||||
public partial class EventDetailsPageViewModel : CalendarBaseViewModel
|
||||
{
|
||||
public partial class EventDetailsPageViewModel : CalendarBaseViewModel
|
||||
private readonly ICalendarService _calendarService;
|
||||
private readonly INativeAppService _nativeAppService;
|
||||
private readonly IPreferencesService _preferencesService;
|
||||
|
||||
public CalendarSettings CurrentSettings { get; }
|
||||
|
||||
#region Details
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(CanViewSeries))]
|
||||
private CalendarItemViewModel _currentEvent;
|
||||
|
||||
[ObservableProperty]
|
||||
private CalendarItemViewModel _seriesParent;
|
||||
|
||||
public bool CanViewSeries => CurrentEvent?.IsRecurringChild ?? false;
|
||||
|
||||
#endregion
|
||||
|
||||
public EventDetailsPageViewModel(ICalendarService calendarService, INativeAppService nativeAppService, IPreferencesService preferencesService)
|
||||
{
|
||||
private readonly ICalendarService _calendarService;
|
||||
private readonly INativeAppService _nativeAppService;
|
||||
private readonly IPreferencesService _preferencesService;
|
||||
_calendarService = calendarService;
|
||||
_nativeAppService = nativeAppService;
|
||||
_preferencesService = preferencesService;
|
||||
|
||||
public CalendarSettings CurrentSettings { get; }
|
||||
CurrentSettings = _preferencesService.GetCurrentCalendarSettings();
|
||||
}
|
||||
|
||||
#region Details
|
||||
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
|
||||
{
|
||||
base.OnNavigatedTo(mode, parameters);
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(CanViewSeries))]
|
||||
private CalendarItemViewModel _currentEvent;
|
||||
Messenger.Send(new DetailsPageStateChangedMessage(true));
|
||||
|
||||
[ObservableProperty]
|
||||
private CalendarItemViewModel _seriesParent;
|
||||
if (parameters == null || parameters is not CalendarItemTarget args)
|
||||
return;
|
||||
|
||||
public bool CanViewSeries => CurrentEvent?.IsRecurringChild ?? false;
|
||||
await LoadCalendarItemTargetAsync(args);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public EventDetailsPageViewModel(ICalendarService calendarService, INativeAppService nativeAppService, IPreferencesService preferencesService)
|
||||
private async Task LoadCalendarItemTargetAsync(CalendarItemTarget target)
|
||||
{
|
||||
try
|
||||
{
|
||||
_calendarService = calendarService;
|
||||
_nativeAppService = nativeAppService;
|
||||
_preferencesService = preferencesService;
|
||||
var currentEventItem = await _calendarService.GetCalendarItemTargetAsync(target);
|
||||
|
||||
CurrentSettings = _preferencesService.GetCurrentCalendarSettings();
|
||||
}
|
||||
|
||||
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
|
||||
{
|
||||
base.OnNavigatedTo(mode, parameters);
|
||||
|
||||
Messenger.Send(new DetailsPageStateChangedMessage(true));
|
||||
|
||||
if (parameters == null || parameters is not CalendarItemTarget args)
|
||||
if (currentEventItem == null)
|
||||
return;
|
||||
|
||||
await LoadCalendarItemTargetAsync(args);
|
||||
}
|
||||
CurrentEvent = new CalendarItemViewModel(currentEventItem);
|
||||
|
||||
private async Task LoadCalendarItemTargetAsync(CalendarItemTarget target)
|
||||
{
|
||||
try
|
||||
var attendees = await _calendarService.GetAttendeesAsync(currentEventItem.EventTrackingId);
|
||||
|
||||
foreach (var item in attendees)
|
||||
{
|
||||
var currentEventItem = await _calendarService.GetCalendarItemTargetAsync(target);
|
||||
|
||||
if (currentEventItem == null)
|
||||
return;
|
||||
|
||||
CurrentEvent = new CalendarItemViewModel(currentEventItem);
|
||||
|
||||
var attendees = await _calendarService.GetAttendeesAsync(currentEventItem.EventTrackingId);
|
||||
|
||||
foreach (var item in attendees)
|
||||
{
|
||||
CurrentEvent.Attendees.Add(item);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
CurrentEvent.Attendees.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNavigatedFrom(NavigationMode mode, object parameters)
|
||||
catch (Exception ex)
|
||||
{
|
||||
base.OnNavigatedFrom(mode, parameters);
|
||||
|
||||
Messenger.Send(new DetailsPageStateChangedMessage(false));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task SaveAsync()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task DeleteAsync()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private Task JoinOnline()
|
||||
{
|
||||
if (CurrentEvent == null || string.IsNullOrEmpty(CurrentEvent.CalendarItem.HtmlLink)) return Task.CompletedTask;
|
||||
|
||||
return _nativeAppService.LaunchUriAsync(new Uri(CurrentEvent.CalendarItem.HtmlLink));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task Respond(CalendarItemStatus status)
|
||||
{
|
||||
if (CurrentEvent == null) return;
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNavigatedFrom(NavigationMode mode, object parameters)
|
||||
{
|
||||
base.OnNavigatedFrom(mode, parameters);
|
||||
|
||||
Messenger.Send(new DetailsPageStateChangedMessage(false));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task SaveAsync()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task DeleteAsync()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private Task JoinOnline()
|
||||
{
|
||||
if (CurrentEvent == null || string.IsNullOrEmpty(CurrentEvent.CalendarItem.HtmlLink)) return Task.CompletedTask;
|
||||
|
||||
return _nativeAppService.LaunchUriAsync(new Uri(CurrentEvent.CalendarItem.HtmlLink));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task Respond(CalendarItemStatus status)
|
||||
{
|
||||
if (CurrentEvent == null) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,26 +6,25 @@ using System.Linq;
|
||||
using Wino.Calendar.ViewModels.Data;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
namespace Wino.Calendar.ViewModels.Interfaces
|
||||
namespace Wino.Calendar.ViewModels.Interfaces;
|
||||
|
||||
public interface IAccountCalendarStateService : INotifyPropertyChanged
|
||||
{
|
||||
public interface IAccountCalendarStateService : INotifyPropertyChanged
|
||||
{
|
||||
ReadOnlyObservableCollection<GroupedAccountCalendarViewModel> GroupedAccountCalendars { get; }
|
||||
ReadOnlyObservableCollection<GroupedAccountCalendarViewModel> GroupedAccountCalendars { get; }
|
||||
|
||||
event EventHandler<GroupedAccountCalendarViewModel> CollectiveAccountGroupSelectionStateChanged;
|
||||
event EventHandler<AccountCalendarViewModel> AccountCalendarSelectionStateChanged;
|
||||
event EventHandler<GroupedAccountCalendarViewModel> CollectiveAccountGroupSelectionStateChanged;
|
||||
event EventHandler<AccountCalendarViewModel> AccountCalendarSelectionStateChanged;
|
||||
|
||||
public void AddGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar);
|
||||
public void RemoveGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar);
|
||||
public void ClearGroupedAccountCalendar();
|
||||
public void AddGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar);
|
||||
public void RemoveGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar);
|
||||
public void ClearGroupedAccountCalendar();
|
||||
|
||||
public void AddAccountCalendar(AccountCalendarViewModel accountCalendar);
|
||||
public void RemoveAccountCalendar(AccountCalendarViewModel accountCalendar);
|
||||
public void AddAccountCalendar(AccountCalendarViewModel accountCalendar);
|
||||
public void RemoveAccountCalendar(AccountCalendarViewModel accountCalendar);
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration of currently selected calendars.
|
||||
/// </summary>
|
||||
IEnumerable<AccountCalendarViewModel> ActiveCalendars { get; }
|
||||
IEnumerable<IGrouping<MailAccount, AccountCalendarViewModel>> GroupedAccountCalendarsEnumerable { get; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Enumeration of currently selected calendars.
|
||||
/// </summary>
|
||||
IEnumerable<AccountCalendarViewModel> ActiveCalendars { get; }
|
||||
IEnumerable<IGrouping<MailAccount, AccountCalendarViewModel>> GroupedAccountCalendarsEnumerable { get; }
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using Wino.Calendar.ViewModels.Data;
|
||||
|
||||
namespace Wino.Calendar.ViewModels.Messages
|
||||
{
|
||||
public class CalendarItemDoubleTappedMessage
|
||||
{
|
||||
public CalendarItemDoubleTappedMessage(CalendarItemViewModel calendarItemViewModel)
|
||||
{
|
||||
CalendarItemViewModel = calendarItemViewModel;
|
||||
}
|
||||
namespace Wino.Calendar.ViewModels.Messages;
|
||||
|
||||
public CalendarItemViewModel CalendarItemViewModel { get; }
|
||||
public class CalendarItemDoubleTappedMessage
|
||||
{
|
||||
public CalendarItemDoubleTappedMessage(CalendarItemViewModel calendarItemViewModel)
|
||||
{
|
||||
CalendarItemViewModel = calendarItemViewModel;
|
||||
}
|
||||
|
||||
public CalendarItemViewModel CalendarItemViewModel { get; }
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using Wino.Calendar.ViewModels.Data;
|
||||
|
||||
namespace Wino.Calendar.ViewModels.Messages
|
||||
{
|
||||
public class CalendarItemRightTappedMessage
|
||||
{
|
||||
public CalendarItemRightTappedMessage(CalendarItemViewModel calendarItemViewModel)
|
||||
{
|
||||
CalendarItemViewModel = calendarItemViewModel;
|
||||
}
|
||||
namespace Wino.Calendar.ViewModels.Messages;
|
||||
|
||||
public CalendarItemViewModel CalendarItemViewModel { get; }
|
||||
public class CalendarItemRightTappedMessage
|
||||
{
|
||||
public CalendarItemRightTappedMessage(CalendarItemViewModel calendarItemViewModel)
|
||||
{
|
||||
CalendarItemViewModel = calendarItemViewModel;
|
||||
}
|
||||
|
||||
public CalendarItemViewModel CalendarItemViewModel { get; }
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
using Wino.Calendar.ViewModels.Data;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
|
||||
namespace Wino.Calendar.ViewModels.Messages
|
||||
{
|
||||
public class CalendarItemTappedMessage
|
||||
{
|
||||
public CalendarItemTappedMessage(CalendarItemViewModel calendarItemViewModel, CalendarDayModel clickedPeriod)
|
||||
{
|
||||
CalendarItemViewModel = calendarItemViewModel;
|
||||
ClickedPeriod = clickedPeriod;
|
||||
}
|
||||
namespace Wino.Calendar.ViewModels.Messages;
|
||||
|
||||
public CalendarItemViewModel CalendarItemViewModel { get; }
|
||||
public CalendarDayModel ClickedPeriod { get; }
|
||||
public class CalendarItemTappedMessage
|
||||
{
|
||||
public CalendarItemTappedMessage(CalendarItemViewModel calendarItemViewModel, CalendarDayModel clickedPeriod)
|
||||
{
|
||||
CalendarItemViewModel = calendarItemViewModel;
|
||||
ClickedPeriod = clickedPeriod;
|
||||
}
|
||||
|
||||
public CalendarItemViewModel CalendarItemViewModel { get; }
|
||||
public CalendarDayModel ClickedPeriod { get; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user