Fix attachment scaling.

This commit is contained in:
Paul
2021-07-10 15:21:35 +01:00
parent ae97a1ecd1
commit e717cb415e
9 changed files with 164 additions and 111 deletions

View File

@@ -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;
.container {
max-width: 100%;
overflow: hidden;
width: fit-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;
> :first-child {
width: min(480px, 100%, var(--width));
}
}
.container, .attachment, .image {
border-radius: 6px;
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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";

View 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>
)
}