Account colors + edit account details. (#592)

* Remove account rename dialog. Implement edit account details page.

* Remove unused folder definition.

* Adressing theming issues and adding reset button. Changing the UI a bit.

* Enable auto indent in initializer. Use service from the application.

* Adding color picker to acc setup dialog. Changing UI of edit acc details page.
This commit is contained in:
Burak Kaan Köse
2025-03-01 01:17:04 +01:00
committed by GitHub
parent 6080646e89
commit 8ecf301eb8
29 changed files with 464 additions and 135 deletions

View File

@@ -25,7 +25,7 @@ public enum WinoPage
AppPreferencesPage,
SettingOptionsPage,
AliasManagementPage,
EditAccountDetailsPage,
// Calendar
CalendarPage,
CalendarSettingsPage,

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Accounts;
using Wino.Core.Domain.Models.Common;
@@ -17,7 +16,6 @@ public interface IDialogServiceBase
void InfoBarMessage(string title, string message, InfoBarMessageType messageType);
void InfoBarMessage(string title, string message, InfoBarMessageType messageType, string actionButtonText, Action action);
void ShowNotSupportedMessage();
Task<MailAccount> ShowEditAccountDialogAsync(MailAccount account);
Task<string> ShowTextInputDialogAsync(string currentInput, string dialogTitle, string dialogDescription, string primaryButtonText);
Task<bool> ShowWinoCustomMessageDialogAsync(string title,
string description,

View File

@@ -14,7 +14,7 @@ public interface IThemeService : IInitializeAsync
Task<List<AppThemeBase>> GetAvailableThemesAsync();
Task<CustomThemeMetadata> CreateNewCustomThemeAsync(string themeName, string accentColor, byte[] wallpaperData);
Task<List<CustomThemeMetadata>> GetCurrentCustomThemesAsync();
List<string> GetAvailableAccountColors();
Task ApplyCustomThemeAsync(bool isInitializing);
// Settings

View File

@@ -56,6 +56,12 @@ public partial class AccountMenuItem : MenuItemBase<MailAccount, MenuItemBase<IM
set => SetProperty(Parameter.Base64ProfilePictureData, value, Parameter, (u, n) => u.Base64ProfilePictureData = n);
}
public string AccountColorHex
{
get => Parameter.AccountColorHex;
set => SetProperty(Parameter.AccountColorHex, value, Parameter, (u, n) => u.AccountColorHex = n);
}
public IEnumerable<MailAccount> HoldingAccounts => new List<MailAccount> { Parameter };
public AccountMenuItem(MailAccount account, IMenuItem parent = null) : base(account, account.Id, parent)
@@ -66,9 +72,11 @@ public partial class AccountMenuItem : MenuItemBase<MailAccount, MenuItemBase<IM
public void UpdateAccount(MailAccount account)
{
Parameter = account;
AccountName = account.Name;
AttentionReason = account.AttentionReason;
Base64ProfilePicture = account.Base64ProfilePictureData;
OnPropertyChanged(nameof(AccountName));
OnPropertyChanged(nameof(Base64ProfilePicture));
OnPropertyChanged(nameof(AccountColorHex));
OnPropertyChanged(nameof(IsAttentionRequired));
if (SubMenuItems == null) return;

View File

@@ -2,4 +2,4 @@
namespace Wino.Core.Domain.Models.Accounts;
public record AccountCreationDialogResult(MailProviderType ProviderType, string AccountName, SpecialImapProviderDetails SpecialImapProviderDetails);
public record AccountCreationDialogResult(MailProviderType ProviderType, string AccountName, SpecialImapProviderDetails SpecialImapProviderDetails, string AccountColorHex);

View File

@@ -22,6 +22,10 @@
"AccountPickerDialog_Title": "Pick an account",
"AccountSettingsDialog_AccountName": "Sender Display Name",
"AccountSettingsDialog_AccountNamePlaceholder": "eg. John Doe",
"AccountDetailsPage_Title": "Account info",
"AccountDetailsPage_Description": "Change the name of the account in Wino and set desired sender name.",
"AccountDetailsPage_ColorPicker_Title": "Account color",
"AccountDetailsPage_ColorPicker_Description": "Assign a new account color to colorize its symbol in the list.",
"AddHyperlink": "Add",
"AppCloseBackgroundSynchronizationWarningTitle": "Background Synchronization",
"AppCloseStartupLaunchDisabledWarningMessageFirstLine": "Application has not been set to launch on Windows startup.",
@@ -566,6 +570,8 @@
"SettingsManageAccountSettings_Title": "Manage Account Settings",
"SettingsManageAliases_Description": "See e-mail aliases assigned for this account, update or delete them.",
"SettingsManageAliases_Title": "Aliases",
"SettingsEditAccountDetails_Title": "Edit Account Details",
"SettingsEditAccountDetails_Description": "Change account name, sender name and assign a new color if you like.",
"SettingsManageLink_Description": "Move items to add new link or remove existing link.",
"SettingsManageLink_Title": "Manage Link",
"SettingsMarkAsRead_Description": "Change what should happen to the selected item.",

View File

@@ -0,0 +1,80 @@
using System;
using System.Globalization;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
namespace Wino.Core.UWP.Converters;
public partial class HexToColorBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is string hexColor && !string.IsNullOrEmpty(hexColor))
{
try
{
// Remove # if present
hexColor = hexColor.Replace("#", "");
// Parse hex to color
byte r = byte.Parse(hexColor.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
byte g = byte.Parse(hexColor.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
byte b = byte.Parse(hexColor.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
return new SolidColorBrush(Color.FromArgb(255, r, g, b));
}
catch
{
return GetDefaultBrush();
}
}
return GetDefaultBrush();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
if (value is string hexColor)
{
try
{
// Remove # if present
hexColor = hexColor.Replace("#", string.Empty);
// Parse ARGB values
byte a = 255; // Default to fully opaque
byte r = byte.Parse(hexColor.Substring(0, 2), NumberStyles.HexNumber);
byte g = byte.Parse(hexColor.Substring(2, 2), NumberStyles.HexNumber);
byte b = byte.Parse(hexColor.Substring(4, 2), NumberStyles.HexNumber);
// If 8-digit hex (with alpha), parse alpha value
if (hexColor.Length == 8)
{
a = byte.Parse(hexColor.Substring(6, 2), NumberStyles.HexNumber);
}
return Color.FromArgb(a, r, g, b);
}
catch
{
return DependencyProperty.UnsetValue;
}
}
return DependencyProperty.UnsetValue;
}
private SolidColorBrush GetDefaultBrush()
{
// Get current theme's foreground brush.
// Bug: This should be ThemeResource to react to theme changes, but it's not.
// So if user changes the dark/light theme, this won't update.
if (WinoApplication.Current.UnderlyingThemeService.IsUnderlyingThemeDark())
return new SolidColorBrush(Colors.White);
else
return new SolidColorBrush(Colors.Black);
}
}

View File

@@ -1,19 +0,0 @@
<ContentDialog
x:Class="Wino.Dialogs.AccountEditDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{x:Bind domain:Translator.AccountEditDialog_Title}"
DefaultButton="Primary"
PrimaryButtonClick="SaveClicked"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_Save}"
SecondaryButtonText="{x:Bind domain:Translator.Buttons_Discard}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<Grid>
<TextBox Header="{x:Bind domain:Translator.AccountEditDialog_Message}" Text="{x:Bind Account.Name, Mode=TwoWay}" />
</Grid>
</ContentDialog>

View File

@@ -1,21 +0,0 @@
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Dialogs;
public sealed partial class AccountEditDialog : ContentDialog
{
public MailAccount Account { get; private set; }
public bool IsSaved { get; set; }
public AccountEditDialog(MailAccount account)
{
InitializeComponent();
Account = account;
}
private void SaveClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
IsSaved = true;
}
}

