Show "You" for active account in mail rendering page (#566)

* Added account contact view model to handle "You" case.

* fix namespaces again
This commit is contained in:
Aleh Khantsevich
2025-02-16 14:38:53 +01:00
committed by GitHub
parent f7836eedce
commit caae751698
9 changed files with 387 additions and 362 deletions

View File

@@ -36,14 +36,6 @@ public class AccountContact : IEquatable<AccountContact>
/// </summary> /// </summary>
public bool IsRootContact { get; set; } public bool IsRootContact { get; set; }
/// <summary>
/// Short display name of the contact.
/// Eather Name or Address.
/// </summary>
public string ShortDisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? $"{Address.ToLowerInvariant()};" : $"{Name};";
public string DisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? Address.ToLowerInvariant() : $"{Name} <{Address.ToLowerInvariant()}>";
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return Equals(obj as AccountContact); return Equals(obj as AccountContact);
@@ -58,10 +50,7 @@ public class AccountContact : IEquatable<AccountContact>
public override int GetHashCode() public override int GetHashCode()
{ {
int hashCode = -1717786383; return HashCode.Combine(Address, Name);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Address);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Name);
return hashCode;
} }
public static bool operator ==(AccountContact left, AccountContact right) public static bool operator ==(AccountContact left, AccountContact right)

View File

@@ -15,6 +15,7 @@
"AccountSettingsDialog_AccountName": "Sender Display Name", "AccountSettingsDialog_AccountName": "Sender Display Name",
"AccountSettingsDialog_AccountNamePlaceholder": "eg. John Doe", "AccountSettingsDialog_AccountNamePlaceholder": "eg. John Doe",
"AddHyperlink": "Add", "AddHyperlink": "Add",
"AccountContactNameYou": "You",
"AutoDiscoveryProgressMessage": "Searching for mail settings...", "AutoDiscoveryProgressMessage": "Searching for mail settings...",
"AppCloseBackgroundSynchronizationWarningTitle": "Background Synchronization", "AppCloseBackgroundSynchronizationWarningTitle": "Background Synchronization",
"AppCloseTerminateBehaviorWarningMessageFirstLine": "You are terminating Wino Mail and your app close behavior is set to 'Terminate'.", "AppCloseTerminateBehaviorWarningMessageFirstLine": "You are terminating Wino Mail and your app close behavior is set to 'Terminate'.",

View File

@@ -22,8 +22,8 @@ using Wino.Core.Domain;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Services; using Wino.Services;
namespace Wino.Core.UWP namespace Wino.Core.UWP;
{
public abstract class WinoApplication : Application public abstract class WinoApplication : Application
{ {
public new static WinoApplication Current => (WinoApplication)Application.Current; public new static WinoApplication Current => (WinoApplication)Application.Current;
@@ -246,4 +246,3 @@ namespace Wino.Core.UWP
LogInitializer.SetupLogger(logFilePath); LogInitializer.SetupLogger(logFilePath);
} }
} }
}

View File

@@ -6,8 +6,8 @@ using Wino.Core.Domain;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
namespace Wino.Core.ViewModels namespace Wino.Core.ViewModels;
{
public partial class AboutPageViewModel : CoreBaseViewModel public partial class AboutPageViewModel : CoreBaseViewModel
{ {
private readonly IStoreRatingService _storeRatingService; private readonly IStoreRatingService _storeRatingService;
@@ -127,4 +127,3 @@ namespace Wino.Core.ViewModels
private Task ShowRateDialogAsync() => _storeRatingService.LaunchStorePageForReviewAsync(); private Task ShowRateDialogAsync() => _storeRatingService.LaunchStorePageForReviewAsync();
} }
}

View File

@@ -0,0 +1,37 @@
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Mail.ViewModels.Data;
public class AccountContactViewModel: AccountContact
{
public AccountContactViewModel(AccountContact contact)
{
Address = contact.Address;
Name = contact.Name;
Base64ContactPicture = contact.Base64ContactPicture;
IsRootContact = contact.IsRootContact;
}
/// <summary>
/// Gets or sets whether the contact is the current account.
/// </summary>
public bool IsMe { get; set; }
/// <summary>
/// Provides a short name of the contact.
/// <see cref="ShortDisplayName"/> or "You"
/// </summary>
public string ShortNameOrYou => IsMe ? Translator.AccountContactNameYou : ShortDisplayName;
/// <summary>
/// Short display name of the contact.
/// Either Name or Address.
/// </summary>
public string ShortDisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? $"{Address.ToLowerInvariant()};" : $"{Name};";
/// <summary>
/// Display name of the contact in a format: Name <Address>.
/// </summary>
public string DisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? Address.ToLowerInvariant() : $"{Name} <{Address.ToLowerInvariant()}>";
}

View File

