akiomik / akiomik/nostui

A note is still lost when the relays reject it

Open
#514 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
71
Forks
5
Avg merge
4h 2m
Merged PRs (30d)
31

Description

Found while reviewing #513. That PR fixes half of this and the half it leaves is worth stating plainly rather than letting it read as handled.

## What #513 fixed, and what it did not

`submit_note` closes the editor after handing the event to the worker, and closing it destroys the text: the next `ComposingStarted` calls `clear_content` (`src/model/editor.rs:82`), so there is no way back to it.

#513 made the **pre-send** failure keep the draft — disconnected, or the worker gone, both knowable synchronously, so the editor simply stays open.

The **post-send** failure still loses it, and that is the common one:

1. Connected, user writes a long note, presses `Ctrl+P`.
2. The editor closes; the status bar reads `[Sending] `.
3. Every relay rejects it, or none acks within the timeout.
4. `resolve_publish` shows `[ERR: Posted] : no relay accepted the event: …`.
5. The text exists only in that status line — normalised to one line, competing for space, and gone as soon as anything else writes a status.

So nostui now *tells* the user their note was not published, and still gives them no way to get it back.

## Why it was not fixed in #513

Both plausible fixes need something #513 does not have:

- **Keep the editor open until the outcome arrives.** The editor captures every keystroke while active, so this would lock the user out of the app for up to the ack timeout (10s per relay by default). Not acceptable.
- **Restore the content on failure.** `model::editor` has no way to set content — only `clear_content`, `ComposingStarted`, `ReplyStarted`, and `KeyEventReceived`. This needs a new message (`DraftRestored { content }` or similar), which is a different subsystem from the publish-confirmation work #513 is about.

It is also a UX decision that deserves its own thought rather than being smuggled in: what happens if the user has already started composing something *else* by the time the failure lands? Silently replacing their new draft with the failed one would be its own data loss.

## Suggested shape

- Add a `DraftRestored { content }` message to `model::editor` that reopens the editor with the given content.
- Carry enough on the pending entry to know a publish came from the editor — reactions, reposts and NIP-38 status events have nothing to restore.
- On failure, restore only when the editor is not already active; otherwise leave the new draft alone and rely on the error message.
- Reply drafts need the reply target restored too, or the retry silently becomes a top-level note.

## Acceptance

- A note rejected by every relay can be recovered and retried without retyping.
- A failure arriving while the user is composing something else does not touch what they are writing.
- A rejected *reply* comes back as a reply, not as a new note.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.