1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-22 10:22:30 +01:00

you get a link, and you get a link, and everyone gets a link

This commit is contained in:
Puyodead1 2023-08-26 23:11:00 -04:00
parent 2db53e2765
commit 0d4ade85b5
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
2 changed files with 56 additions and 5 deletions

16
src/components/Link.tsx Normal file
View File

@ -0,0 +1,16 @@
import styled from "styled-components";
export const Link = styled.a`
// remove the default underline
text-decoration: none;
// set the color to the primary color
color: var(--primary-light);
// remove the color when already visited because ew
&:visited {
color: var(--primary-light);
}
// when hovered, add underline
&:hover {
text-decoration: underline;
}
`;

View File

@ -8,8 +8,13 @@ import { QueuedMessage } from "../../stores/MessageQueue";
import { default as MessageObject } from "../../stores/objects/Message";
import { calendarStrings } from "../../utils/i18n";
import Avatar from "../Avatar";
import { Link } from "../Link";
import { IContextMenuItem } from "./../ContextMenuItem";
// max width/height for images
const maxWidth = 400;
const maxHeight = 300;
type MessageLike = MessageObject | QueuedMessage;
const MessageListItem = styled.li`
@ -55,10 +60,6 @@ const MessageContent = styled.div<{ sending?: boolean; failed?: boolean }>`
color: ${(props) => (props.failed ? "var(--error)" : undefined)};
`;
// max width/height for images
const maxWidth = 400;
const maxHeight = 300;
function calculateImageRatio(width: number, height: number) {
let o = 1;
width > maxWidth && (o = maxWidth / width);
@ -96,6 +97,40 @@ function calculateScaledDimensions(
return { scaledWidth, scaledHeight };
}
// https://www.js-craft.io/blog/react-detect-url-text-convert-link/
const Linkify = ({ children }: { children: string }) => {
const isUrl = (word: string) => {
const urlPattern =
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
return word.match(urlPattern);
};
// const addMarkup = (word: string) => {
// return isUrl(word) ? `<a href="${word}" target="_blank" noreferer>${word}</a>` : word;
// };
// split spaces and newlines
const words = children.split(/(\s+)/);
return (
<div>
{words.map((x) => {
if (isUrl(x)) {
return (
<>
<Link href={x} target="_blank" rel="noreferrer">
{x}
</Link>{" "}
</>
);
} else {
return <>{x}</>;
}
})}
</div>
);
};
interface Props {
message: MessageLike;
isHeader?: boolean;
@ -188,7 +223,7 @@ function Message({ message, isHeader, isSending, isFailed }: Props) {
{message.type === MessageType.Default ? (
<MessageContent sending={isSending} failed={isFailed}>
{message.content}
{message.content ? <Linkify>{message.content}</Linkify> : null}
{"attachments" in message &&
message.attachments.map((attachment) => {
let a: JSX.Element = <></>;