feat(privacy): reconnect the message export
The exporter has worked since v1.4.8. The form that drives it went out with the old settings window in May, which left PRIVACY.md promising an access request the plugin had no way to answer. New section in the data and privacy tab: time range, sender substring, channel groups, format, and a save dialog. Form state lives in the tab, not the config -- a filter describes one action, and a stale "last 7 days, sender Mira" reappearing weeks later is a worse start than an empty form. StreamForExport now takes a caller-owned connection. The reader stays open for as long as the file is written, seconds to minutes on a large history, and chat keeps arriving throughout -- so the primary connection would be read here and written by UpsertMessage at once, and SqliteConnection is not thread-safe. Holding the read lock instead would trade that for freezing the game. ChannelGroups lifts the eight groups out of the deleted tab and finishes them: 37 of 89 channels belonged to no group and were therefore unreachable in the UI. Game Master channels follow ChatTypeExt.Parent(), so GmTell sits with the other tells rather than under system traffic -- an access request that quietly drops part of what it promises is the dangerous kind of gap. Also here: - OpenSecondaryConnection disposes on a failing pragma. Open can succeed and journal_mode=WAL still time out, and with Pooling=false the connection then survives until a finalizer reaches it. Affects the full-text rebuild worker too. - StreamForExport builds its logger before the reader, so a throwing CreateLogger cannot leave a reader nobody owns. - The export thread takes the gate itself instead of the caller taking it first. Acquiring before Start would strand the gate for the session if thread creation failed, and the gate also holds back the sweep. - Notifications are skipped once teardown has started. The thread has no cancellation path and finishing the file is right, but reporting it to a plugin that is gone is not. - Transient widget rows that return their value instead of saving it. Writing the config file on every keystroke of a sender filter would be both pointless and slow. - Five translated keys for "another database operation is running", in all 25 languages. Two of the four operation names have no trigger yet; they arrive with the cleanup and maintenance sections.
This commit is contained in:
@@ -169,6 +169,11 @@ public sealed class Plugin : IAsyncDalamudPlugin
|
||||
// because the tick reads it from a different thread than the writer.
|
||||
private volatile bool _isDisposing;
|
||||
|
||||
// Read by background workers that outlive a teardown -- the export thread
|
||||
// finishes its file either way, but a notification for a plugin the user
|
||||
// just unloaded belongs to nobody.
|
||||
internal bool IsDisposing => _isDisposing;
|
||||
|
||||
// v1.9.0 B5: last full Draw() wall-time in ms, written once per frame at
|
||||
// the end of the UiBuilder.Draw handler. Covers the GlobalStyleScope push
|
||||
// and the font push (§7.5 First-Frame-HITCH must include atlas/style
|
||||
|
||||
Reference in New Issue
Block a user