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