diff --git a/pkg/interface/src/logic/lib/useModal.tsx b/pkg/interface/src/logic/lib/useModal.tsx index 83b30ecc58..e2a10c143f 100644 --- a/pkg/interface/src/logic/lib/useModal.tsx +++ b/pkg/interface/src/logic/lib/useModal.tsx @@ -11,6 +11,7 @@ import React, { import { Box } from "@tlon/indigo-react"; import { useOutsideClick } from "./useOutsideClick"; import { ModalOverlay } from "~/views/components/ModalOverlay"; +import {Portal} from "~/views/components/Portal"; type ModalFunc = (dismiss: () => void) => JSX.Element; interface UseModalProps { @@ -48,7 +49,8 @@ export function useModal(props: UseModalProps): UseModalResult { const modal = useMemo( () => - !inner ? null : ( + !inner ? null : ( + {inner} + ), [inner, dismiss] ); diff --git a/pkg/interface/src/views/apps/chat/ChatResource.tsx b/pkg/interface/src/views/apps/chat/ChatResource.tsx index 34c512f7c6..c75ceb18f8 100644 --- a/pkg/interface/src/views/apps/chat/ChatResource.tsx +++ b/pkg/interface/src/views/apps/chat/ChatResource.tsx @@ -111,6 +111,8 @@ export function ChatResource(props: ChatResourceProps) { envelopes={[]} contacts={contacts} association={props.association} + associations={props.associations} + groups={props.groups} group={group} ship={owner} station={station} diff --git a/pkg/interface/src/views/apps/chat/components/ChatMessage.tsx b/pkg/interface/src/views/apps/chat/components/ChatMessage.tsx index e19544d477..4744bab369 100644 --- a/pkg/interface/src/views/apps/chat/components/ChatMessage.tsx +++ b/pkg/interface/src/views/apps/chat/components/ChatMessage.tsx @@ -17,7 +17,7 @@ import { useShowNickname, useHovering } from '~/logic/lib/util'; -import { Group, Association, Contacts, Post } from '~/types'; +import { Group, Association, Contacts, Post, Groups, Associations } from '~/types'; import TextContent from './content/text'; import CodeContent from './content/code'; import RemoteContent from '~/views/components/RemoteContent'; @@ -108,7 +108,9 @@ export default class ChatMessage extends Component { history, api, highlighted, - fontSize + fontSize, + groups, + associations } = this.props; const renderSigil = Boolean( @@ -145,7 +147,9 @@ export default class ChatMessage extends Component { api, scrollWindow, highlighted, - fontSize + fontSize, + associations, + groups, }; const unreadContainerStyle = { @@ -206,6 +210,8 @@ interface MessageProps { style: any; measure(element): void; scrollWindow: HTMLDivElement; + associations: Associations; + groups: Groups; } export const MessageWithSigil = (props) => { @@ -214,6 +220,8 @@ export const MessageWithSigil = (props) => { timestamp, contacts, association, + associations, + groups, group, measure, api, @@ -355,6 +363,9 @@ export const MessageWithSigil = (props) => { scrollWindow={scrollWindow} fontSize={fontSize} group={group} + api={api} + associations={associations} + groups={groups} /> ))} @@ -375,6 +386,9 @@ export const MessageWithoutSigil = ({ msg, measure, group, + api, + associations, + groups, scrollWindow }) => { const { hovering, bind } = useHovering(); @@ -409,6 +423,9 @@ export const MessageWithoutSigil = ({ group={group} measure={measure} scrollWindow={scrollWindow} + groups={groups} + associations={associations} + api={api} /> ))} @@ -419,6 +436,9 @@ export const MessageWithoutSigil = ({ export const MessageContent = ({ content, contacts, + api, + associations, + groups, measure, scrollWindow, fontSize, @@ -461,7 +481,15 @@ export const MessageContent = ({ ); } else if ('text' in content) { - return ; + return ( + ); } else if ('mention' in content) { return ( ( plugins={[RemarkBreaks]} /> )); +export default function TextContent(props) { + const content = props.content; -export default class TextContent extends Component { + const group = content.text.match( + /([~][/])?(~[a-z]{3,6})(-[a-z]{6})?([/])(([a-z0-9-])+([/-])?)+/ + ); + const isGroupLink = ((group !== null) // matched possible chatroom + && (group[2].length > 2) // possible ship? + && (urbitOb.isValidPatp(group[2]) // valid patp? + && (group[0] === content.text))) // entire message is room name? - render() { - const { props } = this; - const content = props.content; + console.log(isGroupLink); - const group = content.text.match( - /([~][/])?(~[a-z]{3,6})(-[a-z]{6})?([/])(([a-z0-9-])+([/-])?)+/ + if(isGroupLink) { + const resource = `/ship/${content.text}`; + return ( + + ); + } else { + return ( + + + ); - if ((group !== null) // matched possible chatroom - && (group[2].length > 2) // possible ship? - && (urbitOb.isValidPatp(group[2]) // valid patp? - && (group[0] === content.text))) { // entire message is room name? - return ( - - - {content.text} - - - ); - } else { - return ( - - - - ); - } } } diff --git a/pkg/interface/src/views/components/GroupLink.tsx b/pkg/interface/src/views/components/GroupLink.tsx new file mode 100644 index 0000000000..d1dd5bf949 --- /dev/null +++ b/pkg/interface/src/views/components/GroupLink.tsx @@ -0,0 +1,75 @@ +import React, { useEffect, useState, useLayoutEffect } from "react"; + +import { Box, Text, Row, Button, Action } from "@tlon/indigo-react"; +import GlobalApi from "~/logic/api/global"; +import { Associations, Groups } from "~/types"; +import { MetadataIcon } from "../landscape/components/MetadataIcon"; +import {JoinGroup} from "../landscape/components/JoinGroup"; +import {useModal} from "~/logic/lib/useModal"; + +export function GroupLink(props: { + api: GlobalApi; + resource: string; + associations: Associations; + groups: Groups; + measure: () => void; +}) { + const { resource, api, measure } = props; + const name = resource.slice(6); + const [preview, setPreview] = useState(null); + + const { modal, showModal } = useModal({ + modal: ( + + ) + }); + + const joined = resource in props.associations.groups; + + useEffect(() => { + (async () => { + setPreview(await api.metadata.preview(resource)); + })(); + + return () => { + setPreview(null); + }; + }, [resource]); + + useLayoutEffect(() => { + measure(); + }, [preview]); + + return ( + + {modal} + + {preview ? ( + <> + + {preview.metadata.title} + + + ) : ( + {name} + )} + + + ); +} diff --git a/pkg/interface/src/views/landscape/components/JoinGroup.tsx b/pkg/interface/src/views/landscape/components/JoinGroup.tsx index 00e5c10d16..9337caa2b3 100644 --- a/pkg/interface/src/views/landscape/components/JoinGroup.tsx +++ b/pkg/interface/src/views/landscape/components/JoinGroup.tsx @@ -45,6 +45,7 @@ interface JoinGroupProps { groups: Groups; associations: Associations; api: GlobalApi; + autojoin?: string; } function Autojoin(props: { autojoin: string | null }) {