Skip to content

feat(extension): save useful posts (Phase 1)#9

Merged
erichuang1425 merged 1 commit into
mainfrom
claude/unmerged-prs-app-dev-ho26fv
Jun 23, 2026
Merged

feat(extension): save useful posts (Phase 1)#9
erichuang1425 merged 1 commit into
mainfrom
claude/unmerged-prs-app-dev-ho26fv

Conversation

@erichuang1425

Copy link
Copy Markdown
Owner

Summary

First, merged the one outstanding unmerged PR (#8, "new posts since last visit") — its lone review comment was already resolved and CI was green, so it merged cleanly into main. Then continued Phase 1 with the next roadmap item: save comments.

ForumForge now lets the reader save any useful post from a thread. Each post gets a Save / Saved toggle in the side panel; saving keeps an on-device snapshot (the post content frozen at save time) plus where it came from, so the saved item stays stable even if the page later changes — and can be revisited and exported to Markdown later (the next Phase 1 item).

Everything stays on-device (local-first, see docs/PRIVACY.md): nothing about what you keep leaves the browser, and no new permissions are needed — saved posts reuse the existing storage permission.

click Save ─▶ post id → frozen snapshot ─▶ key by thread ─▶ persist ─▶ reflect "Saved"

What changed

  • src/savedPosts.ts (new) — a SavedPosts store over a @forumforge/storage Collection. A SavedPost is a frozen snapshot plus provenance (thread key, page URL, title, savedAt). Keys are namespaced per thread (<threadKey> <postId>), so the same post id in two different threads can't collide; the thread key reuses readHistory's fragment-normalization so a post anchor in the URL doesn't fork the key. API: save / remove / isSaved / toggle / savedIdsFor / all.
  • src/render.ts — each post gets a Save/Saved toggle reflecting options.savedPostIds. The state is carried by the label and aria-pressed (not color alone). renderThread stays a pure view; setSaveButtonState is exported and shared by initial render and the panel's click update so the two never drift.
  • src/sidepanel.ts — loads the thread's saved ids, passes them to render, and a single delegated click handler (on the persistent output container) toggles save state against the frozen post snapshot. The button reflects what storage actually reached — a failed write leaves the label honest.
  • public/sidepanel.html — Save toggle styles (pill button, pressed state).

Docs synced in the same change: ROADMAP.md, the canonical Initial Plan.md checklist, and the extension README.md.

Roadmap (Phase 1)

  • Clean reading mode
  • OP highlighting
  • New posts since last visit
  • Save comments ← this PR
  • Local user notes
  • Markdown export
  • Discourse adapter
  • Hacker News adapter

Verification

  • pnpm -r typecheck — passes (core + parser + storage + extension)
  • pnpm test102 tests pass (+12: saved-post store, per-thread key namespacing, Save rendering & state toggling)
  • pnpm --filter @forumforge/extension build — bundles dist/

Intentionally not done

  • A saved-posts list / management view and Markdown exportSavedPosts.all() already returns saved posts most-recent-first to feed it, but the UI and export are the next Phase 1 items, out of scope here.
  • Clicking through in a real browser is a manual step (needs a browser); the store, render, and wiring are unit-tested.

🤖 Generated with Claude Code


Generated by Claude Code

Adds the "save comments" Phase 1 feature: a per-post Save toggle in the
side panel that keeps an on-device snapshot of useful posts.

- src/savedPosts.ts (new): SavedPosts store over a @forumforge/storage
  Collection. A saved post is a frozen snapshot plus provenance (thread
  key, page URL, title, savedAt), keyed per thread so the same post id in
  two threads can't collide. toggle/save/remove/isSaved/savedIdsFor/all.
- src/render.ts: each post gets a "Save"/"Saved" toggle (aria-pressed +
  label, not color alone) reflecting savedPostIds; render stays a pure
  view. setSaveButtonState is shared by render and the panel update.
- src/sidepanel.ts: loads saved ids for the thread, passes them to render,
  and a delegated click handler persists toggles against the frozen post
  snapshot. Honest UI — the button reflects what storage actually reached.
- public/sidepanel.html: Save toggle styles.

Everything stays on-device (local-first, docs/PRIVACY.md); no new
permissions. Docs synced: ROADMAP.md, Initial Plan.md checklist, and the
extension README.

Verification: pnpm -r typecheck passes; pnpm test 102 pass (+12: saved
post store, key namespacing, Save rendering); extension build bundles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ujybr1sbfakZamZJsZxUfz
@erichuang1425 erichuang1425 merged commit d892c6d into main Jun 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants