]> Untitled Git - lemmy.git/blob - ui/src/components/site-form.tsx
Merge branch 'admin_settings' into dev
[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   // Necessary to stop the loading
62   componentWillReceiveProps() {
63     this.state.loading = false;
64     this.setState(this.state);
65   }
66
67   render() {
68     return (
69       <>
70         <Prompt
71           when={
72             !this.state.loading &&
73             !this.props.site &&
74             (this.state.siteForm.name || this.state.siteForm.description)
75           }
76           message={i18n.t('block_leaving')}
77         />
78         <form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
79           <h5>{`${
80             this.props.site
81               ? capitalizeFirstLetter(i18n.t('edit'))
82               : capitalizeFirstLetter(i18n.t('name'))
83           } ${i18n.t('your_site')}`}</h5>
84           <div class="form-group row">
85             <label class="col-12 col-form-label" htmlFor="create-site-name">
86               {i18n.t('name')}
87             </label>
88             <div class="col-12">
89               <input
90                 type="text"
91                 id="create-site-name"
92                 class="form-control"
93                 value={this.state.siteForm.name}
94                 onInput={linkEvent(this, this.handleSiteNameChange)}
95                 required
96                 minLength={3}
97                 maxLength={20}
98               />
99             </div>
100           </div>
101           <div class="form-group row">
102             <label class="col-12 col-form-label" htmlFor={this.id}>
103               {i18n.t('sidebar')}
104             </label>
105             <div class="col-12">
106               <textarea
107                 id={this.id}
108                 value={this.state.siteForm.description}
109                 onInput={linkEvent(this, this.handleSiteDescriptionChange)}
110                 class="form-control"
111                 rows={3}
112                 maxLength={10000}
113               />
114             </div>
115           </div>
116           <div class="form-group row">
117             <div class="col-12">
118               <div class="form-check">
119                 <input
120                   class="form-check-input"
121                   id="create-site-downvotes"
122                   type="checkbox"
123                   checked={this.state.siteForm.enable_downvotes}
124                   onChange={linkEvent(
125                     this,
126                     this.handleSiteEnableDownvotesChange
127                   )}
128                 />
129                 <label class="form-check-label" htmlFor="create-site-downvotes">
130                   {i18n.t('enable_downvotes')}
131                 </label>
132               </div>
133             </div>
134           </div>
135           <div class="form-group row">
136             <div class="col-12">
137               <div class="form-check">
138                 <input
139                   class="form-check-input"
140                   id="create-site-enable-nsfw"
141                   type="checkbox"
142                   checked={this.state.siteForm.enable_nsfw}
143                   onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
144                 />
145                 <label
146                   class="form-check-label"
147                   htmlFor="create-site-enable-nsfw"
148                 >
149                   {i18n.t('enable_nsfw')}
150                 </label>
151               </div>
152             </div>
153           </div>
154           <div class="form-group row">
155             <div class="col-12">
156               <div class="form-check">
157                 <input
158                   class="form-check-input"
159                   id="create-site-open-registration"
160                   type="checkbox"
161                   checked={this.state.siteForm.open_registration}
162                   onChange={linkEvent(
163                     this,
164                     this.handleSiteOpenRegistrationChange
165                   )}
166                 />
167                 <label
168                   class="form-check-label"
169                   htmlFor="create-site-open-registration"
170                 >
171                   {i18n.t('open_registration')}
172                 </label>
173               </div>
174             </div>
175           </div>
176           <div class="form-group row">
177             <div class="col-12">
178               <button type="submit" class="btn btn-secondary mr-2">
179                 {this.state.loading ? (
180                   <svg class="icon icon-spinner spin">
181                     <use xlinkHref="#icon-spinner"></use>
182                   </svg>
183                 ) : this.props.site ? (
184                   capitalizeFirstLetter(i18n.t('save'))
185                 ) : (
186                   capitalizeFirstLetter(i18n.t('create'))
187                 )}
188               </button>
189               {this.props.site && (
190                 <button
191                   type="button"
192                   class="btn btn-secondary"
193                   onClick={linkEvent(this, this.handleCancel)}
194                 >
195                   {i18n.t('cancel')}
196                 </button>
197               )}
198             </div>
199           </div>
200         </form>
201       </>
202     );
203   }
204
205   handleCreateSiteSubmit(i: SiteForm, event: any) {
206     event.preventDefault();
207     i.state.loading = true;
208     if (i.props.site) {
209       WebSocketService.Instance.editSite(i.state.siteForm);
210     } else {
211       WebSocketService.Instance.createSite(i.state.siteForm);
212     }
213     i.setState(i.state);
214   }
215
216   handleSiteNameChange(i: SiteForm, event: any) {
217     i.state.siteForm.name = event.target.value;
218     i.setState(i.state);
219   }
220
221   handleSiteDescriptionChange(i: SiteForm, event: any) {
222     i.state.siteForm.description = event.target.value;
223     i.setState(i.state);
224   }
225
226   handleSiteEnableNsfwChange(i: SiteForm, event: any) {
227     i.state.siteForm.enable_nsfw = event.target.checked;
228     i.setState(i.state);
229   }
230
231   handleSiteOpenRegistrationChange(i: SiteForm, event: any) {
232     i.state.siteForm.open_registration = event.target.checked;
233     i.setState(i.state);
234   }
235
236   handleSiteEnableDownvotesChange(i: SiteForm, event: any) {
237     i.state.siteForm.enable_downvotes = event.target.checked;
238     i.setState(i.state);
239   }
240
241   handleCancel(i: SiteForm) {
242     i.props.onCancel();
243   }
244 }