Initial commit.

This commit is contained in:
Burak Kaan Köse
2024-04-18 01:44:37 +02:00
parent 524ea4c0e1
commit 12d3814626
671 changed files with 77295 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Mail.ViewModels.Data
{
public partial class AccountProviderDetailViewModel : ObservableObject, IAccountProviderDetailViewModel
{
[ObservableProperty]
private MailAccount account;
public IProviderDetail ProviderDetail { get; set; }
public Guid StartupEntityId => Account.Id;
public string StartupEntityTitle => Account.Name;
public AccountProviderDetailViewModel(IProviderDetail providerDetail, MailAccount account)
{
ProviderDetail = providerDetail;
Account = account;
}
}
}

View File

@@ -0,0 +1,23 @@
using CommunityToolkit.Mvvm.ComponentModel;
namespace Wino.Mail.ViewModels.Data
{
public class AppColorViewModel : ObservableObject
{
private string _hex;
public string Hex
{
get => _hex;
set => SetProperty(ref _hex, value);
}
public bool IsAccentColor { get; }
public AppColorViewModel(string hex, bool isAccentColor = false)
{
IsAccentColor = isAccentColor;
Hex = hex;
}
}
}

View File

@@ -0,0 +1,33 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Messages.Navigation;
namespace Wino.Mail.ViewModels.Data
{
public class BreadcrumbNavigationItemViewModel : ObservableObject
{
public BreadcrumbNavigationRequested Request { get; set; }
public BreadcrumbNavigationItemViewModel(BreadcrumbNavigationRequested request, bool isActive)
{
Request = request;
Title = request.PageTitle;
this.isActive = isActive;
}
private string title;
public string Title
{
get => title;
set => SetProperty(ref title, value);
}
private bool isActive;
public bool IsActive
{
get => isActive;
set => SetProperty(ref isActive, value);
}
}
}

View File

@@ -0,0 +1,33 @@
using System.Diagnostics;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain;
namespace Wino.Mail.ViewModels.Data
{
[DebuggerDisplay("{FolderTitle}")]
public partial class FolderPivotViewModel : ObservableObject
{
public bool? IsFocused { get; set; }
public string FolderTitle { get; }
public bool ShouldDisplaySelectedItemCount => IsExtendedMode ? SelectedItemCount > 1 : SelectedItemCount > 0;
[ObservableProperty]
private bool isSelected;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ShouldDisplaySelectedItemCount))]
private int selectedItemCount;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ShouldDisplaySelectedItemCount))]
private bool isExtendedMode = true;
public FolderPivotViewModel(string folderName, bool? isFocused)
{
IsFocused = isFocused;
FolderTitle = IsFocused == null ? folderName : (IsFocused == true ? Translator.Focused : Translator.Other);
}
}
}

View File

