From 7d97e3d82fdde28c4de0c39e2e47ec4d67ceeaf3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 22 Aug 2024 19:12:35 +0200 Subject: [PATCH 1/4] [Glitch] Change how content warnings and filters are displayed in web UI Partially apply 500f4925a5e5ee45f2576ee3b0c603a0ab851840 to glitch-soc Signed-off-by: Claire --- .../glitch/components/content_warning.tsx | 15 +++ .../glitch/components/filter_warning.tsx | 23 +++++ .../glitch/components/status_banner.tsx | 37 +++++++ .../components/embedded_status.tsx | 35 +++++-- .../flavours/glitch/styles/components.scss | 96 +++++++++++++++++-- 5 files changed, 190 insertions(+), 16 deletions(-) create mode 100644 app/javascript/flavours/glitch/components/content_warning.tsx create mode 100644 app/javascript/flavours/glitch/components/filter_warning.tsx create mode 100644 app/javascript/flavours/glitch/components/status_banner.tsx diff --git a/app/javascript/flavours/glitch/components/content_warning.tsx b/app/javascript/flavours/glitch/components/content_warning.tsx new file mode 100644 index 0000000000..df8afca74d --- /dev/null +++ b/app/javascript/flavours/glitch/components/content_warning.tsx @@ -0,0 +1,15 @@ +import { StatusBanner, BannerVariant } from './status_banner'; + +export const ContentWarning: React.FC<{ + text: string; + expanded?: boolean; + onClick?: () => void; +}> = ({ text, expanded, onClick }) => ( + +

+ +); diff --git a/app/javascript/flavours/glitch/components/filter_warning.tsx b/app/javascript/flavours/glitch/components/filter_warning.tsx new file mode 100644 index 0000000000..4305e43038 --- /dev/null +++ b/app/javascript/flavours/glitch/components/filter_warning.tsx @@ -0,0 +1,23 @@ +import { FormattedMessage } from 'react-intl'; + +import { StatusBanner, BannerVariant } from './status_banner'; + +export const FilterWarning: React.FC<{ + title: string; + expanded?: boolean; + onClick?: () => void; +}> = ({ title, expanded, onClick }) => ( + +

+ +

+
+); diff --git a/app/javascript/flavours/glitch/components/status_banner.tsx b/app/javascript/flavours/glitch/components/status_banner.tsx new file mode 100644 index 0000000000..8ff17a9b2e --- /dev/null +++ b/app/javascript/flavours/glitch/components/status_banner.tsx @@ -0,0 +1,37 @@ +import { FormattedMessage } from 'react-intl'; + +export enum BannerVariant { + Yellow = 'yellow', + Blue = 'blue', +} + +export const StatusBanner: React.FC<{ + children: React.ReactNode; + variant: BannerVariant; + expanded?: boolean; + onClick?: () => void; +}> = ({ children, variant, expanded, onClick }) => ( +
+ {children} + + +
+); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx index 3ff021e574..6a67b5c849 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx @@ -8,11 +8,13 @@ import type { List as ImmutableList, RecordOf } from 'immutable'; import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react'; import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react'; +import { toggleStatusSpoilers } from 'flavours/glitch/actions/statuses'; import { Avatar } from 'flavours/glitch/components/avatar'; +import { ContentWarning } from 'flavours/glitch/components/content_warning'; import { DisplayName } from 'flavours/glitch/components/display_name'; import { Icon } from 'flavours/glitch/components/icon'; import type { Status } from 'flavours/glitch/models/status'; -import { useAppSelector } from 'flavours/glitch/store'; +import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; import { EmbeddedStatusContent } from './embedded_status_content'; @@ -23,6 +25,7 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ }) => { const history = useHistory(); const clickCoordinatesRef = useRef<[number, number] | null>(); + const dispatch = useAppDispatch(); const status = useAppSelector( (state) => state.statuses.get(statusId) as Status | undefined, @@ -96,15 +99,21 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ [], ); + const handleContentWarningClick = useCallback(() => { + dispatch(toggleStatusSpoilers(statusId)); + }, [dispatch, statusId]); + if (!status) { return null; } // Assign status attributes to variables with a forced type, as status is not yet properly typed const contentHtml = status.get('contentHtml') as string; + const contentWarning = status.get('spoilerHtml') as string; const poll = status.get('poll'); const language = status.get('language') as string; const mentions = status.get('mentions') as ImmutableList; + const expanded = !status.get('hidden') || !contentWarning; const mediaAttachmentsSize = ( status.get('media_attachments') as ImmutableList ).size; @@ -124,14 +133,24 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ - + {contentWarning && ( + + )} - {(poll || mediaAttachmentsSize > 0) && ( + {(!contentWarning || expanded) && ( + + )} + + {expanded && (poll || mediaAttachmentsSize > 0) && (
{!!poll && ( <> diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index f044227c95..44bee55ffc 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -620,7 +620,7 @@ body > [data-popper-placement] { .spoiler-input__input { padding: 12px 12px - 5px; - background: mix($ui-base-color, $ui-highlight-color, 85%); + background: rgba($ui-highlight-color, 0.05); color: $highlight-text-color; } @@ -1447,6 +1447,14 @@ body > [data-popper-placement] { } } + .content-warning { + margin-bottom: 10px; + + &:last-child { + margin-bottom: 0; + } + } + .media-gallery, .video-player, .audio-player, @@ -1771,6 +1779,14 @@ body > [data-popper-placement] { .media-gallery__item-thumbnail { cursor: default; } + + .content-warning { + margin-bottom: 16px; + + &:last-child { + margin-bottom: 0; + } + } } .status__prepend { @@ -11185,39 +11201,53 @@ noscript { } &__embedded-status { + display: flex; + flex-direction: column; + gap: 8px; cursor: pointer; &__account { display: flex; align-items: center; gap: 4px; - margin-bottom: 8px; color: $dark-text-color; + font-size: 15px; + line-height: 22px; bdi { - color: inherit; + color: $darker-text-color; } } - .account__avatar { - opacity: 0.5; - } - &__content { display: -webkit-box; font-size: 15px; line-height: 22px; - color: $dark-text-color; + color: $darker-text-color; -webkit-line-clamp: 4; -webkit-box-orient: vertical; max-height: 4 * 22px; overflow: hidden; + p { + display: none; + + &:first-child { + display: initial; + } + } + p, a { color: inherit; } } + + .reply-indicator__attachments { + font-size: 15px; + line-height: 22px; + color: $dark-text-color; + } } } @@ -11492,3 +11522,53 @@ noscript { } } } + +.content-warning { + background: rgba($ui-highlight-color, 0.05); + color: $secondary-text-color; + border-top: 1px solid; + border-bottom: 1px solid; + border-color: rgba($ui-highlight-color, 0.15); + padding: 8px (5px + 8px); + position: relative; + font-size: 15px; + line-height: 22px; + + p { + margin-bottom: 8px; + } + + .link-button { + font-size: inherit; + line-height: inherit; + font-weight: 500; + } + + &::before, + &::after { + content: ''; + display: block; + position: absolute; + height: 100%; + background: url('~images/warning-stripes.svg') repeat-y; + width: 5px; + top: 0; + } + + &::before { + border-start-start-radius: 4px; + border-end-start-radius: 4px; + inset-inline-start: 0; + } + + &::after { + border-start-end-radius: 4px; + border-end-end-radius: 4px; + inset-inline-end: 0; + } + + &--filter::before, + &--filter::after { + background-image: url('~images/filter-stripes.svg'); + } +} From 0d26c9fb0b54470f4da3429ec6c7d98c01938ff5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 5 Sep 2024 11:46:11 +0200 Subject: [PATCH 2/4] [Glitch] Fix wrong width on content warnings and filters in web UI Port b265a654d74f649b6a58debe39a439cc9b07b730 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 44bee55ffc..fe8e85c69b 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -11524,6 +11524,7 @@ noscript { } .content-warning { + box-sizing: border-box; background: rgba($ui-highlight-color, 0.05); color: $secondary-text-color; border-top: 1px solid; From 4d754935a98aa9970f2d90db81c83f77be6ca654 Mon Sep 17 00:00:00 2001 From: Claire Date: Sun, 22 Sep 2024 20:21:46 +0200 Subject: [PATCH 3/4] Replace new-style upstream CWs with old-style CWs for now --- .../glitch/components/content_warning.tsx | 26 +++++++++++++------ .../flavours/glitch/styles/components.scss | 11 ++++++-- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/app/javascript/flavours/glitch/components/content_warning.tsx b/app/javascript/flavours/glitch/components/content_warning.tsx index df8afca74d..a4c1e6e43f 100644 --- a/app/javascript/flavours/glitch/components/content_warning.tsx +++ b/app/javascript/flavours/glitch/components/content_warning.tsx @@ -1,15 +1,25 @@ -import { StatusBanner, BannerVariant } from './status_banner'; +/* Significantly rewritten from upstream to keep the old design for now */ + +import { FormattedMessage } from 'react-intl'; export const ContentWarning: React.FC<{ text: string; expanded?: boolean; onClick?: () => void; }> = ({ text, expanded, onClick }) => ( - -

- +

+ {' '} + +

); diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index fe8e85c69b..6ee86f5ee0 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -1365,7 +1365,7 @@ body > [data-popper-placement] { .status__content__spoiler-link { display: inline-flex; // glitch: media icon in spoiler button border-radius: 2px; - background: transparent; + background: $action-button-color; // glitch: design used in more places border: 0; color: $inverted-text-color; font-weight: 700; @@ -1378,7 +1378,8 @@ body > [data-popper-placement] { align-items: center; // glitch: content indicator &:hover { - background: lighten($ui-base-color, 33%); + // glitch: design used in more places + background: lighten($action-button-color, 7%); text-decoration: none; } @@ -11219,6 +11220,12 @@ noscript { } } + /* glitch: used for CWs */ + p { + font-size: 15px; + color: $darker-text-color; + } + &__content { display: -webkit-box; font-size: 15px; From 7c148ed1cb45195e170b3c5945b3de455a59a378 Mon Sep 17 00:00:00 2001 From: Claire Date: Sun, 22 Sep 2024 20:54:11 +0200 Subject: [PATCH 4/4] Use new CW class in more places --- .../glitch/components/content_warning.tsx | 4 +- .../glitch/components/status_content.jsx | 68 ++++++------------- 2 files changed, 24 insertions(+), 48 deletions(-) diff --git a/app/javascript/flavours/glitch/components/content_warning.tsx b/app/javascript/flavours/glitch/components/content_warning.tsx index a4c1e6e43f..82f9ca83ed 100644 --- a/app/javascript/flavours/glitch/components/content_warning.tsx +++ b/app/javascript/flavours/glitch/components/content_warning.tsx @@ -6,7 +6,8 @@ export const ContentWarning: React.FC<{ text: string; expanded?: boolean; onClick?: () => void; -}> = ({ text, expanded, onClick }) => ( + icons?: React.ReactNode[]; +}> = ({ text, expanded, onClick, icons }) => (

{' '}

); diff --git a/app/javascript/flavours/glitch/components/status_content.jsx b/app/javascript/flavours/glitch/components/status_content.jsx index 634ab0db29..d6dfd9f490 100644 --- a/app/javascript/flavours/glitch/components/status_content.jsx +++ b/app/javascript/flavours/glitch/components/status_content.jsx @@ -14,6 +14,7 @@ import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react'; import LinkIcon from '@/material-icons/400-24px/link.svg?react'; import MovieIcon from '@/material-icons/400-24px/movie.svg?react'; import MusicNoteIcon from '@/material-icons/400-24px/music_note.svg?react'; +import { ContentWarning } from 'flavours/glitch/components/content_warning'; import { Icon } from 'flavours/glitch/components/icon'; import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; import { autoPlayGif, languages as preloadedLanguages } from 'flavours/glitch/initial_state'; @@ -350,7 +351,7 @@ class StatusContent extends PureComponent { const renderTranslate = this.props.onTranslate && this.props.identity.signedIn && ['public', 'unlisted'].includes(status.get('visibility')) && status.get('search_index').trim().length > 0 && targetLanguages?.includes(contentLocale); const content = { __html: statusContent ?? getStatusContent(status) }; - const spoilerContent = { __html: status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml') }; + const spoilerHtml = status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml'); const language = status.getIn(['translation', 'language']) || status.get('language'); const classNames = classnames('status__content', { 'status__content--with-action': parseClick && !disabled, @@ -375,45 +376,26 @@ class StatusContent extends PureComponent { )).reduce((aggregate, item) => [...aggregate, item, ' '], []); - let toggleText = null; - if (hidden) { - toggleText = [ - , - ]; - if (mediaIcons) { - const mediaComponents = { - 'link': LinkIcon, - 'picture-o': ImageIcon, - 'tasks': InsertChartIcon, - 'video-camera': MovieIcon, - 'music': MusicNoteIcon, - }; + let spoilerIcons = []; + if (hidden && mediaIcons) { + const mediaComponents = { + 'link': LinkIcon, + 'picture-o': ImageIcon, + 'tasks': InsertChartIcon, + 'video-camera': MovieIcon, + 'music': MusicNoteIcon, + }; - mediaIcons.forEach((mediaIcon, idx) => { - toggleText.push( -