mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 13:54:20 +03:00
interface: build in mentions FE support
This commit is contained in:
parent
26f2e9e951
commit
94f787d120
@ -3,10 +3,10 @@ import { StoreState } from '../store/type';
|
||||
import { Patp, Path, PatpNoSig } from '~/types/noun';
|
||||
import _ from 'lodash';
|
||||
import {makeResource, resourceFromPath} from '../lib/group';
|
||||
import {GroupPolicy, Enc, Post, NodeMap} from '~/types';
|
||||
import {GroupPolicy, Enc, Post, NodeMap, Content} from '~/types';
|
||||
import { numToUd, unixToDa } from '~/logic/lib/util';
|
||||
|
||||
export const createPost = (contents: Object[], parentIndex: string = '') => {
|
||||
export const createPost = (contents: Content[], parentIndex: string = '') => {
|
||||
return {
|
||||
author: `~${window.ship}`,
|
||||
index: parentIndex + '/' + unixToDa(Date.now()).toString(),
|
||||
|
24
pkg/interface/src/logic/lib/graph.ts
Normal file
24
pkg/interface/src/logic/lib/graph.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Content } from "~/types";
|
||||
import urbitOb from "urbit-ob";
|
||||
|
||||
export function scanForMentions(text: string) {
|
||||
const regex = /~([a-z]|-)+/g;
|
||||
let result: Content[] = [];
|
||||
let match: RegExpExecArray | null;
|
||||
let lastPos = 0;
|
||||
while ((match = regex.exec(text)) !== null) {
|
||||
const newPos = match.index + match[0].length;
|
||||
if (urbitOb.isValidPatp(match[0])) {
|
||||
if (match.index !== lastPos) {
|
||||
result.push({ text: text.slice(lastPos, match.index) });
|
||||
}
|
||||
result.push({ mention: match[0] });
|
||||
}
|
||||
lastPos = newPos;
|
||||
}
|
||||
const remainder = text.slice(lastPos, text.length);
|
||||
if (remainder) {
|
||||
result.push({ text: remainder });
|
||||
}
|
||||
return result;
|
||||
}
|
@ -1,12 +1,28 @@
|
||||
import { Patp } from "./noun";
|
||||
import { BigIntOrderedMap } from "~/logic/lib/BigIntOrderedMap";
|
||||
|
||||
|
||||
export interface TextContent { text: string; };
|
||||
export interface UrlContent { url: string; }
|
||||
export interface CodeContent { expresssion: string; output: string; };
|
||||
export interface ReferenceContent { uid: string; }
|
||||
export type Content = TextContent | UrlContent | CodeContent | ReferenceContent;
|
||||
export interface TextContent {
|
||||
text: string;
|
||||
}
|
||||
export interface UrlContent {
|
||||
url: string;
|
||||
}
|
||||
export interface CodeContent {
|
||||
expresssion: string;
|
||||
output: string;
|
||||
}
|
||||
export interface ReferenceContent {
|
||||
uid: string;
|
||||
}
|
||||
export interface MentionContent {
|
||||
mention: string;
|
||||
}
|
||||
export type Content =
|
||||
| TextContent
|
||||
| UrlContent
|
||||
| CodeContent
|
||||
| ReferenceContent
|
||||
| MentionContent;
|
||||
|
||||
export interface Post {
|
||||
author: Patp;
|
||||
@ -15,10 +31,9 @@ export interface Post {
|
||||
index: string;
|
||||
pending?: boolean;
|
||||
signatures: string[];
|
||||
'time-sent': number;
|
||||
"time-sent": number;
|
||||
}
|
||||
|
||||
|
||||
export interface GraphNode {
|
||||
children: Graph;
|
||||
post: Post;
|
||||
@ -27,5 +42,3 @@ export interface GraphNode {
|
||||
export type Graph = BigIntOrderedMap<GraphNode>;
|
||||
|
||||
export type Graphs = { [rid: string]: Graph };
|
||||
|
||||
|
||||
|
51
pkg/interface/src/views/components/MentionText.tsx
Normal file
51
pkg/interface/src/views/components/MentionText.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import React from "react";
|
||||
import _ from "lodash";
|
||||
import { Text } from "@tlon/indigo-react";
|
||||
import { Contacts, Content, LocalUpdateRemoteContentPolicy } from "~/types";
|
||||
import RichText from "~/views/components/RichText";
|
||||
import { cite } from "~/logic/lib/util";
|
||||
|
||||
interface MentionTextProps {
|
||||
contacts: Contacts;
|
||||
content: Content[];
|
||||
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
|
||||
}
|
||||
export function MentionText(props: MentionTextProps) {
|
||||
const { content, contacts } = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
{_.map(content, (c, idx) => {
|
||||
if ("text" in c) {
|
||||
return (
|
||||
<RichText
|
||||
inline
|
||||
key={idx}
|
||||
remoteContentPolicy={props.remoteContentPolicy}
|
||||
>
|
||||
{c.text}
|
||||
</RichText>
|
||||
);
|
||||
} else if ("mention" in c) {
|
||||
return (
|
||||
<Mention key={idx} contacts={contacts || {}} ship={c.mention} />
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Mention(props: { ship: string; contacts: Contacts }) {
|
||||
const { contacts, ship } = props;
|
||||
const contact = contacts[ship];
|
||||
const showNickname = !!contact?.nickname;
|
||||
const name = showNickname ? contact?.nickname : cite(ship);
|
||||
|
||||
return (
|
||||
<Text mx="2px" px="2px" bg="washedBlue" color="blue" mono={!showNickname}>
|
||||
{name}
|
||||
</Text>
|
||||
);
|
||||
}
|
@ -30,7 +30,7 @@ const RichText = React.memo(({ remoteContentPolicy, ...props }) => (
|
||||
return <BaseAnchor target='_blank' rel='noreferrer noopener' borderBottom='1px solid' {...props}>{props.children}</BaseAnchor>;
|
||||
},
|
||||
paragraph: (paraProps) => {
|
||||
return <Text display='block' mb='2' {...props}>{paraProps.children}</Text>;
|
||||
return <Text display={props.inline ? 'inline' : 'block'} mb='2' {...props}>{paraProps.children}</Text>;
|
||||
}
|
||||
}}
|
||||
plugins={[[
|
||||
|
Loading…
Reference in New Issue
Block a user