View File

@@ -5,6 +5,7 @@
xmlns:accounts="using:Wino.Core.Domain.Models.Accounts"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:helpers="using:Wino.Helpers"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
Title="{x:Bind domain:Translator.NewAccountDialog_Title}"
@@ -45,30 +46,47 @@
<Grid MinWidth="400" RowSpacing="12">
<Grid Visibility="{x:Bind IsProviderSelectionVisible, Mode=OneWay}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Account Name -->
<TextBox
x:Name="AccountNameTextbox"
Header="{x:Bind domain:Translator.NewAccountDialog_AccountName}"
PlaceholderText="{x:Bind domain:Translator.NewAccountDialog_AccountNamePlaceholder}"
TextChanged="InputChanged" />
<!--
TODO: Move Name, Sender Name and Color Picker to another Frame.
Provider selection should be first, then account details.
-->
<!--<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Color" />
<muxc:ColorPicker x:Name="AccountColorPicker" Grid.Column="1" />
</Grid>-->
<Grid ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox
x:Name="AccountNameTextbox"
Header="{x:Bind domain:Translator.NewAccountDialog_AccountName}"
PlaceholderText="{x:Bind domain:Translator.NewAccountDialog_AccountNamePlaceholder}"
TextChanged="InputChanged" />
<Button Grid.Column="1" VerticalAlignment="Bottom">
<Grid>
<Ellipse
x:Name="SelectedColorEllipse"
Width="16"
Height="16" />
<TextBlock x:Name="PickColorTextblock" Text="{x:Bind domain:Translator.CalendarDisplayOptions_Color}" />
</Grid>
<Button.Flyout>
<Flyout Placement="TopEdgeAlignedLeft">
<GridView
Width="150"
ItemTemplate="{StaticResource AccountColorTemplate}"
ItemsSource="{x:Bind AvailableColors, Mode=OneWay}"
SelectedItem="{x:Bind SelectedColor, Mode=TwoWay}" />
</Flyout>
</Button.Flyout>
</Button>
</Grid>
<ListView
Grid.Row="2"

