Note -> EventComponent, split NoteInner
continuous-integration/drone/push Build is running Details

This commit is contained in:
Martti Malmi 2024-01-08 13:15:20 +02:00
parent 615f3ca504
commit 5adaed2737
29 changed files with 133 additions and 135 deletions

View File

@ -2,7 +2,7 @@ import { NostrPrefix, tryParseNostrLink } from "@snort/system";
import { Link } from "react-router-dom";
import Mention from "@/Components/Embed/Mention";
import NoteQuote from "@/Components/Event/NoteQuote";
import NoteQuote from "@/Components/Event/Note/NoteQuote";
export default function NostrLink({ link, depth }: { link: string; depth?: number }) {
const nav = tryParseNostrLink(link);

View File

@ -12,7 +12,7 @@ import { AsyncIcon } from "@/Components/Button/AsyncIcon";
import CloseButton from "@/Components/Button/CloseButton";
import { TrendingHashTagsLine } from "@/Components/Event/Create/TrendingHashTagsLine";
import { sendEventToRelays } from "@/Components/Event/Create/util";
import Note from "@/Components/Event/Note";
import Note from "@/Components/Event/EventComponent";
import Icon from "@/Components/Icons/Icon";
import { ToggleSwitch } from "@/Components/Icons/Toggle";
import Modal from "@/Components/Modal/Modal";

View File

@ -1,4 +1,4 @@
import "./Note.css";
import "./EventComponent.css";
import { EventKind, NostrEvent, TaggedNostrEvent } from "@snort/system";
import { memo, ReactNode } from "react";
@ -13,7 +13,7 @@ import { LiveEvent } from "@/Components/LiveStream/LiveEvent";
import ProfilePreview from "@/Components/User/ProfilePreview";
import { LongFormText } from "./LongFormText";
import { NoteInner } from "./NoteInner";
import { NoteInner } from "./Note/NoteInner";
export interface NoteProps {
data: TaggedNostrEvent;

View File

@ -12,8 +12,8 @@ import useImgProxy from "@/Hooks/useImgProxy";
import { findTag } from "@/Utils";
import { Markdown } from "./Markdown";
import NoteFooter from "./NoteFooter";
import NoteTime from "./NoteTime";
import NoteFooter from "./Note/NoteFooter";
import NoteTime from "./Note/NoteTime";
interface LongFormTextProps {
ev: TaggedNostrEvent;

View File

@ -12,7 +12,7 @@ import useModeration from "@/Hooks/useModeration";
import { setBookmarked, setPinned } from "@/Utils/Login";
import { getCurrentSubscription, SubscriptionType } from "@/Utils/Subscription";
import { ReBroadcaster } from "../ReBroadcaster";
import { ReBroadcaster } from "../../ReBroadcaster";
export interface NoteTranslation {
text: string;

View File

@ -21,7 +21,7 @@ import { Zapper, ZapTarget } from "@/Utils/Zapper";
import { ZapPoolController } from "@/Utils/ZapPoolController";
import { useWallet } from "@/Wallet";
import messages from "../messages";
import messages from "../../messages";
let isZapperBusy = false;
const barrierZapper = async <T,>(then: () => Promise<T>): Promise<T> => {

View File

@ -1,4 +1,4 @@
import "./Note.css";
import "../EventComponent.css";
import ProfileImage from "@/Components/User/ProfileImage";

View File

@ -1,11 +1,12 @@
import { EventExt, EventKind, HexKey, NostrLink, NostrPrefix, TaggedNostrEvent } from "@snort/system";
import classNames from "classnames";
import React, { ReactNode, useMemo, useState } from "react";
import React, { ReactNode, useState } from "react";
import { useInView } from "react-intersection-observer";
import { FormattedMessage, useIntl } from "react-intl";
import { Link, useNavigate } from "react-router-dom";
import { UserCache } from "@/Cache";
import { NoteText } from "@/Components/Event/Note/NoteText";
import Icon from "@/Components/Icons/Icon";
import DisplayName from "@/Components/User/DisplayName";
import { ProfileLink } from "@/Components/User/ProfileLink";
@ -16,19 +17,16 @@ import { chainKey } from "@/Hooks/useThreadContext";
import { findTag, hexToBech32 } from "@/Utils";
import { setBookmarked, setPinned } from "@/Utils/Login";
import messages from "../messages";
import Text from "../Text/Text";
import ProfileImage from "../User/ProfileImage";
import HiddenNote from "./HiddenNote";
import { NoteProps } from "./Note";
import messages from "../../messages";
import Text from "../../Text/Text";
import ProfileImage from "../../User/ProfileImage";
import { NoteProps } from "../EventComponent";
import HiddenNote from "../HiddenNote";
import Poll from "../Poll";
import { NoteContextMenu, NoteTranslation } from "./NoteContextMenu";
import NoteFooter from "./NoteFooter";
import NoteTime from "./NoteTime";
import Poll from "./Poll";
import ReactionsModal from "./ReactionsModal";
import Reveal from "./Reveal";
const TEXT_TRUNCATE_LENGTH = 400;
export function NoteInner(props: NoteProps) {
const { data: ev, highlight, options: opt, ignoreModeration = false, className, waitUntilInView } = props;
@ -42,10 +40,9 @@ export function NoteInner(props: NoteProps) {
const login = useLogin();
const { pinned, bookmarked } = useLogin();
const { publisher, system } = useEventPublisher();
const [translated, setTranslated] = useState<NoteTranslation>();
const [showTranslation, setShowTranslation] = useState(true);
const [translated, setTranslated] = useState<NoteTranslation>();
const { formatMessage } = useIntl();
const [showMore, setShowMore] = useState(false);
const options = {
showHeader: true,
@ -79,101 +76,6 @@ export function NoteInner(props: NoteProps) {
}
}
const ToggleShowMore = () => (
<a
className="highlight"
onClick={e => {
e.preventDefault();
e.stopPropagation();
setShowMore(!showMore);
}}>
{showMore ? (
<FormattedMessage defaultMessage="Show less" id="qyJtWy" />
) : (
<FormattedMessage defaultMessage="Show more" id="aWpBzj" />
)}
</a>
);
const innerContent = useMemo(() => {
const body = translated && showTranslation ? translated.text : ev?.content ?? "";
const id = translated && showTranslation ? `${ev.id}-translated` : ev.id;
const shouldTruncate = opt?.truncate && body.length > TEXT_TRUNCATE_LENGTH;
return (
<>
{shouldTruncate && showMore && <ToggleShowMore />}
<Text
id={id}
highlighText={props.searchedValue}
content={body}
tags={ev.tags}
creator={ev.pubkey}
depth={props.depth}
disableMedia={!(options.showMedia ?? true)}
disableMediaSpotlight={!(props.options?.showMediaSpotlight ?? true)}
truncate={shouldTruncate && !showMore ? TEXT_TRUNCATE_LENGTH : undefined}
/>
{shouldTruncate && !showMore && <ToggleShowMore />}
</>
);
}, [
showMore,
ev,
translated,
showTranslation,
props.searchedValue,
props.depth,
options.showMedia,
props.options?.showMediaSpotlight,
opt?.truncate,
TEXT_TRUNCATE_LENGTH,
]);
const transformBody = () => {
if (!login.appData.item.showContentWarningPosts) {
const contentWarning = ev.tags.find(a => a[0] === "content-warning");
if (contentWarning) {
return (
<Reveal
message={
<>
<FormattedMessage
defaultMessage="The author has marked this note as a <i>sensitive topic</i>"
id="StKzTE"
values={{
i: c => <i>{c}</i>,
}}
/>
{contentWarning[1] && (
<>
&nbsp;
<FormattedMessage
defaultMessage="Reason: <i>{reason}</i>"
id="6OSOXl"
values={{
i: c => <i>{c}</i>,
reason: contentWarning[1],
}}
/>
</>
)}
. <FormattedMessage defaultMessage="Click here to load anyway" id="IoQq+a" />.{" "}
<Link to="/settings/moderation">
<i>
<FormattedMessage defaultMessage="Settings" id="D3idYv" />
</i>
</Link>
</>
}>
{innerContent}
</Reveal>
);
}
}
return innerContent;
};
function goToEvent(e: React.MouseEvent, eTarget: TaggedNostrEvent) {
if (opt?.canClick === false) {
return;
@ -359,7 +261,7 @@ export function NoteInner(props: NoteProps) {
</div>
)}
<div className="body" onClick={e => goToEvent(e, ev, true)}>
{transformBody()}
<NoteText {...props} translated={translated} showTranslation={showTranslation} login={login} />
{translation()}
{pollOptions()}
</div>

View File

@ -1,7 +1,7 @@
import { NostrLink } from "@snort/system";
import { useEventFeed } from "@snort/system-react";
import Note from "@/Components/Event/Note";
import Note from "@/Components/Event/EventComponent";
import PageSpinner from "@/Components/PageSpinner";
export default function NoteQuote({ link, depth }: { link: NostrLink; depth?: number }) {

View File

@ -0,0 +1,96 @@
import React, { useState } from "react";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import { NoteProps } from "@/Components/Event/EventComponent";
import { NoteTranslation } from "@/Components/Event/Note/NoteContextMenu";
import Reveal from "@/Components/Event/Reveal";
import Text from "@/Components/Text/Text";
import { LoginSession } from "@/Utils/Login";
const TEXT_TRUNCATE_LENGTH = 400;
export const NoteText = function InnerContent(
props: NoteProps & { translated: NoteTranslation; showTranslation?: boolean; login: LoginSession },
) {
const { data: ev, options, translated, showTranslation, login } = props;
const [showMore, setShowMore] = useState(false);
const body = translated && showTranslation ? translated.text : ev?.content ?? "";
const id = translated && showTranslation ? `${ev.id}-translated` : ev.id;
const shouldTruncate = options?.truncate && body.length > TEXT_TRUNCATE_LENGTH;
const ToggleShowMore = () => (
<a
className="highlight"
onClick={e => {
e.preventDefault();
e.stopPropagation();
setShowMore(!showMore);
}}>
{showMore ? (
<FormattedMessage defaultMessage="Show less" id="qyJtWy" />
) : (
<FormattedMessage defaultMessage="Show more" id="aWpBzj" />
)}
</a>
);
const innerContent = (
<>
{shouldTruncate && showMore && <ToggleShowMore />}
<Text
id={id}
highlighText={props.searchedValue}
content={body}
tags={ev.tags}
creator={ev.pubkey}
depth={props.depth}
disableMedia={!(options?.showMedia ?? true)}
disableMediaSpotlight={!(props.options?.showMediaSpotlight ?? true)}
truncate={shouldTruncate && !showMore ? TEXT_TRUNCATE_LENGTH : undefined}
/>
{shouldTruncate && !showMore && <ToggleShowMore />}
</>
);
if (!login.appData.item.showContentWarningPosts) {
const contentWarning = ev.tags.find(a => a[0] === "content-warning");
if (contentWarning) {
return (
<Reveal
message={
<>
<FormattedMessage
defaultMessage="The author has marked this note as a <i>sensitive topic</i>"
id="StKzTE"
values={{
i: c => <i>{c}</i>,
}}
/>
{contentWarning[1] && (
<>
&nbsp;
<FormattedMessage
defaultMessage="Reason: <i>{reason}</i>"
id="6OSOXl"
values={{
i: c => <i>{c}</i>,
reason: contentWarning[1],
}}
/>
</>
)}
. <FormattedMessage defaultMessage="Click here to load anyway" id="IoQq+a" />.{" "}
<Link to="/settings/moderation">
<i>
<FormattedMessage defaultMessage="Settings" id="D3idYv" />
</i>
</Link>
</>
}>
{innerContent}
</Reveal>
);
}
}
return innerContent;
};

View File

@ -1,4 +1,4 @@
import "./Reactions.css";
import "./ReactionsModal.css";
import { NostrLink, socialGraphInstance, TaggedNostrEvent } from "@snort/system";
import { useEventReactions, useReactions } from "@snort/system-react";
@ -12,7 +12,7 @@ import Tabs from "@/Components/Tabs/Tabs";
import ProfileImage from "@/Components/User/ProfileImage";
import { formatShort } from "@/Utils/Number";
import messages from "../messages";
import messages from "../../messages";
interface ReactionsModalProps {
show: boolean;

View File

@ -7,7 +7,7 @@ import { useInView } from "react-intersection-observer";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import Note from "@/Components/Event/Note";
import Note from "@/Components/Event/EventComponent";
import Icon from "@/Components/Icons/Icon";
import useModeration from "@/Hooks/useModeration";
import { eventLink, getDisplayName, hexToBech32 } from "@/Utils";

View File

@ -8,8 +8,8 @@ import { useNavigate, useParams } from "react-router-dom";
import BackButton from "@/Components/Button/BackButton";
import Collapsed from "@/Components/Collapsed";
import Note from "@/Components/Event/Note";
import NoteGhost from "@/Components/Event/NoteGhost";
import Note from "@/Components/Event/EventComponent";
import NoteGhost from "@/Components/Event/Note/NoteGhost";
import { chainKey, ThreadContext, ThreadContextWrapper } from "@/Hooks/useThreadContext";
import messages from "../messages";

View File

@ -4,7 +4,7 @@ import { useArticles } from "@/Feed/ArticlesFeed";
import { DeckContext } from "@/Pages/DeckLayout";
import { orderDescending } from "@/Utils";
import Note from "../Event/Note";
import Note from "../Event/EventComponent";
export default function Articles() {
const data = useArticles();

View File

@ -2,9 +2,9 @@ import { NostrLink, TaggedNostrEvent } from "@snort/system";
import { MouseEvent } from "react";
import { Link } from "react-router-dom";
import getEventMedia from "@/Components/Event/getEventMedia";
import Icon from "@/Components/Icons/Icon";
import { ProxyImg } from "@/Components/ProxyImg";
import getEventMedia from "@/Utils/getEventMedia";
const ImageGridItem = (props: { event: TaggedNostrEvent; onClick: (e: MouseEvent) => void }) => {
const { event, onClick } = props;

View File

@ -1,7 +1,7 @@
import { TaggedNostrEvent } from "@snort/system";
import { ReactNode } from "react";
import Note from "@/Components/Event/Note";
import Note from "@/Components/Event/EventComponent";
export interface TimelineFragment {
events: Array<TaggedNostrEvent>;

View File

@ -4,13 +4,13 @@ import { useInView } from "react-intersection-observer";
import { FormattedMessage } from "react-intl";
import ErrorBoundary from "@/Components/ErrorBoundary";
import getEventMedia from "@/Components/Event/getEventMedia";
import { DisplayAs } from "@/Components/Feed/DisplayAsSelector";
import ImageGridItem from "@/Components/Feed/ImageGridItem";
import { TimelineFragment } from "@/Components/Feed/TimelineFragment";
import Icon from "@/Components/Icons/Icon";
import { SpotlightThreadModal } from "@/Components/Spotlight/SpotlightThreadModal";
import ProfileImage from "@/Components/User/ProfileImage";
import getEventMedia from "@/Utils/getEventMedia";
export interface TimelineRendererProps {
frags: Array<TimelineFragment>;

View File

@ -1,10 +1,10 @@
import { NostrLink, TaggedNostrEvent } from "@snort/system";
import getEventMedia from "@/Components/Event/getEventMedia";
import { Thread } from "@/Components/Event/Thread";
import Modal from "@/Components/Modal/Modal";
import { SpotlightMedia } from "@/Components/Spotlight/SpotlightMedia";
import { ThreadContextWrapper } from "@/Hooks/useThreadContext";
import getEventMedia from "@/Utils/getEventMedia";
interface SpotlightThreadModalProps {
thread?: NostrLink;

View File

@ -1,7 +1,7 @@
import { NostrLink, TaggedNostrEvent } from "@snort/system";
import { Link } from "react-router-dom";
import NoteTime from "@/Components/Event/NoteTime";
import NoteTime from "@/Components/Event/Note/NoteTime";
import Text from "@/Components/Text/Text";
import ProfileImage from "@/Components/User/ProfileImage";

View File

@ -4,7 +4,7 @@ import classNames from "classnames";
import { useState } from "react";
import { ErrorOrOffline } from "@/Components/ErrorOrOffline";
import Note from "@/Components/Event/Note";
import Note from "@/Components/Event/EventComponent";
import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector";
import ImageGridItem from "@/Components/Feed/ImageGridItem";
import PageSpinner from "@/Components/PageSpinner";

View File

@ -3,7 +3,7 @@ import { ChangeEvent, useMemo, useState } from "react";
import { FormattedMessage } from "react-intl";
import { UserCache } from "@/Cache";
import Note from "@/Components/Event/Note";
import Note from "@/Components/Event/EventComponent";
import useLogin from "@/Hooks/useLogin";
import messages from "../messages";

View File

@ -5,7 +5,7 @@ import { useInView } from "react-intersection-observer";
import { FormattedMessage, useIntl } from "react-intl";
import { Chat, ChatMessage, ChatType, setLastReadIn } from "@/chat";
import NoteTime from "@/Components/Event/NoteTime";
import NoteTime from "@/Components/Event/Note/NoteTime";
import messages from "@/Components/messages";
import Text from "@/Components/Text/Text";
import ProfileImage from "@/Components/User/ProfileImage";

View File

@ -4,7 +4,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import { useNavigate, useParams } from "react-router-dom";
import { Chat, ChatType, useChatSystem } from "@/chat";
import NoteTime from "@/Components/Event/NoteTime";
import NoteTime from "@/Components/Event/Note/NoteTime";
import NoteToSelf from "@/Components/User/NoteToSelf";
import ProfileImage from "@/Components/User/ProfileImage";
import useLogin from "@/Hooks/useLogin";

View File

@ -16,7 +16,7 @@ import { Link, useLocation, useNavigate, useParams } from "react-router-dom";
import IconButton from "@/Components/Button/IconButton";
import Copy from "@/Components/Copy/Copy";
import Note from "@/Components/Event/Note";
import Note from "@/Components/Event/EventComponent";
import Timeline from "@/Components/Feed/Timeline";
import Icon from "@/Components/Icons/Icon";
import Modal from "@/Components/Modal/Modal";

View File

@ -5,7 +5,7 @@ import { useNavigate } from "react-router-dom";
import AsyncButton from "@/Components/Button/AsyncButton";
import { AsyncIcon } from "@/Components/Button/AsyncIcon";
import NoteTime from "@/Components/Event/NoteTime";
import NoteTime from "@/Components/Event/Note/NoteTime";
import Icon from "@/Components/Icons/Icon";
import { useRates } from "@/Hooks/useRates";
import { unwrap } from "@/Utils";