mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-12 15:01:38 +03:00
chat: improve multicontent rendering
This commit is contained in:
parent
b516926510
commit
e7de3533ee
@ -11,6 +11,7 @@ import TextContent from './content/text';
|
||||
import CodeContent from './content/code';
|
||||
import RemoteContent from '~/views/components/RemoteContent';
|
||||
import { Mention } from "~/views/components/MentionText";
|
||||
import styled from "styled-components";
|
||||
|
||||
export const DATESTAMP_FORMAT = '[~]YYYY.M.D';
|
||||
|
||||
@ -251,7 +252,7 @@ export class MessageWithSigil extends PureComponent<MessageProps> {
|
||||
<Text flexShrink='0' gray mono className="v-mid">{timestamp}</Text>
|
||||
<Text flexShrink={0} gray mono ml={2} className="v-mid child dn-s">{datestamp}</Text>
|
||||
</Box>
|
||||
<Box flexShrink={0} fontSize={fontSize ? fontSize : '14px'}>
|
||||
<ContentBox flexShrink={0} fontSize={fontSize ? fontSize : '14px'}>
|
||||
{msg.contents.map(c =>
|
||||
<MessageContent
|
||||
contacts={contacts}
|
||||
@ -260,19 +261,26 @@ export class MessageWithSigil extends PureComponent<MessageProps> {
|
||||
measure={measure}
|
||||
fontSize={fontSize}
|
||||
/>)}
|
||||
</Box>
|
||||
</ContentBox>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const ContentBox = styled(Box)`
|
||||
& > :first-child {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
export const MessageWithoutSigil = ({ timestamp, contacts, msg, remoteContentPolicy, measure }) => (
|
||||
<>
|
||||
<Text flexShrink={0} mono gray display='inline-block' pt='2px' lineHeight='tall' className="child">{timestamp}</Text>
|
||||
<Box flexShrink={0} fontSize='14px' className="clamp-message" style={{ flexGrow: 1 }}>
|
||||
<ContentBox flexShrink={0} fontSize='14px' className="clamp-message" style={{ flexGrow: 1 }}>
|
||||
{msg.contents.map(c => (<MessageContent contacts={contacts} content={c} remoteContentPolicy={remoteContentPolicy} measure={measure}/>))}
|
||||
</Box>
|
||||
</ContentBox>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -281,7 +289,7 @@ export const MessageContent = ({ content, contacts, remoteContentPolicy, measure
|
||||
return <CodeContent content={content} />;
|
||||
} else if ('url' in content) {
|
||||
return (
|
||||
<Text flexShrink={0} fontSize={fontSize ? fontSize : '14px'} lineHeight="tall" color='black'>
|
||||
<Text mx="2px" flexShrink={0} fontSize={fontSize ? fontSize : '14px'} lineHeight="tall" color='black'>
|
||||
<RemoteContent
|
||||
url={content.url}
|
||||
remoteContentPolicy={remoteContentPolicy}
|
||||
|
@ -261,7 +261,6 @@ export default class ChatWindow extends Component<ChatWindowProps, ChatWindowSta
|
||||
|
||||
const unreadMarkerRef = this.unreadMarkerRef;
|
||||
|
||||
let lastMessage = 0;
|
||||
|
||||
const messageProps = { association, group, contacts, hideAvatars, hideNicknames, remoteContentPolicy, unreadMarkerRef, history, api };
|
||||
|
||||
@ -297,7 +296,7 @@ export default class ChatWindow extends Component<ChatWindowProps, ChatWindowSta
|
||||
return <MessagePlaceholder key={index.toString()} height="64px" index={index} />;
|
||||
}
|
||||
const isPending: boolean = 'pending' in msg && Boolean(msg.pending);
|
||||
const isLastMessage: boolean = Boolean(index.eq(bigInt(lastMessage)));
|
||||
const isLastMessage = index.eq(graph.peekLargest()?.[0] ?? bigInt.zero);
|
||||
const highlighted = bigInt(this.props.scrollTo || -1).eq(index);
|
||||
const graphIdx = keys.findIndex(idx => idx.eq(index));
|
||||
const prevIdx = keys[graphIdx+1];
|
||||
|
@ -86,7 +86,7 @@ export default class TextContent extends Component {
|
||||
&& (urbitOb.isValidPatp(group[2]) // valid patp?
|
||||
&& (group[0] === content.text))) { // entire message is room name?
|
||||
return (
|
||||
<Text flexShrink={0} fontSize={props.fontSize ? props.fontSize : '14px'} color='black' lineHeight="tall">
|
||||
<Text mx="2px" flexShrink={0} fontSize={props.fontSize ? props.fontSize : '14px'} color='black' lineHeight="tall">
|
||||
<Link
|
||||
className="bb b--black b--white-d mono"
|
||||
to={'/~landscape/join/' + group.input}>
|
||||
@ -96,7 +96,7 @@ export default class TextContent extends Component {
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Text flexShrink={0} color='black' fontSize={props.fontSize ? props.fontSize : '14px'} lineHeight="tall" style={{ overflowWrap: 'break-word' }}>
|
||||
<Text mx="2px" flexShrink={0} color='black' fontSize={props.fontSize ? props.fontSize : '14px'} lineHeight="tall" style={{ overflowWrap: 'break-word' }}>
|
||||
<MessageMarkdown source={content.text} />
|
||||
</Text>
|
||||
);
|
||||
|
@ -1,9 +1,16 @@
|
||||
import React from "react";
|
||||
import React, { useState, useCallback } from "react";
|
||||
import _ from "lodash";
|
||||
import { Text } from "@tlon/indigo-react";
|
||||
import { Contacts, Content, LocalUpdateRemoteContentPolicy } from "~/types";
|
||||
import { Text, Box } from "@tlon/indigo-react";
|
||||
import {
|
||||
Contacts,
|
||||
Content,
|
||||
LocalUpdateRemoteContentPolicy,
|
||||
Group,
|
||||
} from "~/types";
|
||||
import RichText from "~/views/components/RichText";
|
||||
import { cite } from "~/logic/lib/util";
|
||||
import { cite, uxToHex } from "~/logic/lib/util";
|
||||
import { ProfileOverlay } from "./ProfileOverlay";
|
||||
import {useHistory} from "react-router-dom";
|
||||
|
||||
interface MentionTextProps {
|
||||
contacts: Contacts;
|
||||
@ -37,15 +44,54 @@ export function MentionText(props: MentionTextProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export function Mention(props: { ship: string; contacts: Contacts }) {
|
||||
export function Mention(props: {
|
||||
ship: string;
|
||||
contacts: Contacts;
|
||||
group: Group;
|
||||
}) {
|
||||
const { contacts, ship } = props;
|
||||
const contact = contacts[ship];
|
||||
const showNickname = !!contact?.nickname;
|
||||
const name = showNickname ? contact?.nickname : cite(ship);
|
||||
const [showOverlay, setShowOverlay] = useState(false);
|
||||
const onDismiss = useCallback(() => {
|
||||
setShowOverlay(false);
|
||||
}, [setShowOverlay]);
|
||||
const onClick = useCallback(() => {
|
||||
setShowOverlay(true);
|
||||
}, [setShowOverlay]);
|
||||
|
||||
const group = props.group ?? { hidden: true };
|
||||
|
||||
const history = useHistory();
|
||||
|
||||
return (
|
||||
<Text mx="2px" px="2px" bg="washedBlue" color="blue" mono={!showNickname}>
|
||||
{name}
|
||||
</Text>
|
||||
<Box
|
||||
position="relative"
|
||||
display="inline-block"
|
||||
>
|
||||
{showOverlay && (
|
||||
<ProfileOverlay
|
||||
ship={ship}
|
||||
contact={contact}
|
||||
color={uxToHex(contact?.color ?? '0x0')}
|
||||
group={group}
|
||||
onDismiss={onDismiss}
|
||||
hideAvatars={false}
|
||||
hideNicknames={false}
|
||||
history={history}
|
||||
/>
|
||||
)}
|
||||
<Text
|
||||
onClick={onClick}
|
||||
mx="2px"
|
||||
px="2px"
|
||||
bg="washedBlue"
|
||||
color="blue"
|
||||
mono={!showNickname}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ export function ContactCard(props: ContactCardProps) {
|
||||
const [,,ship] = props.path.split('/');
|
||||
values.color = uxToHex(values.color);
|
||||
const sharedValues = Object.assign({}, values);
|
||||
sharedValues.avatar = (values.avatar === "") ? null : { url: values.avatar };
|
||||
sharedValues.avatar = !values.avatar ? null : { url: values.avatar };
|
||||
console.log(values);
|
||||
await props.api.contacts.share(ship, props.path, us, sharedValues);
|
||||
actions.setStatus({ success: null });
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component, useEffect } from 'react';
|
||||
import React, { Component, useEffect, useCallback } from 'react';
|
||||
import { Route, Switch, RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
import './css/custom.css';
|
||||
@ -25,18 +25,21 @@ type LandscapeProps = StoreState & {
|
||||
|
||||
export function DMRedirect(props: LandscapeProps & RouteComponentProps & { ship: string; }) {
|
||||
const { ship, api, history, graphKeys } = props;
|
||||
const goToGraph = useCallback((graph: string) => {
|
||||
history.push(`/~landscape/home/resource/chat/ship/~${graph}`);
|
||||
}, [history]);
|
||||
|
||||
useEffect(() => {
|
||||
const station = `/ship/~${window.ship}/dm--${ship}`;
|
||||
const theirStation = `/ship/~${ship}/dm--${window.ship}`;
|
||||
const station = `${window.ship}/dm--${ship}`;
|
||||
const theirStation = `${ship}/dm--${window.ship}`;
|
||||
|
||||
if (graphKeys.has(station)) {
|
||||
history.push(`/~landscape/home/resource/chat${station}`);
|
||||
goToGraph(station);
|
||||
return;
|
||||
}
|
||||
|
||||
if (graphKeys.has(theirStation)) {
|
||||
history.push(`/~landscape/home/resource/chat${theirStation}`);
|
||||
goToGraph(theirStation);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -51,7 +54,7 @@ export function DMRedirect(props: LandscapeProps & RouteComponentProps & { ship:
|
||||
{ invite: { pending: aud } },
|
||||
'chat'
|
||||
).then(() => {
|
||||
history.push(`/~landscape/home/resource/chat${station}`);
|
||||
goToGraph(station);
|
||||
});
|
||||
|
||||
}, []);
|
||||
@ -70,9 +73,6 @@ export default class Landscape extends Component<LandscapeProps, {}> {
|
||||
this.props.subscription.startApp('graph');
|
||||
}
|
||||
|
||||
createandRedirectToDM(api, ship, history, allStations) {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { props } = this;
|
||||
const { api } = props;
|
||||
|
Loading…
Reference in New Issue
Block a user