Skip to content

New Feature: Mute#677

Draft
marcustyphoon wants to merge 100 commits into
AprilSylph:masterfrom
marcustyphoon:mute
Draft

New Feature: Mute#677
marcustyphoon wants to merge 100 commits into
AprilSylph:masterfrom
marcustyphoon:mute

Conversation

@marcustyphoon

@marcustyphoon marcustyphoon commented Jul 28, 2022

Copy link
Copy Markdown
Collaborator

User-facing changes

  • As per the specification in the linked issue, adds a script that selectively mutes original posts, reblogged posts, or all posts from a user across Tumblr, with controls accessible from the meatball menu as well as within XKit's settings menu.

This departs slightly from the linked specification in a few ways:

  • An interactive informational/warning element with the ability to temporarily show all posts is placed at the start of the timeline in the blog view modal if the user in question is muted in any mode, not just in "all posts" mode. (Along with being a nice feature, the special case logic got really weird looking otherwise). The ability to show posts anyway in the modal is applied only to posts muted because of that user (onBlogHiddenClass).
  • Muted blogs, despite being key-value, are stored as an array of [key, value] entries instead of in an object. Web extension storage does not preserve insertion order on objects, annoyingly.
  • The UUID -> blog name dictionary is stored as a separate object, to guarantee that the race condition mentioned in the specification does not occur no matter when the script updates the dictionary.
  • Minor UI stuff ("unmute" is a button in the preference iframe, etc).

Does not currently implement a meatball menu button on blogs themselves; see #910.

Technical explanation

See comment history.

Also, note that posts are hidden via visibility: hidden instead of display: none in "hide everything on this blog" mode so that they take up space and Redpop doesn't just try to load posts forever until the tab runs out of memory.

Issues this closes

resolves #674

@marcustyphoon

This comment was marked as outdated.

this css is intended as temporary anyway
moves original/reblogged/all logic to css; moves state logic to control element before timeline
@marcustyphoon

marcustyphoon commented Aug 4, 2022

Copy link
Copy Markdown
Collaborator Author

The blog name should be updated whenever the mute modal is opened for a muted blog - not when processing posts, despite the opportunity existing. (It is potentially problematic to have both a passive and an active way to affect the same storage key, as one may overwrite the other.)

One potential fix for this, I think, is to have two separate storage keys: one for uuid => is this muted or not, and one for uuid => what blog name corresponds to this uuid. Thus, passive updates to the name dictionary cannot overwrite a simultaneous attempt to mute/unmute a blog.

The format for the feature's storage I have in mind is to have one object stored on mute.mutedBlogs. Blog UUIDs will be the object's keys, each with an array value of the blog's last seen name and applied mute setting, e.g. "t:Fft_7iTGnBlHdl-UtlllwQ": ["april", "reblogs"].

One drawback of this is that the order blogs you have blocked will appear arbitrary; it seems like local storage does not preserve object key order, and so the entries appear sorted alphabetically by UUID, which is sort of weird.


edit: in 6cae4f2, I tried:
a) Using two storage keys, each a single dictionary with uuid keys. not sure how to bug test this, but this should allow instantaneous updates of changed blog names without the potential for overwriting mute mode data
b) Actually storing the mute mode data as an array using Object.entries() on set and Object.fromEntries() on get. This ensures insertion order is preserved, which feels a lot less weird than sorting alphabetically by uuid or blog name. Kind of weird, though?

@marcustyphoon

This comment was marked as outdated.

@marcustyphoon

This comment was marked as outdated.

@marcustyphoon

Copy link
Copy Markdown
Collaborator Author

On the blog view, when hiding all posts from that blog, no posts should be hidden - instead, the entire timeline should be hidden, and an interactive warning put in its place, informing the user that this blog is muted, with a button to show its posts anyway.

Maybe better and arguably simpler-to-understand form of this might be:

On the blog view of a muted blog, an interactive warning is shown above the timeline informing the user that this blog is muted (and in what mode), with a button to show its posts anyway that removes the warning.

In processing, posts are given a special class if muted because they match the current timeline and a generic one if not. Posts with the generic one are always display:
none.

Special-class posts are hidden when they are preceded by the warning element. If the mode for the blog in question is "all," special-class posts are hidden with visibility to avoid infinite loading, otherwise they're hidden with display: none.

(This really doesn't simplify things all that much, honestly. What we really need is "set this CSS ruleset on elements that match ruleset a unless they match ruleset b, where both a and b can include descendants", but, y'know, that's not a thing afaik.)

@marcustyphoon marcustyphoon marked this pull request as ready for review December 12, 2022 08:43
@marcustyphoon marcustyphoon changed the title New Script (prototype): Mute New Script: Mute Dec 12, 2022
@marcustyphoon

Copy link
Copy Markdown
Collaborator Author

Note to self: the "Hide all posts from blogs I've blocked" tweak currently hides posts unconditionally when they're viewed by themselves if they have a blocked blog in the trail, something which this PR (iirc) carefully avoids; consider making these consistent.

@marcustyphoon

marcustyphoon commented Dec 9, 2025

Copy link
Copy Markdown
Collaborator Author

Ooh, you know what: it would also be fairly easy to make it active but have alternative behavior. Override content: linear-gradient(transparent, transparent); height: 0; with content: 'some info'; /* styling */.

edit: Ah, that's not how content works; it'd have to be a pseudo. Oh well, slightly more code than that.

@AprilSylph

Copy link
Copy Markdown
Owner

Note to self: the "Hide all posts from blogs I've blocked" tweak currently hides posts unconditionally when they're viewed by themselves if they have a blocked blog in the trail, something which this PR (iirc) carefully avoids; consider making these consistent.

I think we should never be outright hiding posts if we're on their permalink page; maybe we should have a "hide this post" util which checks for that and inserts a signpost in the permalink case. (No plans to do this myself, please implement this if you want to.)

@marcustyphoon marcustyphoon self-assigned this Apr 9, 2026
@marcustyphoon marcustyphoon marked this pull request as draft April 9, 2026 17:08
@marcustyphoon

marcustyphoon commented Apr 9, 2026

Copy link
Copy Markdown
Collaborator Author

marcustyphoon and others added 7 commits April 29, 2026 20:05
Co-Authored-By: April Sylph <28949509+AprilSylph@users.noreply.github.com>
Co-Authored-By: April Sylph <28949509+AprilSylph@users.noreply.github.com>
can't reference event after await statement
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.

new feature: Mute

2 participants