Add link modal and fix input (#67)
This commit is contained in:
parent
2a38552281
commit
7bb7f059b8
|
@ -56,7 +56,7 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
|
|||
setContent("");
|
||||
}
|
||||
},
|
||||
[]
|
||||
[content, imageUint]
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -15,12 +15,14 @@ type ChatMessageContentProps = {
|
|||
message: ChatMessage;
|
||||
fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
|
||||
setImage: (image: string) => void;
|
||||
setLinkOpen: (link: string) => void;
|
||||
};
|
||||
|
||||
export function ChatMessageContent({
|
||||
message,
|
||||
fetchMetadata,
|
||||
setImage,
|
||||
setLinkOpen,
|
||||
}: ChatMessageContentProps) {
|
||||
const { content, image } = useMemo(() => message, [message]);
|
||||
const [elements, setElements] = useState<(string | React.ReactElement)[]>([
|
||||
|
@ -40,7 +42,7 @@ export function ChatMessageContent({
|
|||
? match
|
||||
: "https://" + match;
|
||||
newSplit.push(
|
||||
<Link key={idx} href={link} target="_blank" rel="noopener noreferrer">
|
||||
<Link key={idx} onClick={() => setLinkOpen(link)}>
|
||||
{match}
|
||||
</Link>,
|
||||
split[idx + 1]
|
||||
|
@ -88,9 +90,7 @@ export function ChatMessageContent({
|
|||
</MessageImageWrapper>
|
||||
)}
|
||||
{openGraph && (
|
||||
<PreviewWrapper
|
||||
onClick={() => window?.open(link, "_blank", "noopener")?.focus()}
|
||||
>
|
||||
<PreviewWrapper onClick={() => setLinkOpen(link ?? "")}>
|
||||
<PreviewImage src={decodeURI(decode(openGraph["og:image"]))} />
|
||||
<PreviewTitleWrapper>{openGraph["og:title"]}</PreviewTitleWrapper>
|
||||
<PreviewSiteNameWrapper>
|
||||
|
@ -167,7 +167,7 @@ const ContentWrapper = styled.div`
|
|||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const Link = styled.a`
|
||||
const Link = styled.div`
|
||||
text-decoration: underline;
|
||||
color: ${({ theme }) => theme.memberNameColor};
|
||||
`;
|
||||
|
|
|
@ -5,6 +5,7 @@ import { ChatMessage } from "../../models/ChatMessage";
|
|||
import { Metadata } from "../../models/Metadata";
|
||||
import { LoadingIcon } from "../Icons/LoadingIcon";
|
||||
import { UserIcon } from "../Icons/UserIcon";
|
||||
import { LinkModal } from "../Modals/LinkModal";
|
||||
import { PictureModal } from "../Modals/PictureModal";
|
||||
import { textSmallStyles } from "../Text";
|
||||
|
||||
|
@ -53,7 +54,7 @@ export function ChatMessages({
|
|||
}, [ref, scrollOnBot]);
|
||||
|
||||
const [image, setImage] = useState("");
|
||||
|
||||
const [link, setLink] = useState("");
|
||||
return (
|
||||
<MessagesWrapper ref={ref}>
|
||||
<PictureModal
|
||||
|
@ -61,6 +62,7 @@ export function ChatMessages({
|
|||
onClose={() => setImage("")}
|
||||
image={image}
|
||||
/>
|
||||
<LinkModal isVisible={!!link} onClose={() => setLink("")} link={link} />
|
||||
<LoadingWrapper>
|
||||
<LoadingIcon className="message" />
|
||||
</LoadingWrapper>
|
||||
|
@ -93,6 +95,7 @@ export function ChatMessages({
|
|||
message={message}
|
||||
fetchMetadata={fetchMetadata}
|
||||
setImage={setImage}
|
||||
setLinkOpen={setLink}
|
||||
/>
|
||||
</MessageText>
|
||||
</ContentWrapper>
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { textMediumStyles } from "../Text";
|
||||
|
||||
import { BasicModalProps, Modal } from "./Modal";
|
||||
|
||||
interface LinkModalProps extends BasicModalProps {
|
||||
link: string;
|
||||
}
|
||||
|
||||
export const LinkModal = ({ isVisible, onClose, link }: LinkModalProps) => {
|
||||
return (
|
||||
<Modal isVisible={isVisible} onClose={onClose}>
|
||||
<Section>
|
||||
<Text>Are you sure you want to visit {link}</Text>
|
||||
</Section>
|
||||
<ButtonSection>
|
||||
<ButtonNo onClick={onClose}>No</ButtonNo>
|
||||
<ButtonYes
|
||||
onClick={() => {
|
||||
window?.open(link, "_blank", "noopener")?.focus();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
Yes
|
||||
</ButtonYes>
|
||||
</ButtonSection>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const ButtonSection = styled.div`
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
const Section = styled.div`
|
||||
padding: 20px 16px;
|
||||
|
||||
& + & {
|
||||
border-top: 1px solid ${({ theme }) => theme.border};
|
||||
}
|
||||
`;
|
||||
|
||||
const Text = styled.p`
|
||||
color: ${({ theme }) => theme.primary};
|
||||
|
||||
${textMediumStyles}
|
||||
`;
|
||||
|
||||
const ButtonYes = styled.button`
|
||||
background-color: ${({ theme }) => theme.tertiary};
|
||||
padding: 10px;
|
||||
width: 50px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
`;
|
||||
|
||||
const ButtonNo = styled.button`
|
||||
background-color: ${({ theme }) => theme.secondary};
|
||||
padding: 10px;
|
||||
width: 50px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
`;
|
Loading…
Reference in New Issue