MailSharp / MailSharp.MailClient / Services / FolderSettingsStore.cs
Code · 59 lines · 2584 bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59using LiteDB;
using MailSharp.MailClient.Models;

namespace MailSharp.MailClient.Services;

public interface IFolderSettingsStore
{
	Dictionary<string, FolderSetting> GetAll(int accountId);
	void Save(int accountId, string folderFullName, FolderSyncMode syncMode, bool subscribed);
	void Remove(int accountId, string folderFullName);

	// Display-only ordering of folders in the main menu (Settings > Mappen beheren) - purely
	// cosmetic, never touches the actual IMAP folder structure. Folders not mentioned here (new
	// ones, or ones never reordered) are appended after the ordered ones in their natural IMAP
	// discovery order - see IImapService.GetFoldersAsync.
	List<string> GetOrder(int accountId);
	void SaveOrder(int accountId, List<string> folderFullNamesInOrder);
}

// Stores the user's per-folder sync mode/subscription choices (Settings > Mappen beheren), keyed
// by (account, folder full name) - separate from the folder list itself, which is always
// re-fetched live from IMAP (see IImapService.GetFoldersAsync) and has no durable identity of its
// own beyond its full name.
public class LiteDbFolderSettingsStore : IFolderSettingsStore, IDisposable
{
	private readonly LiteDatabase _db;

	public LiteDbFolderSettingsStore(IWebHostEnvironment env)
	{
		var dir = Path.Combine(env.ContentRootPath, "App_Data");
		Directory.CreateDirectory(dir);
		_db = new LiteDatabase(Path.Combine(dir, "foldersettings.db"));
	}

	private ILiteCollection<FolderSetting> Settings => _db.GetCollection<FolderSetting>("folderSettings");
	private ILiteCollection<FolderOrder> Orders => _db.GetCollection<FolderOrder>("folderOrders");

	private static string Key(int accountId, string folderFullName) => $"{accountId}:{folderFullName}";

	public Dictionary<string, FolderSetting> GetAll(int accountId)
	{
		var prefix = accountId + ":";
		return Settings.Find(x => x.Id.StartsWith(prefix))
			.ToDictionary(x => x.Id[prefix.Length..], x => x);
	}

	public void Save(int accountId, string folderFullName, FolderSyncMode syncMode, bool subscribed) =>
		Settings.Upsert(new FolderSetting { Id = Key(accountId, folderFullName), SyncMode = syncMode, Subscribed = subscribed });

	public void Remove(int accountId, string folderFullName) =>
		Settings.Delete(Key(accountId, folderFullName));

	public List<string> GetOrder(int accountId) => Orders.FindById(accountId)?.Names ?? [];

	public void SaveOrder(int accountId, List<string> folderFullNamesInOrder) =>
		Orders.Upsert(new FolderOrder { Id = accountId, Names = folderFullNamesInOrder });

	public void Dispose() => _db.Dispose();
}