@@ -0,0 +1,100 @@
using System.IO;
using CommunityToolkit.Mvvm.ComponentModel;
using MimeKit;
using Wino.Core.Domain.Enums;
using Wino.Core.Extensions;
namespace Wino.Mail.ViewModels.Data
{
public class MailAttachmentViewModel : ObservableObject
{
private bool isBusy;
private readonly MimePart _mimePart;
public MailAttachmentType AttachmentType { get; }
public string FileName { get; }
public string FilePath { get; set; }
public string ReadableSize { get; }
public byte[] Content { get; set; }
public IMimeContent MimeContent => _mimePart.Content;
/// <summary>
/// Gets or sets whether attachment is busy with opening or saving etc.
/// </summary>
public bool IsBusy
{
get => isBusy;
set => SetProperty(ref isBusy, value);
}
public MailAttachmentViewModel(MimePart mimePart)
{
_mimePart = mimePart;
var array = new byte[_mimePart.Content.Stream.Length];
_mimePart.Content.Stream.Read(array, 0, (int)_mimePart.Content.Stream.Length);
Content = array;
FileName = mimePart.FileName;
ReadableSize = mimePart.Content.Stream.Length.GetBytesReadable();
var extension = Path.GetExtension(FileName);
AttachmentType = GetAttachmentType(extension);
}
public MailAttachmentViewModel(string fullFilePath, byte[] content)
{
Content = content;
FileName = Path.GetFileName(fullFilePath);
FilePath = fullFilePath;
ReadableSize = ((long)content.Length).GetBytesReadable();
var extension = Path.GetExtension(FileName);
AttachmentType = GetAttachmentType(extension);
}
public MailAttachmentType GetAttachmentType(string mediaSubtype)
{
if (string.IsNullOrEmpty(mediaSubtype))
return MailAttachmentType.None;
switch (mediaSubtype.ToLower())
{
case ".exe":
return MailAttachmentType.Executable;
case ".rar":
return MailAttachmentType.RarArchive;
case ".zip":
return MailAttachmentType.Archive;
case ".ogg":
case ".mp3":
case ".wav":
case ".aac":
case ".alac":
return MailAttachmentType.Audio;
case ".mp4":
case ".wmv":
case ".avi":
case ".flv":
return MailAttachmentType.Video;
case ".pdf":
return MailAttachmentType.PDF;
case ".htm":
case ".html":
return MailAttachmentType.HTML;
case ".png":
case ".jpg":
case ".jpeg":
case ".gif":
case ".jiff":
return MailAttachmentType.Image;
default:
return MailAttachmentType.Other;
}
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace Wino.Mail.ViewModels.Data
{
public class MailItemContainer
{
public MailItemViewModel ItemViewModel { get; set; }
public ThreadMailItemViewModel ThreadViewModel { get; set; }
public MailItemContainer(MailItemViewModel itemViewModel, ThreadMailItemViewModel threadViewModel) : this(itemViewModel)
{
ThreadViewModel = threadViewModel ?? throw new ArgumentNullException(nameof(threadViewModel));
}
public MailItemContainer(MailItemViewModel itemViewModel)
{
ItemViewModel = itemViewModel ?? throw new ArgumentNullException(nameof(itemViewModel));
}
}
}

View File

@@ -0,0 +1,106 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Models.MailItem;
namespace Wino.Mail.ViewModels.Data
{
/// <summary>
/// Single view model for IMailItem representation.
/// </summary>
public partial class MailItemViewModel(MailCopy mailCopy) : ObservableObject, IMailItem
{
public MailCopy MailCopy { get; private set; } = mailCopy;
public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix);
public Guid UniqueId => ((IMailItem)MailCopy).UniqueId;
public string ThreadId => ((IMailItem)MailCopy).ThreadId;
public string MessageId => ((IMailItem)MailCopy).MessageId;
public string FromName => ((IMailItem)MailCopy).FromName ?? FromAddress;
public DateTime CreationDate => ((IMailItem)MailCopy).CreationDate;
public string FromAddress => ((IMailItem)MailCopy).FromAddress;
public bool HasAttachments => ((IMailItem)MailCopy).HasAttachments;
public string References => ((IMailItem)MailCopy).References;
public string InReplyTo => ((IMailItem)MailCopy).InReplyTo;
[ObservableProperty]
private bool isCustomFocused;
[ObservableProperty]
private bool isSelected;
public bool IsFlagged
{
get => MailCopy.IsFlagged;
set => SetProperty(MailCopy.IsFlagged, value, MailCopy, (u, n) => u.IsFlagged = n);
}
public bool IsFocused
{
get => MailCopy.IsFocused;
set => SetProperty(MailCopy.IsFocused, value, MailCopy, (u, n) => u.IsFocused = n);
}
public bool IsRead
{
get => MailCopy.IsRead;
set => SetProperty(MailCopy.IsRead, value, MailCopy, (u, n) => u.IsRead = n);
}
public bool IsDraft
{
get => MailCopy.IsDraft;
set => SetProperty(MailCopy.IsDraft, value, MailCopy, (u, n) => u.IsDraft = n);
}
public string DraftId
{
get => MailCopy.DraftId;
set => SetProperty(MailCopy.DraftId, value, MailCopy, (u, n) => u.DraftId = n);
}
public string Id
{
get => MailCopy.Id;
set => SetProperty(MailCopy.Id, value, MailCopy, (u, n) => u.Id = n);
}
public string Subject
{
get => MailCopy.Subject;
set => SetProperty(MailCopy.Subject, value, MailCopy, (u, n) => u.Subject = n);
}
public string PreviewText
{
get => MailCopy.PreviewText;
set => SetProperty(MailCopy.PreviewText, value, MailCopy, (u, n) => u.PreviewText = n);
}
public MailItemFolder AssignedFolder => ((IMailItem)MailCopy).AssignedFolder;
public MailAccount AssignedAccount => ((IMailItem)MailCopy).AssignedAccount;
public Guid FileId => ((IMailItem)MailCopy).FileId;
public void Update(MailCopy updatedMailItem)
{
MailCopy = updatedMailItem;
// DEBUG
//if (updatedMailItem.AssignedAccount == null || updatedMailItem.AssignedFolder == null)
// throw new Exception("Assigned account or folder is null.");
OnPropertyChanged(nameof(IsRead));
OnPropertyChanged(nameof(IsFocused));
OnPropertyChanged(nameof(IsFlagged));
OnPropertyChanged(nameof(IsDraft));
OnPropertyChanged(nameof(DraftId));
OnPropertyChanged(nameof(Subject));
OnPropertyChanged(nameof(PreviewText));
OnPropertyChanged(nameof(IsLocalDraft));
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Mail.ViewModels.Data
{
public partial class MergedAccountProviderDetailViewModel : ObservableObject, IAccountProviderDetailViewModel
{
public List<AccountProviderDetailViewModel> HoldingAccounts { get; }
public MergedInbox MergedInbox { get; }
public string AccountAddresses => string.Join(", ", HoldingAccounts.Select(a => a.Account.Address));
public Guid StartupEntityId => MergedInbox.Id;
public string StartupEntityTitle => MergedInbox.Name;
public MergedAccountProviderDetailViewModel(MergedInbox mergedInbox, List<AccountProviderDetailViewModel> holdingAccounts)
{
MergedInbox = mergedInbox;
HoldingAccounts = holdingAccounts;
}
}
}

View File

@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Models.MailItem;
namespace Wino.Mail.ViewModels.Data
{
/// <summary>
/// Thread mail item (multiple IMailItem) view model representation.
/// </summary>
public class ThreadMailItemViewModel : ObservableObject, IMailItemThread, IComparable<string>, IComparable<DateTime>
{
public ObservableCollection<IMailItem> ThreadItems => ((IMailItemThread)_threadMailItem).ThreadItems;
private readonly ThreadMailItem _threadMailItem;
private bool isThreadExpanded;
public bool IsThreadExpanded
{
get => isThreadExpanded;
set => SetProperty(ref isThreadExpanded, value);
}
public ThreadMailItemViewModel(ThreadMailItem threadMailItem)
{
_threadMailItem = new ThreadMailItem();
// Local copies
foreach (var item in threadMailItem.ThreadItems)
{
AddMailItemViewModel(item);
}
}
public IEnumerable<MailCopy> GetMailCopies()
=> ThreadItems.OfType<MailItemViewModel>().Select(a => a.MailCopy);
public void AddMailItemViewModel(IMailItem mailItem)
{
if (mailItem == null) return;
if (mailItem is MailCopy mailCopy)
_threadMailItem.AddThreadItem(new MailItemViewModel(mailCopy));
else if (mailItem is MailItemViewModel mailItemViewModel)
_threadMailItem.AddThreadItem(mailItemViewModel);
else
Debugger.Break();
}
public bool HasUniqueId(Guid uniqueMailId)
=> ThreadItems.Any(a => a.UniqueId == uniqueMailId);
public IMailItem GetItemById(Guid uniqueMailId)
=> ThreadItems.FirstOrDefault(a => a.UniqueId == uniqueMailId);
public void RemoveCopyItem(IMailItem item)
{
MailCopy copyToRemove = null;
if (item is MailItemViewModel mailItemViewModel)
copyToRemove = mailItemViewModel.MailCopy;
else if (item is MailCopy copyItem)
copyToRemove = copyItem;
var existedItem = ThreadItems.FirstOrDefault(a => a.Id == copyToRemove.Id);
if (existedItem == null) return;
ThreadItems.Remove(existedItem);
NotifyPropertyChanges();
}
public void NotifyPropertyChanges()
{
OnPropertyChanged(nameof(Subject));
OnPropertyChanged(nameof(PreviewText));
OnPropertyChanged(nameof(FromName));
OnPropertyChanged(nameof(FromAddress));
OnPropertyChanged(nameof(HasAttachments));
OnPropertyChanged(nameof(IsFlagged));
OnPropertyChanged(nameof(IsDraft));
OnPropertyChanged(nameof(IsRead));
OnPropertyChanged(nameof(IsFocused));
OnPropertyChanged(nameof(CreationDate));
}
public IMailItem LatestMailItem => ((IMailItemThread)_threadMailItem).LatestMailItem;
public IMailItem FirstMailItem => ((IMailItemThread)_threadMailItem).FirstMailItem;
public string Id => ((IMailItem)_threadMailItem).Id;
public string Subject => ((IMailItem)_threadMailItem).Subject;
public string ThreadId => ((IMailItem)_threadMailItem).ThreadId;
public string MessageId => ((IMailItem)_threadMailItem).MessageId;
public string References => ((IMailItem)_threadMailItem).References;
public string PreviewText => ((IMailItem)_threadMailItem).PreviewText;
public string FromName => ((IMailItem)_threadMailItem).FromName;
public DateTime CreationDate => ((IMailItem)_threadMailItem).CreationDate;
public string FromAddress => ((IMailItem)_threadMailItem).FromAddress;
public bool HasAttachments => ((IMailItem)_threadMailItem).HasAttachments;
public bool IsFlagged => ((IMailItem)_threadMailItem).IsFlagged;
public bool IsFocused => ((IMailItem)_threadMailItem).IsFocused;
public bool IsRead => ((IMailItem)_threadMailItem).IsRead;
public bool IsDraft => ((IMailItem)_threadMailItem).IsDraft;
public string DraftId => string.Empty;
public string InReplyTo => ((IMailItem)_threadMailItem).InReplyTo;
public MailItemFolder AssignedFolder => ((IMailItem)_threadMailItem).AssignedFolder;
public MailAccount AssignedAccount => ((IMailItem)_threadMailItem).AssignedAccount;
public Guid UniqueId => ((IMailItem)_threadMailItem).UniqueId;
public Guid FileId => ((IMailItem)_threadMailItem).FileId;
public int CompareTo(DateTime other) => CreationDate.CompareTo(other);
public int CompareTo(string other) => FromName.CompareTo(other);
// Get single mail item view model out of the only item in thread items.
public MailItemViewModel GetSingleItemViewModel() => ThreadItems.First() as MailItemViewModel;
}
}