RegularToot: support content warning
This commit is contained in:
		
							parent
							
								
									cff0c2880a
								
							
						
					
					
						commit
						737d63f88a
					
				
					 3 changed files with 64 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -5,6 +5,8 @@ import {
 | 
			
		|||
  type JSX,
 | 
			
		||||
  Show,
 | 
			
		||||
  createRenderEffect,
 | 
			
		||||
  createSignal,
 | 
			
		||||
  type Setter,
 | 
			
		||||
} from "solid-js";
 | 
			
		||||
import tootStyle from "./toot.module.css";
 | 
			
		||||
import { formatRelative } from "date-fns";
 | 
			
		||||
| 
						 | 
				
			
			@ -200,6 +202,11 @@ export function findElementActionable(
 | 
			
		|||
  return current;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onToggleReveal(setValue: Setter<boolean>, event: Event) {
 | 
			
		||||
  event.stopPropagation();
 | 
			
		||||
  setValue((x) => !x);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component for a toot.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -239,6 +246,7 @@ const RegularToot: Component<TootCardProps> = (props) => {
 | 
			
		|||
  const status = () => managed.status;
 | 
			
		||||
  const toot = () => status().reblog ?? status();
 | 
			
		||||
  const session = useDefaultSession();
 | 
			
		||||
  const [reveal, setReveal] = createSignal(false);
 | 
			
		||||
 | 
			
		||||
  css`
 | 
			
		||||
    .reply-sep {
 | 
			
		||||
| 
						 | 
				
			
			@ -326,6 +334,10 @@ const RegularToot: Component<TootCardProps> = (props) => {
 | 
			
		|||
          emojis={toot().emojis}
 | 
			
		||||
          mentions={toot().mentions}
 | 
			
		||||
          class={cardStyle.cardNoPad}
 | 
			
		||||
          sensitive={toot().sensitive}
 | 
			
		||||
          spoilerText={toot().spoilerText}
 | 
			
		||||
          reveal={reveal()}
 | 
			
		||||
          onToggleReveal={[onToggleReveal, setReveal]}
 | 
			
		||||
        />
 | 
			
		||||
        <Show when={toot().card}>
 | 
			
		||||
          <PreviewCard src={toot().card!} />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,10 @@
 | 
			
		|||
  margin-right: var(--card-pad, 0);
 | 
			
		||||
  line-height: 1.5;
 | 
			
		||||
 | 
			
		||||
  > .content {
 | 
			
		||||
    display: contents;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  & * {
 | 
			
		||||
    user-select: text;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,20 +5,26 @@ import {
 | 
			
		|||
  type JSX,
 | 
			
		||||
  createRenderEffect,
 | 
			
		||||
  createMemo,
 | 
			
		||||
  Show,
 | 
			
		||||
} from "solid-js";
 | 
			
		||||
import { resolveCustomEmoji } from "../../masto/toot.js";
 | 
			
		||||
import { makeAcctText, useDefaultSession } from "../../masto/clients";
 | 
			
		||||
import "./TootContent.css";
 | 
			
		||||
import { Button } from "@suid/material";
 | 
			
		||||
 | 
			
		||||
function preventDefault(event: Event) {
 | 
			
		||||
  event.preventDefault();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type TootContentProps = {
 | 
			
		||||
export type TootContentProps = JSX.HTMLAttributes<HTMLDivElement> & {
 | 
			
		||||
  source?: string;
 | 
			
		||||
  emojis?: mastodon.v1.CustomEmoji[];
 | 
			
		||||
  mentions: mastodon.v1.StatusMention[];
 | 
			
		||||
} & JSX.HTMLAttributes<HTMLDivElement>;
 | 
			
		||||
  sensitive?: boolean;
 | 
			
		||||
  spoilerText?: string;
 | 
			
		||||
  reveal?: boolean;
 | 
			
		||||
  onToggleReveal?: JSX.EventHandlerUnion<HTMLElement, Event>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const TootContent: Component<TootContentProps> = (oprops) => {
 | 
			
		||||
  const session = useDefaultSession();
 | 
			
		||||
| 
						 | 
				
			
			@ -27,23 +33,23 @@ const TootContent: Component<TootContentProps> = (oprops) => {
 | 
			
		|||
    "emojis",
 | 
			
		||||
    "mentions",
 | 
			
		||||
    "class",
 | 
			
		||||
    "sensitive",
 | 
			
		||||
    "spoilerText",
 | 
			
		||||
    "reveal",
 | 
			
		||||
    "onToggleReveal",
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  const clientFinder = createMemo(() =>
 | 
			
		||||
    session() ? makeAcctText(session()!) : undefined,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const shouldRevealContent = () => {
 | 
			
		||||
    return !props.sensitive || (props.sensitive && props.reveal);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div
 | 
			
		||||
      ref={(ref) => {
 | 
			
		||||
        createRenderEffect(() => {
 | 
			
		||||
          ref.innerHTML = props.source
 | 
			
		||||
            ? props.emojis
 | 
			
		||||
              ? resolveCustomEmoji(props.source, props.emojis)
 | 
			
		||||
              : props.source
 | 
			
		||||
            : "";
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        createRenderEffect(() => {
 | 
			
		||||
          const finder = clientFinder();
 | 
			
		||||
          for (const mention of props.mentions) {
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +67,38 @@ const TootContent: Component<TootContentProps> = (oprops) => {
 | 
			
		|||
      }}
 | 
			
		||||
      class={`TootContent ${props.class || ""}`}
 | 
			
		||||
      {...rest}
 | 
			
		||||
    ></div>
 | 
			
		||||
    >
 | 
			
		||||
      <Show when={props.sensitive}>
 | 
			
		||||
        <div>
 | 
			
		||||
          <span
 | 
			
		||||
            ref={(ref) => {
 | 
			
		||||
              createRenderEffect(() => {
 | 
			
		||||
                ref.innerHTML = props.spoilerText
 | 
			
		||||
                  ? props.emojis
 | 
			
		||||
                    ? resolveCustomEmoji(props.spoilerText, props.emojis)
 | 
			
		||||
                    : props.spoilerText
 | 
			
		||||
                  : "";
 | 
			
		||||
              });
 | 
			
		||||
            }}
 | 
			
		||||
          ></span>
 | 
			
		||||
          <Button onClick={props.onToggleReveal}>"Content Warning"</Button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </Show>
 | 
			
		||||
      <Show when={shouldRevealContent()}>
 | 
			
		||||
        <div
 | 
			
		||||
          class="content"
 | 
			
		||||
          ref={(ref) =>
 | 
			
		||||
            createRenderEffect(() => {
 | 
			
		||||
              ref.innerHTML = props.source
 | 
			
		||||
                ? props.emojis
 | 
			
		||||
                  ? resolveCustomEmoji(props.source, props.emojis)
 | 
			
		||||
                  : props.source
 | 
			
		||||
                : "";
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
        ></div>
 | 
			
		||||
      </Show>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue