]> Untitled Git - lemmy-ui.git/blob - src/shared/components/common/image-upload-form.tsx
cfb861501b0f5a456a6ecbcee967aca30276f854
[lemmy-ui.git] / src / shared / components / common / image-upload-form.tsx
1 import { Component, linkEvent } from "inferno";
2 import { i18n } from "../../i18next";
3 import { UserService } from "../../services";
4 import { randomStr, toast, uploadImage } from "../../utils";
5 import { Icon } from "./icon";
6
7 interface ImageUploadFormProps {
8   uploadTitle: string;
9   imageSrc?: string;
10   onUpload(url: string): any;
11   onRemove(): any;
12   rounded?: boolean;
13 }
14
15 interface ImageUploadFormState {
16   loading: boolean;
17 }
18
19 export class ImageUploadForm extends Component<
20   ImageUploadFormProps,
21   ImageUploadFormState
22 > {
23   private id = `image-upload-form-${randomStr()}`;
24   private emptyState: ImageUploadFormState = {
25     loading: false,
26   };
27
28   constructor(props: any, context: any) {
29     super(props, context);
30     this.state = this.emptyState;
31   }
32
33   render() {
34     return (
35       <form className="d-inline">
36         <label
37           htmlFor={this.id}
38           className="pointer text-muted small font-weight-bold"
39         >
40           {this.props.imageSrc ? (
41             <span className="d-inline-block position-relative">
42               <img
43                 src={this.props.imageSrc}
44                 height={this.props.rounded ? 60 : ""}
45                 width={this.props.rounded ? 60 : ""}
46                 className={`img-fluid ${
47                   this.props.rounded ? "rounded-circle" : ""
48                 }`}
49               />
50               <a
51                 onClick={linkEvent(this, this.handleRemoveImage)}
52                 aria-label={i18n.t("remove")}
53               >
54                 <Icon icon="x" classes="mini-overlay" />
55               </a>
56             </span>
57           ) : (
58             <span className="btn btn-secondary">{this.props.uploadTitle}</span>
59           )}
60         </label>
61         <input
62           id={this.id}
63           type="file"
64           accept="image/*,video/*"
65           name={this.id}
66           className="d-none"
67           disabled={!UserService.Instance.myUserInfo}
68           onChange={linkEvent(this, this.handleImageUpload)}
69         />
70       </form>
71     );
72   }
73
74   handleImageUpload(i: ImageUploadForm, event: any) {
75     event.preventDefault();
76     const file = event.target.files[0];
77
78     i.setState({ loading: true });
79
80     uploadImage(file)
81       .then(res => {
82         console.log("pictrs upload:");
83         console.log(res);
84         if (res.msg === "ok") {
85           i.setState({ loading: false });
86           i.props.onUpload(res.url as string);
87         } else {
88           i.setState({ loading: false });
89           toast(JSON.stringify(res), "danger");
90         }
91       })
92       .catch(error => {
93         i.setState({ loading: false });
94         console.error(error);
95         toast(error, "danger");
96       });
97   }
98
99   handleRemoveImage(i: ImageUploadForm, event: any) {
100     event.preventDefault();
101     i.setState({ loading: true });
102     i.props.onRemove();
103   }
104 }