View File

@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Accounts;
using Wino.Core.ViewModels.Data;
using Wino.Helpers;
namespace Wino.Core.UWP.Dialogs;
@@ -20,8 +23,15 @@ public sealed partial class NewAccountDialog : ContentDialog
public static readonly DependencyProperty IsProviderSelectionVisibleProperty = DependencyProperty.Register(nameof(IsProviderSelectionVisible), typeof(bool), typeof(NewAccountDialog), new PropertyMetadata(true));
public static readonly DependencyProperty IsSpecialImapServerPartVisibleProperty = DependencyProperty.Register(nameof(IsSpecialImapServerPartVisible), typeof(bool), typeof(NewAccountDialog), new PropertyMetadata(false));
public static readonly DependencyProperty SelectedMailProviderProperty = DependencyProperty.Register(nameof(SelectedMailProvider), typeof(ProviderDetail), typeof(NewAccountDialog), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedProviderChanged)));
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register(nameof(SelectedColor), typeof(AppColorViewModel), typeof(NewAccountDialog), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedColorChanged)));
public AppColorViewModel SelectedColor
{
get { return (AppColorViewModel)GetValue(SelectedColorProperty); }
set { SetValue(SelectedColorProperty, value); }
}
/// <summary>
/// Gets or sets current selected mail provider in the dialog.
/// </summary>
@@ -48,13 +58,19 @@ public sealed partial class NewAccountDialog : ContentDialog
public List<IProviderDetail> Providers { get; set; }
public List<AppColorViewModel> AvailableColors { get; set; }
public AccountCreationDialogResult Result = null;
public NewAccountDialog()
{
InitializeComponent();
// AccountColorPicker.Color = Colors.Blue;
var themeService = WinoApplication.Current.ThemeService.GetAvailableAccountColors();
AvailableColors = themeService.Select(a => new AppColorViewModel(a)).ToList();
UpdateSelectedColor();
}
private static void OnSelectedProviderChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
@@ -63,6 +79,19 @@ public sealed partial class NewAccountDialog : ContentDialog
dialog.Validate();
}
private static void OnSelectedColorChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is NewAccountDialog dialog)
dialog.UpdateSelectedColor();
}
private void UpdateSelectedColor()
{
PickColorTextblock.Visibility = SelectedColor == null ? Visibility.Visible : Visibility.Collapsed;
SelectedColorEllipse.Fill = SelectedColor == null ? null : XamlHelpers.GetSolidColorBrushFromHex(SelectedColor.Hex);
}
private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
Hide();
@@ -75,7 +104,7 @@ public sealed partial class NewAccountDialog : ContentDialog
// Special imap detail input.
var details = new SpecialImapProviderDetails(SpecialImapAddress.Text.Trim(), AppSpecificPassword.Password.Trim(), DisplayNameTextBox.Text.Trim(), SelectedMailProvider.SpecialImapProvider);
Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), details);
Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), details, SelectedColor?.Hex ?? string.Empty);
Hide();
return;
@@ -97,7 +126,7 @@ public sealed partial class NewAccountDialog : ContentDialog
}
else
{
Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), null);
Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), null, SelectedColor?.Hex ?? string.Empty);
Hide();
}
}

View File

