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