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
|
|
|
}
|
2025-10-18 22:16:28 +02: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);
|
2025-10-26 14:53:22 +01:00
|
|
|
|
|
|
|
|
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
|
|
|
}
|