From 6dd54633e0ba343285addf63e5149e45c0b89c9c Mon Sep 17 00:00:00 2001 From: Lim Chee Aun <cheeaun@gmail.com> Date: Sun, 24 Dec 2023 21:07:46 +0800 Subject: [PATCH] Finally revisiting this CW thing Respect reading:expand:spoilers and reading:expand:media but differently than Mastodon's logic --- src/components/status.css | 111 ++++++++++++++++------------------ src/components/status.jsx | 122 +++++++++++++++++++++++++------------- src/index.css | 2 +- src/utils/states.js | 1 + 4 files changed, 134 insertions(+), 102 deletions(-) diff --git a/src/components/status.css b/src/components/status.css index 69c58480..9b527ccc 100644 --- a/src/components/status.css +++ b/src/components/status.css @@ -499,76 +499,69 @@ padding-bottom: 10px; } -.status .content-container.has-spoiler .spoiler { +.status + .content-container.has-spoiler + :is(.spoiler-button, .spoiler-media-button):not([hidden]) { margin: 4px 0; font-size: 90%; border: 1px dashed var(--button-bg-color); display: flex; - gap: 8px; + gap: 4px; align-items: center; } -.status - .content-container.has-spoiler:not(.show-spoiler) - .spoiler - ~ *:not(.media-container, .card, .media-figure-multiple), -.status - .content-container.has-spoiler:not(.show-spoiler) - .spoiler - ~ .card - .meta-container, -.status - .content-container.has-spoiler:not(.show-spoiler) - .spoiler - ~ :is(.media-container, .media-figure-multiple) - figcaption { - filter: blur(5px) invert(0.5); - image-rendering: crisp-edges; - image-rendering: pixelated; - pointer-events: none; - user-select: none; - contain: layout; - transform: scale(0.97); - transition: transform 0.1s ease-in-out; +.status .content-container.has-spoiler:not(.show-spoiler) .spoiler-button { + ~ *:not( + .media-container, + .card, + .media-figure-multiple, + .spoiler-media-button + ), + ~ .card .meta-container, + ~ :is(.media-container, .media-figure-multiple) figcaption { + filter: blur(5px) invert(0.5); + image-rendering: crisp-edges; + image-rendering: pixelated; + pointer-events: none; + user-select: none; + contain: layout; + transform: scale(0.97); + transition: transform 0.1s ease-in-out; + } + + /* ~ :is(.media-container, .media-figure-multiple) .media > *, */ + ~ .card > img { + filter: blur(32px); + image-rendering: crisp-edges; + image-rendering: pixelated; + animation: none !important; + } +} +.status .content-container.has-spoiler:not(.show-media) .spoiler-media-button { + ~ :is(.media-container, .media-figure-multiple) .media > * { + filter: blur(32px); + image-rendering: crisp-edges; + image-rendering: pixelated; + animation: none !important; + } } .status - .content-container.has-spoiler:not(.show-spoiler) - .spoiler - ~ :is(.media-container, .media-figure-multiple) - .media - > *, -.status - .content-container.has-spoiler:not(.show-spoiler) - .spoiler - ~ .card - > img { - filter: blur(32px); - image-rendering: crisp-edges; - image-rendering: pixelated; - animation: none !important; -} -.status .content-container.show-spoiler .spoiler { + .content-container.show-spoiler + :is(.spoiler-button, .spoiler-media-button).spoiling { border-style: dotted; } -/* .status - .content-container.show-spoiler - .spoiler - ~ *:not(.media-container, .card), -.status .content-container.show-spoiler .spoiler ~ .card .meta-container { - filter: none !important; - transform: none; - pointer-events: auto; - user-select: auto; - text-rendering: auto; - image-rendering: auto; + +.status .content-container .spoiler-divider { + display: flex; + align-items: center; + gap: 4px; + color: var(--text-insignificant-color); + text-transform: uppercase; + font-size: 0.8em; + margin-top: 0.25em; + margin-bottom: 1em; + padding-block: 0.25em; + border-bottom: 1px dashed var(--divider-color); } -.status .content-container.show-spoiler .spoiler ~ .media-container .media > *, -.status .content-container.show-spoiler .spoiler ~ .card > img { - filter: none; - image-rendering: auto; -} */ -/* .status .content a:not(.mention):not(:has(span)) { - color: inherit; -} */ .status .content-comment-hint { margin-top: 0.25em; diff --git a/src/components/status.jsx b/src/components/status.jsx index 1e2bd255..5c76bc89 100644 --- a/src/components/status.jsx +++ b/src/components/status.jsx @@ -275,8 +275,21 @@ function Status({ const prefs = store.account.get('preferences') || {}; return !!prefs['reading:expand:spoilers']; }, []); + const readingExpandMedia = useMemo(() => { + // default | show_all | hide_all + // Ignore hide_all because it means hide *ALL* media including non-sensitive ones + const prefs = store.account.get('preferences') || {}; + return prefs['reading:expand:media'] || 'default'; + }, []); + // FOR TESTING: + // const readingExpandSpoilers = true; + // const readingExpandMedia = 'show_all'; const showSpoiler = - previewMode || readingExpandSpoilers || !!snapStates.spoilers[id] || false; + previewMode || readingExpandSpoilers || !!snapStates.spoilers[id]; + const showSpoilerMedia = + previewMode || + readingExpandMedia === 'show_all' || + !!snapStates.spoilersMedia[id]; if (reblog) { // If has statusID, means useItemID (cached in states) @@ -1078,11 +1091,19 @@ function Status({ ); if (activeStatus) { const spoilerButton = activeStatus.querySelector( - 'button.spoiler:not(.spoiling)', + '.spoiler-button:not(.spoiling)', ); if (spoilerButton) { e.stopPropagation(); spoilerButton.click(); + } else { + const spoilerMediaButton = activeStatus.querySelector( + '.spoiler-media-button:not(.spoiling)', + ); + if (spoilerMediaButton) { + e.stopPropagation(); + spoilerMediaButton.click(); + } } } }); @@ -1487,7 +1508,9 @@ function Status({ <div class={`content-container ${ spoilerText || sensitive ? 'has-spoiler' : '' - } ${showSpoiler ? 'show-spoiler' : ''}`} + } ${showSpoiler ? 'show-spoiler' : ''} ${ + showSpoilerMedia ? 'show-media' : '' + }`} data-content-text-weight={contentTextWeight ? textWeight() : null} style={ (isSizeLarge || contentTextWeight) && { @@ -1508,27 +1531,36 @@ function Status({ <EmojiText text={spoilerText} emojis={emojis} /> </p> </div> - <button - class={`light spoiler ${showSpoiler ? 'spoiling' : ''}`} - type="button" - disabled={readingExpandSpoilers} - onClick={(e) => { - e.preventDefault(); - e.stopPropagation(); - if (showSpoiler) { - delete states.spoilers[id]; - } else { - states.spoilers[id] = true; - } - }} - > - <Icon icon={showSpoiler ? 'eye-open' : 'eye-close'} />{' '} - {readingExpandSpoilers - ? 'Content warning' - : showSpoiler - ? 'Show less' - : 'Show more'} - </button> + {readingExpandSpoilers || previewMode ? ( + <div class="spoiler-divider"> + <Icon icon="eye-open" /> Content warning + </div> + ) : ( + <button + class={`light spoiler-button ${ + showSpoiler ? 'spoiling' : '' + }`} + type="button" + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + if (showSpoiler) { + delete states.spoilers[id]; + if (!readingExpandSpoilers) { + delete states.spoilersMedia[id]; + } + } else { + states.spoilers[id] = true; + if (!readingExpandSpoilers) { + states.spoilersMedia[id] = true; + } + } + }} + > + <Icon icon={showSpoiler ? 'eye-open' : 'eye-close'} />{' '} + {showSpoiler ? 'Show less' : 'Show content'} + </button> + )} </> )} {!!content && ( @@ -1632,24 +1664,30 @@ function Status({ text={getPostText(status)} /> )} - {!spoilerText && sensitive && !!mediaAttachments.length && ( - <button - class={`plain spoiler ${showSpoiler ? 'spoiling' : ''}`} - type="button" - onClick={(e) => { - e.preventDefault(); - e.stopPropagation(); - if (showSpoiler) { - delete states.spoilers[id]; - } else { - states.spoilers[id] = true; - } - }} - > - <Icon icon={showSpoiler ? 'eye-open' : 'eye-close'} /> Sensitive - content - </button> - )} + {!previewMode && + sensitive && + !!mediaAttachments.length && + readingExpandMedia !== 'show_all' && ( + <button + class={`plain spoiler-media-button ${ + showSpoilerMedia ? 'spoiling' : '' + }`} + type="button" + hidden={!readingExpandSpoilers && !!spoilerText} + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + if (showSpoilerMedia) { + delete states.spoilersMedia[id]; + } else { + states.spoilersMedia[id] = true; + } + }} + > + <Icon icon={showSpoilerMedia ? 'eye-open' : 'eye-close'} />{' '} + {showSpoilerMedia ? 'Show less' : 'Show media'} + </button> + )} {!!mediaAttachments.length && ( <MultipleMediaFigure lang={language} diff --git a/src/index.css b/src/index.css index 9371df43..09c0d609 100644 --- a/src/index.css +++ b/src/index.css @@ -203,7 +203,7 @@ textarea { max-width: 100%; } -button, +button:not([hidden]), .button { display: inline-block; padding: 8px 12px; diff --git a/src/utils/states.js b/src/utils/states.js index 0a5db2c2..ab422a7d 100644 --- a/src/utils/states.js +++ b/src/utils/states.js @@ -29,6 +29,7 @@ const states = proxy({ counter: 0, }, spoilers: {}, + spoilersMedia: {}, scrollPositions: {}, unfurledLinks: {}, statusQuotes: {},