Contacts management.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Calendar;
|
||||
|
||||
// TODO: Connect to Contact store with Wino People.
|
||||
public class CalendarEventAttendee
|
||||
{
|
||||
[PrimaryKey]
|
||||
@@ -16,4 +16,11 @@ public class CalendarEventAttendee
|
||||
public bool IsOrganizer { get; set; }
|
||||
public bool IsOptionalAttendee { get; set; }
|
||||
public string Comment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Resolved contact from the contact store. Populated at runtime via IContactService;
|
||||
/// not persisted to the database.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public AccountContact ResolvedContact { get; set; }
|
||||
}
|
||||
|
||||
@@ -25,7 +25,16 @@ public class AccountContact : IEquatable<AccountContact>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Base64 encoded profile image of the contact.
|
||||
/// File ID for the contact picture stored on disk.
|
||||
/// The actual file lives at {ApplicationDataFolderPath}/contacts/{ContactPictureFileId}.jpg.
|
||||
/// Preferred over Base64ContactPicture — allows native BitmapImage file loading and avoids SQLite bloat.
|
||||
/// </summary>
|
||||
public Guid? ContactPictureFileId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Legacy base64 encoded profile image of the contact.
|
||||
/// For user-set contact pictures: migrate to file storage via ContactPictureFileId instead.
|
||||
/// Still used for OAuth account profile pictures (MailAccount.Base64ProfilePictureData).
|
||||
/// </summary>
|
||||
public string Base64ContactPicture { get; set; }
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
/// <summary>
|
||||
/// A named group of contacts that can be expanded to individual addresses during mail composition.
|
||||
/// </summary>
|
||||
public class ContactGroup
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>Display name of the group (e.g., "Team Alpha", "Family").</summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>Optional description for the group.</summary>
|
||||
public string Description { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
/// <summary>
|
||||
/// Associates an e-mail address with a <see cref="ContactGroup"/>.
|
||||
/// </summary>
|
||||
public class ContactGroupMember
|
||||
{
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>Group this member belongs to.</summary>
|
||||
[Indexed]
|
||||
public Guid GroupId { get; set; }
|
||||
|
||||
/// <summary>E-mail address of the member (FK to AccountContact.Address).</summary>
|
||||
[Indexed]
|
||||
public string MemberAddress { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Manages contact picture files stored on disk instead of as base64 in SQLite,
|
||||
/// eliminating DB bloat and enabling native WIC hardware-accelerated image loading.
|
||||
/// </summary>
|
||||
public interface IContactPictureFileService
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the full file path for the given file ID, or null if the file does not exist on disk.
|
||||
/// </summary>
|
||||
string GetContactPicturePath(Guid fileId);
|
||||
|
||||
/// <summary>
|
||||
/// Saves raw image bytes to disk and returns the new file ID.
|
||||
/// </summary>
|
||||
Task<Guid> SaveContactPictureAsync(byte[] imageData);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the picture file for the given file ID if it exists.
|
||||
/// </summary>
|
||||
Task DeleteContactPictureAsync(Guid fileId);
|
||||
|
||||
/// <summary>
|
||||
/// One-time startup migration: reads AccountContact rows where Base64ContactPicture is set
|
||||
/// but ContactPictureFileId is null, writes the picture bytes to disk, updates the DB row,
|
||||
/// and clears the Base64ContactPicture column.
|
||||
/// </summary>
|
||||
Task MigrateBase64PicturesAsync();
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MimeKit;
|
||||
@@ -16,11 +17,25 @@ public interface IContactService
|
||||
Task SaveAddressInformationAsync(IEnumerable<AccountContact> contacts);
|
||||
Task<AccountContact> CreateNewContactAsync(string address, string displayName);
|
||||
|
||||
// New methods for ContactsPage
|
||||
// Paged contact queries for ContactsPage
|
||||
Task<List<AccountContact>> GetAllContactsAsync();
|
||||
Task<List<AccountContact>> SearchContactsAsync(string searchQuery);
|
||||
Task<PagedContactsResult> GetContactsPageAsync(int offset, int pageSize, string searchQuery = null, bool excludeRootContacts = false);
|
||||
Task<AccountContact> UpdateContactAsync(AccountContact contact);
|
||||
Task DeleteContactAsync(string address);
|
||||
Task DeleteContactsAsync(IEnumerable<string> addresses);
|
||||
|
||||
// Group / distribution list support
|
||||
Task<List<ContactGroup>> GetGroupsAsync();
|
||||
Task<ContactGroup> CreateGroupAsync(string name, string description = null);
|
||||
Task DeleteGroupAsync(Guid groupId);
|
||||
Task<List<AccountContact>> GetGroupMembersAsync(Guid groupId);
|
||||
Task AddGroupMemberAsync(Guid groupId, string memberAddress);
|
||||
Task RemoveGroupMemberAsync(Guid groupId, string memberAddress);
|
||||
|
||||
/// <summary>
|
||||
/// Expands a contact group to the individual <see cref="AccountContact"/> entries of its members.
|
||||
/// Returns an empty list if the group does not exist or has no members.
|
||||
/// </summary>
|
||||
Task<List<AccountContact>> ExpandGroupAsync(Guid groupId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user