Compare commits
5 commits
4c0925a6a1
...
5d6eb7282a
Author | SHA1 | Date | |
---|---|---|---|
|
5d6eb7282a | ||
|
f56b92fff0 | ||
|
edfbf5505b | ||
|
2c35950d27 | ||
|
5199f2bb6a |
15 changed files with 144 additions and 179 deletions
2
.env
2
.env
|
@ -2,4 +2,4 @@ DEV_SERVER_HTTPS_CERT_BASE=
|
|||
DEV_SERVER_HTTPS_CERT_PASS=
|
||||
DEV_LOCATOR_EDITOR=vscode
|
||||
VITE_DEVTOOLS_OVERLAY=true
|
||||
VITE_PLATFROM_MASONRY_ALWAYS_COMPAT=
|
||||
VITE_PLATFORM_MASONRY_ALWAYS_COMPAT=
|
|
@ -20,17 +20,6 @@ export function resolveCustomEmoji(
|
|||
});
|
||||
}
|
||||
|
||||
export function appliedCustomEmoji(
|
||||
target: { innerHTML: string },
|
||||
content: string,
|
||||
emojis?: mastodon.v1.CustomEmoji[],
|
||||
) {
|
||||
createRenderEffect(() => {
|
||||
const result = emojis ? resolveCustomEmoji(content, emojis) : content;
|
||||
target.innerHTML = result;
|
||||
});
|
||||
}
|
||||
|
||||
export function hasCustomEmoji(s: string) {
|
||||
return CUSTOM_EMOJI_REGEX.test(s);
|
||||
}
|
||||
|
|
2
src/overrides.d.ts
vendored
2
src/overrides.d.ts
vendored
|
@ -14,7 +14,7 @@ interface ImportMetaEnv {
|
|||
/**
|
||||
* Always use compatible version of Masonry.
|
||||
*/
|
||||
readonly VITE_PLATFROM_MASONRY_ALWAYS_COMPAT?: string
|
||||
readonly VITE_PLATFORM_MASONRY_ALWAYS_COMPAT?: string
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
|
|
|
@ -46,30 +46,49 @@ function createCompatMasonry(
|
|||
|
||||
const size = createElementSize(element);
|
||||
|
||||
const treeMutObx = new MutationObserver(() => {
|
||||
layout.reloadItems?.();
|
||||
});
|
||||
let layoutNotRequested = true;
|
||||
|
||||
onCleanup(() => treeMutObx.disconnect());
|
||||
const reflow = () => {
|
||||
layout.layout?.();
|
||||
layoutNotRequested = true;
|
||||
};
|
||||
|
||||
createRenderEffect(() => {
|
||||
const opts = options();
|
||||
layout.option?.(opts);
|
||||
});
|
||||
|
||||
const treeMutObx = new MutationObserver(() => {
|
||||
layout.reloadItems?.();
|
||||
if (layoutNotRequested) {
|
||||
layoutNotRequested = false;
|
||||
requestAnimationFrame(reflow);
|
||||
}
|
||||
});
|
||||
|
||||
onCleanup(() => treeMutObx.disconnect());
|
||||
|
||||
createRenderEffect(() => {
|
||||
treeMutObx.observe(element, { childList: true });
|
||||
});
|
||||
|
||||
createRenderEffect(() => {
|
||||
const width = size.width; // only tracking width
|
||||
layout.layout?.();
|
||||
if (layoutNotRequested) {
|
||||
layoutNotRequested = false;
|
||||
requestAnimationFrame(reflow);
|
||||
}
|
||||
});
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.on("vite:afterUpdate", () => {
|
||||
layout.layout?.();
|
||||
});
|
||||
const onHotReloadUpdate = () => {
|
||||
if (layoutNotRequested) {
|
||||
layoutNotRequested = false;
|
||||
requestAnimationFrame(reflow);
|
||||
}
|
||||
};
|
||||
import.meta.hot.on("vite:afterUpdate", onHotReloadUpdate);
|
||||
import.meta.hot.off("vite:afterUpdate", onHotReloadUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,11 +99,11 @@ const supportsCSSMasonryLayout = /* @__PURE__ */ CSS.supports(
|
|||
|
||||
console.debug("supports css masonry layout", supportsCSSMasonryLayout);
|
||||
|
||||
const useNativeImpl = import.meta.env.VITE_PLATFROM_MASONRY_ALWAYS_COMPAT
|
||||
const useNativeImpl = import.meta.env.VITE_PLATFORM_MASONRY_ALWAYS_COMPAT
|
||||
? false
|
||||
: supportsCSSMasonryLayout;
|
||||
|
||||
if (import.meta.env.VITE_PLATFROM_MASONRY_ALWAYS_COMPAT) {
|
||||
if (import.meta.env.VITE_PLATFORM_MASONRY_ALWAYS_COMPAT) {
|
||||
console.warn(
|
||||
"Masonry is in compat mode because VITE_PLATFORM_MASONRY_ALWAYS_COMPAT is enabled",
|
||||
);
|
||||
|
|
|
@ -171,10 +171,6 @@ const Profile: Component = () => {
|
|||
),
|
||||
);
|
||||
|
||||
const useSessionDisplayName = (e: HTMLElement) => {
|
||||
createRenderEffect(() => (e.innerHTML = sessionDisplayName()));
|
||||
};
|
||||
|
||||
const toggleSubscribeHome = async (event: Event) => {
|
||||
const client = session().client;
|
||||
if (!session().account) return;
|
||||
|
@ -218,9 +214,7 @@ const Profile: Component = () => {
|
|||
style={{
|
||||
visibility: scrolledPastBanner() ? undefined : "hidden",
|
||||
}}
|
||||
ref={(e: HTMLElement) =>
|
||||
createRenderEffect(() => (e.innerHTML = displayName()))
|
||||
}
|
||||
innerHTML={displayName()}
|
||||
></Title>
|
||||
|
||||
<IconButton
|
||||
|
@ -253,7 +247,7 @@ const Profile: Component = () => {
|
|||
<Avatar src={session().account?.inf?.avatar} />
|
||||
</ListItemAvatar>
|
||||
<ListItemText secondary={"Default account"}>
|
||||
<span ref={useSessionDisplayName}></span>
|
||||
<span innerHTML={sessionDisplayName()}></span>
|
||||
</ListItemText>
|
||||
{/* <ArrowRight /> // for future */}
|
||||
</MenuItem>
|
||||
|
@ -384,7 +378,7 @@ const Profile: Component = () => {
|
|||
: undefined
|
||||
}
|
||||
>
|
||||
<span ref={useSessionDisplayName}></span>
|
||||
<span innerHTML={sessionDisplayName()}></span>
|
||||
<span>'s Home</span>
|
||||
</ListItemText>
|
||||
|
||||
|
@ -419,9 +413,7 @@ const Profile: Component = () => {
|
|||
</Show>
|
||||
<Body2
|
||||
component="span"
|
||||
ref={(e: HTMLElement) =>
|
||||
createRenderEffect(() => (e.innerHTML = displayName()))
|
||||
}
|
||||
innerHTML={displayName()}
|
||||
aria-label="Display name"
|
||||
></Body2>
|
||||
</div>
|
||||
|
@ -464,9 +456,7 @@ const Profile: Component = () => {
|
|||
<section
|
||||
class="description"
|
||||
aria-label={`${profile()?.displayName || "the user"}'s description`}
|
||||
ref={(e) =>
|
||||
createRenderEffect(() => (e.innerHTML = description() || ""))
|
||||
}
|
||||
innerHTML={description() || ""}
|
||||
></section>
|
||||
|
||||
<table
|
||||
|
@ -484,11 +474,7 @@ const Profile: Component = () => {
|
|||
<Verified />
|
||||
</Show>
|
||||
</td>
|
||||
<td
|
||||
ref={(e) => {
|
||||
createRenderEffect(() => (e.innerHTML = item.value));
|
||||
}}
|
||||
></td>
|
||||
<td innerHTML={item.value}></td>
|
||||
</tr>
|
||||
);
|
||||
}}
|
||||
|
|
|
@ -10,23 +10,19 @@ import {
|
|||
createContext,
|
||||
useContext,
|
||||
} from "solid-js";
|
||||
import tootStyle from "./toot.module.css";
|
||||
import { formatRelative } from "date-fns";
|
||||
import Img from "~material/Img.js";
|
||||
import { Body2 } from "~material/typography.js";
|
||||
import { SmartToySharp, Lock } from "@suid/icons-material";
|
||||
import { useTimeSource } from "~platform/timesrc.js";
|
||||
import { resolveCustomEmoji } from "../masto/toot.js";
|
||||
import { Divider } from "@suid/material";
|
||||
import cardStyle from "~material/cards.module.css";
|
||||
import MediaAttachmentGrid from "./toots/MediaAttachmentGrid.jsx";
|
||||
import { useDateFnLocale } from "~platform/i18n";
|
||||
import { makeAcctText, useDefaultSession } from "../masto/clients";
|
||||
import TootContent from "./toots/TootContent";
|
||||
import BoostIcon from "./toots/BoostIcon";
|
||||
import PreviewCard from "./toots/PreviewCard";
|
||||
import TootPoll from "./toots/TootPoll";
|
||||
import TootActionGroup from "./toots/TootActionGroup.js";
|
||||
import TootAuthorGroup from "./toots/TootAuthorGroup.js";
|
||||
import "./RegularToot.css";
|
||||
|
||||
export type TootEnv = {
|
||||
|
@ -66,63 +62,15 @@ type RegularTootProps = {
|
|||
|
||||
export function findRootToot(element: HTMLElement) {
|
||||
let current: HTMLElement | null = element;
|
||||
while (current && !current.classList.contains(tootStyle.toot)) {
|
||||
while (current && !current.classList.contains("RegularToot")) {
|
||||
current = current.parentElement;
|
||||
}
|
||||
if (!current) {
|
||||
throw Error(
|
||||
`the element must be placed under a element with ${tootStyle.toot}`,
|
||||
);
|
||||
throw Error(`the element must be placed under a element with .RegularToot`);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
function TootAuthorGroup(
|
||||
props: {
|
||||
status: mastodon.v1.Status;
|
||||
now: Date;
|
||||
} & JSX.HTMLElementTags["div"],
|
||||
) {
|
||||
const [managed, rest] = splitProps(props, ["status", "now"]);
|
||||
const toot = () => managed.status;
|
||||
const dateFnLocale = useDateFnLocale();
|
||||
|
||||
return (
|
||||
<div class={tootStyle.tootAuthorGrp} {...rest}>
|
||||
<Img src={toot().account.avatar} class={tootStyle.tootAvatar} />
|
||||
<div class={tootStyle.tootAuthorNameGrp}>
|
||||
<div class={tootStyle.tootAuthorNamePrimary}>
|
||||
<Show when={toot().account.bot}>
|
||||
<SmartToySharp class="acct-mark" aria-label="Bot" />
|
||||
</Show>
|
||||
<Show when={toot().account.locked}>
|
||||
<Lock class="acct-mark" aria-label="Locked" />
|
||||
</Show>
|
||||
<Body2
|
||||
component="span"
|
||||
ref={(e: { innerHTML: string }) => {
|
||||
createRenderEffect(() => {
|
||||
e.innerHTML = resolveCustomEmoji(
|
||||
toot().account.displayName,
|
||||
toot().account.emojis,
|
||||
);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<time datetime={toot().createdAt}>
|
||||
{formatRelative(toot().createdAt, managed.now, {
|
||||
locale: dateFnLocale(),
|
||||
})}
|
||||
</time>
|
||||
<span>
|
||||
@{toot().account.username}@{new URL(toot().account.url).hostname}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* find bottom-to-top the element with `data-action`.
|
||||
*/
|
||||
|
@ -195,8 +143,8 @@ const RegularToot: Component<RegularTootProps> = (oprops) => {
|
|||
<>
|
||||
<article
|
||||
classList={{
|
||||
"RegularToot": true,
|
||||
"expanded": props.evaluated,
|
||||
RegularToot: true,
|
||||
expanded: props.evaluated,
|
||||
"thread-top": props.thread === "top",
|
||||
"thread-mid": props.thread === "middle",
|
||||
"thread-btm": props.thread === "bottom",
|
||||
|
@ -210,14 +158,10 @@ const RegularToot: Component<RegularTootProps> = (oprops) => {
|
|||
<div class="retoot-grp">
|
||||
<BoostIcon />
|
||||
<Body2
|
||||
ref={(e: { innerHTML: string }) => {
|
||||
createRenderEffect(() => {
|
||||
e.innerHTML = resolveCustomEmoji(
|
||||
status().account.displayName,
|
||||
toot().emojis,
|
||||
);
|
||||
});
|
||||
}}
|
||||
innerHTML={resolveCustomEmoji(
|
||||
status().account.displayName,
|
||||
toot().emojis,
|
||||
)}
|
||||
></Body2>
|
||||
<span>boosts</span>
|
||||
</div>
|
||||
|
|
|
@ -261,13 +261,7 @@ const TootBottomSheet: Component = (props) => {
|
|||
>
|
||||
<BackButton color="inherit" />
|
||||
<Title component="div" class="name" use:solid-styled>
|
||||
<span
|
||||
ref={(e: HTMLElement) =>
|
||||
createRenderEffect(
|
||||
() => (e.innerHTML = tootDisplayName() ?? "Someone"),
|
||||
)
|
||||
}
|
||||
></span>
|
||||
<span innerHTML={tootDisplayName() ?? "Someone"}></span>
|
||||
<span>'s toot</span>
|
||||
</Title>
|
||||
</Toolbar>
|
||||
|
|
|
@ -44,7 +44,7 @@ import "./TootComposer.css";
|
|||
import BottomSheet from "~material/BottomSheet";
|
||||
import { useAppLocale } from "~platform/i18n";
|
||||
import iso639_1 from "iso-639-1";
|
||||
import ChooseTootLang from "./ChooseTootLang";
|
||||
import ChooseTootLang from "./TootLangPicker";
|
||||
import type { mastodon } from "masto";
|
||||
import cardStyles from "~material/cards.module.css";
|
||||
import Menu, { createManagedMenuState } from "~material/Menu";
|
||||
|
@ -349,15 +349,10 @@ const TootComposer: Component<{
|
|||
</ListItemAvatar>
|
||||
<ListItemText secondary={"Default account"}>
|
||||
<span
|
||||
ref={(e) => {
|
||||
createRenderEffect(() => {
|
||||
const inf = session()?.account.inf;
|
||||
return (e.innerHTML = resolveCustomEmoji(
|
||||
inf?.displayName || "",
|
||||
inf?.emojis ?? [],
|
||||
));
|
||||
});
|
||||
}}
|
||||
innerHTML={resolveCustomEmoji(
|
||||
session()?.account.inf?.displayName || "",
|
||||
session()?.account.inf?.emojis ?? [],
|
||||
)}
|
||||
></span>
|
||||
</ListItemText>
|
||||
</MenuItem>
|
||||
|
|
4
src/timelines/TootLangPicker.css
Normal file
4
src/timelines/TootLangPicker.css
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
.TootLangPicker {
|
||||
overflow: auto;
|
||||
}
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
For,
|
||||
onMount,
|
||||
type Component,
|
||||
type JSX,
|
||||
} from "solid-js";
|
||||
import { For, onMount, type Component, type JSX } from "solid-js";
|
||||
import Scaffold from "~material/Scaffold";
|
||||
import {
|
||||
AppBar,
|
||||
|
@ -19,6 +14,7 @@ import { Close as CloseIcon } from "@suid/icons-material";
|
|||
import iso639_1 from "iso-639-1";
|
||||
import { createTranslator } from "~platform/i18n";
|
||||
import { Title } from "~material/typography";
|
||||
import "./TootLangPicker.css";
|
||||
|
||||
type ChooseTootLangProps = {
|
||||
code: string;
|
||||
|
@ -58,6 +54,7 @@ const ChooseTootLang: Component<ChooseTootLangProps> = (props) => {
|
|||
</Toolbar>
|
||||
</AppBar>
|
||||
}
|
||||
class="TootLangPicker"
|
||||
>
|
||||
<List
|
||||
ref={listRef!}
|
|
@ -1,4 +1,4 @@
|
|||
.tootAuthorGrp {
|
||||
.TootAuthorGroup {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
|
@ -10,7 +10,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tootAuthorNameGrp {
|
||||
.TootAuthorGroup > .name-grp {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
color: var(--tutu-color-secondary-text-on-surface);
|
||||
|
@ -30,10 +30,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tootAuthorNamePrimary {
|
||||
.TootAuthorGroup > .name-grp > .name-primary {
|
||||
color: var(--tutu-color-on-surface);
|
||||
|
||||
> :global(.acct-mark) {
|
||||
> .acct-mark {
|
||||
font-size: 1.2em;
|
||||
color: var(--tutu-color-secondary-text-on-surface);
|
||||
vertical-align: sub;
|
||||
|
@ -41,7 +41,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tootAvatar {
|
||||
.TootAuthorGroup > .avatar {
|
||||
width: calc(var(--toot-avatar-size, 40px) - 1px);
|
||||
aspect-ratio: 1/1;
|
||||
object-fit: contain;
|
||||
|
@ -49,4 +49,4 @@
|
|||
overflow: hidden;
|
||||
border: 1px solid var(--tutu-color-surface);
|
||||
background-color: var(--tutu-color-surface-d);
|
||||
}
|
||||
}
|
53
src/timelines/toots/TootAuthorGroup.tsx
Normal file
53
src/timelines/toots/TootAuthorGroup.tsx
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { SmartToySharp, Lock } from "@suid/icons-material";
|
||||
import { formatRelative } from "date-fns";
|
||||
import type { mastodon } from "masto";
|
||||
import { createRenderEffect, Show, splitProps, type JSX } from "solid-js";
|
||||
import Img from "~material/Img";
|
||||
import { Body2 } from "~material/typography";
|
||||
import { useAppLocale } from "~platform/i18n";
|
||||
import { resolveCustomEmoji } from "../../masto/toot";
|
||||
import "./TootAuthorGroup.css";
|
||||
|
||||
function TootAuthorGroup(
|
||||
props: {
|
||||
status: mastodon.v1.Status;
|
||||
now: Date;
|
||||
} & JSX.HTMLElementTags["div"],
|
||||
) {
|
||||
const [managed, rest] = splitProps(props, ["status", "now"]);
|
||||
const toot = () => managed.status;
|
||||
const { dateFn: dateFnLocale } = useAppLocale();
|
||||
|
||||
return (
|
||||
<div class="TootAuthorGroup" {...rest}>
|
||||
<Img src={toot().account.avatar} class="avatar" />
|
||||
<div class={"name-grp"}>
|
||||
<div class="name-primary">
|
||||
<Show when={toot().account.bot}>
|
||||
<SmartToySharp class="acct-mark" aria-label="Bot" />
|
||||
</Show>
|
||||
<Show when={toot().account.locked}>
|
||||
<Lock class="acct-mark" aria-label="Locked" />
|
||||
</Show>
|
||||
<Body2
|
||||
component="span"
|
||||
innerHTML={resolveCustomEmoji(
|
||||
toot().account.displayName,
|
||||
toot().account.emojis,
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<time datetime={toot().createdAt}>
|
||||
{formatRelative(toot().createdAt, managed.now, {
|
||||
locale: dateFnLocale(),
|
||||
})}
|
||||
</time>
|
||||
<span>
|
||||
@{toot().account.username}@{new URL(toot().account.url).hostname}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TootAuthorGroup;
|
|
@ -81,15 +81,13 @@ const TootContent: Component<TootContentProps> = (oprops) => {
|
|||
<Show when={props.sensitive}>
|
||||
<div>
|
||||
<span
|
||||
ref={(ref) => {
|
||||
createRenderEffect(() => {
|
||||
ref.innerHTML = props.spoilerText
|
||||
? props.emojis
|
||||
? resolveCustomEmoji(props.spoilerText, props.emojis)
|
||||
: props.spoilerText
|
||||
: "";
|
||||
});
|
||||
}}
|
||||
innerHTML={
|
||||
props.spoilerText
|
||||
? props.emojis
|
||||
? resolveCustomEmoji(props.spoilerText, props.emojis)
|
||||
: props.spoilerText
|
||||
: ""
|
||||
}
|
||||
></span>
|
||||
<Button onClick={props.onToggleReveal}>{t("cw")}</Button>
|
||||
</div>
|
||||
|
@ -97,14 +95,12 @@ const TootContent: Component<TootContentProps> = (oprops) => {
|
|||
<Show when={shouldRevealContent()}>
|
||||
<div
|
||||
class="content"
|
||||
ref={(ref) =>
|
||||
createRenderEffect(() => {
|
||||
ref.innerHTML = props.source
|
||||
? props.emojis
|
||||
? resolveCustomEmoji(props.source, props.emojis)
|
||||
: props.source
|
||||
: "";
|
||||
})
|
||||
innerHTML={
|
||||
props.source
|
||||
? props.emojis
|
||||
? resolveCustomEmoji(props.source, props.emojis)
|
||||
: props.source
|
||||
: ""
|
||||
}
|
||||
></div>
|
||||
</Show>
|
||||
|
|
|
@ -20,10 +20,7 @@ import {
|
|||
ListItemText,
|
||||
Radio,
|
||||
} from "@suid/material";
|
||||
import {
|
||||
formatDistance,
|
||||
isBefore,
|
||||
} from "date-fns";
|
||||
import { formatDistance, isBefore } from "date-fns";
|
||||
import { useTimeSource } from "~platform/timesrc";
|
||||
import { useDateFnLocale } from "~platform/i18n";
|
||||
import TootPollDialog from "./TootPollDialog";
|
||||
|
@ -31,13 +28,13 @@ import { ANIM_CURVE_STD } from "~material/theme";
|
|||
import { useTootEnv } from "../RegularToot";
|
||||
|
||||
type TootPollProps = {
|
||||
value: mastodon.v1.Poll
|
||||
status: mastodon.v1.Status
|
||||
value: mastodon.v1.Poll;
|
||||
status: mastodon.v1.Status;
|
||||
};
|
||||
|
||||
const TootPoll: Component<TootPollProps> = (props) => {
|
||||
let list: HTMLUListElement;
|
||||
const {vote}= useTootEnv()
|
||||
const { vote } = useTootEnv();
|
||||
|
||||
const now = useTimeSource();
|
||||
const dateFnLocale = useDateFnLocale();
|
||||
|
@ -46,7 +43,7 @@ const TootPoll: Component<TootPollProps> = (props) => {
|
|||
|
||||
const [initialVote, setInitialVote] = createSignal(0);
|
||||
|
||||
const poll = () => props.value
|
||||
const poll = () => props.value;
|
||||
|
||||
const isShowResult = () => {
|
||||
const n = mustShowResult();
|
||||
|
@ -118,14 +115,10 @@ const TootPoll: Component<TootPollProps> = (props) => {
|
|||
>
|
||||
<ListItemText>
|
||||
<span
|
||||
ref={(e) =>
|
||||
createRenderEffect(() => {
|
||||
e.innerHTML = resolveCustomEmoji(
|
||||
option().title,
|
||||
option().emojis,
|
||||
);
|
||||
})
|
||||
}
|
||||
innerHTML={resolveCustomEmoji(
|
||||
option().title,
|
||||
option().emojis,
|
||||
)}
|
||||
></span>
|
||||
</ListItemText>
|
||||
|
||||
|
|
|
@ -96,15 +96,10 @@ const TootPollDialog: Component<TootPollDialogPoll> = (props) => {
|
|||
>
|
||||
<ListItemText>
|
||||
<span
|
||||
ref={(e) =>
|
||||
createRenderEffect(
|
||||
() =>
|
||||
(e.innerHTML = resolveCustomEmoji(
|
||||
option().title,
|
||||
option().emojis,
|
||||
)),
|
||||
)
|
||||
}
|
||||
innerHTML={resolveCustomEmoji(
|
||||
option().title,
|
||||
option().emojis,
|
||||
)}
|
||||
></span>
|
||||
</ListItemText>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue