]> Untitled Git - lemmy.git/blob - ui/src/components/site-form.tsx
Hide navigation warnings on markdown textarea for site-form and user bios. Fixes...
[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                 hideNavigationWarnings
115               />
116             </div>
117           </div>
118           <div class="form-group row">
119             <div class="col-12">
120               <div class="form-check">
121                 <input
122                   class="form-check-input"
123                   id="create-site-downvotes"
124                   type="checkbox"
125                   checked={this.state.siteForm.enable_downvotes}
126                   onChange={linkEvent(
127                     this,
128                     this.handleSiteEnableDownvotesChange
129                   )}
130                 />
131                 <label class="form-check-label" htmlFor="create-site-downvotes">
132                   {i18n.t('enable_downvotes')}
133                 </label>
134               </div>
135             </div>
136           </div>
137           <div class="form-group row">
138             <div class="col-12">
139               <div class="form-check">
140                 <input
141                   class="form-check-input"
142                   id="create-site-enable-nsfw"
143                   type="checkbox"
144                   checked={this.state.siteForm.enable_nsfw}
145                   onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
146                 />
147                 <label
148                   class="form-check-label"
149                   htmlFor="create-site-enable-nsfw"
150                 >
151                   {i18n.t('enable_nsfw')}
152                 </label>
153               </div>
154             </div>
155           </div>
156           <div class="form-group row">
157             <div class="col-12">
158               <div class="form-check">
159                 <input
160                   class="form-check-input"
161                   id="create-site-open-registration"
162                   type="checkbox"
163                   checked={this.state.siteForm.open_registration}
164                   onChange={linkEvent(
165                     this,
166                     this.handleSiteOpenRegistrationChange
167                   )}
168                 />
169                 <label
170                   class="form-check-label"
171                   htmlFor="create-site-open-registration"
172                 >
173                   {i18n.t('open_registration')}
174                 </label>
175               </div>
176             </div>
177           </div>
178           <div class="form-group row">
179             <div class="col-12">
180               <button
181                 type="submit"
182                 class="btn btn-secondary mr-2"
183                 disabled={this.state.loading}
184               >
185                 {this.state.loading ? (
186                   <svg class="icon icon-spinner spin">
187                     <use xlinkHref="#icon-spinner"></use>
188                   </svg>
189                 ) : this.props.site ? (
190                   capitalizeFirstLetter(i18n.t('save'))
191                 ) : (
192                   capitalizeFirstLetter(i18n.t('create'))
193                 )}
194               </button>
195               {this.props.site && (
196                 <button
197                   type="button"
198                   class="btn btn-secondary"
199                   onClick={linkEvent(this, this.handleCancel)}
200                 >
201                   {i18n.t('cancel')}
202                 </button>
203               )}
204             </div>
205           </div>
206         </form>
207       </>
208     );
209   }
210
211   handleCreateSiteSubmit(i: SiteForm, event: any) {
212     event.preventDefault();
213     i.state.loading = true;
214     if (i.props.site) {
215       WebSocketService.Instance.editSite(i.state.siteForm);
216     } else {
217       WebSocketService.Instance.createSite(i.state.siteForm);
218     }
219     i.setState(i.state);
220   }
221
222   handleSiteNameChange(i: SiteForm, event: any) {
223     i.state.siteForm.name = event.target.value;
224     i.setState(i.state);
225   }
226
227   handleSiteDescriptionChange(val: string) {
228     this.state.siteForm.description = val;
229     this.setState(this.state);
230   }
231
232   handleSiteEnableNsfwChange(i: SiteForm, event: any) {
233     i.state.siteForm.enable_nsfw = event.target.checked;
234     i.setState(i.state);
235   }
236
237   handleSiteOpenRegistrationChange(i: SiteForm, event: any) {
238     i.state.siteForm.open_registration = event.target.checked;
239     i.setState(i.state);
240   }
241
242   handleSiteEnableDownvotesChange(i: SiteForm, event: any) {
243     i.state.siteForm.enable_downvotes = event.target.checked;
244     i.setState(i.state);
245   }
246
247   handleCancel(i: SiteForm) {
248     i.props.onCancel();
249   }
250 }