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