[edit] Grids refresh immediately after editing a video (#52)

Editing left grids showing the pre-edit version until a manual reload. The edit
flow already re-ran loadVideos(), but the cache still held the OLD version: unlike
new publishes (#46's optimistic insert), the edit never ingested its signed
replaceable event locally, so the cache-first render stayed stale until relays
echoed the update back.

handleEditVideoSubmit now ingests the edited signed event via
ingestLocalVideoEvent — newest-wins replace in the active store + videos:updated —
so the grid shows the new title/thumbnail/description immediately, with the relay
echo confirming behind it.

Test: nostr-service suite +1 (edited event ingested, videos:updated + videos:edited
emitted, result passed through). Lint green.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-07-02 23:19:15 -04:00
1 parent 9afbc0cbbb
commit 3bc79f8e48
3 files changed
+50 -5

No files matched your search

+12
View File
@@ -2134,6 +2134,18 @@ export class NostrService {
async handleEditVideoSubmit({ originalEvent, updatedData, pubkey }) {
const result = await this.nostrClient.editVideo(originalEvent, updatedData, pubkey);
// #52: ingest the edited (signed) event locally — the same optimistic path
// new publishes use (#46). The edit is a replaceable event; without this the
// grids re-render from cache showing the PRE-edit version until relays echo
// the update back. Ingesting replaces the old version in the active store
// (newest-wins) and emits videos:updated so grids refresh immediately.
if (result && typeof result === "object" && result.id) {
try {
this.ingestLocalVideoEvent(result);
} catch (error) {
this.log("[nostrService] Failed to ingest edited video locally", error);
}
}
this.emit("videos:edited", { originalEvent, updatedData, pubkey, result });
return result;
}
+31
View File
@@ -84,6 +84,37 @@ describe("NostrService", () => {
// Account switch must not leave the previous account's DMs on screen: the DM
// store lives here (nostrService), so a switch clears the in-memory store. With
// keepSnapshot it preserves each account's persisted cache for fast switch-back.
// #52: an edit must refresh the grids immediately — the edited signed event
// is ingested locally (same optimistic path as publish) instead of waiting
// for the relay echo of the replaceable event.
describe("handleEditVideoSubmit", () => {
it("ingests the edited event locally and emits videos:edited", async () => {
const signed = { id: "edited-1", kind: 30078, pubkey: "p", created_at: 2000 };
mockClient.editVideo = mock.fn(async () => signed);
const ingested = [];
mockClient.ingestLocalVideoEvent = mock.fn((evt) => {
ingested.push(evt);
return { id: evt.id, deleted: false, invalid: false };
});
const events = [];
const originalEmit = nostrService.emit;
nostrService.emit = (name, detail) => events.push(name);
try {
const result = await nostrService.handleEditVideoSubmit({
originalEvent: { id: "orig" },
updatedData: { title: "t" },
pubkey: "p",
});
assert.equal(result, signed);
} finally {
nostrService.emit = originalEmit;
}
assert.deepEqual(ingested, [signed], "edited event ingested for instant grid refresh");
assert.ok(events.includes("videos:updated"), "grids notified");
assert.ok(events.includes("videos:edited"));
});
});
describe("clearDirectMessages", () => {
it("empties the in-memory DM store and resets the active actor", () => {
nostrService.dmMessages = [{ id: "m1" }, { id: "m2" }];
+7 -5
View File
@@ -1629,11 +1629,13 @@ passphrase-encrypted). Items 51, 56, 57 are all facets of that.
in the storage/wallet panes for users who set it up there rather than via a prompt.
### 52. After editing a video, the video grids don't refresh to show the update (BUG)
- [ ] Editing a video leaves the grids showing the pre-edit version until a manual
reload. Publishing a NEW video already refreshes the feed (**#46**); the **edit**
path needs the same post-publish grid refresh (title/thumbnail/description/url).
Likely wire the edit-submit success into the same `refreshAllVideoGrids` /
`onVideosShouldRefresh` path #46 uses, keyed by `videoRootId`.
- [x] **FIXED 2026-07-02.** The edit flow already re-ran `loadVideos()`, but the cache
still held the PRE-edit version: unlike new publishes (#46), the edit never
ingested its signed replaceable event locally, so grids re-rendered stale until
relays echoed the update. `nostrService.handleEditVideoSubmit` now ingests the
edited event via `ingestLocalVideoEvent` (newest-wins replace in the active
store + `videos:updated`), so grids show the new title/thumbnail/etc.
immediately. Test: `tests/services/nostr-service.test.mjs` (+1).
### 53. Channel-profile link in the video player modal doesn't work (BUG)
- [x] **FIXED 2026-07-02.** Event-name mismatch: `VideoModal.handleCreatorNavigation`