Fix couple issues with starting mode.

This commit is contained in:
Burak Kaan Köse
2026-02-27 10:22:52 +01:00
parent 4b22608bc5
commit e1ce85698c
4 changed files with 165 additions and 79 deletions
@@ -222,8 +222,15 @@ public partial class WinoCalendarControl : Control
private void UpdateIdleState() private void UpdateIdleState()
{ {
InternalFlipView.Opacity = IsFlipIdle ? 0 : 1; if (InternalFlipView != null)
IdleGrid.Visibility = IsFlipIdle ? Visibility.Visible : Visibility.Collapsed; {
InternalFlipView.Opacity = IsFlipIdle ? 0 : 1;
}
if (IdleGrid != null)
{
IdleGrid.Visibility = IsFlipIdle ? Visibility.Visible : Visibility.Collapsed;
}
} }
private void ActiveTimelineCellUnselected(object sender, TimelineCellUnselectedArgs e) private void ActiveTimelineCellUnselected(object sender, TimelineCellUnselectedArgs e)
@@ -49,6 +49,8 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
internal event EventHandler<ProgrammaticNavigationCompletedEventArgs>? ProgrammaticNavigationCompleted; internal event EventHandler<ProgrammaticNavigationCompletedEventArgs>? ProgrammaticNavigationCompleted;
private INotifyCollectionChanged? _trackedItemsSource;
public WinoCalendarFlipView() public WinoCalendarFlipView()
{ {
RegisterPropertyChangedCallback(ItemsSourceProperty, new DependencyPropertyChangedCallback(OnItemsSourceChanged)); RegisterPropertyChangedCallback(ItemsSourceProperty, new DependencyPropertyChangedCallback(OnItemsSourceChanged));
@@ -64,10 +66,19 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
private void RegisterItemsSourceChange() private void RegisterItemsSourceChange()
{ {
if (GetItemsSource() is INotifyCollectionChanged notifyCollectionChanged) if (_trackedItemsSource != null)
{ {
notifyCollectionChanged.CollectionChanged += ItemsSourceUpdated; _trackedItemsSource.CollectionChanged -= ItemsSourceUpdated;
} }
_trackedItemsSource = GetItemsSource();
if (_trackedItemsSource != null)
{
_trackedItemsSource.CollectionChanged += ItemsSourceUpdated;
}
UpdateIdleState();
} }
protected override void OnSelectedItemChanged(object oldValue, object newValue) protected override void OnSelectedItemChanged(object oldValue, object newValue)
@@ -92,7 +103,13 @@ public partial class WinoCalendarFlipView : CustomCalendarFlipView
private void ItemsSourceUpdated(object sender, NotifyCollectionChangedEventArgs e) private void ItemsSourceUpdated(object sender, NotifyCollectionChangedEventArgs e)
{ {
IsIdle = e.Action == NotifyCollectionChangedAction.Reset || e.Action == NotifyCollectionChangedAction.Replace; UpdateIdleState();
}
private void UpdateIdleState()
{
var itemsSource = GetItemsSource();
IsIdle = itemsSource == null || itemsSource.Count == 0;
} }
private void UpdateActiveElements() private void UpdateActiveElements()
@@ -25,6 +25,8 @@ public partial class AccountCalendarStateService : ObservableRecipient,
IRecipient<CalendarListDeleted>, IRecipient<CalendarListDeleted>,
IRecipient<AccountRemovedMessage> IRecipient<AccountRemovedMessage>
{ {
private readonly object _calendarStateLock = new();
public IDispatcher? Dispatcher { get; set; } public IDispatcher? Dispatcher { get; set; }
public event EventHandler<GroupedAccountCalendarViewModel>? CollectiveAccountGroupSelectionStateChanged; public event EventHandler<GroupedAccountCalendarViewModel>? CollectiveAccountGroupSelectionStateChanged;
@@ -43,9 +45,13 @@ public partial class AccountCalendarStateService : ObservableRecipient,
{ {
get get
{ {
return _internalGroupedAccountCalendars lock (_calendarStateLock)
.SelectMany(a => a.AccountCalendars) {
.Where(b => b.IsChecked); return _internalGroupedAccountCalendars
.SelectMany(a => a.AccountCalendars)
.Where(b => b.IsChecked)
.ToList();
}
} }
} }
@@ -53,8 +59,12 @@ public partial class AccountCalendarStateService : ObservableRecipient,
{ {
get get
{ {
return _internalGroupedAccountCalendars lock (_calendarStateLock)
.SelectMany(a => a.AccountCalendars); {
return _internalGroupedAccountCalendars
.SelectMany(a => a.AccountCalendars)
.ToList();
}
} }
} }
@@ -84,109 +94,124 @@ public partial class AccountCalendarStateService : ObservableRecipient,
public void AddGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar) public void AddGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar)
{ {
groupedAccountCalendar.CalendarSelectionStateChanged += SingleCalendarSelectionStateChanged; lock (_calendarStateLock)
groupedAccountCalendar.CollectiveSelectionStateChanged += SingleGroupCalendarCollectiveStateChanged;
_internalGroupedAccountCalendars.Add(groupedAccountCalendar);
// Maintain the grouped calendars collection
var group = _internalGroupedCalendars.FirstOrDefault<ObservableGroup<MailAccount, AccountCalendarViewModel>>(g => g.Key.Id == groupedAccountCalendar.Account.Id);
if (group == null)
{ {
_internalGroupedCalendars.Add(new ObservableGroup<MailAccount, AccountCalendarViewModel>(groupedAccountCalendar.Account, groupedAccountCalendar.AccountCalendars)); groupedAccountCalendar.CalendarSelectionStateChanged += SingleCalendarSelectionStateChanged;
} groupedAccountCalendar.CollectiveSelectionStateChanged += SingleGroupCalendarCollectiveStateChanged;
else
{ _internalGroupedAccountCalendars.Add(groupedAccountCalendar);
foreach (var calendar in groupedAccountCalendar.AccountCalendars)
// Maintain the grouped calendars collection
var group = _internalGroupedCalendars.FirstOrDefault<ObservableGroup<MailAccount, AccountCalendarViewModel>>(g => g.Key.Id == groupedAccountCalendar.Account.Id);
if (group == null)
{ {
group.Add(calendar); _internalGroupedCalendars.Add(new ObservableGroup<MailAccount, AccountCalendarViewModel>(groupedAccountCalendar.Account, groupedAccountCalendar.AccountCalendars));
}
else
{
foreach (var calendar in groupedAccountCalendar.AccountCalendars)
{
group.Add(calendar);
}
} }
} }
} }
public void RemoveGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar) public void RemoveGroupedAccountCalendar(GroupedAccountCalendarViewModel groupedAccountCalendar)
{ {
groupedAccountCalendar.CalendarSelectionStateChanged -= SingleCalendarSelectionStateChanged; lock (_calendarStateLock)
groupedAccountCalendar.CollectiveSelectionStateChanged -= SingleGroupCalendarCollectiveStateChanged;
_internalGroupedAccountCalendars.Remove(groupedAccountCalendar);
// Maintain the grouped calendars collection
var group = _internalGroupedCalendars.FirstOrDefault<ObservableGroup<MailAccount, AccountCalendarViewModel>>(g => g.Key.Id == groupedAccountCalendar.Account.Id);
if (group != null)
{ {
foreach (var calendar in groupedAccountCalendar.AccountCalendars.ToList()) groupedAccountCalendar.CalendarSelectionStateChanged -= SingleCalendarSelectionStateChanged;
{ groupedAccountCalendar.CollectiveSelectionStateChanged -= SingleGroupCalendarCollectiveStateChanged;
group.Remove(calendar);
}
if (group.Count == 0) _internalGroupedAccountCalendars.Remove(groupedAccountCalendar);
// Maintain the grouped calendars collection
var group = _internalGroupedCalendars.FirstOrDefault<ObservableGroup<MailAccount, AccountCalendarViewModel>>(g => g.Key.Id == groupedAccountCalendar.Account.Id);
if (group != null)
{ {
_internalGroupedCalendars.Remove(group); foreach (var calendar in groupedAccountCalendar.AccountCalendars.ToList())
{
group.Remove(calendar);
}
if (group.Count == 0)
{
_internalGroupedCalendars.Remove(group);
}
} }
} }
} }
public void ClearGroupedAccountCalendars() public void ClearGroupedAccountCalendars()
{ {
while (_internalGroupedAccountCalendars.Any()) lock (_calendarStateLock)
{ {
RemoveGroupedAccountCalendar(_internalGroupedAccountCalendars[0]); while (_internalGroupedAccountCalendars.Any())
{
RemoveGroupedAccountCalendar(_internalGroupedAccountCalendars[0]);
}
} }
} }
public void AddAccountCalendar(AccountCalendarViewModel accountCalendar) public void AddAccountCalendar(AccountCalendarViewModel accountCalendar)
{ {
// Find the group that this calendar belongs to. lock (_calendarStateLock)
var group = _internalGroupedAccountCalendars.FirstOrDefault(g => g.Account.Id == accountCalendar.Account.Id);
if (group == null)
{ {
// If the group doesn't exist, create it. // Find the group that this calendar belongs to.
group = new GroupedAccountCalendarViewModel(accountCalendar.Account, new[] { accountCalendar }); var group = _internalGroupedAccountCalendars.FirstOrDefault(g => g.Account.Id == accountCalendar.Account.Id);
AddGroupedAccountCalendar(group);
}
else
{
group.AccountCalendars.Add(accountCalendar);
// Maintain the grouped calendars collection if (group == null)
var calendarGroup = _internalGroupedCalendars.FirstOrDefault<ObservableGroup<MailAccount, AccountCalendarViewModel>>(g => g.Key.Id == accountCalendar.Account.Id);
if (calendarGroup == null)
{ {
_internalGroupedCalendars.Add(new ObservableGroup<MailAccount, AccountCalendarViewModel>(accountCalendar.Account, new[] { accountCalendar })); // If the group doesn't exist, create it.
group = new GroupedAccountCalendarViewModel(accountCalendar.Account, new[] { accountCalendar });
AddGroupedAccountCalendar(group);
} }
else else
{ {
calendarGroup.Add(accountCalendar); group.AccountCalendars.Add(accountCalendar);
// Maintain the grouped calendars collection
var calendarGroup = _internalGroupedCalendars.FirstOrDefault<ObservableGroup<MailAccount, AccountCalendarViewModel>>(g => g.Key.Id == accountCalendar.Account.Id);
if (calendarGroup == null)
{
_internalGroupedCalendars.Add(new ObservableGroup<MailAccount, AccountCalendarViewModel>(accountCalendar.Account, new[] { accountCalendar }));
}
else
{
calendarGroup.Add(accountCalendar);
}
} }
} }
} }
public void RemoveAccountCalendar(AccountCalendarViewModel accountCalendar) public void RemoveAccountCalendar(AccountCalendarViewModel accountCalendar)
{ {
var group = _internalGroupedAccountCalendars.FirstOrDefault(g => g.Account.Id == accountCalendar.Account.Id); lock (_calendarStateLock)
// We don't expect but just in case.
if (group == null) return;
group.AccountCalendars.Remove(accountCalendar);
// Maintain the grouped calendars collection
var calendarGroup = _internalGroupedCalendars.FirstOrDefault<ObservableGroup<MailAccount, AccountCalendarViewModel>>(g => g.Key.Id == accountCalendar.Account.Id);
if (calendarGroup != null)
{ {
calendarGroup.Remove(accountCalendar); var group = _internalGroupedAccountCalendars.FirstOrDefault(g => g.Account.Id == accountCalendar.Account.Id);
if (calendarGroup.Count == 0) // We don't expect but just in case.
if (group == null) return;
group.AccountCalendars.Remove(accountCalendar);
// Maintain the grouped calendars collection
var calendarGroup = _internalGroupedCalendars.FirstOrDefault<ObservableGroup<MailAccount, AccountCalendarViewModel>>(g => g.Key.Id == accountCalendar.Account.Id);
if (calendarGroup != null)
{ {
_internalGroupedCalendars.Remove(calendarGroup); calendarGroup.Remove(accountCalendar);
}
}
if (group.AccountCalendars.Count == 0) if (calendarGroup.Count == 0)
{ {
RemoveGroupedAccountCalendar(group); _internalGroupedCalendars.Remove(calendarGroup);
}
}
if (group.AccountCalendars.Count == 0)
{
RemoveGroupedAccountCalendar(group);
}
} }
} }
@@ -289,7 +314,11 @@ public partial class AccountCalendarStateService : ObservableRecipient,
{ {
await Dispatcher.ExecuteOnUIThread(() => await Dispatcher.ExecuteOnUIThread(() =>
{ {
var groupedAccount = _internalGroupedAccountCalendars.FirstOrDefault(a => a.Account.Id == removedAccountId); GroupedAccountCalendarViewModel? groupedAccount;
lock (_calendarStateLock)
{
groupedAccount = _internalGroupedAccountCalendars.FirstOrDefault(a => a.Account.Id == removedAccountId);
}
if (groupedAccount != null) if (groupedAccount != null)
{ {
@@ -299,7 +328,11 @@ public partial class AccountCalendarStateService : ObservableRecipient,
} }
else else
{ {
var groupedAccount = _internalGroupedAccountCalendars.FirstOrDefault(a => a.Account.Id == removedAccountId); GroupedAccountCalendarViewModel? groupedAccount;
lock (_calendarStateLock)
{
groupedAccount = _internalGroupedAccountCalendars.FirstOrDefault(a => a.Account.Id == removedAccountId);
}
if (groupedAccount != null) if (groupedAccount != null)
{ {
+32 -3
View File
@@ -35,6 +35,21 @@ public class NavigationService : NavigationServiceBase, INavigationService
WinoPage.ComposePage WinoPage.ComposePage
}; };
private static readonly WinoPage[] MailOnlyPages =
[
WinoPage.MailListPage,
WinoPage.MailRenderingPage,
WinoPage.ComposePage,
WinoPage.IdlePage,
WinoPage.WelcomePage
];
private static readonly WinoPage[] CalendarOnlyPages =
[
WinoPage.CalendarPage,
WinoPage.EventDetailsPage
];
public NavigationService(IStatePersistanceService statePersistanceService) public NavigationService(IStatePersistanceService statePersistanceService)
{ {
_statePersistanceService = statePersistanceService; _statePersistanceService = statePersistanceService;
@@ -140,9 +155,17 @@ public class NavigationService : NavigationServiceBase, INavigationService
var pageType = GetPageType(page); var pageType = GetPageType(page);
if (pageType == null) return false; if (pageType == null) return false;
var currentApplicationMode = GetCoreFrame(NavigationReferenceFrame.ShellFrame)?.Content?.GetType() == typeof(MailAppShell) var currentApplicationMode = _statePersistanceService.ApplicationMode;
? WinoApplicationMode.Mail
: WinoApplicationMode.Calendar; if (currentApplicationMode == WinoApplicationMode.Calendar && IsMailOnlyPage(page))
{
return false;
}
if (currentApplicationMode == WinoApplicationMode.Mail && IsCalendarOnlyPage(page))
{
return false;
}
_statePersistanceService.IsReadingMail = _renderingPageTypes.Contains(page); _statePersistanceService.IsReadingMail = _renderingPageTypes.Contains(page);
_statePersistanceService.IsEventDetailsVisible = page == WinoPage.EventDetailsPage; _statePersistanceService.IsEventDetailsVisible = page == WinoPage.EventDetailsPage;
@@ -248,6 +271,12 @@ public class NavigationService : NavigationServiceBase, INavigationService
return false; return false;
} }
private static bool IsMailOnlyPage(WinoPage page)
=> MailOnlyPages.Contains(page);
private static bool IsCalendarOnlyPage(WinoPage page)
=> CalendarOnlyPages.Contains(page);
private static LoadCalendarMessage CreateLoadCalendarMessage(CalendarPageNavigationArgs args) private static LoadCalendarMessage CreateLoadCalendarMessage(CalendarPageNavigationArgs args)
{ {
var targetDate = args.RequestDefaultNavigation var targetDate = args.RequestDefaultNavigation