feat: mask ||spoiler|| text until the message is revealed#238
Open
RoJoPM wants to merge 1 commit into
Open
Conversation
Discord spoiler syntax (||text||) was rendered as plain text including the pipes (chojs23#204). Detect ||...|| spans and mask them as a solid block until the reader reveals the message by clicking it. - Add a Spoiler TextHighlightKind whose paint style sets fg == bg, reusing the existing byte-range highlight pipeline (same mechanism as URLs/mentions). Because the mask is the same width as the hidden text, revealing never changes layout and does not invalidate the row-metrics cache. - Detect spans with spoiler_ranges() (non-empty content, ignores |||| and unclosed openers), with unit tests. - Track revealed messages in an ephemeral per-session set on DashboardState, keyed by message id, so spoilers re-hide on restart like Discord. - Single left-click on a message toggles its spoilers; a double-click leaves them revealed and still activates the message. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Fixes #204.
Problem
Discord spoiler syntax
||text||was rendered as plain text (pipes and all), so spoilers were never hidden.Approach
Spoilers reuse the existing byte-range highlight pipeline (the same mechanism as URLs and mentions):
SpoilerTextHighlightKindwhose paint style setsfg == bg, so the masked text renders as a solid block. Because the mask is the same width as the hidden text, revealing never changes layout or invalidates the row-metrics cache.spoiler_ranges()detects||...||spans (requires non-empty content; ignores||||and unclosed openers).DashboardState, keyed by message id — spoilers re-hide on restart, matching Discord.Interaction (mouse)
A single left-click on a message toggles its spoilers (reveal / re-hide). A double-click leaves them revealed and still activates the message. Only messages that actually contain a spoiler participate, so ordinary clicks never accumulate state.
Tests
spoiler_rangesunit tests (single / multiple / empty / unclosed / plain).cargo test --lib: 1546 passed),cargo clippyclean.Known limitations (happy to address based on your preference)
||text||(pipes visible), kept intentionally so hidden/revealed widths are identical and nothing reflows. Can strip the pipes on reveal if preferred.🤖 Generated with Claude Code