Render mail categories in list items
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
@@ -71,6 +73,8 @@ public partial class AccountContactViewModel : ObservableObject, IMailItemDispla
|
||||
public bool HasReadReceiptTracking => false;
|
||||
public bool IsReadReceiptAcknowledged => false;
|
||||
public string ReadReceiptDisplayText => string.Empty;
|
||||
public IReadOnlyList<MailCategory> Categories => [];
|
||||
public bool HasCategories => false;
|
||||
public AccountContact SenderContact => new()
|
||||
{
|
||||
Address = Address,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
@@ -39,6 +40,8 @@ public partial class MailItemViewModel(MailCopy mailCopy) : ObservableRecipient,
|
||||
[NotifyPropertyChangedFor(nameof(UniqueId))]
|
||||
[NotifyPropertyChangedFor(nameof(ContactPictureFileId))]
|
||||
[NotifyPropertyChangedFor(nameof(SenderContact))]
|
||||
[NotifyPropertyChangedFor(nameof(Categories))]
|
||||
[NotifyPropertyChangedFor(nameof(HasCategories))]
|
||||
public partial MailCopy MailCopy { get; set; } = mailCopy;
|
||||
|
||||
[ObservableProperty]
|
||||
@@ -124,6 +127,10 @@ public partial class MailItemViewModel(MailCopy mailCopy) : ObservableRecipient,
|
||||
_ => string.Empty
|
||||
};
|
||||
|
||||
public IReadOnlyList<MailCategory> Categories => MailCopy.Categories;
|
||||
|
||||
public bool HasCategories => Categories.Count > 0;
|
||||
|
||||
public string DraftId
|
||||
{
|
||||
get => MailCopy.DraftId;
|
||||
@@ -262,6 +269,7 @@ public partial class MailItemViewModel(MailCopy mailCopy) : ObservableRecipient,
|
||||
nameof(FolderId) => MailCopyChangeFlags.FolderId,
|
||||
nameof(UniqueId) => MailCopyChangeFlags.UniqueId,
|
||||
nameof(ContactPictureFileId) or nameof(SenderContact) => MailCopyChangeFlags.SenderContact,
|
||||
nameof(Categories) or nameof(HasCategories) => MailCopyChangeFlags.Categories,
|
||||
_ => MailCopyChangeFlags.None
|
||||
};
|
||||
}
|
||||
@@ -474,9 +482,21 @@ public partial class MailItemViewModel(MailCopy mailCopy) : ObservableRecipient,
|
||||
Queue(nameof(SenderContact));
|
||||
}
|
||||
|
||||
if ((changedFlags & MailCopyChangeFlags.Categories) != 0)
|
||||
{
|
||||
Queue(nameof(Categories));
|
||||
Queue(nameof(HasCategories));
|
||||
}
|
||||
|
||||
foreach (var changedProperty in changedProperties)
|
||||
{
|
||||
OnPropertyChanged(changedProperty);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCategories(IReadOnlyList<MailCategory> categories)
|
||||
{
|
||||
MailCopy.Categories = categories?.ToList() ?? [];
|
||||
RaisePropertyChanges(MailCopyChangeFlags.Categories);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
@@ -111,6 +112,13 @@ public partial class ThreadMailItemViewModel : ObservableRecipient, IMailListIte
|
||||
public bool IsReadReceiptAcknowledged => newestMailViewModel?.IsReadReceiptAcknowledged ?? false;
|
||||
|
||||
public string ReadReceiptDisplayText => newestMailViewModel?.ReadReceiptDisplayText ?? string.Empty;
|
||||
public IReadOnlyList<MailCategory> Categories => ThreadEmails
|
||||
.SelectMany(a => a.Categories)
|
||||
.GroupBy(a => a.Id)
|
||||
.Select(a => a.First())
|
||||
.OrderBy(a => a.Name)
|
||||
.ToList();
|
||||
public bool HasCategories => ThreadEmails.Any(a => a.HasCategories);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether any email in this thread is a draft
|
||||
@@ -206,6 +214,8 @@ public partial class ThreadMailItemViewModel : ObservableRecipient, IMailListIte
|
||||
[NotifyPropertyChangedFor(nameof(UniqueId))]
|
||||
[NotifyPropertyChangedFor(nameof(ContactPictureFileId))]
|
||||
[NotifyPropertyChangedFor(nameof(SenderContact))]
|
||||
[NotifyPropertyChangedFor(nameof(Categories))]
|
||||
[NotifyPropertyChangedFor(nameof(HasCategories))]
|
||||
public partial ObservableCollection<MailItemViewModel> ThreadEmails { get; set; } = [];
|
||||
|
||||
private MailItemViewModel newestMailViewModel => _cachedNewestMailViewModel;
|
||||
@@ -467,6 +477,12 @@ public partial class ThreadMailItemViewModel : ObservableRecipient, IMailListIte
|
||||
Queue(nameof(ContactPictureFileId));
|
||||
Queue(nameof(SenderContact));
|
||||
}
|
||||
|
||||
if ((changedFlags & MailCopyChangeFlags.Categories) != 0)
|
||||
{
|
||||
Queue(nameof(Categories));
|
||||
Queue(nameof(HasCategories));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,6 +511,12 @@ public partial class ThreadMailItemViewModel : ObservableRecipient, IMailListIte
|
||||
if ((changedFlags & MailCopyChangeFlags.IsDraft) != 0 || changedFlags == MailCopyChangeFlags.All)
|
||||
Queue(nameof(IsDraft));
|
||||
|
||||
if ((changedFlags & MailCopyChangeFlags.Categories) != 0 || changedFlags == MailCopyChangeFlags.All)
|
||||
{
|
||||
Queue(nameof(Categories));
|
||||
Queue(nameof(HasCategories));
|
||||
}
|
||||
|
||||
foreach (var changedProperty in changedProperties)
|
||||
{
|
||||
OnPropertyChanged(changedProperty);
|
||||
|
||||
@@ -1329,6 +1329,8 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
|
||||
private async Task<List<MailItemViewModel>> PrepareMailViewModelsAsync(IEnumerable<MailCopy> mailItems, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await PopulateMailCategoriesAsync(mailItems, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Run ViewModel creation on background thread to avoid blocking UI
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
@@ -1342,6 +1344,38 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task PopulateMailCategoriesAsync(IEnumerable<MailCopy> mailItems, CancellationToken cancellationToken)
|
||||
{
|
||||
var mails = mailItems?.Where(a => a != null).ToList() ?? [];
|
||||
if (mails.Count == 0)
|
||||
return;
|
||||
|
||||
var accountIdsByFolderId = ActiveFolder?.HandlingFolders?
|
||||
.GroupBy(a => a.Id)
|
||||
.ToDictionary(a => a.Key, a => a.First().MailAccountId) ?? new Dictionary<Guid, Guid>();
|
||||
|
||||
var mailsByAccount = mails
|
||||
.GroupBy(mail => ResolveMailAccountId(mail, accountIdsByFolderId))
|
||||
.Where(group => group.Key != Guid.Empty)
|
||||
.ToList();
|
||||
|
||||
foreach (var groupedMails in mailsByAccount)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var categoriesByMail = await _mailCategoryService
|
||||
.GetCategoriesByMailAsync(groupedMails.Key, groupedMails.Select(a => a.UniqueId))
|
||||
.ConfigureAwait(false);
|
||||
|
||||
foreach (var mail in groupedMails)
|
||||
{
|
||||
mail.Categories = categoriesByMail.TryGetValue(mail.UniqueId, out var categories)
|
||||
? categories.ToList()
|
||||
: [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HashSet<Guid>> GetPendingOperationUniqueIdsForActiveFolderAccountsAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var pendingOperationUniqueIds = new HashSet<Guid>();
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
@@ -187,6 +188,24 @@ public partial class MessageListPageViewModel : MailBaseViewModel
|
||||
public bool HasReadReceiptTracking => true;
|
||||
public bool IsReadReceiptAcknowledged => false;
|
||||
public string ReadReceiptDisplayText => Translator.MailReceiptStatus_Requested;
|
||||
public IReadOnlyList<MailCategory> Categories =>
|
||||
[
|
||||
new()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = "Urgent",
|
||||
BackgroundColorHex = "#FFE1DE",
|
||||
TextColorHex = "#A1260D"
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = "Client",
|
||||
BackgroundColorHex = "#E4E8FF",
|
||||
TextColorHex = "#4255C5"
|
||||
}
|
||||
];
|
||||
public bool HasCategories => Categories.Count > 0;
|
||||
public AccountContact SenderContact => new()
|
||||
{
|
||||
Address = "hi@bkaan.dev",
|
||||
|
||||
Reference in New Issue
Block a user