mirror of
https://github.com/MAKS-IT-COM/maksit-postclient.git
synced 2026-09-30 03:18:09 +02:00
(feature): index keyword and meaning progress across all mailboxes
This commit is contained in:
parent
7198014a21
commit
adee0696ba
@ -6,6 +6,14 @@ The format follows [Keep a Changelog](https://keepachangelog.com/) and [Semantic
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.3.5] - 2026-09-20
|
||||
|
||||
Index status covers every mailbox, not one folder or one account.
|
||||
|
||||
### Changed
|
||||
|
||||
- Status bar keyword and meaning index lines show one done / total across all mailboxes, not the folder or mailbox currently being scanned.
|
||||
|
||||
## [0.3.4] - 2026-09-20
|
||||
|
||||
Status bar index lines no longer flash between batches.
|
||||
|
||||
@ -30,6 +30,11 @@
|
||||
<display_length compare="ge">768</display_length>
|
||||
</requires>
|
||||
<releases>
|
||||
<release version="0.3.5" date="2026-09-20">
|
||||
<description>
|
||||
<p>Keyword and meaning index status shows one done / total across all mailboxes, not the current folder or a single account.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.3.4" date="2026-09-20">
|
||||
<description>
|
||||
<p>Status bar indexing and meaning-index lines stay visible between batches instead of flashing.</p>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>0.3.4</Version>
|
||||
<Version>0.3.5</Version>
|
||||
<Product>Postclient</Product>
|
||||
<AssemblyTitle>Postclient</AssemblyTitle>
|
||||
<Authors>Maksym Sadovnychyy</Authors>
|
||||
|
||||
@ -197,13 +197,21 @@ public sealed class SemanticSearchService : ISemanticSearchService {
|
||||
await DelayAsync(TimeSpan.FromMilliseconds(800), token).ConfigureAwait(false);
|
||||
if (_archive.PendingEmbeddings(EmbeddingModelSpec.Id, 1, ready).Count > 0)
|
||||
continue;
|
||||
var leftAll = _archive.EmbeddingPendingCount(EmbeddingModelSpec.Id);
|
||||
var doneAll = _archive.EmbeddingCount(EmbeddingModelSpec.Id);
|
||||
if (leftAll > 0) {
|
||||
SetStatus(MailIndexProgress.MeaningLine(doneAll, doneAll + leftAll), ready: true);
|
||||
await WaitAsync(token).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SetStatus("", ready: true);
|
||||
await WaitAsync(token).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var left = _archive.EmbeddingPendingCount(EmbeddingModelSpec.Id, ready);
|
||||
var done = _archive.EmbeddingCount(EmbeddingModelSpec.Id, ready);
|
||||
var left = _archive.EmbeddingPendingCount(EmbeddingModelSpec.Id);
|
||||
var done = _archive.EmbeddingCount(EmbeddingModelSpec.Id);
|
||||
SetStatus(MailIndexProgress.MeaningLine(done, done + left), ready: true);
|
||||
foreach (var item in pending) {
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
@ -105,6 +105,14 @@ public sealed class MailArchiveCatalog : IDisposable {
|
||||
public int MessageCount(string mailboxId) =>
|
||||
OffUi(() => TryGet(mailboxId)?.MessageCount(mailboxId) ?? 0);
|
||||
|
||||
public int TotalMessageCount() =>
|
||||
OffUi(() => {
|
||||
var count = 0;
|
||||
foreach (var pair in _stores)
|
||||
count += pair.Value.MessageCount(pair.Key);
|
||||
return count;
|
||||
});
|
||||
|
||||
public int RebuildKeywordIndex(string mailboxId) =>
|
||||
OffUi(() => TryGet(mailboxId)?.RebuildKeywordIndex() ?? 0);
|
||||
|
||||
|
||||
@ -38,7 +38,6 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
private readonly HashSet<string> _catalogFolders = new(StringComparer.OrdinalIgnoreCase);
|
||||
private const int IndexCatalogChunk = 2_000;
|
||||
private const int IndexUiChunk = 250;
|
||||
private int _indexBodyTotal;
|
||||
private readonly StatusLineHold _indexHold;
|
||||
private readonly StatusLineHold _semanticHold;
|
||||
private bool _uiReady;
|
||||
@ -3756,10 +3755,10 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
}
|
||||
|
||||
private void EnsureIndexing(string mailboxId) {
|
||||
if (string.IsNullOrWhiteSpace(mailboxId))
|
||||
return;
|
||||
if (!string.IsNullOrWhiteSpace(mailboxId))
|
||||
_indexMailboxes.Add(mailboxId);
|
||||
if (_backfill is not null)
|
||||
TrackConnectedMailboxes();
|
||||
if (_backfill is not null || _indexMailboxes.Count == 0)
|
||||
return;
|
||||
StartIndexing();
|
||||
}
|
||||
@ -3799,7 +3798,10 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
try {
|
||||
while (!token.IsCancellationRequested) {
|
||||
await WaitIfIndexingPausedAsync(token).ConfigureAwait(false);
|
||||
var snapshot = await Dispatcher.UIThread.InvokeAsync(CaptureIndexSnapshot);
|
||||
var (snapshot, readyIds) = await Dispatcher.UIThread.InvokeAsync(() => {
|
||||
TrackConnectedMailboxes();
|
||||
return (CaptureIndexSnapshot(), ReadyMailboxIds());
|
||||
});
|
||||
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
|
||||
if (snapshot.Count == 0)
|
||||
break;
|
||||
@ -3824,11 +3826,6 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
pendingFolders = true;
|
||||
cataloged = true;
|
||||
await WaitIfIndexingPausedAsync(token).ConfigureAwait(false);
|
||||
var folderDone = box.CatalogedFolders.Count;
|
||||
await SetIndexLineAsync(
|
||||
MailIndexProgress.Line(folderDone, Math.Max(box.Folders.Count, 1), folder.Name),
|
||||
token)
|
||||
.ConfigureAwait(false);
|
||||
var known = _archive.Uids(box.Id, folder.FullName);
|
||||
var listed = await box.Session
|
||||
.ListMessagesAsync(folder.FullName, known, token, IndexCatalogChunk)
|
||||
@ -3837,6 +3834,8 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
continue;
|
||||
var sync = listed.Value ?? new MailFolderSync();
|
||||
ApplyFolderSync(box.Id, folder.FullName, sync);
|
||||
await SetIndexLineAsync(GlobalIndexLine(), token)
|
||||
.ConfigureAwait(false);
|
||||
var counts = _archive.FolderCounts(box.Id, folder.FullName);
|
||||
await UiAsync(() => RefreshIndexedFolderCounts(box.Id, folder.FullName, counts))
|
||||
.ConfigureAwait(false);
|
||||
@ -3855,10 +3854,6 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
}
|
||||
|
||||
await WaitIfIndexingPausedAsync(token).ConfigureAwait(false);
|
||||
var readyIds = snapshot
|
||||
.Where(s => IsInitialSyncComplete(s.Id))
|
||||
.Select(s => s.Id)
|
||||
.ToList();
|
||||
var pending = readyIds.Count == 0 ? [] : _archive.MissingBodies(readyIds, 16);
|
||||
if (pending.Count == 0) {
|
||||
if (!cataloged)
|
||||
@ -3866,11 +3861,7 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
continue;
|
||||
}
|
||||
|
||||
var left = _archive.MissingBodyCount(readyIds);
|
||||
if (_indexBodyTotal < left)
|
||||
_indexBodyTotal = left;
|
||||
var done = Math.Max(0, _indexBodyTotal - left);
|
||||
await SetIndexLineAsync(MailIndexProgress.Line(done, _indexBodyTotal), token)
|
||||
await SetIndexLineAsync(GlobalIndexLine(), token)
|
||||
.ConfigureAwait(false);
|
||||
var fetched = 0;
|
||||
foreach (var item in pending) {
|
||||
@ -3916,7 +3907,6 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
var again = _indexMailboxes.Any(id => SessionFor(MailboxById(id)) is { IsConnected: true });
|
||||
if (!again) {
|
||||
_indexHold.Set("");
|
||||
_indexBodyTotal = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3962,6 +3952,29 @@ public partial class MainViewModel : ObservableObject, IAsyncDisposable {
|
||||
_indexHold.Set(line);
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
private void TrackConnectedMailboxes() {
|
||||
foreach (var box in Mailboxes) {
|
||||
if (SessionFor(box) is { IsConnected: true })
|
||||
_indexMailboxes.Add(box.Id);
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> ReadyMailboxIds() {
|
||||
var ids = new List<string>();
|
||||
foreach (var box in Mailboxes) {
|
||||
if (IsInitialSyncComplete(box.Id))
|
||||
ids.Add(box.Id);
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
private string GlobalIndexLine() {
|
||||
var total = _archive.TotalMessageCount();
|
||||
var missing = _archive.MissingBodyCount();
|
||||
return MailIndexProgress.Line(Math.Max(0, total - missing), total);
|
||||
}
|
||||
|
||||
private MailboxAccount? MailboxById(string mailboxId) =>
|
||||
Mailboxes.FirstOrDefault(m => m.Id.Equals(mailboxId, StringComparison.OrdinalIgnoreCase))
|
||||
?? _files.Current.FindMailbox(mailboxId);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user