@@ -10,7 +10,6 @@ using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Accounts;
@@ -38,18 +37,6 @@ public class DialogServiceBase : IDialogServiceBase
ApplicationResourceManager = applicationResourceManager;
}
public async Task<MailAccount> ShowEditAccountDialogAsync(MailAccount account)
{
var editAccountDialog = new AccountEditDialog(account)
{
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme()
};
await HandleDialogPresentationAsync(editAccountDialog);
return editAccountDialog.IsSaved ? editAccountDialog.Account : null;
}
public async Task<string> PickFilePathAsync(string saveFileName)
{
var picker = new FolderPicker()

View File

@@ -458,4 +458,59 @@ public class ThemeService : IThemeService
public string GetSystemAccentColorHex()
=> uiSettings.GetColorValue(UIColorType.Accent).ToHex();
public List<string> GetAvailableAccountColors()
{
return new List<string>()
{
"#e74c3c",
"#c0392b",
"#e53935",
"#d81b60",
// Pinks
"#e91e63",
"#ec407a",
"#ff4081",
// Purples
"#9b59b6",
"#8e44ad",
"#673ab7",
// Blues
"#3498db",
"#2980b9",
"#2196f3",
"#03a9f4",
"#00bcd4",
// Teals
"#009688",
"#1abc9c",
"#16a085",
// Greens
"#2ecc71",
"#27ae60",
"#4caf50",
"#8bc34a",
// Yellows & Oranges
"#f1c40f",
"#f39c12",
"#ff9800",
"#ff5722",
// Browns
"#795548",
"#a0522d",
// Grays
"#9e9e9e",
"#607d8b",
"#34495e",
"#2c3e50",
};
}
}

View File

@@ -16,9 +16,6 @@ public class UnderlyingThemeService : IUnderlyingThemeService
_configurationService = configurationService;
}
// This should not rely on application window to be present.
// Check theme from the settings, rely on UISettings background color if Default.
public bool IsUnderlyingThemeDark()
{
var currentTheme = _configurationService.Get(SelectedAppThemeKey, ApplicationElementTheme.Default);

View File

@@ -6,6 +6,7 @@
xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
xmlns:coreControls="using:Wino.Core.UWP.Controls"
xmlns:coreSelectors="using:Wino.Core.UWP.Selectors"
xmlns:coreViewModelData="using:Wino.Core.ViewModels.Data"
xmlns:domain="using:Wino.Core.Domain"
xmlns:helpers="using:Wino.Helpers"
xmlns:local="using:Wino.Core.UWP.Styles"
@@ -202,6 +203,19 @@
</Grid>
</DataTemplate>
<!-- Account Color Picker Template -->
<DataTemplate x:Key="AccountColorTemplate" x:DataType="coreViewModelData:AppColorViewModel">
<Grid
Width="32"
Height="32"
Margin="2">
<Rectangle
Fill="{x:Bind helpers:XamlHelpers.GetSolidColorBrushFromHex(Hex)}"
RadiusX="4"
RadiusY="4" />
</Grid>
</DataTemplate>
<coreSelectors:AppThemePreviewTemplateSelector
x:Key="AppThemePreviewTemplateSelector"
CustomAppTemplate="{StaticResource CustomAppThemeTemplate}"

View File

@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using CommunityToolkit.Mvvm.Messaging;
using MoreLinq;
@@ -16,7 +17,8 @@ namespace Wino.Views;
public sealed partial class ManageAccountsPage : ManageAccountsPageAbstract,
IRecipient<BackBreadcrumNavigationRequested>,
IRecipient<BreadcrumbNavigationRequested>,
IRecipient<MergedInboxRenamed>
IRecipient<MergedInboxRenamed>,
IRecipient<AccountUpdatedMessage>
{
public ObservableCollection<BreadcrumbNavigationItemViewModel> PageHistory { get; set; } = new ObservableCollection<BreadcrumbNavigationItemViewModel>();
@@ -79,14 +81,16 @@ public sealed partial class ManageAccountsPage : ManageAccountsPageAbstract,
GoBackFrame();
}
public void Receive(AccountUpdatedMessage message)
public async void Receive(AccountUpdatedMessage message)
{
// TODO: Find better way to retrieve page history from the stack for the account.
var activePage = PageHistory.LastOrDefault();
var activePage = PageHistory.FirstOrDefault(a => a.Request.PageType == WinoPage.AccountDetailsPage);
if (activePage == null) return;
activePage.Title = message.Account.Name;
await Dispatcher.TryRunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
activePage.Title = message.Account.Name;
});
}
public void Receive(MergedInboxRenamed message)

View File

@@ -38,7 +38,8 @@ public abstract class WinoApplication : Application, IRecipient<LanguageChanged>
protected IWinoLogger LogInitializer { get; }
protected IApplicationConfiguration AppConfiguration { get; }
protected IWinoServerConnectionManager<AppServiceConnection> AppServiceConnectionManager { get; }
protected IThemeService ThemeService { get; }
public IThemeService ThemeService { get; }
public IUnderlyingThemeService UnderlyingThemeService { get; }
protected IDatabaseService DatabaseService { get; }
protected ITranslationService TranslationService { get; }
@@ -62,6 +63,7 @@ public abstract class WinoApplication : Application, IRecipient<LanguageChanged>
ThemeService = Services.GetService<IThemeService>();
DatabaseService = Services.GetService<IDatabaseService>();
TranslationService = Services.GetService<ITranslationService>();
UnderlyingThemeService = Services.GetService<IUnderlyingThemeService>();
// Make sure the paths are setup on app start.
AppConfiguration.ApplicationDataFolderPath = ApplicationData.Current.LocalFolder.Path;

