Add URL preview (#1511)

* URL preview - WIP

* fix url preview regex

* update url match regex

* add url preview components

* add scroll btn url preview holder

* add message body component

* add url preview toggle in settings

* update url regex

* improve url regex

* increase thumbnail size in url preview

* hide url preview in encrypted rooms

* add encrypted room url preview toggle
This commit is contained in:
Ajay Bura 2023-10-30 07:14:58 +11:00 committed by GitHub
parent a98903a85b
commit 9f9173c691
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 444 additions and 42 deletions

View file

@ -1,5 +1,5 @@
import React from 'react';
import { as } from 'folds';
import { Text, as } from 'folds';
import classNames from 'classnames';
import * as css from './layout.css';
@ -23,3 +23,16 @@ export const AvatarBase = as<'span'>(({ className, ...props }, ref) => (
export const Username = as<'span'>(({ as: AsUsername = 'span', className, ...props }, ref) => (
<AsUsername className={classNames(css.Username, className)} {...props} ref={ref} />
));
export const MessageTextBody = as<'div', css.MessageTextBodyVariants & { notice?: boolean }>(
({ as: asComp = 'div', className, preWrap, jumboEmoji, emote, notice, ...props }, ref) => (
<Text
as={asComp}
size="T400"
priority={notice ? '300' : '400'}
className={classNames(css.MessageTextBody({ preWrap, jumboEmoji, emote }), className)}
{...props}
ref={ref}
/>
)
);

View file

@ -153,3 +153,30 @@ export const Username = style({
},
},
});
export const MessageTextBody = recipe({
base: {
wordBreak: 'break-word',
},
variants: {
preWrap: {
true: {
whiteSpace: 'pre-wrap',
},
},
jumboEmoji: {
true: {
fontSize: '1.504em',
lineHeight: '1.4962em',
},
},
emote: {
true: {
color: color.Success.Main,
fontStyle: 'italic',
},
},
},
});
export type MessageTextBodyVariants = RecipeVariants<typeof MessageTextBody>;

View file

@ -0,0 +1,45 @@
import { style } from '@vanilla-extract/css';
import { DefaultReset, color, config, toRem } from 'folds';
export const UrlPreview = style([
DefaultReset,
{
width: toRem(400),
minHeight: toRem(102),
backgroundColor: color.SurfaceVariant.Container,
color: color.SurfaceVariant.OnContainer,
border: `${config.borderWidth.B300} solid ${color.SurfaceVariant.ContainerLine}`,
borderRadius: config.radii.R300,
overflow: 'hidden',
},
]);
export const UrlPreviewImg = style([
DefaultReset,
{
width: toRem(100),
height: toRem(100),
objectFit: 'cover',
objectPosition: 'left',
backgroundPosition: 'start',
flexShrink: 0,
overflow: 'hidden',
},
]);
export const UrlPreviewContent = style([
DefaultReset,
{
padding: config.space.S200,
},
]);
export const UrlPreviewDescription = style([
DefaultReset,
{
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
},
]);

View file

@ -0,0 +1,27 @@
import React from 'react';
import classNames from 'classnames';
import { Box, as } from 'folds';
import * as css from './UrlPreview.css';
export const UrlPreview = as<'div'>(({ className, ...props }, ref) => (
<Box shrink="No" className={classNames(css.UrlPreview, className)} {...props} ref={ref} />
));
export const UrlPreviewImg = as<'img'>(({ className, alt, ...props }, ref) => (
<img className={classNames(css.UrlPreviewImg, className)} alt={alt} {...props} ref={ref} />
));
export const UrlPreviewContent = as<'div'>(({ className, ...props }, ref) => (
<Box
grow="Yes"
direction="Column"
gap="100"
className={classNames(css.UrlPreviewContent, className)}
{...props}
ref={ref}
/>
));
export const UrlPreviewDescription = as<'span'>(({ className, ...props }, ref) => (
<span className={classNames(css.UrlPreviewDescription, className)} {...props} ref={ref} />
));

View file

@ -0,0 +1 @@
export * from './UrlPreview';