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