Add link modal and fix input (#67)

This commit is contained in:
Szymon Szlachtowicz 2021-10-12 14:58:28 +02:00 committed by GitHub
parent 2a38552281
commit 7bb7f059b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 7 deletions

View File

@ -56,7 +56,7 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
setContent(""); setContent("");
} }
}, },
[] [content, imageUint]
); );
return ( return (

View File

@ -15,12 +15,14 @@ type ChatMessageContentProps = {
message: ChatMessage; message: ChatMessage;
fetchMetadata?: (url: string) => Promise<Metadata | undefined>; fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
setImage: (image: string) => void; setImage: (image: string) => void;
setLinkOpen: (link: string) => void;
}; };
export function ChatMessageContent({ export function ChatMessageContent({
message, message,
fetchMetadata, fetchMetadata,
setImage, setImage,
setLinkOpen,
}: ChatMessageContentProps) { }: ChatMessageContentProps) {
const { content, image } = useMemo(() => message, [message]); const { content, image } = useMemo(() => message, [message]);
const [elements, setElements] = useState<(string | React.ReactElement)[]>([ const [elements, setElements] = useState<(string | React.ReactElement)[]>([
@ -40,7 +42,7 @@ export function ChatMessageContent({
? match ? match
: "https://" + match; : "https://" + match;
newSplit.push( newSplit.push(
<Link key={idx} href={link} target="_blank" rel="noopener noreferrer"> <Link key={idx} onClick={() => setLinkOpen(link)}>
{match} {match}
</Link>, </Link>,
split[idx + 1] split[idx + 1]
@ -88,9 +90,7 @@ export function ChatMessageContent({
</MessageImageWrapper> </MessageImageWrapper>
)} )}
{openGraph && ( {openGraph && (
<PreviewWrapper <PreviewWrapper onClick={() => setLinkOpen(link ?? "")}>
onClick={() => window?.open(link, "_blank", "noopener")?.focus()}
>
<PreviewImage src={decodeURI(decode(openGraph["og:image"]))} /> <PreviewImage src={decodeURI(decode(openGraph["og:image"]))} />
<PreviewTitleWrapper>{openGraph["og:title"]}</PreviewTitleWrapper> <PreviewTitleWrapper>{openGraph["og:title"]}</PreviewTitleWrapper>
<PreviewSiteNameWrapper> <PreviewSiteNameWrapper>
@ -167,7 +167,7 @@ const ContentWrapper = styled.div`
flex-direction: column; flex-direction: column;
`; `;
const Link = styled.a` const Link = styled.div`
text-decoration: underline; text-decoration: underline;
color: ${({ theme }) => theme.memberNameColor}; color: ${({ theme }) => theme.memberNameColor};
`; `;

View File

@ -5,6 +5,7 @@ import { ChatMessage } from "../../models/ChatMessage";
import { Metadata } from "../../models/Metadata"; import { Metadata } from "../../models/Metadata";
import { LoadingIcon } from "../Icons/LoadingIcon"; import { LoadingIcon } from "../Icons/LoadingIcon";
import { UserIcon } from "../Icons/UserIcon"; import { UserIcon } from "../Icons/UserIcon";
import { LinkModal } from "../Modals/LinkModal";
import { PictureModal } from "../Modals/PictureModal"; import { PictureModal } from "../Modals/PictureModal";
import { textSmallStyles } from "../Text"; import { textSmallStyles } from "../Text";
@ -53,7 +54,7 @@ export function ChatMessages({
}, [ref, scrollOnBot]); }, [ref, scrollOnBot]);
const [image, setImage] = useState(""); const [image, setImage] = useState("");
const [link, setLink] = useState("");
return ( return (
<MessagesWrapper ref={ref}> <MessagesWrapper ref={ref}>
<PictureModal <PictureModal
@ -61,6 +62,7 @@ export function ChatMessages({
onClose={() => setImage("")} onClose={() => setImage("")}
image={image} image={image}
/> />
<LinkModal isVisible={!!link} onClose={() => setLink("")} link={link} />
<LoadingWrapper> <LoadingWrapper>
<LoadingIcon className="message" /> <LoadingIcon className="message" />
</LoadingWrapper> </LoadingWrapper>
@ -93,6 +95,7 @@ export function ChatMessages({
message={message} message={message}
fetchMetadata={fetchMetadata} fetchMetadata={fetchMetadata}
setImage={setImage} setImage={setImage}
setLinkOpen={setLink}
/> />
</MessageText> </MessageText>
</ContentWrapper> </ContentWrapper>

View File

@ -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;
`;