diff --git a/packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.module.css b/packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.module.css index 4d181ad831f..bbb913ecda6 100644 --- a/packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.module.css +++ b/packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.module.css @@ -9,38 +9,61 @@ button.preview { background-color: #fff; } -.preview { - display: flex; - position: relative; +.containerCollapsed { max-width: 100%; - width: 478px; - height: 200px; - background-size: cover; - background-position: center; - border: none; - padding: 0; + width: calc(478px - 32px); + /* minus the padding */ + display: flex; + border: 1px solid var(--cpd-color-border-interactive-primary); + border-radius: 12px; + /* Get radius from cpd */ + flex-direction: row; + color: var(--cpd-color-gray-900); + overflow: clip; + gap: 8px; + padding: 12px 16px; - .playButton[data-kind="primary"] { - padding: 0; - width: 50px; - height: 50px; - margin: auto; - background: var(--cpd-color-text-on-solid-primary); - > svg { - margin: auto; - border-radius: 50px; - color: var(--cpd-color-icon-primary); - } + background: var(--cpd-color-bg-subtle-secondary); + + .textContent { + display: flex; + flex-direction: column; + } + + .preview { + width: 40px; + height: 40px; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + border-radius: 8px; + border: none; + flex-shrink: 0; + } + + .siteName { + line-height: 17.5px; + } + + .title, + .siteName>span { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + line-clamp: 1; + overflow: hidden; + min-width: 0; } } -.container { +.containerExpanded { box-sizing: border-box; max-width: 100%; width: 478px; display: flex; border: 1px solid var(--cpd-color-border-interactive-secondary); - border-radius: 12px; /* Get radius from cpd */ + border-radius: 12px; + /* Get radius from cpd */ flex-direction: column; color: var(--cpd-color-gray-900); overflow: clip; @@ -67,9 +90,11 @@ button.preview { .textContent { padding: var(--cpd-space-3x) var(--cpd-space-4x); + &.inline { padding: 0; } + display: flex; flex-direction: column; gap: var(--cpd-space-1x); @@ -78,20 +103,59 @@ button.preview { .caption { display: inline-flex; flex-direction: column; - min-width: 0; /* Prevent blowout */ + min-width: 0; + /* Prevent blowout */ } + .caption { flex: 1; - overflow: hidden; /* cause it to wrap rather than clip */ + overflow: hidden; + /* cause it to wrap rather than clip */ + } + + .preview { + display: flex; + position: relative; + max-width: 100%; + width: 478px; + height: 200px; + background-size: cover; + background-position: center; + border: none; + padding: 0; + + .playButton[data-kind="primary"] { + padding: 0; + width: 50px; + height: 50px; + margin: auto; + background: var(--cpd-color-text-on-solid-primary); + + >svg { + margin: auto; + border-radius: 50px; + color: var(--cpd-color-icon-primary); + } + } + } + + .siteName { + margin-top: var(--cpd-space-1x); + } + + .title, + .description { + line-clamp: 2; + -webkit-line-clamp: 2; } } .siteName { - margin-top: var(--cpd-space-1x); vertical-align: middle; display: flex; gap: var(--cpd-space-1-5x); - > * { + + >* { /* Center everything */ margin: auto 0; } @@ -103,8 +167,6 @@ button.preview { -webkit-box-orient: vertical; overflow: hidden; white-space: normal; - line-clamp: 2; - -webkit-line-clamp: 2; margin: 0; } diff --git a/packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.tsx b/packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.tsx index d8cfc6cec2b..a20f020f1a6 100644 --- a/packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.tsx +++ b/packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.tsx @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -import React, { type MouseEventHandler, type JSX, useCallback } from "react"; +import React, { type JSX } from "react"; import { Tooltip, Text, Avatar, Button } from "@vector-im/compound-web"; import PlaySolidIcon from "@vector-im/compound-design-tokens/assets/web/icons/play-solid"; import classNames from "classnames"; @@ -19,7 +19,7 @@ export interface LinkPreviewActions { onImageClick: () => void; } -export type LinkPreviewProps = UrlPreview & LinkPreviewActions; +export type LinkPreviewProps = UrlPreview & LinkPreviewActions & { collapsed: boolean }; export function LinkTitle({ title, @@ -66,7 +66,7 @@ function LinkPreviewInline({ link, }: Omit): JSX.Element { return ( -
+
{siteIcon && (
@@ -84,21 +84,56 @@ function LinkPreviewInline({ * LinkPreview renders a single preview component for a single link on an event. It is usually rendered as part of * a `UrlPreviewGroupView`. */ -export function LinkPreview({ onImageClick, ...preview }: LinkPreviewProps): JSX.Element { +export function LinkPreview(props: LinkPreviewProps): JSX.Element { + if (props.collapsed) { + return ; + } else { + return ; + } +} + +function createImageClickHandler({ onImageClick, ...preview }: LinkPreviewProps): React.MouseEventHandler { + return (ev) => { + if (ev.button != 0 || ev.metaKey) return; + ev.preventDefault(); + + if (!preview.image?.imageFull) { + return; + } + onImageClick(); + }; +} + +export function LinkPreviewCollapsed(preview: LinkPreviewProps): JSX.Element { const { translate: _t } = useI18n(); + let img: JSX.Element | undefined; + + if (preview.image && !preview.image.playable) { + img = ( +