mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-22 15:10:57 -05:00
Fix attachment scaling.
This commit is contained in:
parent
92fed40e40
commit
9846262e8b
9 changed files with 164 additions and 111 deletions
|
@ -57,6 +57,7 @@ export default function ChannelIcon(
|
||||||
{...imgProps}
|
{...imgProps}
|
||||||
width={size}
|
width={size}
|
||||||
height={size}
|
height={size}
|
||||||
|
loading="lazy"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
square={isServerChannel}
|
square={isServerChannel}
|
||||||
src={iconURL ?? fallback}
|
src={iconURL ?? fallback}
|
||||||
|
|
|
@ -61,8 +61,9 @@ export default function ServerIcon(
|
||||||
{...imgProps}
|
{...imgProps}
|
||||||
width={size}
|
width={size}
|
||||||
height={size}
|
height={size}
|
||||||
aria-hidden="true"
|
|
||||||
src={iconURL}
|
src={iconURL}
|
||||||
|
loading="lazy"
|
||||||
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,67 +3,15 @@
|
||||||
grid-auto-columns: min(100%, 480px);
|
grid-auto-columns: min(100%, 480px);
|
||||||
grid-auto-flow: row dense;
|
grid-auto-flow: row dense;
|
||||||
|
|
||||||
|
margin: .125rem 0 .125rem;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
border-radius: 6px;
|
|
||||||
margin: .125rem 0 .125rem;
|
|
||||||
|
|
||||||
&[data-spoiler="true"] {
|
&[data-spoiler="true"] {
|
||||||
filter: blur(30px);
|
filter: blur(30px);
|
||||||
pointer-events: none;
|
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 {
|
&.audio {
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
|
@ -125,52 +73,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions.imageAction {
|
.margin {
|
||||||
grid-template:
|
margin-top: 4px;
|
||||||
"name icon external download" auto
|
|
||||||
"size icon external download" auto
|
|
||||||
/ minmax(20px, 1fr) min-content min-content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
.container {
|
||||||
display: grid;
|
max-width: 100%;
|
||||||
grid-template:
|
overflow: hidden;
|
||||||
"icon name external download" auto
|
width: fit-content;
|
||||||
"icon size external download" auto
|
|
||||||
/ min-content minmax(20px, 1fr) min-content;
|
|
||||||
|
|
||||||
align-items: center;
|
> :first-child {
|
||||||
column-gap: 12px;
|
width: min(480px, 100%, var(--width));
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container, .attachment, .image {
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ import { useContext, useState } from "preact/hooks";
|
||||||
import { useIntermediate } from "../../../../context/intermediate/Intermediate";
|
import { useIntermediate } from "../../../../context/intermediate/Intermediate";
|
||||||
import { AppContext } from "../../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
import { MessageAreaWidthContext } from "../../../../pages/channels/messaging/MessageArea";
|
|
||||||
import AttachmentActions from "./AttachmentActions";
|
import AttachmentActions from "./AttachmentActions";
|
||||||
import TextFile from "./TextFile";
|
import TextFile from "./TextFile";
|
||||||
|
import { SizedGrid } from "./Grid";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
attachment: AttachmentRJS;
|
attachment: AttachmentRJS;
|
||||||
|
@ -35,6 +35,44 @@ export default function Attachment({ attachment, hasContent }: Props) {
|
||||||
switch (metadata.type) {
|
switch (metadata.type) {
|
||||||
case "Image": {
|
case "Image": {
|
||||||
return (
|
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
|
<div
|
||||||
className={styles.container}
|
className={styles.container}
|
||||||
onClick={() => spoiler && setSpoiler(false)}>
|
onClick={() => spoiler && setSpoiler(false)}>
|
||||||
|
@ -51,8 +89,8 @@ export default function Attachment({ attachment, hasContent }: Props) {
|
||||||
width={metadata.width}
|
width={metadata.width}
|
||||||
height={metadata.height}
|
height={metadata.height}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
data-spoiler={spoiler}
|
|
||||||
data-has-content={hasContent}
|
data-has-content={hasContent}
|
||||||
|
data-spoiler={spoiler}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
styles.attachment,
|
styles.attachment,
|
||||||
styles.image,
|
styles.image,
|
||||||
|
@ -70,14 +108,14 @@ export default function Attachment({ attachment, hasContent }: Props) {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openScreen({ id: "image_viewer", attachment })
|
openScreen({ id: "image_viewer", attachment })
|
||||||
}
|
}
|
||||||
onLoad={() => setLoaded(true)}
|
|
||||||
onMouseDown={(ev) =>
|
onMouseDown={(ev) =>
|
||||||
ev.button === 1 && window.open(url, "_blank")
|
ev.button === 1 && window.open(url, "_blank")
|
||||||
}
|
}
|
||||||
|
onLoad={() => setLoaded(true)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}*/
|
||||||
case "Audio": {
|
case "Audio": {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -88,7 +126,7 @@ export default function Attachment({ attachment, hasContent }: Props) {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "Video": {
|
/*case "Video": {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={styles.container}
|
className={styles.container}
|
||||||
|
@ -129,7 +167,7 @@ export default function Attachment({ attachment, hasContent }: Props) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}*/
|
||||||
case "Text": {
|
case "Text": {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import {
|
||||||
} from "@styled-icons/boxicons-regular";
|
} from "@styled-icons/boxicons-regular";
|
||||||
import { Attachment } from "revolt.js/dist/api/objects";
|
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 classNames from "classnames";
|
||||||
import { useContext } from "preact/hooks";
|
import { useContext } from "preact/hooks";
|
||||||
|
|
||||||
|
|
47
src/components/common/messaging/attachments/Grid.tsx
Normal file
47
src/components/common/messaging/attachments/Grid.tsx
Normal file
|
@ -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>
|
||||||
|
)
|
||||||
|
}
|
|
@ -87,7 +87,7 @@ export default function UserIcon(
|
||||||
width="32"
|
width="32"
|
||||||
height="32"
|
height="32"
|
||||||
mask={mask ?? (status ? "url(#user)" : undefined)}>
|
mask={mask ?? (status ? "url(#user)" : undefined)}>
|
||||||
{<img src={iconURL} draggable={false} />}
|
{<img src={iconURL} draggable={false} loading="lazy" />}
|
||||||
</foreignObject>
|
</foreignObject>
|
||||||
{props.status && (
|
{props.status && (
|
||||||
<circle cx="27" cy="27" r="5" fill={useStatusColour(target)} />
|
<circle cx="27" cy="27" r="5" fill={useStatusColour(target)} />
|
||||||
|
|
|
@ -132,7 +132,8 @@ const ServerEntry = styled.div<{ active: boolean; home?: boolean }>`
|
||||||
` }
|
` }
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
width: 56.5px;
|
width: 57px;
|
||||||
|
height: 117px;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
display: relative;
|
display: relative;
|
||||||
|
|
||||||
|
@ -151,10 +152,10 @@ const ServerEntry = styled.div<{ active: boolean; home?: boolean }>`
|
||||||
function Swoosh() {
|
function Swoosh() {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<svg width="56" height="118" viewBox="0 0 56 118" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" width="57" height="117" fill="var(--sidebar-active)">
|
||||||
<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="M27.746 86.465c14 0 28 11.407 28 28s.256-56 .256-56-42.256 28-28.256 28z"/>
|
||||||
<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="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="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)"/>
|
<path d="M28.002 30.465c14 0 28-11.407 28-28s0 56 0 56-42-28-28-28z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue