From 9846262e8b5e50d455eeb76814efc220aed96146 Mon Sep 17 00:00:00 2001 From: Paul <paulmakles@gmail.com> Date: Sat, 10 Jul 2021 15:21:35 +0100 Subject: [PATCH] Fix attachment scaling. --- src/components/common/ChannelIcon.tsx | 1 + src/components/common/ServerIcon.tsx | 3 +- .../attachments/Attachment.module.scss | 108 ++---------------- .../messaging/attachments/Attachment.tsx | 50 +++++++- .../attachments/AttachmentActions.module.scss | 49 ++++++++ .../attachments/AttachmentActions.tsx | 2 +- .../common/messaging/attachments/Grid.tsx | 47 ++++++++ src/components/common/user/UserIcon.tsx | 2 +- .../navigation/left/ServerListSidebar.tsx | 11 +- 9 files changed, 163 insertions(+), 110 deletions(-) create mode 100644 src/components/common/messaging/attachments/AttachmentActions.module.scss create mode 100644 src/components/common/messaging/attachments/Grid.tsx diff --git a/src/components/common/ChannelIcon.tsx b/src/components/common/ChannelIcon.tsx index 9145d5f..01c48bf 100644 --- a/src/components/common/ChannelIcon.tsx +++ b/src/components/common/ChannelIcon.tsx @@ -57,6 +57,7 @@ export default function ChannelIcon( {...imgProps} width={size} height={size} + loading="lazy" aria-hidden="true" square={isServerChannel} src={iconURL ?? fallback} diff --git a/src/components/common/ServerIcon.tsx b/src/components/common/ServerIcon.tsx index 5b9dad8..168af8a 100644 --- a/src/components/common/ServerIcon.tsx +++ b/src/components/common/ServerIcon.tsx @@ -61,8 +61,9 @@ export default function ServerIcon( {...imgProps} width={size} height={size} - aria-hidden="true" src={iconURL} + loading="lazy" + aria-hidden="true" /> ); } diff --git a/src/components/common/messaging/attachments/Attachment.module.scss b/src/components/common/messaging/attachments/Attachment.module.scss index 111be64..0088878 100644 --- a/src/components/common/messaging/attachments/Attachment.module.scss +++ b/src/components/common/messaging/attachments/Attachment.module.scss @@ -3,67 +3,15 @@ grid-auto-columns: min(100%, 480px); grid-auto-flow: row dense; + margin: .125rem 0 .125rem; width: max-content; max-width: 100%; - - border-radius: 6px; - margin: .125rem 0 .125rem; &[data-spoiler="true"] { filter: blur(30px); pointer-events: none; } - &[data-has-content="true"] { - margin-top: 4px; - } - - &.image, &.video > video { - cursor: pointer; - - aspect-ratio: var(--width) / var(--height); - max-height: min(640px, var(--height-px)); - max-width: min(480px, 100%, var(--width-px)); - - object-fit: contain; - object-position: top left; - } - - &.image { - &.long { - width: min(100%, var(--width-px)); - height: auto; - } - - &.tall { - height: min(100%, var(--height-px)); - width: 100%; - - &.loaded { - width: auto; - } - } - } - - &.video { - .actions { - padding: 10px 12px; - border-radius: 6px 6px 0 0; - } - - video { - border-radius: 0 0 6px 6px; - - &.long { - height: auto; - } - - &.tall { - width: auto; - } - } - } - &.audio { gap: 4px; padding: 6px; @@ -125,52 +73,20 @@ } } -.actions.imageAction { - grid-template: - "name icon external download" auto - "size icon external download" auto - / minmax(20px, 1fr) min-content min-content; +.margin { + margin-top: 4px; } -.actions { - display: grid; - grid-template: - "icon name external download" auto - "icon size external download" auto - / min-content minmax(20px, 1fr) min-content; - - align-items: center; - column-gap: 12px; - - width: 100%; - padding: 8px; - overflow: none; - - color: var(--foreground); - background: var(--secondary-background); - - span { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } - - .filesize { - grid-area: size; - - font-size: 10px; - color: var(--secondary-foreground); - } - - .downloadIcon { - grid-area: download; - } +.container { + max-width: 100%; + overflow: hidden; + width: fit-content; - .externalType { - grid-area: external; + > :first-child { + width: min(480px, 100%, var(--width)); } +} - .iconType { - grid-area: icon; - } +.container, .attachment, .image { + border-radius: 6px; } diff --git a/src/components/common/messaging/attachments/Attachment.tsx b/src/components/common/messaging/attachments/Attachment.tsx index 1b56382..d3a9980 100644 --- a/src/components/common/messaging/attachments/Attachment.tsx +++ b/src/components/common/messaging/attachments/Attachment.tsx @@ -8,9 +8,9 @@ import { useContext, useState } from "preact/hooks"; import { useIntermediate } from "../../../../context/intermediate/Intermediate"; import { AppContext } from "../../../../context/revoltjs/RevoltClient"; -import { MessageAreaWidthContext } from "../../../../pages/channels/messaging/MessageArea"; import AttachmentActions from "./AttachmentActions"; import TextFile from "./TextFile"; +import { SizedGrid } from "./Grid"; interface Props { attachment: AttachmentRJS; @@ -35,6 +35,44 @@ export default function Attachment({ attachment, hasContent }: Props) { switch (metadata.type) { case "Image": { return ( + <SizedGrid width={metadata.width} height={metadata.height} + className={classNames({ [styles.margin]: hasContent })}> + <img src={url} alt={filename} + className={styles.image} + loading="lazy" + onClick={() => + openScreen({ id: "image_viewer", attachment }) + } + onMouseDown={(ev) => + ev.button === 1 && window.open(url, "_blank") + } /> + </SizedGrid> + ) + } + case "Video": { + return ( + <div className={classNames(styles.container, { [styles.margin]: hasContent })} + style={{ '--width': metadata.width + 'px' }}> + <AttachmentActions attachment={attachment} /> + <SizedGrid width={metadata.width} height={metadata.height}> + <video src={url} alt={filename} + controls + loading="lazy" + width={metadata.width} + height={metadata.height} + onMouseDown={(ev) => + ev.button === 1 && window.open(url, "_blank") + } + /> + </SizedGrid> + </div> + ) + } + + + + + /*return ( <div className={styles.container} onClick={() => spoiler && setSpoiler(false)}> @@ -51,8 +89,8 @@ export default function Attachment({ attachment, hasContent }: Props) { width={metadata.width} height={metadata.height} loading="lazy" - data-spoiler={spoiler} data-has-content={hasContent} + data-spoiler={spoiler} className={classNames( styles.attachment, styles.image, @@ -70,14 +108,14 @@ export default function Attachment({ attachment, hasContent }: Props) { onClick={() => openScreen({ id: "image_viewer", attachment }) } - onLoad={() => setLoaded(true)} onMouseDown={(ev) => ev.button === 1 && window.open(url, "_blank") } + onLoad={() => setLoaded(true)} /> </div> ); - } + }*/ case "Audio": { return ( <div @@ -88,7 +126,7 @@ export default function Attachment({ attachment, hasContent }: Props) { </div> ); } - case "Video": { + /*case "Video": { return ( <div className={styles.container} @@ -129,7 +167,7 @@ export default function Attachment({ attachment, hasContent }: Props) { </div> </div> ); - } + }*/ case "Text": { return ( <div diff --git a/src/components/common/messaging/attachments/AttachmentActions.module.scss b/src/components/common/messaging/attachments/AttachmentActions.module.scss new file mode 100644 index 0000000..5eeb9a4 --- /dev/null +++ b/src/components/common/messaging/attachments/AttachmentActions.module.scss @@ -0,0 +1,49 @@ +.actions.imageAction { + grid-template: + "name icon external download" auto + "size icon external download" auto + / minmax(20px, 1fr) min-content min-content; +} + +.actions { + display: grid; + grid-template: + "icon name external download" auto + "icon size external download" auto + / min-content minmax(20px, 1fr) min-content; + + align-items: center; + column-gap: 12px; + + width: 100%; + padding: 8px; + overflow: none; + + color: var(--foreground); + background: var(--secondary-background); + + span { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + + .filesize { + grid-area: size; + + font-size: 10px; + color: var(--secondary-foreground); + } + + .downloadIcon { + grid-area: download; + } + + .externalType { + grid-area: external; + } + + .iconType { + grid-area: icon; + } +} diff --git a/src/components/common/messaging/attachments/AttachmentActions.tsx b/src/components/common/messaging/attachments/AttachmentActions.tsx index 591494b..0f18b31 100644 --- a/src/components/common/messaging/attachments/AttachmentActions.tsx +++ b/src/components/common/messaging/attachments/AttachmentActions.tsx @@ -7,7 +7,7 @@ import { } from "@styled-icons/boxicons-regular"; import { Attachment } from "revolt.js/dist/api/objects"; -import styles from "./Attachment.module.scss"; +import styles from "./AttachmentActions.module.scss"; import classNames from "classnames"; import { useContext } from "preact/hooks"; diff --git a/src/components/common/messaging/attachments/Grid.tsx b/src/components/common/messaging/attachments/Grid.tsx new file mode 100644 index 0000000..abdfde3 --- /dev/null +++ b/src/components/common/messaging/attachments/Grid.tsx @@ -0,0 +1,47 @@ +import styled from "styled-components"; +import { Children } from "../../../../types/Preact"; + +const Grid = styled.div` + display: grid; + max-width: min(480px, 100%, var(--width)); + max-height: min(640px, var(--height)); + aspect-ratio: var(--aspect-ratio); + + img, video { + min-width: 100%; + min-height: 100%; + + width: auto; + height: auto; + + max-width: 100%; + max-height: 100%; + + grid-area: 1 / 1; + } +`; + +export default Grid; + +type Props = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'children' | 'as' | 'style'> & { + style?: JSX.CSSProperties, + children?: Children, + width: number, + height: number, +}; + +export function SizedGrid(props: Props) { + const { width, height, children, style, ...divProps } = props; + + return ( + <Grid {...divProps} + style={{ + ...style, + "--width": width + 'px', + "--height": height + 'px', + "--aspect-ratio": width / height, + }}> + { children } + </Grid> + ) +} diff --git a/src/components/common/user/UserIcon.tsx b/src/components/common/user/UserIcon.tsx index e5cd3dc..15e1a00 100644 --- a/src/components/common/user/UserIcon.tsx +++ b/src/components/common/user/UserIcon.tsx @@ -87,7 +87,7 @@ export default function UserIcon( width="32" height="32" mask={mask ?? (status ? "url(#user)" : undefined)}> - {<img src={iconURL} draggable={false} />} + {<img src={iconURL} draggable={false} loading="lazy" />} </foreignObject> {props.status && ( <circle cx="27" cy="27" r="5" fill={useStatusColour(target)} /> diff --git a/src/components/navigation/left/ServerListSidebar.tsx b/src/components/navigation/left/ServerListSidebar.tsx index c4f76f3..e10a730 100644 --- a/src/components/navigation/left/ServerListSidebar.tsx +++ b/src/components/navigation/left/ServerListSidebar.tsx @@ -132,7 +132,8 @@ const ServerEntry = styled.div<{ active: boolean; home?: boolean }>` ` } svg { - width: 56.5px; + width: 57px; + height: 117px; margin-top: 4px; display: relative; @@ -151,10 +152,10 @@ const ServerEntry = styled.div<{ active: boolean; home?: boolean }>` function Swoosh() { return ( <span> - <svg width="56" height="118" viewBox="0 0 56 118" fill="none" xmlns="http://www.w3.org/2000/svg"> - <path d="M55.9957 0C55.6241 18.5052 31.292 28.1152 19.2904 32.1029L56 68.8124L55.9957 0Z" fill="var(--sidebar-active)"/> - <path d="M55.9963 117.633C55.8689 98.6899 31.3298 87.9423 19.2144 84.8847L55.9968 47.5654L55.9963 117.633Z" fill="var(--sidebar-active)"/> - <path d="M55.5682 58.4474C55.5682 73.7921 43.1288 86.2315 27.7841 86.2315C12.4394 86.2315 0 73.7921 0 58.4474C0 43.1026 12.4394 30.6633 27.7841 30.6633C43.1288 30.6633 55.5682 43.1026 55.5682 58.4474Z" fill="var(--sidebar-active)"/> + <svg xmlns="http://www.w3.org/2000/svg" width="57" height="117" fill="var(--sidebar-active)"> + <path d="M27.746 86.465c14 0 28 11.407 28 28s.256-56 .256-56-42.256 28-28.256 28z"/> + <path d="M56 58.465c0 15.464-12.536 28-28 28s-28-12.536-28-28 12.536-28 28-28 28 12.536 28 28z"/> + <path d="M28.002 30.465c14 0 28-11.407 28-28s0 56 0 56-42-28-28-28z"/> </svg> </span> ) -- GitLab