View File

@@ -13,7 +13,6 @@ using Wino.Core.Domain.Models.Folders;
using Wino.Core.Domain.Models.Navigation;
using Wino.Messaging.Client.Navigation;
using Wino.Messaging.Server;
using Wino.Messaging.UI;
namespace Wino.Mail.ViewModels;
@@ -23,6 +22,7 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
private readonly IAccountService _accountService;
private readonly IWinoServerConnectionManager _serverConnectionManager;
private readonly IFolderService _folderService;
private bool isLoaded = false;
public MailAccount Account { get; set; }
public ObservableCollection<IMailItemFolder> CurrentFolders { get; set; } = [];
@@ -78,20 +78,8 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
=> _folderService.ChangeFolderShowUnreadCountStateAsync(folderStructure.Id, isEnabled);
[RelayCommand]
private async Task RenameAccount()
{
if (Account == null)
return;
var updatedAccount = await _dialogService.ShowEditAccountDialogAsync(Account);
if (updatedAccount != null)
{
await _accountService.UpdateAccountAsync(updatedAccount);
ReportUIChange(new AccountUpdatedMessage(updatedAccount));
}
}
private void EditAccountDetails()
=> Messenger.Send(new BreadcrumbNavigationRequested(Translator.SettingsEditAccountDetails_Title, WinoPage.EditAccountDetailsPage, Account));
[RelayCommand]
private async Task DeleteAccount()
@@ -119,6 +107,9 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
}
}
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
{
base.OnNavigatedTo(mode, parameters);
@@ -143,6 +134,8 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
{
CurrentFolders.Add(folder);
}
isLoaded = true;
}
}
@@ -150,6 +143,8 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
{
base.OnPropertyChanged(e);
if (!IsActive || !isLoaded) return;
switch (e.PropertyName)
{
case nameof(IsFocusedInboxEnabled) when IsFocusedInboxSupportedForAccount:

View File

@@ -111,7 +111,8 @@ public partial class AccountManagementViewModel : AccountManagementPageViewModel
ProviderType = accountCreationDialogResult.ProviderType,
Name = accountCreationDialogResult.AccountName,
SpecialImapProvider = accountCreationDialogResult.SpecialImapProviderDetails?.SpecialImapProvider ?? SpecialImapProvider.None,
Id = Guid.NewGuid()
Id = Guid.NewGuid(),
AccountColorHex = accountCreationDialogResult.AccountColorHex
};
await creationDialog.ShowDialogAsync(accountCreationCancellationTokenSource);

View File

@@ -0,0 +1,88 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Navigation;
using Wino.Core.ViewModels.Data;
using Wino.Messaging.Client.Navigation;
namespace Wino.Mail.ViewModels;
public partial class EditAccountDetailsPageViewModel : MailBaseViewModel
{
private readonly IAccountService _accountService;
private readonly IThemeService _themeService;
[ObservableProperty]
public partial MailAccount Account { get; set; }
[ObservableProperty]
public partial string AccountName { get; set; }
[ObservableProperty]
public partial string SenderName { get; set; }
[ObservableProperty]
public partial AppColorViewModel SelectedColor { get; set; }
[ObservableProperty]
public partial List<AppColorViewModel> AvailableColors { get; set; }
public EditAccountDetailsPageViewModel(IAccountService accountService, IThemeService themeService)
{
_accountService = accountService;
_themeService = themeService;
var colorHexList = _themeService.GetAvailableAccountColors();
AvailableColors = colorHexList.Select(a => new AppColorViewModel(a)).ToList();
}
[RelayCommand]
private async Task SaveChangesAsync()
{
await UpdateAccountAsync();
Messenger.Send(new BackBreadcrumNavigationRequested());
}
private Task UpdateAccountAsync()
{
Account.Name = AccountName;
Account.SenderName = SenderName;
Account.AccountColorHex = SelectedColor == null ? string.Empty : SelectedColor.Hex;
return _accountService.UpdateAccountAsync(Account);
}
[RelayCommand]
private void ResetColor()
=> SelectedColor = null;
partial void OnSelectedColorChanged(AppColorViewModel oldValue, AppColorViewModel newValue)
{
_ = UpdateAccountAsync();
}
public override void OnNavigatedTo(NavigationMode mode, object parameters)
{
base.OnNavigatedTo(mode, parameters);
if (parameters is MailAccount account)
{
Account = account;
AccountName = account.Name;
SenderName = account.SenderName;
if (!string.IsNullOrEmpty(account.AccountColorHex))
{
SelectedColor = AvailableColors.FirstOrDefault(a => a.Hex == account.AccountColorHex);
}
}
}
}

View File

@@ -112,6 +112,7 @@ public sealed partial class App : WinoApplication,
services.AddTransient(typeof(ComposePageViewModel));
services.AddTransient(typeof(IdlePageViewModel));
services.AddTransient(typeof(EditAccountDetailsPageViewModel));
services.AddTransient(typeof(AccountDetailsPageViewModel));
services.AddTransient(typeof(SignatureManagementPageViewModel));
services.AddTransient(typeof(MessageListPageViewModel));

View File

@@ -9,6 +9,7 @@
xmlns:controls="using:Wino.Controls"
xmlns:controls1="using:CommunityToolkit.WinUI.Controls"
xmlns:coreControls="using:Wino.Core.UWP.Controls"
xmlns:coreConverters="using:Wino.Core.UWP.Converters"
xmlns:coreSelectors="using:Wino.Core.UWP.Selectors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
@@ -23,6 +24,8 @@
<Page.Resources>
<coreConverters:HexToColorBrushConverter x:Key="HexToColorBrushConverter" />
<!-- Clickable New Style Account Template -->
<DataTemplate x:Key="ClickableAccountMenuTemplate" x:DataType="menu:AccountMenuItem">
<controls:AccountNavigationItem
@@ -41,7 +44,10 @@
</TransitionCollection>
</coreControls:WinoNavigationViewItem.ContentTransitions>
<muxc:NavigationViewItem.Icon>
<coreControls:WinoFontIcon FontSize="12" Icon="{x:Bind helpers:XamlHelpers.GetProviderIcon(Parameter)}" />
<coreControls:WinoFontIcon
FontSize="12"
Foreground="{x:Bind AccountColorHex, Converter={StaticResource HexToColorBrushConverter}, Mode=OneWay}"
Icon="{x:Bind helpers:XamlHelpers.GetProviderIcon(Parameter)}" />
</muxc:NavigationViewItem.Icon>
<muxc:NavigationViewItem.InfoBadge>
<muxc:InfoBadge
@@ -252,7 +258,7 @@
</TransitionCollection>
</coreControls:WinoNavigationViewItem.ContentTransitions>
<coreControls:WinoNavigationViewItem.Icon>
<PathIcon Data="F1 M 8.613281 17.5 C 8.75 17.942709 8.945312 18.359375 9.199219 18.75 L 4.921875 18.75 C 4.433594 18.75 3.966471 18.650717 3.520508 18.452148 C 3.074544 18.25358 2.683919 17.986654 2.348633 17.651367 C 2.013346 17.31608 1.746419 16.925455 1.547852 16.479492 C 1.349284 16.033529 1.25 15.566406 1.25 15.078125 L 1.25 4.921875 C 1.25 4.433594 1.349284 3.966473 1.547852 3.520508 C 1.746419 3.074545 2.013346 2.68392 2.348633 2.348633 C 2.683919 2.013348 3.074544 1.74642 3.520508 1.547852 C 3.966471 1.349285 4.433594 1.25 4.921875 1.25 L 15.078125 1.25 C 15.566406 1.25 16.033527 1.349285 16.479492 1.547852 C 16.925455 1.74642 17.31608 2.013348 17.651367 2.348633 C 17.986652 2.68392 18.25358 3.074545 18.452148 3.520508 C 18.650715 3.966473 18.75 4.433594 18.75 4.921875 L 18.75 6.572266 C 18.580729 6.344402 18.390299 6.132813 18.178711 5.9375 C 17.967121 5.742188 17.740885 5.566407 17.5 5.410156 L 17.5 4.951172 C 17.5 4.625651 17.433268 4.314779 17.299805 4.018555 C 17.16634 3.722332 16.987305 3.461914 16.762695 3.237305 C 16.538086 3.012695 16.277668 2.83366 15.981445 2.700195 C 15.685221 2.566732 15.374349 2.5 15.048828 2.5 L 4.951172 2.5 C 4.619141 2.5 4.303385 2.568359 4.003906 2.705078 C 3.704427 2.841797 3.44401 3.02409 3.222656 3.251953 C 3.001302 3.479818 2.825521 3.745117 2.695312 4.047852 C 2.565104 4.350587 2.5 4.66797 2.5 5 L 13.310547 5 C 12.60091 5.266928 11.998697 5.683594 11.503906 6.25 L 2.5 6.25 L 2.5 15.048828 C 2.5 15.38737 2.568359 15.704753 2.705078 16.000977 C 2.841797 16.297201 3.024088 16.55599 3.251953 16.777344 C 3.479818 16.998697 3.745117 17.174479 4.047852 17.304688 C 4.350586 17.434896 4.667969 17.5 5 17.5 Z M 18.125 9.443359 C 18.125 9.866537 18.040363 10.263672 17.871094 10.634766 C 17.701822 11.005859 17.473957 11.329753 17.1875 11.606445 C 16.901041 11.883139 16.56901 12.101237 16.191406 12.260742 C 15.813802 12.420248 15.416666 12.5 15 12.5 C 14.563802 12.5 14.1569 12.41862 13.779297 12.255859 C 13.401691 12.0931 13.071288 11.870117 12.788086 11.586914 C 12.504882 11.303711 12.2819 10.973308 12.119141 10.595703 C 11.95638 10.2181 11.875 9.811198 11.875 9.375 C 11.875 8.938803 11.95638 8.531901 12.119141 8.154297 C 12.2819 7.776693 12.504882 7.446289 12.788086 7.163086 C 13.071288 6.879883 13.401691 6.656901 13.779297 6.494141 C 14.1569 6.331381 14.563802 6.25 15 6.25 C 15.449218 6.25 15.864257 6.333008 16.245117 6.499023 C 16.625977 6.665039 16.956379 6.892904 17.236328 7.182617 C 17.516275 7.472331 17.734375 7.810873 17.890625 8.198242 C 18.046875 8.585612 18.125 9.000651 18.125 9.443359 Z M 20 16.25 C 20 16.666666 19.926758 17.049154 19.780273 17.397461 C 19.633789 17.745768 19.435221 18.058268 19.18457 18.334961 C 18.933918 18.611654 18.642578 18.854166 18.310547 19.0625 C 17.978516 19.270834 17.626953 19.444986 17.255859 19.584961 C 16.884766 19.724936 16.505533 19.829102 16.118164 19.897461 C 15.730794 19.96582 15.358072 20 15 20 C 14.654947 20 14.291992 19.96582 13.911133 19.897461 C 13.530273 19.829102 13.154297 19.726562 12.783203 19.589844 C 12.412109 19.453125 12.058919 19.282227 11.723633 19.077148 C 11.388346 18.87207 11.092122 18.632812 10.834961 18.359375 C 10.577799 18.085938 10.374349 17.779947 10.224609 17.441406 C 10.074869 17.102865 10 16.731771 10 16.328125 L 10 15.78125 C 10 15.501303 10.052083 15.237631 10.15625 14.990234 C 10.260416 14.742839 10.405273 14.526367 10.59082 14.34082 C 10.776367 14.155273 10.991211 14.010417 11.235352 13.90625 C 11.479492 13.802084 11.744791 13.75 12.03125 13.75 L 17.96875 13.75 C 18.248697 13.75 18.512369 13.803711 18.759766 13.911133 C 19.00716 14.018555 19.222004 14.163412 19.404297 14.345703 C 19.586588 14.527995 19.731445 14.742839 19.838867 14.990234 C 19.946289 15.237631 20 15.501303 20 15.78125 Z " />
<PathIcon Data="F1 M 8.613281 17.5 C 8.75 17.942709 8.945312 18.359375 9.199219 18.75 L 4.921875 18.75 C 4.433594 18.75 3.966471 18.650717 3.520508 18.452148 C 3.074544 18.25358 2.683919 17.986654 2.348633 17.651367 C 2.013346 17.31608 1.746419 16.925455 1.547852 16.479492 C 1.349284 16.033529 1.25 15.566406 1.25 15.078125 L 1.25 4.921875 C 1.25 4.433594 1.349284 3.966473 1.547852 3.520508 C 1.746419 3.074545 2.013346 2.68392 2.348633 2.348633 C 2.683919 2.013348 3.074544 1.74642 3.520508 1.547852 C 3.966471 1.349285 4.433594 1.25 4.921875 1.25 L 15.078125 1.25 C 15.566406 1.25 16.033527 1.349285 16.479492 1.547852 C 16.925455 1.74642 17.31608 2.013348 17.651367 2.348633 C 17.986652 2.68392 18.25358 3.074545 18.452148 3.520508 C 18.650715 3.966473 18.75 4.433594 18.75 4.921875 L 18.75 6.572266 C 18.580729 6.344402 18.390299 6.132813 18.178711 5.9375 C 17.967121 5.742188 17.740885 5.566407 17.5 5.410156 L 17.5 4.951172 C 17.5 4.625651 17.433268 4.314779 17.299805 4.018555 C 17.16634 3.722332 16.987305 3.461914 16.762695 3.237305 C 16.538086 3.012695 16.277668 2.83366 15.981445 2.700195 C 15.685221 2.566732 15.374349 2.5 15.048828 2.5 L 4.951172 2.5 C 4.619141 2.5 4.303385 2.568359 4.003906 2.705078 C 3.704427 2.841797 3.44401 3.02409 3.222656 3.251953 C 3.001302 3.479818 2.825521 3.745117 2.695312 4.047852 C 2.565104 4.350587 2.5 4.66797 2.5 5 L 13.310547 5 C 12.60091 5.266928 11.998697 5.683594 11.503906 6.25 L 2.5 6.25 L 2.5 15.048828 C 2.5 15.38737 2.568359 15.704753 2.705078 16.000977 C 2.841797 16.297201 3.024088 16.55599 3.251953 16.777344 C 3.479818 16.998697 3.745117 17.174479 4.047852 17.304688 C 4.350586 17.434896 4.667969 17.5 5 17.5 Z" />
</coreControls:WinoNavigationViewItem.Icon>
<Grid MinHeight="50">

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Threading.Tasks;
using CommunityToolkit.WinUI;
@@ -10,12 +9,11 @@ using Microsoft.Web.WebView2.Core;
using Windows.UI.ViewManagement.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Media;
using Wino.Core.Domain;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models;
using Wino.Core.Domain.Models.Reader;
using Wino.Core.UWP;
using Wino.Core.UWP.Extensions;
namespace Wino.Mail.Controls;
@@ -24,7 +22,6 @@ public sealed partial class WebViewEditorControl : Control, IDisposable
private readonly INativeAppService _nativeAppService = App.Current.Services.GetService<INativeAppService>();
private readonly IFontService _fontService = App.Current.Services.GetService<IFontService>();
private readonly IPreferencesService _preferencesService = App.Current.Services.GetService<IPreferencesService>();
private readonly IUnderlyingThemeService _underlyingThemeService = App.Current.Services.GetService<IUnderlyingThemeService>();
[GeneratedDependencyProperty]
public partial bool IsEditorDarkMode { get; set; }
@@ -99,7 +96,7 @@ public sealed partial class WebViewEditorControl : Control, IDisposable
}
}
[GeneratedDependencyProperty]
[GeneratedDependencyProperty(DefaultValue = true)]
public partial bool IsEditorIndentEnabled { get; private set; }
[GeneratedDependencyProperty]
@@ -142,9 +139,7 @@ public sealed partial class WebViewEditorControl : Control, IDisposable
{
this.DefaultStyleKey = typeof(WebViewEditorControl);
IsEditorIndentEnabled = true;
IsEditorDarkMode = _underlyingThemeService.IsUnderlyingThemeDark();
IsEditorDarkMode = WinoApplication.Current.UnderlyingThemeService.IsUnderlyingThemeDark();
}
protected override async void OnApplyTemplate()

