Files
Wino-Mail/Wino.Mail.ViewModels/Data/ThreadMailItemViewModel.cs
T

138 lines
3.9 KiB
C#
Raw Normal View History

2024-04-18 01:44:37 +02:00
using System;
using System.Collections.Generic;
2025-10-26 23:35:09 +01:00
using System.Collections.ObjectModel;
2024-04-18 01:44:37 +02:00
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
2025-02-16 11:54:23 +01:00
namespace Wino.Mail.ViewModels.Data;
/// <summary>
/// Thread mail item (multiple IMailItem) view model representation.
/// </summary>
2025-10-25 10:54:38 +02:00
public partial class ThreadMailItemViewModel : ObservableRecipient, IDisposable, IMailListItem
2024-04-18 01:44:37 +02:00
{
2025-10-03 15:46:38 +02:00
private readonly string _threadId;
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
private bool _disposed;
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
[ObservableProperty]
2025-10-03 15:46:38 +02:00
[NotifyPropertyChangedRecipients]
public partial bool IsThreadExpanded { get; set; }
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
[ObservableProperty]
public partial bool IsSelected { get; set; }
/// <summary>
/// Gets the number of emails in this thread
/// </summary>
2025-10-26 23:35:09 +01:00
public int EmailCount => ThreadEmails.Count;
2025-10-03 15:46:38 +02:00
/// <summary>
/// Gets the latest email's subject for display
/// </summary>
2025-10-26 23:35:09 +01:00
public string Subject => ThreadEmails
2025-10-03 15:46:38 +02:00
.OrderByDescending(e => e.MailCopy?.CreationDate)
.FirstOrDefault()?.MailCopy?.Subject;
/// <summary>
/// Gets the latest email's sender name for display
/// </summary>
2025-10-26 23:35:09 +01:00
public string FromName => ThreadEmails
2025-10-03 15:46:38 +02:00
.OrderByDescending(e => e.MailCopy?.CreationDate)
.FirstOrDefault()?.MailCopy?.SenderContact.Name;
/// <summary>
/// Gets the latest email's creation date for sorting
/// </summary>
2025-10-26 23:35:09 +01:00
public DateTime CreationDate => ThreadEmails
2025-10-03 15:46:38 +02:00
.OrderByDescending(e => e.MailCopy?.CreationDate)
.FirstOrDefault()?.MailCopy?.CreationDate ?? DateTime.MinValue;
/// <summary>
2025-10-26 23:35:09 +01:00
/// Gets all emails in this thread (observable)
2025-10-03 15:46:38 +02:00
/// </summary>
2025-10-26 23:35:09 +01:00
///
[ObservableProperty]
public partial ObservableCollection<MailItemViewModel> ThreadEmails { get; set; } = [];
2025-10-03 15:46:38 +02:00
2025-10-26 23:35:09 +01:00
public MailItemViewModel LatestMailViewModel => ThreadEmails.OrderByDescending(e => e.MailCopy?.CreationDate).FirstOrDefault()!;
2025-10-18 11:45:10 +02:00
2025-10-03 15:46:38 +02:00
public ThreadMailItemViewModel(string threadId)
2025-02-16 11:54:23 +01:00
{
2025-10-03 15:46:38 +02:00
_threadId = threadId;
2025-02-16 11:54:23 +01:00
}
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
protected virtual void Dispose(bool disposing)
2025-02-16 11:54:23 +01:00
{
2025-10-03 15:46:38 +02:00
if (_disposed)
return;
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
if (disposing)
{
2025-10-26 23:35:09 +01:00
ThreadEmails.Clear();
2025-10-03 15:46:38 +02:00
}
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
_disposed = true;
}
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
public void Dispose()
2025-02-16 11:54:23 +01:00
{
2025-10-03 15:46:38 +02:00
Dispose(true);
GC.SuppressFinalize(this);
}
2024-04-18 01:44:37 +02:00
2025-10-25 10:54:38 +02:00
public void NotifyPropertyChanges()
2025-10-03 15:46:38 +02:00
{
OnPropertyChanged(nameof(Subject));
OnPropertyChanged(nameof(FromName));
2025-10-25 10:54:38 +02:00
OnPropertyChanged(nameof(CreationDate));
2025-10-18 11:45:10 +02:00
OnPropertyChanged(nameof(LatestMailViewModel));
2025-10-26 23:35:09 +01:00
OnPropertyChanged(nameof(ThreadEmails));
2025-10-03 15:46:38 +02:00
}
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
/// <summary>
/// Adds an email to this thread
/// </summary>
public void AddEmail(MailItemViewModel email)
{
if (email.MailCopy.ThreadId != _threadId)
throw new ArgumentException($"Email ThreadId '{email.MailCopy.ThreadId}' does not match expander ThreadId '{_threadId}'");
2024-04-18 01:44:37 +02:00
2025-10-26 23:35:09 +01:00
ThreadEmails.Add(email);
2025-02-16 11:54:23 +01:00
NotifyPropertyChanges();
}
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
/// <summary>
/// Removes an email from this thread
/// </summary>
public void RemoveEmail(MailItemViewModel email)
2025-02-16 11:54:23 +01:00
{
2025-10-26 23:35:09 +01:00
if (ThreadEmails.Remove(email))
2025-10-03 15:46:38 +02:00
{
NotifyPropertyChanges();
}
2025-02-16 11:54:23 +01:00
}
/// <summary>
/// Checks if this thread contains an email with the specified unique ID
/// </summary>
2025-10-26 23:35:09 +01:00
public bool HasUniqueId(Guid uniqueId) => ThreadEmails.Any(email => email.MailCopy.UniqueId == uniqueId);
2025-10-25 10:54:38 +02:00
public IEnumerable<Guid> GetContainingIds() => ThreadEmails.Select(a => a.MailCopy.UniqueId);
public IEnumerable<MailItemViewModel> GetSelectedMailItems()
{
if (IsSelected)
{
// If the thread itself is selected, return all emails in the thread
return ThreadEmails;
}
else
{
// Otherwise, return only individually selected emails within the thread
return ThreadEmails.Where(e => e.IsSelected);
}
}
2024-04-18 01:44:37 +02:00
}