]> Untitled Git - lemmy-ui.git/blob - src/shared/components/common/pictrs-image.tsx
98d0791966a03afca5be631476c46d4f38f52f2a
[lemmy-ui.git] / src / shared / components / common / pictrs-image.tsx
1 import classNames from "classnames";
2 import { Component } from "inferno";
3
4 const iconThumbnailSize = 96;
5 const thumbnailSize = 256;
6
7 interface PictrsImageProps {
8   src: string;
9   alt?: string;
10   icon?: boolean;
11   banner?: boolean;
12   thumbnail?: boolean;
13   nsfw?: boolean;
14   iconOverlay?: boolean;
15   pushup?: boolean;
16 }
17
18 export class PictrsImage extends Component<PictrsImageProps, any> {
19   constructor(props: any, context: any) {
20     super(props, context);
21   }
22
23   render() {
24     return (
25       <picture className="d-inline-block overflow-hidden">
26         <source srcSet={this.src("webp")} type="image/webp" />
27         <source srcSet={this.props.src} />
28         <source srcSet={this.src("jpg")} type="image/jpeg" />
29         <img
30           src={this.props.src}
31           alt={this.alt()}
32           title={this.alt()}
33           loading="lazy"
34           className={classNames({
35             "img-fluid": !this.props.icon && !this.props.iconOverlay,
36             banner: this.props.banner,
37             "thumbnail rounded":
38               this.props.thumbnail && !this.props.icon && !this.props.banner,
39             "img-expanded slight-radius":
40               !this.props.thumbnail && !this.props.icon,
41             "img-blur": this.props.thumbnail && this.props.nsfw,
42             "rounded-circle img-cover img-icon me-2": this.props.icon,
43             "ms-2 mb-0 rounded-circle img-cover avatar-overlay":
44               this.props.iconOverlay,
45             "avatar-pushup": this.props.pushup,
46           })}
47         />
48       </picture>
49     );
50   }
51
52   src(format: string): string {
53     // sample url:
54     // http://localhost:8535/pictrs/image/file.png?thumbnail=256&format=jpg
55
56     const split = this.props.src.split("/pictrs/image/");
57
58     // If theres not multiple, then its not a pictrs image
59     if (split.length == 1) {
60       return this.props.src;
61     }
62
63     const host = split[0];
64     const path = split[1];
65
66     const params = { format };
67
68     if (this.props.thumbnail) {
69       params["thumbnail"] = thumbnailSize;
70     } else if (this.props.icon) {
71       params["thumbnail"] = iconThumbnailSize;
72     }
73
74     const paramsStr = new URLSearchParams(params).toString();
75     const out = `${host}/pictrs/image/${path}?${paramsStr}`;
76
77     return out;
78   }
79
80   alt(): string {
81     if (this.props.icon) {
82       return "";
83     }
84     return this.props.alt || "";
85   }
86 }