links, publish: changing comments to new design

This commit is contained in:
Tyler Brown Cifu Shuster 2020-11-09 20:30:34 -08:00
parent 567c77cd48
commit 1bad160173
11 changed files with 157 additions and 118 deletions

View File

@ -215,7 +215,6 @@ export class MessageWithSigil extends PureComponent<MessageProps> {
contact={contact}
color={color}
sigilClass={sigilClass}
association={association}
group={group}
hideAvatars={hideAvatars}
hideNicknames={hideNicknames}

View File

@ -6,10 +6,9 @@ import bigInt from 'big-integer';
import GlobalApi from "~/logic/api/global";
import { StoreState } from "~/logic/store/type";
import { uxToHex } from '~/logic/lib/util';
import { Association, GraphNode } from "~/types";
import { RouteComponentProps } from "react-router-dom";
import { LinkItem } from "./components/link-item";
import { LinkItem } from "./components/LinkItem";
import { LinkSubmit } from "./components/link-submit";
import { LinkPreview } from "./components/link-preview";
import { Comments } from "~/views/components/comments";
@ -77,14 +76,14 @@ export function LinkResource(props: LinkResourceProps) {
const contact = contactDetails[node.post.author];
return (
<LinkItem
contacts={contacts}
key={date.toString()}
resource={resourcePath}
node={node}
nickname={contact?.nickname}
hideAvatars={hideAvatars}
hideNicknames={hideNicknames}
remoteContentPolicy={remoteContentPolicy}
baseUrl={resourceUrl}
color={uxToHex(contact?.color || '0x0')}
group={group}
api={api}
/>
@ -115,13 +114,18 @@ export function LinkResource(props: LinkResourceProps) {
return (
<Col width="100%" p={3} maxWidth="640px">
<Link to={resourceUrl}>{"<- Back"}</Link>
<LinkPreview
resourcePath={resourcePath}
post={node.post}
nickname={contact?.nickname}
<LinkItem
contacts={contacts}
key={node.post.index}
resource={resourcePath}
node={node}
hideAvatars={hideAvatars}
hideNicknames={hideNicknames}
commentNumber={node.children.size}
remoteContentPolicy={remoteContentPolicy}
baseUrl={resourceUrl}
group={group}
api={api}
mt={2}
/>
<Comments
ship={ship}

View File

@ -0,0 +1,106 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Row, Col, Anchor, Box, Text, BaseImage, Icon } from '@tlon/indigo-react';
import { Sigil } from '~/logic/lib/sigil';
import { cite } from '~/logic/lib/util';
import Author from '~/views/components/Author';
import { roleForShip } from '~/logic/lib/group';
import { Contacts, GraphNode, Group, LocalUpdateRemoteContentPolicy, Rolodex } from '~/types';
import GlobalApi from '~/logic/api/global';
interface LinkItemProps {
node: GraphNode;
resource: string;
hideAvatars: boolean;
hideNicknames: boolean;
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
api: GlobalApi;
group: Group;
contacts: Rolodex;
}
export const LinkItem = (props: LinkItemProps) => {
const {
node,
resource,
hideAvatars,
hideNicknames,
remoteContentPolicy,
api,
group,
contacts,
...rest
} = props;
const URLparser = new RegExp(
/((?:([\w\d\.-]+)\:\/\/?){1}(?:(www)\.?){0,1}(((?:[\w\d-]+\.)*)([\w\d-]+\.[\w\d]+))){1}(?:\:(\d+)){0,1}((\/(?:(?:[^\/\s\?]+\/)*))(?:([^\?\/\s#]+?(?:.[^\?\s]+){0,1}){0,1}(?:\?([^\s#]+)){0,1})){0,1}(?:#([^#\s]+)){0,1}/
);
const author = node.post.author;
const index = node.post.index.split('/').join('-');
const size = node.children ? node.children.size : 0;
const contents = node.post.contents;
const hostname = URLparser.exec(contents[1].url) ? URLparser.exec(contents[1].url)[4] : null;
const baseUrl = props.baseUrl || `/~404/${resource}`;
const ourRole = group ? roleForShip(group, window.ship) : undefined;
const [ship, name] = resource.split('/');
return (
<Box width="100%" {...rest}>
{/* <Box width="100%">
<Link to={`${baseUrl}/${index}`}>
<Text color="gray">{size} comment{size > 1 ? 's' : null}</Text>
</Link>
{(ourRole === 'admin' || node.post.author === window.ship)
&& (<Text color='red' ml='2' cursor='pointer' onClick={() => api.graph.removeNodes(`~${ship}`, name, [node.post.index])}>Delete</Text>)}
</Box> */}
<Anchor
lineHeight="tall"
display='flex'
flexDirection='column'
style={{ textDecoration: 'none' }}
href={contents[1].url}
width="100%"
target="_blank"
rel="noopener noreferrer"
p={2}
borderColor='black'
border={1}
borderRadius={2}
>
<Text overflow='hidden' style={{ textOverflow: 'ellipsis', whiteSpace: 'pre' }} mb={2}>{contents[0].text}</Text>
<Text color="gray" flexShrink={0}><Box display='flex'><Icon icon='ArrowExternal' mr={1}/>{hostname}</Box></Text>
</Anchor>
<Row minWidth='0' flexShrink={0} width="100%" justifyContent="space-between" py={3} bg="white">
<Author
showImage
contacts={contacts}
ship={author}
date={node.post['time-sent']}
hideAvatars={hideAvatars}
hideNicknames={hideNicknames}
remoteContentPolicy={remoteContentPolicy}
group={group}
api={api}
>
</Author>
<Link to={`${baseUrl}/${index}`}>
<Box display='flex'>
<Icon color='blue' icon='Chat' />
<Text color='blue' ml={1}>{node.children.size}</Text>
</Box>
</Link>
</Row>
</Box>
);
};

View File

@ -41,7 +41,6 @@ export const CommentItem = (props) => {
contact={contact}
color={color}
sigilClass={sigilClass}
association={association}
group={group}
hideAvatars={hideAvatars}
hideNicknames={hideNicknames}

View File

@ -1,76 +0,0 @@
import React from 'react';
import { Row, Col, Anchor, Box, Text, BaseImage } from '@tlon/indigo-react';
import { Sigil } from '~/logic/lib/sigil';
import { Link } from 'react-router-dom';
import { cite } from '~/logic/lib/util';
import { roleForShip } from '~/logic/lib/group';
export const LinkItem = (props) => {
const {
node,
nickname,
avatar,
resource,
hideAvatars,
hideNicknames,
api,
group
} = props;
const URLparser = new RegExp(
/((?:([\w\d\.-]+)\:\/\/?){1}(?:(www)\.?){0,1}(((?:[\w\d-]+\.)*)([\w\d-]+\.[\w\d]+))){1}(?:\:(\d+)){0,1}((\/(?:(?:[^\/\s\?]+\/)*))(?:([^\?\/\s#]+?(?:.[^\?\s]+){0,1}){0,1}(?:\?([^\s#]+)){0,1})){0,1}(?:#([^#\s]+)){0,1}/
);
const author = node.post.author;
const index = node.post.index.split('/')[1];
const size = node.children ? node.children.size : 0;
const contents = node.post.contents;
const hostname = URLparser.exec(contents[1].url) ? URLparser.exec(contents[1].url)[4] : null;
const showAvatar = avatar && !hideAvatars;
const showNickname = nickname && !hideNicknames;
const img = showAvatar
? <BaseImage display='inline-block' src={props.avatar} height={36} width={36} />
: <Sigil ship={`~${author}`} size={36} color={'#' + props.color} />;
const baseUrl = props.baseUrl || `/~404/${resource}`;
const ourRole = group ? roleForShip(group, window.ship) : undefined;
const [ship, name] = resource.split('/');
return (
<Row minWidth='0' flexShrink='0' width="100%" alignItems="center" py={3} bg="white">
{img}
<Col minWidth='0' height="100%" width='100%' justifyContent="space-between" ml={2}>
<Anchor
lineHeight="tall"
display='flex'
style={{ textDecoration: 'none' }}
href={contents[1].url}
width="100%"
target="_blank"
rel="noopener noreferrer"
>
<Text display='inline-block' overflow='hidden' style={{ textOverflow: 'ellipsis', whiteSpace: 'pre' }}>{contents[0].text}</Text>
<Text ml="2" color="gray" display='inline-block' flexShrink='0'>{hostname} </Text>
</Anchor>
<Box width="100%">
<Text
fontFamily={showNickname ? 'sans' : 'mono'} pr={2}
>
{showNickname ? nickname : cite(author) }
</Text>
<Link to={`${baseUrl}/${index}`}>
<Text color="gray">{size} comment{size > 1 ? 's' : null}</Text>
</Link>
{(ourRole === 'admin' || node.post.author === window.ship)
&& (<Text color='red' ml='2' cursor='pointer' onClick={() => api.graph.removeNodes(`~${ship}`, name, [node.post.index])}>Delete</Text>)}
</Box>
</Col>
</Row>
);
};

View File

@ -9,7 +9,7 @@ import { Comments } from "~/views/components/Comments";
import { NoteNavigation } from "./NoteNavigation";
import GlobalApi from "~/logic/api/global";
import { getLatestRevision, getComments } from '~/logic/lib/publish';
import { Author } from "./Author";
import Author from "~/views/components/Author";
import { Contacts, GraphNode, Graph, LocalUpdateRemoteContentPolicy } from "~/types";
interface NoteProps {

View File

@ -1,28 +1,32 @@
import React, {ReactNode} from "react";
import moment from "moment";
import { Sigil } from "~/logic/lib/sigil"
import { uxToHex, cite } from "~/logic/lib/util";
import { Contacts } from "~/types/contact-update";
import { Row, Box } from "@tlon/indigo-react";
import { Sigil } from "~/logic/lib/sigil"
import { uxToHex, cite } from "~/logic/lib/util";
import { Contacts, Rolodex } from "~/types/contact-update";
import OverlaySigil from "./OverlaySigil";
import { Group, Association, LocalUpdateRemoteContentPolicy } from "~/types";
interface AuthorProps {
contacts: Contacts;
contacts: Rolodex;
ship: string;
date: number;
showImage?: boolean;
hideAvatars: boolean;
hideNicknames: boolean;
children?: ReactNode;
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
group: Group;
}
export function Author(props: AuthorProps) {
const { contacts, ship = '', date, showImage } = props;
export default function Author(props: AuthorProps) {
const { contacts, ship = '', date, showImage, hideAvatars, hideNicknames, remoteContentPolicy, group, api } = props;
let contact = null;
if (contacts) {
contact = ship in contacts ? contacts[ship] : null;
}
const color = contact?.color ? `#${uxToHex(contact?.color)}` : "#000000";
const showAvatar = !props.hideAvatars && contact?.avatar;
const showNickname = !props.hideNicknames && contact?.nickname;
const name = showNickname ? contact?.nickname : cite(ship);
@ -31,18 +35,19 @@ export function Author(props: AuthorProps) {
<Row alignItems="center" width="auto">
{showImage && (
<Box>
{showAvatar ? (
<img src={contact?.avatar} height={16} width={16} className="dib" />
) : (
<Sigil
<OverlaySigil
ship={ship}
size={16}
icon
padded
contact={contact}
color={color}
classes={contact?.color ? '' : "mix-blend-diff"}
sigilClass={''}
group={group}
hideAvatars={hideAvatars}
hideNicknames={hideNicknames}
scrollWindow={document.createElement('div')}
history={history}
api={api}
className="fl v-top pt1"
/>
)}
</Box>
)}
<Box

View File

@ -1,13 +1,13 @@
import React from 'react';
import React, { useState } from 'react';
import { Link } from "react-router-dom";
import { Contacts } from '~/types/contact-update';
import GlobalApi from '~/logic/api/global';
import { Box, Row, Text } from '@tlon/indigo-react';
import styled from 'styled-components';
import { Author } from '~/views/apps/publish/components/Author';
import Author from '~/views/components/Author';
import { GraphNode, TextContent } from '~/types/graph-update';
import tokenizeMessage from '~/logic/lib/tokenizeMessage';
import { LocalUpdateRemoteContentPolicy } from '~/types';
import { LocalUpdateRemoteContentPolicy, Group } from '~/types';
import { MentionText } from '~/views/components/MentionText';
import { getLatestCommentRevision } from '~/logic/lib/publish';
@ -27,10 +27,11 @@ interface CommentItemProps {
hideNicknames: boolean;
hideAvatars: boolean;
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
group: Group;
}
export function CommentItem(props: CommentItemProps) {
const { ship, contacts, name, api, remoteContentPolicy, comment } = props;
const { ship, contacts, name, api, remoteContentPolicy, comment, group } = props;
const [revNum, post] = getLatestCommentRevision(comment);
const disabled = props.pending || window.ship !== post?.author;
@ -52,6 +53,9 @@ export function CommentItem(props: CommentItemProps) {
date={post?.['time-sent']}
hideAvatars={props.hideAvatars}
hideNicknames={props.hideNicknames}
remoteContentPolicy={remoteContentPolicy}
group={group}
api={api}
>
{!disabled && (
<Box display="inline-block" verticalAlign="middle">

View File

@ -9,7 +9,7 @@ import { FormikHelpers } from 'formik';
import { GraphNode } from '~/types/graph-update';
import { createPost, createBlankNodeWithChildPost } from '~/logic/api/graph';
import { getLatestCommentRevision } from '~/logic/lib/publish';
import { LocalUpdateRemoteContentPolicy } from '~/types';
import { LocalUpdateRemoteContentPolicy, Group } from '~/types';
import { scanForMentions } from '~/logic/lib/graph';
interface CommentsProps {
@ -23,10 +23,11 @@ interface CommentsProps {
hideAvatars: boolean;
hideNicknames: boolean;
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
group: Group;
}
export function Comments(props: CommentsProps) {
const { comments, ship, name, api, baseUrl, history} = props;
const { comments, ship, name, api, baseUrl, history, group } = props;
const onSubmit = async (
{ comment },

View File

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react';
import { Sigil } from '~/logic/lib/sigil';
import { Contact, Association, Group } from '~/types';
import { Contact, Group } from '~/types';
import {
ProfileOverlay,
@ -14,7 +14,6 @@ interface OverlaySigilProps {
contact?: Contact;
color: string;
sigilClass: string;
association: Association;
group: Group;
hideAvatars: boolean;
hideNicknames: boolean;
@ -108,7 +107,6 @@ export default class OverlaySigil extends PureComponent<OverlaySigilProps, Overl
color={props.color}
topSpace={state.topSpace}
bottomSpace={state.bottomSpace}
association={props.association}
group={props.group}
onDismiss={this.profileHide}
hideAvatars={hideAvatars}

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import { Contact, Association, Group } from '~/types';
import { Contact, Group } from '~/types';
import { cite } from '~/logic/lib/util';
import { Sigil } from '~/logic/lib/sigil';
@ -14,7 +14,6 @@ interface ProfileOverlayProps {
color: string;
topSpace: number;
bottomSpace: number;
association: Association;
group: Group;
onDismiss(): void;
hideAvatars: boolean;