@@ -90,35 +90,33 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(ShouldDisplayDownloadProgress))] [NotifyPropertyChangedFor(nameof(ShouldDisplayDownloadProgress))]
private bool isIndetermineProgress; public partial bool IsIndetermineProgress { get; set; }
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(ShouldDisplayDownloadProgress))] [NotifyPropertyChangedFor(nameof(ShouldDisplayDownloadProgress))]
private double currentDownloadPercentage; public partial double CurrentDownloadPercentage { get; set; }
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(CanUnsubscribe))] [NotifyPropertyChangedFor(nameof(CanUnsubscribe))]
private MailRenderModel currentRenderModel; public partial MailRenderModel CurrentRenderModel { get; set; }
[ObservableProperty] [ObservableProperty]
private string subject; public partial string Subject { get; set; }
[ObservableProperty] [ObservableProperty]
private string fromAddress; public partial string FromAddress { get; set; }
[ObservableProperty] [ObservableProperty]
private string fromName; public partial string FromName { get; set; }
[ObservableProperty] [ObservableProperty]
private string contactPicture; public partial string ContactPicture { get; set; }
[ObservableProperty] [ObservableProperty]
private DateTime creationDate; public partial DateTime CreationDate { get; set; }
public ObservableCollection<AccountContactViewModel> ToItems { get; set; } = [];
public ObservableCollection<AccountContactViewModel> CcItems { get; set; } = [];
public ObservableCollection<AccountContact> ToItems { get; set; } = []; public ObservableCollection<AccountContactViewModel> BccItems { get; set; } = [];
public ObservableCollection<AccountContact> CcItems { get; set; } = [];
public ObservableCollection<AccountContact> BccItems { get; set; } = [];
public ObservableCollection<MailAttachmentViewModel> Attachments { get; set; } = []; public ObservableCollection<MailAttachmentViewModel> Attachments { get; set; } = [];
public ObservableCollection<MailOperationMenuItem> MenuItems { get; set; } = []; public ObservableCollection<MailOperationMenuItem> MenuItems { get; set; } = [];
@@ -467,9 +465,9 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
}); });
} }
private async Task<List<AccountContact>> GetAccountContacts(InternetAddressList internetAddresses) private async Task<List<AccountContactViewModel>> GetAccountContacts(InternetAddressList internetAddresses)
{ {
var accounts = new List<AccountContact>(); List<AccountContactViewModel> accounts = [];
foreach (var item in internetAddresses) foreach (var item in internetAddresses)
{ {
if (item is MailboxAddress mailboxAddress) if (item is MailboxAddress mailboxAddress)
@@ -477,14 +475,17 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
var foundContact = await _contactService.GetAddressInformationByAddressAsync(mailboxAddress.Address).ConfigureAwait(false) var foundContact = await _contactService.GetAddressInformationByAddressAsync(mailboxAddress.Address).ConfigureAwait(false)
?? new AccountContact() { Name = mailboxAddress.Name, Address = mailboxAddress.Address }; ?? new AccountContact() { Name = mailboxAddress.Name, Address = mailboxAddress.Address };
var contactViewModel = new AccountContactViewModel(foundContact);
// Make sure that user account first in the list. // Make sure that user account first in the list.
if (foundContact.Address == initializedMailItemViewModel?.AssignedAccount?.Address) if (string.Equals(contactViewModel.Address, initializedMailItemViewModel?.AssignedAccount?.Address, StringComparison.OrdinalIgnoreCase))
{ {
accounts.Insert(0, foundContact); contactViewModel.IsMe = true;
accounts.Insert(0, contactViewModel);
} }
else else
{ {
accounts.Add(foundContact); accounts.Add(contactViewModel);
} }
} }
else if (item is GroupAddress groupAddress) else if (item is GroupAddress groupAddress)

View File

@@ -21,12 +21,12 @@
mc:Ignorable="d"> mc:Ignorable="d">
<Page.Resources> <Page.Resources>
<DataTemplate x:Key="InternetAddressTemplate" x:DataType="entities:AccountContact"> <DataTemplate x:Key="InternetAddressTemplate" x:DataType="viewModelData:AccountContactViewModel">
<HyperlinkButton <HyperlinkButton
Margin="-2,-2" Margin="-2,-2"
Padding="4,2" Padding="4,2"
Click="InternetAddressClicked" Click="InternetAddressClicked"
Content="{x:Bind ShortDisplayName}" Content="{x:Bind ShortNameOrYou}"
ToolTipService.ToolTip="{x:Bind DisplayName}"> ToolTipService.ToolTip="{x:Bind DisplayName}">
<HyperlinkButton.ContextFlyout> <HyperlinkButton.ContextFlyout>
<Flyout Placement="Bottom"> <Flyout Placement="Bottom">

View File

@@ -37,7 +37,7 @@ public class ContactService : BaseDatabaseService, IContactService
} }
public Task<AccountContact> GetAddressInformationByAddressAsync(string address) public Task<AccountContact> GetAddressInformationByAddressAsync(string address)
=> Connection.Table<AccountContact>().Where(a => a.Address == address).FirstOrDefaultAsync(); => Connection.Table<AccountContact>().FirstOrDefaultAsync(a => a.Address == address);
public async Task SaveAddressInformationAsync(MimeMessage message) public async Task SaveAddressInformationAsync(MimeMessage message)
{ {

View File

@@ -2,8 +2,8 @@
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Services.Threading; using Wino.Services.Threading;
namespace Wino.Services namespace Wino.Services;
{
public static class ServicesContainerSetup public static class ServicesContainerSetup
{ {
public static void RegisterSharedServices(this IServiceCollection services) public static void RegisterSharedServices(this IServiceCollection services)
@@ -33,4 +33,3 @@ namespace Wino.Services
} }
} }
}