diff --git a/Wino.Core.Domain/Interfaces/IAccountProviderDetailViewModel.cs b/Wino.Core.Domain/Interfaces/IAccountProviderDetailViewModel.cs
index b535fea1..2778acd2 100644
--- a/Wino.Core.Domain/Interfaces/IAccountProviderDetailViewModel.cs
+++ b/Wino.Core.Domain/Interfaces/IAccountProviderDetailViewModel.cs
@@ -13,5 +13,21 @@ namespace Wino.Core.Domain.Interfaces
/// Name representation of the view model that will be used to identify the startup entity on launch.
///
string StartupEntityTitle { get; }
+
+ ///
+ /// E-mail addresses that this account holds.
+ ///
+
+ string StartupEntityAddresses { get; }
+
+ ///
+ /// Represents the account order in the accounts list.
+ ///
+ int Order { get; }
+
+ ///
+ /// Provider details of the account.
+ ///
+ IProviderDetail ProviderDetail { get; set; }
}
}
diff --git a/Wino.Core.Domain/Interfaces/IDialogService.cs b/Wino.Core.Domain/Interfaces/IDialogService.cs
index af54f79f..6493fcb7 100644
--- a/Wino.Core.Domain/Interfaces/IDialogService.cs
+++ b/Wino.Core.Domain/Interfaces/IDialogService.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums;
@@ -32,6 +33,13 @@ namespace Wino.Core.Domain.Interfaces
Task ShowEditAccountDialogAsync(MailAccount account);
Task ShowAccountPickerDialogAsync(List availableAccounts);
+ ///
+ /// Displays a dialog to the user for reordering accounts.
+ ///
+ /// Available accounts in order.
+ /// Result model that has dict of AccountId-AccountOrder.
+ Task ShowAccountReorderDialogAsync(ObservableCollection availableAccounts);
+
///
/// Presents a dialog to the user for selecting folder.
///
diff --git a/Wino.Core/Messages/Accounts/AccountMenuItemsReordered.cs b/Wino.Core/Messages/Accounts/AccountMenuItemsReordered.cs
new file mode 100644
index 00000000..d9a9d74b
--- /dev/null
+++ b/Wino.Core/Messages/Accounts/AccountMenuItemsReordered.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+
+namespace Wino.Core.Messages.Accounts
+{
+ ///
+ /// Emitted when account menu items are reordered.
+ ///
+ /// New order info.
+ public record AccountMenuItemsReordered(Dictionary newOrderDictionary);
+}
diff --git a/Wino.Core/Services/AccountService.cs b/Wino.Core/Services/AccountService.cs
index dd8a9f8a..80660e87 100644
--- a/Wino.Core/Services/AccountService.cs
+++ b/Wino.Core/Services/AccountService.cs
@@ -423,7 +423,7 @@ namespace Wino.Core.Services
if (account == null)
{
- _logger.Error("Could not find account with id {AccountId}", pair.Key);
+ _logger.Information("Could not find account with id {Key} for reordering. It may be a linked account.", pair.Key);
continue;
}
@@ -431,6 +431,8 @@ namespace Wino.Core.Services
await Connection.UpdateAsync(account);
}
+
+ Messenger.Send(new AccountMenuItemsReordered(accountIdOrderPair));
}
}
}
diff --git a/Wino.Mail.ViewModels/AccountManagementViewModel.cs b/Wino.Mail.ViewModels/AccountManagementViewModel.cs
index 4c06374d..712ac35a 100644
--- a/Wino.Mail.ViewModels/AccountManagementViewModel.cs
+++ b/Wino.Mail.ViewModels/AccountManagementViewModel.cs
@@ -264,11 +264,8 @@ namespace Wino.Mail.ViewModels
mergedAccountProviderDetailViewModel));
}
- [RelayCommand]
- private async Task ReorderAccountsAsync()
- {
-
- }
+ [RelayCommand(CanExecute = nameof(CanReorderAccounts))]
+ private Task ReorderAccountsAsync() => DialogService.ShowAccountReorderDialogAsync(availableAccounts: Accounts);
public override void OnNavigatedFrom(NavigationMode mode, object parameters)
{
diff --git a/Wino.Mail.ViewModels/AppShellViewModel.cs b/Wino.Mail.ViewModels/AppShellViewModel.cs
index 33fb15cf..5b0a4cb5 100644
--- a/Wino.Mail.ViewModels/AppShellViewModel.cs
+++ b/Wino.Mail.ViewModels/AppShellViewModel.cs
@@ -39,7 +39,8 @@ namespace Wino.Mail.ViewModels
IRecipient,
IRecipient,
IRecipient,
- IRecipient
+ IRecipient,
+ IRecipient
{
#region Menu Items
@@ -1059,5 +1060,19 @@ namespace Wino.Mail.ViewModels
ChangeLoadedAccount(latestSelectedAccountMenuItem, navigateInbox: false);
}
+
+ private void ReorderAccountMenuItems(Dictionary newAccountOrder)
+ {
+ foreach (var item in newAccountOrder)
+ {
+ var menuItem = MenuItems.GetAccountMenuItem(item.Key);
+
+ if (menuItem == null) continue;
+
+ MenuItems.Move(MenuItems.IndexOf(menuItem), item.Value);
+ }
+ }
+
+ public void Receive(AccountMenuItemsReordered message) => ReorderAccountMenuItems(message.newOrderDictionary);
}
}
diff --git a/Wino.Mail.ViewModels/Data/AccountProviderDetailViewModel.cs b/Wino.Mail.ViewModels/Data/AccountProviderDetailViewModel.cs
index 4f629e99..cd2d2a89 100644
--- a/Wino.Mail.ViewModels/Data/AccountProviderDetailViewModel.cs
+++ b/Wino.Mail.ViewModels/Data/AccountProviderDetailViewModel.cs
@@ -17,6 +17,10 @@ namespace Wino.Mail.ViewModels.Data
public string StartupEntityTitle => Account.Name;
+ public int Order => Account.Order;
+
+ public string StartupEntityAddresses => Account.Address;
+
public AccountProviderDetailViewModel(IProviderDetail providerDetail, MailAccount account)
{
ProviderDetail = providerDetail;
diff --git a/Wino.Mail.ViewModels/Data/MergedAccountProviderDetailViewModel.cs b/Wino.Mail.ViewModels/Data/MergedAccountProviderDetailViewModel.cs
index 6dda7ac3..1bd7de5b 100644
--- a/Wino.Mail.ViewModels/Data/MergedAccountProviderDetailViewModel.cs
+++ b/Wino.Mail.ViewModels/Data/MergedAccountProviderDetailViewModel.cs
@@ -18,6 +18,12 @@ namespace Wino.Mail.ViewModels.Data
public string StartupEntityTitle => MergedInbox.Name;
+ public int Order => 0;
+
+ public IProviderDetail ProviderDetail { get; set; }
+
+ public string StartupEntityAddresses => AccountAddresses;
+
public MergedAccountProviderDetailViewModel(MergedInbox mergedInbox, List holdingAccounts)
{
MergedInbox = mergedInbox;
diff --git a/Wino.Mail/Dialogs/AccountReorderDialog.xaml b/Wino.Mail/Dialogs/AccountReorderDialog.xaml
new file mode 100644
index 00000000..4f733a3a
--- /dev/null
+++ b/Wino.Mail/Dialogs/AccountReorderDialog.xaml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Wino.Mail/Dialogs/AccountReorderDialog.xaml.cs b/Wino.Mail/Dialogs/AccountReorderDialog.xaml.cs
new file mode 100644
index 00000000..c5433c7e
--- /dev/null
+++ b/Wino.Mail/Dialogs/AccountReorderDialog.xaml.cs
@@ -0,0 +1,52 @@
+using System.Collections.ObjectModel;
+using System.Linq;
+using Microsoft.Extensions.DependencyInjection;
+using Windows.UI.Xaml.Controls;
+using Wino.Core.Domain.Interfaces;
+
+namespace Wino.Dialogs
+{
+ public sealed partial class AccountReorderDialog : ContentDialog
+ {
+ public ObservableCollection Accounts { get; }
+
+ private int count;
+ private bool isOrdering = false;
+
+ private readonly IAccountService _accountService = App.Current.Services.GetService();
+
+ public AccountReorderDialog(ObservableCollection accounts)
+ {
+ Accounts = accounts;
+
+ count = accounts.Count;
+
+ InitializeComponent();
+ }
+
+ private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
+ {
+ Accounts.CollectionChanged -= AccountsChanged;
+ Accounts.CollectionChanged += AccountsChanged;
+ }
+
+ private void DialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args) => Accounts.CollectionChanged -= AccountsChanged;
+
+ private async void AccountsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ if (count - 1 == Accounts.Count)
+ isOrdering = true;
+
+ if (count == Accounts.Count && isOrdering)
+ {
+ // Order is completed. Apply changes.
+
+ var dict = Accounts.ToDictionary(a => a.StartupEntityId, a => Accounts.IndexOf(a));
+
+ await _accountService.UpdateAccountOrdersAsync(dict);
+
+ isOrdering = false;
+ }
+ }
+ }
+}
diff --git a/Wino.Mail/Selectors/AccountReorderTemplateSelector.cs b/Wino.Mail/Selectors/AccountReorderTemplateSelector.cs
new file mode 100644
index 00000000..07574892
--- /dev/null
+++ b/Wino.Mail/Selectors/AccountReorderTemplateSelector.cs
@@ -0,0 +1,22 @@
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Wino.Mail.ViewModels.Data;
+
+namespace Wino.Selectors
+{
+ public class AccountReorderTemplateSelector : DataTemplateSelector
+ {
+ public DataTemplate MergedAccountReorderTemplate { get; set; }
+ public DataTemplate RootAccountReorderTemplate { get; set; }
+
+ protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
+ {
+ if (item is MergedAccountProviderDetailViewModel)
+ {
+ return MergedAccountReorderTemplate;
+ }
+
+ return RootAccountReorderTemplate;
+ }
+ }
+}
diff --git a/Wino.Mail/Services/DialogService.cs b/Wino.Mail/Services/DialogService.cs
index e38ba569..2d751080 100644
--- a/Wino.Mail/Services/DialogService.cs
+++ b/Wino.Mail/Services/DialogService.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Messaging;
@@ -331,6 +332,14 @@ namespace Wino.Services
return accountPicker.PickedAccount;
}
+ public async Task ShowAccountReorderDialogAsync(ObservableCollection availableAccounts)
+ {
+ var accountReorderDialog = new AccountReorderDialog(availableAccounts)
+ {
+ RequestedTheme = _themeService.RootTheme.ToWindowsElementTheme()
+ };
+ await HandleDialogPresentationAsync(accountReorderDialog);
+ }
}
}
diff --git a/Wino.Mail/Views/Account/AccountManagementPage.xaml b/Wino.Mail/Views/Account/AccountManagementPage.xaml
index 6876ae12..1f79d9cd 100644
--- a/Wino.Mail/Views/Account/AccountManagementPage.xaml
+++ b/Wino.Mail/Views/Account/AccountManagementPage.xaml
@@ -220,7 +220,6 @@
Description="{x:Bind domain:Translator.SettingsLinkAccounts_Description}">
-
diff --git a/Wino.Mail/Wino.Mail.csproj b/Wino.Mail/Wino.Mail.csproj
index c27cf3d5..a0e55b3b 100644
--- a/Wino.Mail/Wino.Mail.csproj
+++ b/Wino.Mail/Wino.Mail.csproj
@@ -252,6 +252,9 @@
AccountPickerDialog.xaml
+
+ AccountReorderDialog.xaml
+
CustomThemeBuilderDialog.xaml
@@ -319,6 +322,7 @@
+
@@ -484,6 +488,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile