]> Untitled Git - lemmy.git/blob - ui/src/components/site-form.tsx
Merge branch 'master' into federation
[lemmy.git] / ui / src / components / site-form.tsx
1 import { Component, linkEvent } from 'inferno';
2 import { Prompt } from 'inferno-router';
3 import { Site, SiteForm as SiteFormI } from '../interfaces';
4 import { WebSocketService } from '../services';
5 import { capitalizeFirstLetter, randomStr, setupTribute } from '../utils';
6 import autosize from 'autosize';
7 import Tribute from 'tributejs/src/Tribute.js';
8 import { i18n } from '../i18next';
9
10 interface SiteFormProps {
11   site?: Site; // If a site is given, that means this is an edit
12   onCancel?(): any;
13 }
14
15 interface SiteFormState {
16   siteForm: SiteFormI;
17   loading: boolean;
18 }
19
20 export class SiteForm extends Component<SiteFormProps, SiteFormState> {
21   private id = `site-form-${randomStr()}`;
22   private tribute: Tribute;
23   private emptyState: SiteFormState = {
24     siteForm: {
25       enable_downvotes: true,
26       open_registration: true,
27       enable_nsfw: true,
28       name: null,
29     },
30     loading: false,
31   };
32
33   constructor(props: any, context: any) {
34     super(props, context);
35
36     this.tribute = setupTribute();
37     this.state = this.emptyState;
38
39     if (this.props.site) {
40       this.state.siteForm = {
41         name: this.props.site.name,
42         description: this.props.site.description,
43         enable_downvotes: this.props.site.enable_downvotes,
44         open_registration: this.props.site.open_registration,
45         enable_nsfw: this.props.site.enable_nsfw,
46       };
47     }
48   }
49
50   componentDidMount() {
51     var textarea: any = document.getElementById(this.id);
52     autosize(textarea);
53     this.tribute.attach(textarea);
54     textarea.addEventListener('tribute-replaced', () => {
55       this.state.siteForm.description = textarea.value;
56       this.setState(this.state);
57       autosize.update(textarea);
58     });
59   }
60
61   render() {
62     return (
63       <>
64         <Prompt
65           when={
66             !this.state.loading &&
67             (this.state.siteForm.name || this.state.siteForm.description)
68           }
69           message={i18n.t('block_leaving')}
70         />
71         <form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
72           <h5>{`${
73             this.props.site
74               ? capitalizeFirstLetter(i18n.t('edit'))
75               : capitalizeFirstLetter(i18n.t('name'))
76           } ${i18n.t('your_site')}`}</h5>
77           <div class="form-group row">
78             <label class="col-12 col-form-label" htmlFor="create-site-name">
79               {i18n.t('name')}
80             </label>
81             <div class="col-12">
82               <input
83                 type="text"
84                 id="create-site-name"
85                 class="form-control"
86                 value={this.state.siteForm.name}
87                 onInput={linkEvent(this, this.handleSiteNameChange)}
88                 required
89                 minLength={3}
90                 maxLength={20}
91               />
92             </div>
93           </div>
94           <div class="form-group row">
95             <label class="col-12 col-form-label" htmlFor={this.id}>
96               {i18n.t('sidebar')}
97             </label>
98             <div class="col-12">
99               <textarea
100                 id={this.id}
101                 value={this.state.siteForm.description}
102                 onInput={linkEvent(this, this.handleSiteDescriptionChange)}
103                 class="form-control"
104                 rows={3}
105                 maxLength={10000}
106               />
107             </div>
108           </div>
109           <div class="form-group row">
110             <div class="col-12">
111               <div class="form-check">
112                 <input
113                   class="form-check-input"
114                   id="create-site-downvotes"
115                   type="checkbox"
116                   checked={this.state.siteForm.enable_downvotes}
117                   onChange={linkEvent(
118                     this,
119                     this.handleSiteEnableDownvotesChange
120                   )}
121                 />
122                 <label class="form-check-label" htmlFor="create-site-downvotes">
123                   {i18n.t('enable_downvotes')}
124                 </label>
125               </div>
126             </div>
127           </div>
128           <div class="form-group row">
129             <div class="col-12">
130               <div class="form-check">
131                 <input
132                   class="form-check-input"
133                   id="create-site-enable-nsfw"
134                   type="checkbox"
135                   checked={this.state.siteForm.enable_nsfw}
136                   onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
137                 />
138                 <label
139                   class="form-check-label"
140                   htmlFor="create-site-enable-nsfw"
141                 >
142                   {i18n.t('enable_nsfw')}
143                 </label>
144               </div>
145             </div>
146           </div>
147           <div class="form-group row">
148             <div class="col-12">
149               <div class="form-check">
150                 <input
151                   class="form-check-input"
152                   id="create-site-open-registration"
153                   type="checkbox"
154                   checked={this.state.siteForm.open_registration}
155                   onChange={linkEvent(
156                     this,
157                     this.handleSiteOpenRegistrationChange
158                   )}
159                 />
160                 <label
161                   class="form-check-label"
162                   htmlFor="create-site-open-registration"
163                 >
164                   {i18n.t('open_registration')}
165                 </label>
166               </div>
167             </div>
168           </div>
169           <div class="form-group row">
170             <div class="col-12">
171               <button type="submit" class="btn btn-secondary mr-2">
172                 {this.state.loading ? (
173                   <svg class="icon icon-spinner spin">
174                     <use xlinkHref="#icon-spinner"></use>
175                   </svg>
176                 ) : this.props.site ? (
177                   capitalizeFirstLetter(i18n.t('save'))
178                 ) : (
179                   capitalizeFirstLetter(i18n.t('create'))
180                 )}
181               </button>
182               {this.props.site && (
183                 <button
184                   type="button"
185                   class="btn btn-secondary"
186                   onClick={linkEvent(this, this.handleCancel)}
187                 >
188                   {i18n.t('cancel')}
189                 </button>
190               )}
191             </div>
192           </div>
193         </form>
194       </>
195     );
196   }
197
198   handleCreateSiteSubmit(i: SiteForm, event: any) {
199     event.preventDefault();
200     i.state.loading = true;
201     if (i.props.site) {
202       WebSocketService.Instance.editSite(i.state.siteForm);
203     } else {
204       WebSocketService.Instance.createSite(i.state.siteForm);
205     }
206     i.setState(i.state);
207   }
208
209   handleSiteNameChange(i: SiteForm, event: any) {
210     i.state.siteForm.name = event.target.value;
211     i.setState(i.state);
212   }
213
214   handleSiteDescriptionChange(i: SiteForm, event: any) {
215     i.state.siteForm.description = event.target.value;
216     i.setState(i.state);
217   }
218
219   handleSiteEnableNsfwChange(i: SiteForm, event: any) {
220     i.state.siteForm.enable_nsfw = event.target.checked;
221     i.setState(i.state);
222   }
223
224   handleSiteOpenRegistrationChange(i: SiteForm, event: any) {
225     i.state.siteForm.open_registration = event.target.checked;
226     i.setState(i.state);
227   }
228
229   handleSiteEnableDownvotesChange(i: SiteForm, event: any) {
230     i.state.siteForm.enable_downvotes = event.target.checked;
231     i.setState(i.state);
232   }
233
234   handleCancel(i: SiteForm) {
235     i.props.onCancel();
236   }
237 }