feat: thread-level muting (mute thread / hellthread mute)#7
Merged
Conversation
Renumbered from 26.12.0: the concurrent home-tab-persistence work shipped 26.12.0 and re-bumped to 26.12.1 on main while this branch was in flight, so thread muting takes the next free patch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Normalizes formatting of the new test files and the MuteListPage 'Muted threads' section. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NotificationItem already hid muted-thread items at render time, but the unread badge (per-column header + favicon/title) is driven by a separate notificationFilter path that did not know about thread mutes. A muted hellthread that kept tagging you still incremented the badge while the list showed nothing. Thread the muteEventIdSet through notificationFilter + useNotificationFilter so counts and list agree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The muted-threads memo keyed on [pubkey], copied from the muted-users list. Users have a MuteButton that masks the stale row, but a thread row has no such toggle, so an unmuted thread lingered until remount. Key the memo on [muteEventIdSet] so the row vanishes on unmute. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying jank with
|
| Latest commit: |
9c698fb
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://3170c011.jank-4ii.pages.dev |
| Branch Preview URL: | https://feat-thread-muting.jank-4ii.pages.dev |
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the ability to mute an entire thread. Pick "Mute thread" from any note's
⋯menu and the whole conversation, including every reply, disappears from feeds, notifications, and the unread counts. Stored privately in your NIP-51 kind-10000 mute list, so it syncs across your devices and interops with other clients.getThreadRootId(evt) = getRootEventHexId(evt) ?? evt.id(NIP-10 aware) computes a note's conversation root; it's used identically at store-time (mute the clicked note's root) and filter-time (isInMutedThread(evt, set)). O(1) per note, no reply-tree walking, robust with partial threads.rootmarker.muteThreadwrites the['e', rootId]into the NIP-44-encrypted portion of the mute list;unmuteThreadstrips from both public and private. Mirrors the existing pubkey-mute pattern (samechanginglock, optimistic overlay + rollback).NoteList,NoteCard), thread reply lists (useFilteredReplies), notifications (NotificationItem), and the unread counts (column badge + favicon/title, vianotificationFilter).<Note>but isn't list-filtered (quotes/embeds and direct detail views): a<MutedNote reason=\"thread\">placeholder — "This note is from a thread you muted" + "Temporarily display this note."MutedNotewas generalized with areasonprop so user- and thread-mute share one component.Ships as v26.12.2 with a "What's new" entry.
Notes for reviewers
<Note>collapse/reveal tier). Feeds + notifications hard-hide; embeds/detail collapse-with-reveal — same as users.muteEventIdSetalso honors any pre-existing publice-tag thread mutes already in a user's kind-10000 list (written by other clients). Previously never applied at filter time; now they hide those threads. Strictly more NIP-51-compliant.Test coverage
22 unit tests on the core predicate + helpers (
getThreadRootId,isInMutedThread,getEventIdsFromETags/appendETag/stripETag,notificationFilterthread exclusion). Full suite: 855 passing,npm run buildclean.Manual test plan (needs a signing account)
⋯menu on a thread note shows "Mute thread"; clicking it removes the note + its replies from the feed🤖 Generated with Claude Code