]> Untitled Git - lemmy-ui.git/blob - src/shared/components/common/image-upload-form.tsx
fix: Use Bootstrap file upload form control styles
[lemmy-ui.git] / src / shared / components / common / image-upload-form.tsx
1 import { randomStr } from "@utils/helpers";
2 import { Component, linkEvent } from "inferno";
3 import { HttpService, I18NextService, UserService } from "../../services";
4 import { toast } from "../../toast";
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="image-upload-form d-inline">
36         {this.props.imageSrc && (
37           <span className="d-inline-block position-relative">
38             {/* TODO: Create "Current Iamge" translation for alt text */}
39             <img
40               alt=""
41               src={this.props.imageSrc}
42               height={this.props.rounded ? 60 : ""}
43               width={this.props.rounded ? 60 : ""}
44               className={`img-fluid ${
45                 this.props.rounded ? "rounded-circle" : ""
46               }`}
47             />
48             <button
49               className="position-absolute d-block p-0 end-0 border-0 top-0 bg-transparent text-white"
50               type="button"
51               onClick={linkEvent(this, this.handleRemoveImage)}
52               aria-label={I18NextService.i18n.t("remove")}
53             >
54               <Icon icon="x" classes="mini-overlay" />
55             </button>
56           </span>
57         )}
58         <input
59           id={this.id}
60           type="file"
61           accept="image/*,video/*"
62           className="small form-control"
63           name={this.id}
64           disabled={!UserService.Instance.myUserInfo}
65           onChange={linkEvent(this, this.handleImageUpload)}
66         />
67       </form>
68     );
69   }
70
71   handleImageUpload(i: ImageUploadForm, event: any) {
72     event.preventDefault();
73     const image = event.target.files[0] as File;
74
75     i.setState({ loading: true });
76
77     HttpService.client.uploadImage({ image }).then(res => {
78       console.log("pictrs upload:");
79       console.log(res);
80       if (res.state === "success") {
81         if (res.data.msg === "ok") {
82           i.props.onUpload(res.data.url as string);
83         } else {
84           toast(JSON.stringify(res), "danger");
85         }
86       } else if (res.state === "failed") {
87         console.error(res.msg);
88         toast(res.msg, "danger");
89       }
90
91       i.setState({ loading: false });
92     });
93   }
94
95   handleRemoveImage(i: ImageUploadForm, event: any) {
96     event.preventDefault();
97     i.setState({ loading: true });
98     i.props.onRemove();
99   }
100 }