View File

@@ -55,17 +55,6 @@ public class DialogService : DialogServiceBase, IMailDialogService
}
}
public async Task<MailAccount> ShowEditAccountDialogAsync(MailAccount account)
{
var editAccountDialog = new AccountEditDialog(account)
{
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme()
};
await HandleDialogPresentationAsync(editAccountDialog);
return editAccountDialog.IsSaved ? editAccountDialog.Account : null;
}
public async Task<ICreateAccountAliasDialog> ShowCreateAccountAliasDialogAsync()
{
@@ -190,7 +179,7 @@ public class DialogService : DialogServiceBase, IMailDialogService
await HandleDialogPresentationAsync(dialog);
if(dialog.Copied)
if (dialog.Copied)
InfoBarMessage(Translator.ClipboardTextCopied_Title, string.Format(Translator.ClipboardTextCopied_Message, Translator.MessageSourceDialog_Title), InfoBarMessageType.Information);
}

View File

@@ -56,6 +56,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
WinoPage.AppPreferencesPage => typeof(AppPreferencesPage),
WinoPage.AliasManagementPage => typeof(AliasManagementPage),
WinoPage.LanguageTimePage => typeof(LanguageTimePage),
WinoPage.EditAccountDetailsPage => typeof(EditAccountDetailsPage),
_ => null,
};
}

View File

@@ -0,0 +1,5 @@
using Wino.Core.UWP;
using Wino.Mail.ViewModels;
namespace Wino.Views.Abstract;
public partial class EditAccountDetailsPageAbstract : BasePage<EditAccountDetailsPageViewModel> { }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
using Wino.Views.Abstract;
namespace Wino.Views;
public sealed partial class EditAccountDetailsPage : EditAccountDetailsPageAbstract
{
public EditAccountDetailsPage()
{
InitializeComponent();
}
}