]> Untitled Git - lemmy.git/blob - ui/src/components/site-form.tsx
Merge branch 'PersianTranslation' of https://github.com/ahangarha/lemmy into ahangarh...
[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 import { T } from 'inferno-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       <form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
64         <h5>{`${
65           this.props.site
66             ? capitalizeFirstLetter(i18n.t('edit'))
67             : capitalizeFirstLetter(i18n.t('name'))
68         } ${i18n.t('your_site')}`}</h5>
69         <div class="form-group row">
70           <label class="col-12 col-form-label">
71             <T i18nKey="name">#</T>
72           </label>
73           <div class="col-12">
74             <input
75               type="text"
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">
87             <T i18nKey="sidebar">#</T>
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                 type="checkbox"
106                 checked={this.state.siteForm.enable_downvotes}
107                 onChange={linkEvent(this, this.handleSiteEnableDownvotesChange)}
108               />
109               <label class="form-check-label">
110                 <T i18nKey="enable_downvotes">#</T>
111               </label>
112             </div>
113           </div>
114         </div>
115         <div class="form-group row">
116           <div class="col-12">
117             <div class="form-check">
118               <input
119                 class="form-check-input"
120                 type="checkbox"
121                 checked={this.state.siteForm.enable_nsfw}
122                 onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
123               />
124               <label class="form-check-label">
125                 <T i18nKey="enable_nsfw">#</T>
126               </label>
127             </div>
128           </div>
129         </div>
130         <div class="form-group row">
131           <div class="col-12">
132             <div class="form-check">
133               <input
134                 class="form-check-input"
135                 type="checkbox"
136                 checked={this.state.siteForm.open_registration}
137                 onChange={linkEvent(
138                   this,
139                   this.handleSiteOpenRegistrationChange
140                 )}
141               />
142               <label class="form-check-label">
143                 <T i18nKey="open_registration">#</T>
144               </label>
145             </div>
146           </div>
147         </div>
148         <div class="form-group row">
149           <div class="col-12">
150             <button type="submit" class="btn btn-secondary mr-2">
151               {this.state.loading ? (
152                 <svg class="icon icon-spinner spin">
153                   <use xlinkHref="#icon-spinner"></use>
154                 </svg>
155               ) : this.props.site ? (
156                 capitalizeFirstLetter(i18n.t('save'))
157               ) : (
158                 capitalizeFirstLetter(i18n.t('create'))
159               )}
160             </button>
161             {this.props.site && (
162               <button
163                 type="button"
164                 class="btn btn-secondary"
165                 onClick={linkEvent(this, this.handleCancel)}
166               >
167                 <T i18nKey="cancel">#</T>
168               </button>
169             )}
170           </div>
171         </div>
172       </form>
173     );
174   }
175
176   handleCreateSiteSubmit(i: SiteForm, event: any) {
177     event.preventDefault();
178     i.state.loading = true;
179     if (i.props.site) {
180       WebSocketService.Instance.editSite(i.state.siteForm);
181     } else {
182       WebSocketService.Instance.createSite(i.state.siteForm);
183     }
184     i.setState(i.state);
185   }
186
187   handleSiteNameChange(i: SiteForm, event: any) {
188     i.state.siteForm.name = event.target.value;
189     i.setState(i.state);
190   }
191
192   handleSiteDescriptionChange(i: SiteForm, event: any) {
193     i.state.siteForm.description = event.target.value;
194     i.setState(i.state);
195   }
196
197   handleSiteEnableNsfwChange(i: SiteForm, event: any) {
198     i.state.siteForm.enable_nsfw = event.target.checked;
199     i.setState(i.state);
200   }
201
202   handleSiteOpenRegistrationChange(i: SiteForm, event: any) {
203     i.state.siteForm.open_registration = event.target.checked;
204     i.setState(i.state);
205   }
206
207   handleSiteEnableDownvotesChange(i: SiteForm, event: any) {
208     i.state.siteForm.enable_downvotes = event.target.checked;
209     i.setState(i.state);
210   }
211
212   handleCancel(i: SiteForm) {
213     i.props.onCancel();
214   }
215 }