Conversation logging and export #114

Closed
opened 2026-09-02 23:25:47 -04:00 by Salastil · 1 comment
Owner

Everything is in scrollback.db and there is no way to get it out: no export of a
conversation, no plain-text or JSON dump. HexChat and WeeChat write logs by default;
Element and Discord both export.

Agreed design (2026-09-11)

Scoped in discussion. This is larger than the original filing, and supersedes it.

Where it is reached from

The conversation's avatar and nameplate at the top of the screen
(main-header in src/renderer/src/App.tsx). Clicking it opens a menu carrying the
same options as the buffer's right-click menu, plus Export.

Deliberately not in the BufferList right-click menu. Export is a rare action and
that menu is already long; putting it there costs every user something to serve a few.
Making the nameplate clickable also gives the header a menu it does not have today,
which is worth having on its own.

This needs the entry builder currently inline in BufferList.tsx (~line 812) hoisted
into something both callers share, and BufferFace extended past kind === 'dm' so
channels have a face to click.

The range dialog

Clicking Export opens a dialog asking for the date/time range. Defaults to
everything; the range is for somebody who knows they want one month.

What is produced

An HTML representation of exactly what is in the chat buffer - the conversation
moved 1:1 to local disk, not a reformatting of it.

  • Written into a folder, not a single file.
  • Embedded media is downloaded into that folder and referenced locally, so the
    export still reads with no network and after the original expires.
  • Lands in the default or user-defined Downloads location.

Fetching

If the requested range needs more history than is held locally, it is paginated from
the service
, and that pagination respects the service's rate limits. A long export
is expected to take a while; it is not expected to get the account limited.

Progress, and stopping it

  • An indicator on the settings cog while an export is running, with a way to cancel.
  • A row in the Downloads pane (the one XDCC transfers use), showing progress and
    speed, with pause and cancel where they can be supported.

Modelled as a transfer rather than as a parallel mechanism: the transfers table, the
panel, the progress and speed rendering and the cancel path all exist already and are
the right shape. Needs a kind on the row so the panel can describe an export
differently from a DCC file.

Not doing

Live per-buffer log files, which the original filing offered as an option. Everything is
already durably in scrollback.db with search and backfill; a live plain-text log is a
second copy that can drift, and it exists in HexChat mainly because HexChat has no
database. Export covers the need that matters.

Everything is in `scrollback.db` and there is no way to get it out: no export of a conversation, no plain-text or JSON dump. HexChat and WeeChat write logs by default; Element and Discord both export. ## Agreed design (2026-09-11) Scoped in discussion. This is larger than the original filing, and supersedes it. ### Where it is reached from The conversation's **avatar and nameplate at the top of the screen** (`main-header` in `src/renderer/src/App.tsx`). Clicking it opens a menu carrying the same options as the buffer's right-click menu, **plus Export**. Deliberately **not** in the BufferList right-click menu. Export is a rare action and that menu is already long; putting it there costs every user something to serve a few. Making the nameplate clickable also gives the header a menu it does not have today, which is worth having on its own. This needs the entry builder currently inline in `BufferList.tsx` (~line 812) hoisted into something both callers share, and `BufferFace` extended past `kind === 'dm'` so channels have a face to click. ### The range dialog Clicking Export opens a dialog asking for the **date/time range**. Defaults to everything; the range is for somebody who knows they want one month. ### What is produced An **HTML representation of exactly what is in the chat buffer** - the conversation moved 1:1 to local disk, not a reformatting of it. - Written into a **folder**, not a single file. - **Embedded media is downloaded** into that folder and referenced locally, so the export still reads with no network and after the original expires. - Lands in the **default or user-defined Downloads location**. ### Fetching If the requested range needs more history than is held locally, it is **paginated from the service**, and that pagination **respects the service's rate limits**. A long export is expected to take a while; it is not expected to get the account limited. ### Progress, and stopping it - An **indicator on the settings cog** while an export is running, with a way to cancel. - A row in the **Downloads pane** (the one XDCC transfers use), showing progress and speed, with **pause and cancel** where they can be supported. Modelled as a transfer rather than as a parallel mechanism: the `transfers` table, the panel, the progress and speed rendering and the cancel path all exist already and are the right shape. Needs a `kind` on the row so the panel can describe an export differently from a DCC file. ### Not doing Live per-buffer log files, which the original filing offered as an option. Everything is already durably in `scrollback.db` with search and backfill; a live plain-text log is a second copy that can drift, and it exists in HexChat mainly because HexChat has no database. Export covers the need that matters.
Salastil added the featurelow priority labels 2026-09-03 13:11:38 -04:00
Author
Owner

Finished.

Daemon — https://git.salastil.com/Salastil/nobilis/commit/2e9bd0d (export engine, transfer kind, pause), https://git.salastil.com/Salastil/nobilis/commit/f3a92e6 (time-paged range reads)
Window — https://git.salastil.com/Salastil/moho/commit/a68752e (the loop, dialog, downloads row, cog), https://git.salastil.com/Salastil/moho/commit/ad06b4e (header menu, the way in)

History pagination needed no new code, which was the good outcome: getBacklog
with a before already pages older history per service - Discord snowflakes,
Kick cursors, IRC CHATHISTORY, Matrix /messages tokens - each with its own
pacing. The export loop drives that rather than growing a second implementation
that would have to learn the same four things again. Sneedchat is the one that
cannot reach back, and the dialog says so before starting rather than quietly
returning short.

Verified end to end against a daemon on its own socket: a folder with
index.html and media, the body part cleaned up on sealing, the transfer row
reading kind=export, pause and resume, cancel refusing further writes, a second
export of the same conversation on the same day landing beside the first, and a
title of "../../escape" staying inside the downloads folder.

527 daemon tests and typecheck green. Deployed.

Finished. Daemon — https://git.salastil.com/Salastil/nobilis/commit/2e9bd0d (export engine, transfer kind, pause), https://git.salastil.com/Salastil/nobilis/commit/f3a92e6 (time-paged range reads) Window — https://git.salastil.com/Salastil/moho/commit/a68752e (the loop, dialog, downloads row, cog), https://git.salastil.com/Salastil/moho/commit/ad06b4e (header menu, the way in) History pagination needed no new code, which was the good outcome: `getBacklog` with a `before` already pages older history per service - Discord snowflakes, Kick cursors, IRC CHATHISTORY, Matrix `/messages` tokens - each with its own pacing. The export loop drives that rather than growing a second implementation that would have to learn the same four things again. Sneedchat is the one that cannot reach back, and the dialog says so before starting rather than quietly returning short. Verified end to end against a daemon on its own socket: a folder with index.html and media, the body part cleaned up on sealing, the transfer row reading kind=export, pause and resume, cancel refusing further writes, a second export of the same conversation on the same day landing beside the first, and a title of "../../escape" staying inside the downloads folder. 527 daemon tests and typecheck green. Deployed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Salastil/moho#114