mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-11 04:48:00 +03:00
ChatMessage: refactor content rendering
This commit is contained in:
parent
186ac17d5d
commit
156f91adb5
@ -29,8 +29,8 @@ import {
|
||||
Groups,
|
||||
Associations
|
||||
} from '~/types';
|
||||
import TextContent from './content/text';
|
||||
import CodeContent from './content/code';
|
||||
import TextContent from '../../../landscape/components/Graph/content/text';
|
||||
import CodeContent from '../../../landscape/components/Graph/content/code';
|
||||
import RemoteContent from '~/views/components/RemoteContent';
|
||||
import { Mention } from '~/views/components/MentionText';
|
||||
import { Dropdown } from '~/views/components/Dropdown';
|
||||
@ -42,8 +42,7 @@ import useContactState from '~/logic/state/contact';
|
||||
import { useIdlingState } from '~/logic/lib/idling';
|
||||
import ProfileOverlay from '~/views/components/ProfileOverlay';
|
||||
import {useCopy} from '~/logic/lib/useCopy';
|
||||
import {PermalinkEmbed} from '../../permalinks/embed';
|
||||
import {referenceToPermalink} from '~/logic/lib/permalinks';
|
||||
import {GraphContentWide} from '~/views/landscape/components/Graph/GraphContentWide';
|
||||
|
||||
|
||||
export const DATESTAMP_FORMAT = '[~]YYYY.M.D';
|
||||
@ -396,12 +395,11 @@ export const MessageAuthor = ({
|
||||
msg.author !== window.ship) &&
|
||||
`~${msg.author}` in contacts
|
||||
? contacts[`~${msg.author}`]
|
||||
: false;
|
||||
: undefined;
|
||||
|
||||
const showNickname = useShowNickname(contact);
|
||||
const { hideAvatars } = useSettingsState(selectCalmState);
|
||||
const shipName = showNickname ? contact.nickname : cite(msg.author);
|
||||
const copyNotice = 'Copied';
|
||||
const shipName = showNickname && contact?.nickname || cite(msg.author) || `~${msg.author}`;
|
||||
const color = contact
|
||||
? `#${uxToHex(contact.color)}`
|
||||
: dark
|
||||
@ -412,28 +410,10 @@ export const MessageAuthor = ({
|
||||
: dark
|
||||
? 'mix-blend-diff'
|
||||
: 'mix-blend-darken';
|
||||
const [displayName, setDisplayName] = useState(shipName);
|
||||
const [nameMono, setNameMono] = useState(showNickname ? false : true);
|
||||
|
||||
const { copyDisplay, doCopy, didCopy } = useCopy(`~${msg.author}`, shipName);
|
||||
const { hovering, bind } = useHovering();
|
||||
const [showOverlay, setShowOverlay] = useState(false);
|
||||
|
||||
const toggleOverlay = () => {
|
||||
setShowOverlay((value) => !value);
|
||||
};
|
||||
|
||||
const showCopyNotice = () => {
|
||||
setDisplayName(copyNotice);
|
||||
setNameMono(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const resetDisplay = () => {
|
||||
setDisplayName(shipName);
|
||||
setNameMono(showNickname ? false : true);
|
||||
};
|
||||
const timer = setTimeout(() => resetDisplay(), 800);
|
||||
return () => clearTimeout(timer);
|
||||
}, [shipName, displayName]);
|
||||
const nameMono = !(showNickname || didCopy);
|
||||
|
||||
const img =
|
||||
contact?.avatar && !hideAvatars ? (
|
||||
@ -470,9 +450,6 @@ export const MessageAuthor = ({
|
||||
return (
|
||||
<Box display='flex' alignItems='flex-start' {...rest}>
|
||||
<Box
|
||||
onClick={() => {
|
||||
setShowOverlay(true);
|
||||
}}
|
||||
height={24}
|
||||
pr={2}
|
||||
mt={'1px'}
|
||||
@ -500,13 +477,10 @@ export const MessageAuthor = ({
|
||||
mono={nameMono}
|
||||
fontWeight={nameMono ? '400' : '500'}
|
||||
cursor='pointer'
|
||||
onClick={() => {
|
||||
writeText(`~${msg.author}`);
|
||||
showCopyNotice();
|
||||
}}
|
||||
onClick={doCopy}
|
||||
title={`~${msg.author}`}
|
||||
>
|
||||
{displayName}
|
||||
{copyDisplay}
|
||||
</Text>
|
||||
<Text flexShrink={0} fontSize={0} gray>
|
||||
{timestamp}
|
||||
@ -538,7 +512,6 @@ export const Message = ({
|
||||
...rest
|
||||
}) => {
|
||||
const { hovering, bind } = useHovering();
|
||||
const contacts = useContactState((state) => state.contacts);
|
||||
return (
|
||||
<Box width="100%" position='relative' {...rest}>
|
||||
{timestampHover ? (
|
||||
@ -557,66 +530,14 @@ export const Message = ({
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<Box width="100%" {...bind}>
|
||||
{msg.contents.map((content, i) => {
|
||||
switch (Object.keys(content)[0]) {
|
||||
case 'text':
|
||||
return (
|
||||
<TextContent
|
||||
key={i}
|
||||
api={api}
|
||||
fontSize={1}
|
||||
lineHeight={'20px'}
|
||||
content={content}
|
||||
/>
|
||||
);
|
||||
case 'code':
|
||||
return <CodeContent key={i} content={content} />;
|
||||
case 'reference':
|
||||
const { link } = referenceToPermalink(content);
|
||||
return (
|
||||
<PermalinkEmbed
|
||||
link={link}
|
||||
api={api}
|
||||
<GraphContentWide
|
||||
{...bind}
|
||||
width="100%"
|
||||
post={msg}
|
||||
transcluded={transcluded}
|
||||
api={api}
|
||||
showOurContact={showOurContact}
|
||||
/>
|
||||
);
|
||||
case 'url':
|
||||
return (
|
||||
<Box
|
||||
key={i}
|
||||
flexShrink={0}
|
||||
fontSize={1}
|
||||
lineHeight='20px'
|
||||
color='black'
|
||||
width="fit-content"
|
||||
maxWidth="500px"
|
||||
>
|
||||
<RemoteContent
|
||||
key={content.url}
|
||||
url={content.url}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
case 'mention':
|
||||
const first = (i) => i === 0;
|
||||
return (
|
||||
<Mention
|
||||
key={i}
|
||||
first={first(i)}
|
||||
group={group}
|
||||
scrollWindow={scrollWindow}
|
||||
ship={content.mention}
|
||||
contact={contacts?.[`~${content.mention}`]}
|
||||
api={api}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@ -6,7 +6,7 @@ import RichText from '~/views/components/RichText';
|
||||
import { cite, useShowNickname, uxToHex } from '~/logic/lib/util';
|
||||
import ProfileOverlay from '~/views/components/ProfileOverlay';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import useContactState from '~/logic/state/contact';
|
||||
import useContactState, {useContact} from '~/logic/state/contact';
|
||||
import {referenceToPermalink} from '~/logic/lib/permalinks';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
|
||||
@ -40,35 +40,18 @@ export function MentionText(props: MentionTextProps) {
|
||||
}
|
||||
|
||||
export function Mention(props: {
|
||||
contact: Contact;
|
||||
group: Group;
|
||||
scrollWindow?: HTMLElement;
|
||||
ship: string;
|
||||
first?: Boolean;
|
||||
api: any;
|
||||
}) {
|
||||
const { ship, scrollWindow, first, api, ...rest } = props;
|
||||
let { contact } = props;
|
||||
const contacts = useContactState(state => state.contacts);
|
||||
contact = contact?.color ? contact : contacts?.[`~${ship}`];
|
||||
const history = useHistory();
|
||||
const { ship, first, api, ...rest } = props;
|
||||
const contact = useContact(ship);
|
||||
const showNickname = useShowNickname(contact);
|
||||
const name = showNickname ? contact?.nickname : cite(ship);
|
||||
const group = props.group ?? { hidden: true };
|
||||
const [showOverlay, setShowOverlay] = useState(false);
|
||||
|
||||
const toggleOverlay = useCallback(() => {
|
||||
setShowOverlay((value) => !value);
|
||||
}, [showOverlay]);
|
||||
|
||||
return (
|
||||
<Box position='relative' display='inline-block' cursor='pointer' {...rest}>
|
||||
<ProfileOverlay
|
||||
ship={ship}
|
||||
api={api}
|
||||
>
|
||||
<ProfileOverlay ship={ship} api={api}>
|
||||
<Text
|
||||
onClick={() => toggleOverlay()}
|
||||
marginLeft={first? 0 : 1}
|
||||
marginRight={1}
|
||||
px={1}
|
||||
@ -80,6 +63,5 @@ export function Mention(props: {
|
||||
{name}
|
||||
</Text>
|
||||
</ProfileOverlay>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { PureComponent, useCallback, useEffect, useRef, useState, useMemo } from 'react';
|
||||
import React, { PureComponent, useCallback, useEffect, useRef, useState, useMemo, ReactNode } from 'react';
|
||||
import { Contact, Group, uxToHex } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import VisibilitySensor from 'react-visibility-sensor';
|
||||
@ -40,6 +40,7 @@ const FixedOverlay = styled(Col)`
|
||||
type ProfileOverlayProps = BoxProps & {
|
||||
ship: string;
|
||||
api: any;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const ProfileOverlay = (props: ProfileOverlayProps) => {
|
||||
|
@ -0,0 +1,82 @@
|
||||
import React from "react";
|
||||
import { Post, ReferenceContent } from "@urbit/api";
|
||||
import { Box } from "@tlon/indigo-react";
|
||||
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import TextContent from "./content/text";
|
||||
import CodeContent from "./content/code";
|
||||
import RemoteContent from "~/views/components/RemoteContent";
|
||||
import { Mention } from "~/views/components/MentionText";
|
||||
import { PermalinkEmbed } from "~/views/apps/permalinks/embed";
|
||||
import { referenceToPermalink } from "~/logic/lib/permalinks";
|
||||
import { PropFunc } from "~/types";
|
||||
|
||||
function GraphContentWideInner(
|
||||
props: {
|
||||
transcluded?: number;
|
||||
post: Post;
|
||||
api: GlobalApi;
|
||||
showOurContact: boolean;
|
||||
} & PropFunc<typeof Box>
|
||||
) {
|
||||
const { post, transcluded = 0, showOurContact, api, ...rest } = props;
|
||||
|
||||
return (
|
||||
<Box {...rest}>
|
||||
{post.contents.map((content, i) => {
|
||||
switch (Object.keys(content)[0]) {
|
||||
case "text":
|
||||
return (
|
||||
<TextContent
|
||||
key={i}
|
||||
api={api}
|
||||
fontSize={1}
|
||||
lineHeight={"20px"}
|
||||
content={content}
|
||||
/>
|
||||
);
|
||||
case "code":
|
||||
return <CodeContent key={i} content={content} />;
|
||||
case "reference":
|
||||
const { link } = referenceToPermalink(content as ReferenceContent);
|
||||
return (
|
||||
<PermalinkEmbed
|
||||
link={link}
|
||||
api={api}
|
||||
transcluded={transcluded}
|
||||
showOurContact={showOurContact}
|
||||
/>
|
||||
);
|
||||
case "url":
|
||||
return (
|
||||
<Box
|
||||
key={i}
|
||||
flexShrink={0}
|
||||
fontSize={1}
|
||||
lineHeight="20px"
|
||||
color="black"
|
||||
width="fit-content"
|
||||
maxWidth="500px"
|
||||
>
|
||||
<RemoteContent key={content.url} url={content.url} />
|
||||
</Box>
|
||||
);
|
||||
case "mention":
|
||||
const first = (i) => i === 0;
|
||||
return (
|
||||
<Mention
|
||||
key={i}
|
||||
first={first(i)}
|
||||
ship={content.mention}
|
||||
api={api}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export const GraphContentWide = React.memo(GraphContentWideInner);
|
Loading…
Reference in New Issue
Block a user