1 import { None, Option, Some } from "@sniptt/monads";
2 import { Component, InfernoMouseEvent, linkEvent } from "inferno";
3 import { Prompt } from "inferno-router";
10 } from "lemmy-js-client";
11 import { i18n } from "../../i18next";
12 import { WebSocketService } from "../../services";
15 capitalizeFirstLetter,
19 import { Icon, Spinner } from "../common/icon";
20 import { ImageUploadForm } from "../common/image-upload-form";
21 import { LanguageSelect } from "../common/language-select";
22 import { ListingTypeSelect } from "../common/listing-type-select";
23 import { MarkdownTextArea } from "../common/markdown-textarea";
25 interface SiteFormProps {
26 siteRes: GetSiteResponse;
30 interface SiteFormState {
33 themeList: Option<string[]>;
36 export class SiteForm extends Component<SiteFormProps, SiteFormState> {
37 private emptyState: SiteFormState = {
38 siteForm: new EditSite({
39 enable_downvotes: None,
40 open_registration: None,
45 require_email_verification: None,
46 require_application: None,
47 application_question: None,
48 private_instance: None,
51 default_post_listing_type: None,
52 legal_information: None,
54 community_creation_admin_only: None,
55 application_email_admins: None,
56 hide_modlog_mod_names: None,
57 discussion_languages: None,
58 slur_filter_regex: None,
59 actor_name_max_length: None,
60 rate_limit_message: None,
61 rate_limit_message_per_second: None,
62 rate_limit_comment: None,
63 rate_limit_comment_per_second: None,
64 rate_limit_image: None,
65 rate_limit_image_per_second: None,
66 rate_limit_post: None,
67 rate_limit_post_per_second: None,
68 rate_limit_register: None,
69 rate_limit_register_per_second: None,
70 rate_limit_search: None,
71 rate_limit_search_per_second: None,
72 federation_enabled: None,
73 federation_debug: None,
74 federation_worker_count: None,
75 captcha_enabled: None,
76 captcha_difficulty: None,
77 allowed_instances: None,
78 blocked_instances: None,
86 constructor(props: any, context: any) {
87 super(props, context);
89 this.state = this.emptyState;
90 this.handleSiteSidebarChange = this.handleSiteSidebarChange.bind(this);
91 this.handleSiteLegalInfoChange = this.handleSiteLegalInfoChange.bind(this);
92 this.handleSiteApplicationQuestionChange =
93 this.handleSiteApplicationQuestionChange.bind(this);
95 this.handleIconUpload = this.handleIconUpload.bind(this);
96 this.handleIconRemove = this.handleIconRemove.bind(this);
98 this.handleBannerUpload = this.handleBannerUpload.bind(this);
99 this.handleBannerRemove = this.handleBannerRemove.bind(this);
101 this.handleDefaultPostListingTypeChange =
102 this.handleDefaultPostListingTypeChange.bind(this);
104 this.handleDiscussionLanguageChange =
105 this.handleDiscussionLanguageChange.bind(this);
107 let site = this.props.siteRes.site_view.site;
108 let ls = this.props.siteRes.site_view.local_site;
109 let lsrl = this.props.siteRes.site_view.local_site_rate_limit;
112 siteForm: new EditSite({
113 name: Some(site.name),
114 sidebar: site.sidebar,
115 description: site.description,
116 enable_downvotes: Some(ls.enable_downvotes),
117 open_registration: Some(ls.open_registration),
118 enable_nsfw: Some(ls.enable_nsfw),
119 community_creation_admin_only: Some(ls.community_creation_admin_only),
122 require_email_verification: Some(ls.require_email_verification),
123 require_application: Some(ls.require_application),
124 application_question: ls.application_question,
125 private_instance: Some(ls.private_instance),
126 default_theme: Some(ls.default_theme),
127 default_post_listing_type: Some(ls.default_post_listing_type),
128 legal_information: ls.legal_information,
129 application_email_admins: Some(ls.application_email_admins),
130 hide_modlog_mod_names: Some(ls.hide_modlog_mod_names),
131 discussion_languages: Some(this.props.siteRes.discussion_languages),
132 slur_filter_regex: ls.slur_filter_regex,
133 actor_name_max_length: Some(ls.actor_name_max_length),
134 rate_limit_message: Some(lsrl.message),
135 rate_limit_message_per_second: Some(lsrl.message_per_second),
136 rate_limit_comment: Some(lsrl.comment),
137 rate_limit_comment_per_second: Some(lsrl.comment_per_second),
138 rate_limit_image: Some(lsrl.image),
139 rate_limit_image_per_second: Some(lsrl.image_per_second),
140 rate_limit_post: Some(lsrl.post),
141 rate_limit_post_per_second: Some(lsrl.post_per_second),
142 rate_limit_register: Some(lsrl.register),
143 rate_limit_register_per_second: Some(lsrl.register_per_second),
144 rate_limit_search: Some(lsrl.search),
145 rate_limit_search_per_second: Some(lsrl.search_per_second),
146 federation_enabled: Some(ls.federation_enabled),
147 federation_debug: Some(ls.federation_debug),
148 federation_worker_count: Some(ls.federation_worker_count),
149 captcha_enabled: Some(ls.captcha_enabled),
150 captcha_difficulty: Some(ls.captcha_difficulty),
151 allowed_instances: this.props.siteRes.federated_instances.andThen(
154 blocked_instances: this.props.siteRes.federated_instances.andThen(
157 taglines: this.props.siteRes.taglines.map(x => x.map(y => y.content)),
163 async componentDidMount() {
164 this.setState({ themeList: Some(await fetchThemeList()) });
167 // Necessary to stop the loading
168 componentWillReceiveProps() {
169 this.setState({ loading: false });
172 componentDidUpdate() {
174 !this.state.loading &&
175 !this.props.siteRes.site_view.local_site.site_setup &&
176 (this.state.siteForm.name ||
177 this.state.siteForm.sidebar ||
178 this.state.siteForm.application_question ||
179 this.state.siteForm.description)
181 window.onbeforeunload = () => true;
183 window.onbeforeunload = undefined;
187 componentWillUnmount() {
188 window.onbeforeunload = null;
192 let siteSetup = this.props.siteRes.site_view.local_site.site_setup;
197 !this.state.loading &&
199 (this.state.siteForm.name ||
200 this.state.siteForm.sidebar ||
201 this.state.siteForm.application_question ||
202 this.state.siteForm.description)
204 message={i18n.t("block_leaving")}
206 <form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
209 ? capitalizeFirstLetter(i18n.t("save"))
210 : capitalizeFirstLetter(i18n.t("name"))
211 } ${i18n.t("your_site")}`}</h5>
212 <div className="form-group row">
213 <label className="col-12 col-form-label" htmlFor="create-site-name">
216 <div className="col-12">
219 id="create-site-name"
220 className="form-control"
221 value={toUndefined(this.state.siteForm.name)}
222 onInput={linkEvent(this, this.handleSiteNameChange)}
229 <div className="form-group">
230 <label>{i18n.t("icon")}</label>
232 uploadTitle={i18n.t("upload_icon")}
233 imageSrc={this.state.siteForm.icon}
234 onUpload={this.handleIconUpload}
235 onRemove={this.handleIconRemove}
239 <div className="form-group">
240 <label>{i18n.t("banner")}</label>
242 uploadTitle={i18n.t("upload_banner")}
243 imageSrc={this.state.siteForm.banner}
244 onUpload={this.handleBannerUpload}
245 onRemove={this.handleBannerRemove}
248 <div className="form-group row">
249 <label className="col-12 col-form-label" htmlFor="site-desc">
250 {i18n.t("description")}
252 <div className="col-12">
255 className="form-control"
257 value={toUndefined(this.state.siteForm.description)}
258 onInput={linkEvent(this, this.handleSiteDescChange)}
263 <div className="form-group row">
264 <label className="col-12 col-form-label">{i18n.t("sidebar")}</label>
265 <div className="col-12">
267 initialContent={this.state.siteForm.sidebar}
268 initialLanguageId={None}
272 onContentChange={this.handleSiteSidebarChange}
273 hideNavigationWarnings
278 <div className="form-group row">
279 <label className="col-12 col-form-label">
280 {i18n.t("legal_information")}
282 <div className="col-12">
284 initialContent={this.state.siteForm.legal_information}
285 initialLanguageId={None}
289 onContentChange={this.handleSiteLegalInfoChange}
290 hideNavigationWarnings
295 {this.state.siteForm.require_application.unwrapOr(false) && (
296 <div className="form-group row">
297 <label className="col-12 col-form-label">
298 {i18n.t("application_questionnaire")}
300 <div className="col-12">
302 initialContent={this.state.siteForm.application_question}
303 initialLanguageId={None}
307 onContentChange={this.handleSiteApplicationQuestionChange}
308 hideNavigationWarnings
314 <div className="form-group row">
315 <div className="col-12">
316 <div className="form-check">
318 className="form-check-input"
319 id="create-site-downvotes"
321 checked={toUndefined(this.state.siteForm.enable_downvotes)}
324 this.handleSiteEnableDownvotesChange
328 className="form-check-label"
329 htmlFor="create-site-downvotes"
331 {i18n.t("enable_downvotes")}
336 <div className="form-group row">
337 <div className="col-12">
338 <div className="form-check">
340 className="form-check-input"
341 id="create-site-enable-nsfw"
343 checked={toUndefined(this.state.siteForm.enable_nsfw)}
344 onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
347 className="form-check-label"
348 htmlFor="create-site-enable-nsfw"
350 {i18n.t("enable_nsfw")}
355 <div className="form-group row">
356 <div className="col-12">
357 <div className="form-check">
359 className="form-check-input"
360 id="create-site-open-registration"
362 checked={toUndefined(this.state.siteForm.open_registration)}
365 this.handleSiteOpenRegistrationChange
369 className="form-check-label"
370 htmlFor="create-site-open-registration"
372 {i18n.t("open_registration")}
377 <div className="form-group row">
378 <div className="col-12">
379 <div className="form-check">
381 className="form-check-input"
382 id="create-site-community-creation-admin-only"
384 checked={toUndefined(
385 this.state.siteForm.community_creation_admin_only
389 this.handleSiteCommunityCreationAdminOnly
393 className="form-check-label"
394 htmlFor="create-site-community-creation-admin-only"
396 {i18n.t("community_creation_admin_only")}
401 <div className="form-group row">
402 <div className="col-12">
403 <div className="form-check">
405 className="form-check-input"
406 id="create-site-require-email-verification"
408 checked={toUndefined(
409 this.state.siteForm.require_email_verification
413 this.handleSiteRequireEmailVerification
417 className="form-check-label"
418 htmlFor="create-site-require-email-verification"
420 {i18n.t("require_email_verification")}
425 <div className="form-group row">
426 <div className="col-12">
427 <div className="form-check">
429 className="form-check-input"
430 id="create-site-require-application"
432 checked={toUndefined(this.state.siteForm.require_application)}
433 onChange={linkEvent(this, this.handleSiteRequireApplication)}
436 className="form-check-label"
437 htmlFor="create-site-require-application"
439 {i18n.t("require_registration_application")}
444 <div className="form-group row">
445 <div className="col-12">
446 <div className="form-check">
448 className="form-check-input"
449 id="create-site-application-email-admins"
451 checked={toUndefined(
452 this.state.siteForm.application_email_admins
456 this.handleSiteApplicationEmailAdmins
460 className="form-check-label"
461 htmlFor="create-site-email-admins"
463 {i18n.t("application_email_admins")}
468 <div className="form-group row">
469 <div className="col-12">
471 className="form-check-label mr-2"
472 htmlFor="create-site-default-theme"
477 id="create-site-default-theme"
478 value={toUndefined(this.state.siteForm.default_theme)}
479 onChange={linkEvent(this, this.handleSiteDefaultTheme)}
480 className="custom-select w-auto"
482 <option value="browser">{i18n.t("browser_default")}</option>
483 {this.state.themeList.unwrapOr([]).map(theme => (
484 <option key={theme} value={theme}>
491 {this.props.showLocal && (
492 <form className="form-group row">
493 <label className="col-sm-3">{i18n.t("listing_type")}</label>
494 <div className="col-sm-9">
498 this.state.siteForm.default_post_listing_type.unwrapOr(
504 showSubscribed={false}
505 onChange={this.handleDefaultPostListingTypeChange}
510 <div className="form-group row">
511 <div className="col-12">
512 <div className="form-check">
514 className="form-check-input"
515 id="create-site-private-instance"
517 checked={toUndefined(this.state.siteForm.private_instance)}
518 onChange={linkEvent(this, this.handleSitePrivateInstance)}
521 className="form-check-label"
522 htmlFor="create-site-private-instance"
524 {i18n.t("private_instance")}
529 <div className="form-group row">
530 <div className="col-12">
531 <div className="form-check">
533 className="form-check-input"
534 id="create-site-hide-modlog-mod-names"
536 checked={toUndefined(
537 this.state.siteForm.hide_modlog_mod_names
539 onChange={linkEvent(this, this.handleSiteHideModlogModNames)}
542 className="form-check-label"
543 htmlFor="create-site-hide-modlog-mod-names"
545 {i18n.t("hide_modlog_mod_names")}
550 <div className="form-group row">
552 className="col-12 col-form-label"
553 htmlFor="create-site-slur-filter-regex"
555 {i18n.t("slur_filter_regex")}
557 <div className="col-12">
560 id="create-site-slur-filter-regex"
561 placeholder="(word1|word2)"
562 className="form-control"
563 value={toUndefined(this.state.siteForm.slur_filter_regex)}
564 onInput={linkEvent(this, this.handleSiteSlurFilterRegex)}
570 allLanguages={this.props.siteRes.all_languages}
571 selectedLanguageIds={this.state.siteForm.discussion_languages}
573 onChange={this.handleDiscussionLanguageChange}
575 <div className="form-group row">
577 className="col-12 col-form-label"
578 htmlFor="create-site-actor-name"
580 {i18n.t("actor_name_max_length")}
582 <div className="col-12">
585 id="create-site-actor-name"
586 className="form-control"
588 value={toUndefined(this.state.siteForm.actor_name_max_length)}
589 onInput={linkEvent(this, this.handleSiteActorNameMaxLength)}
593 <div className="form-group row">
594 <div className="col-12">
595 <div className="form-check">
597 className="form-check-input"
598 id="create-site-federation-enabled"
600 checked={toUndefined(this.state.siteForm.federation_enabled)}
601 onChange={linkEvent(this, this.handleSiteFederationEnabled)}
604 className="form-check-label"
605 htmlFor="create-site-federation-enabled"
607 {i18n.t("federation_enabled")}
612 {this.state.siteForm.federation_enabled.unwrapOr(false) && (
614 <div className="form-group row">
616 className="col-12 col-form-label"
617 htmlFor="create-site-allowed-instances"
619 {i18n.t("allowed_instances")}
621 <div className="col-12">
624 placeholder="instance1.tld,instance2.tld"
625 id="create-site-allowed-instances"
626 className="form-control"
627 value={this.instancesToString(
628 this.state.siteForm.allowed_instances
630 onInput={linkEvent(this, this.handleSiteAllowedInstances)}
634 <div className="form-group row">
636 className="col-12 col-form-label"
637 htmlFor="create-site-blocked-instances"
639 {i18n.t("blocked_instances")}
641 <div className="col-12">
644 placeholder="instance1.tld,instance2.tld"
645 id="create-site-blocked-instances"
646 className="form-control"
647 value={this.instancesToString(
648 this.state.siteForm.blocked_instances
650 onInput={linkEvent(this, this.handleSiteBlockedInstances)}
654 <div className="form-group row">
655 <div className="col-12">
656 <div className="form-check">
658 className="form-check-input"
659 id="create-site-federation-debug"
661 checked={toUndefined(
662 this.state.siteForm.federation_debug
664 onChange={linkEvent(this, this.handleSiteFederationDebug)}
667 className="form-check-label"
668 htmlFor="create-site-federation-debug"
670 {i18n.t("federation_debug")}
675 <div className="form-group row">
677 className="col-12 col-form-label"
678 htmlFor="create-site-federation-worker-count"
680 {i18n.t("federation_worker_count")}
682 <div className="col-12">
685 id="create-site-federation-worker-count"
686 className="form-control"
689 this.state.siteForm.federation_worker_count
693 this.handleSiteFederationWorkerCount
700 <div className="form-group row">
701 <div className="col-12">
702 <div className="form-check">
704 className="form-check-input"
705 id="create-site-captcha-enabled"
707 checked={toUndefined(this.state.siteForm.captcha_enabled)}
708 onChange={linkEvent(this, this.handleSiteCaptchaEnabled)}
711 className="form-check-label"
712 htmlFor="create-site-captcha-enabled"
714 {i18n.t("captcha_enabled")}
719 {this.state.siteForm.captcha_enabled.unwrapOr(false) && (
720 <div className="form-group row">
721 <div className="col-12">
723 className="form-check-label mr-2"
724 htmlFor="create-site-captcha-difficulty"
726 {i18n.t("captcha_difficulty")}
729 id="create-site-captcha-difficulty"
730 value={toUndefined(this.state.siteForm.captcha_difficulty)}
731 onChange={linkEvent(this, this.handleSiteCaptchaDifficulty)}
732 className="custom-select w-auto"
734 <option value="easy">{i18n.t("easy")}</option>
735 <option value="medium">{i18n.t("medium")}</option>
736 <option value="hard">{i18n.t("hard")}</option>
741 <div className="form-group row">
743 className="col-12 col-form-label"
744 htmlFor="create-site-rate-limit-message"
746 {i18n.t("rate_limit_message")}
748 <div className="col-12">
751 id="create-site-rate-limit-message"
752 className="form-control"
754 value={toUndefined(this.state.siteForm.rate_limit_message)}
755 onInput={linkEvent(this, this.handleSiteRateLimitMessage)}
759 <div className="form-group row">
761 className="col-12 col-form-label"
762 htmlFor="create-site-rate-limit-message-per-second"
764 {i18n.t("per_second")}
766 <div className="col-12">
769 id="create-site-rate-limit-message-per-second"
770 className="form-control"
773 this.state.siteForm.rate_limit_message_per_second
777 this.handleSiteRateLimitMessagePerSecond
782 <div className="form-group row">
784 className="col-12 col-form-label"
785 htmlFor="create-site-rate-limit-post"
787 {i18n.t("rate_limit_post")}
789 <div className="col-12">
792 id="create-site-rate-limit-post"
793 className="form-control"
795 value={toUndefined(this.state.siteForm.rate_limit_post)}
796 onInput={linkEvent(this, this.handleSiteRateLimitPost)}
800 <div className="form-group row">
802 className="col-12 col-form-label"
803 htmlFor="create-site-rate-limit-post-per-second"
805 {i18n.t("per_second")}
807 <div className="col-12">
810 id="create-site-rate-limit-post-per-second"
811 className="form-control"
814 this.state.siteForm.rate_limit_post_per_second
816 onInput={linkEvent(this, this.handleSiteRateLimitPostPerSecond)}
820 <div className="form-group row">
822 className="col-12 col-form-label"
823 htmlFor="create-site-rate-limit-register"
825 {i18n.t("rate_limit_register")}
827 <div className="col-12">
830 id="create-site-rate-limit-register"
831 className="form-control"
833 value={toUndefined(this.state.siteForm.rate_limit_register)}
834 onInput={linkEvent(this, this.handleSiteRateLimitRegister)}
838 <div className="form-group row">
840 className="col-12 col-form-label"
841 htmlFor="create-site-rate-limit-register-per-second"
843 {i18n.t("per_second")}
845 <div className="col-12">
848 id="create-site-rate-limit-register-per-second"
849 className="form-control"
852 this.state.siteForm.rate_limit_register_per_second
856 this.handleSiteRateLimitRegisterPerSecond
861 <div className="form-group row">
863 className="col-12 col-form-label"
864 htmlFor="create-site-rate-limit-image"
866 {i18n.t("rate_limit_image")}
868 <div className="col-12">
871 id="create-site-rate-limit-image"
872 className="form-control"
874 value={toUndefined(this.state.siteForm.rate_limit_image)}
875 onInput={linkEvent(this, this.handleSiteRateLimitImage)}
879 <div className="form-group row">
881 className="col-12 col-form-label"
882 htmlFor="create-site-rate-limit-image-per-second"
884 {i18n.t("per_second")}
886 <div className="col-12">
889 id="create-site-rate-limit-image-per-second"
890 className="form-control"
893 this.state.siteForm.rate_limit_image_per_second
897 this.handleSiteRateLimitImagePerSecond
902 <div className="form-group row">
904 className="col-12 col-form-label"
905 htmlFor="create-site-rate-limit-comment"
907 {i18n.t("rate_limit_comment")}
909 <div className="col-12">
912 id="create-site-rate-limit-comment"
913 className="form-control"
915 value={toUndefined(this.state.siteForm.rate_limit_comment)}
916 onInput={linkEvent(this, this.handleSiteRateLimitComment)}
920 <div className="form-group row">
922 className="col-12 col-form-label"
923 htmlFor="create-site-rate-limit-comment-per-second"
925 {i18n.t("per_second")}
927 <div className="col-12">
930 id="create-site-rate-limit-comment-per-second"
931 className="form-control"
934 this.state.siteForm.rate_limit_comment_per_second
938 this.handleSiteRateLimitCommentPerSecond
943 <div className="form-group row">
945 className="col-12 col-form-label"
946 htmlFor="create-site-rate-limit-search"
948 {i18n.t("rate_limit_search")}
950 <div className="col-12">
953 id="create-site-rate-limit-search"
954 className="form-control"
956 value={toUndefined(this.state.siteForm.rate_limit_search)}
957 onInput={linkEvent(this, this.handleSiteRateLimitSearch)}
961 <div className="form-group row">
963 className="col-12 col-form-label"
964 htmlFor="create-site-rate-limit-search-per-second"
966 {i18n.t("per_second")}
968 <div className="col-12">
971 id="create-site-rate-limit-search-per-second"
972 className="form-control"
975 this.state.siteForm.rate_limit_search_per_second
979 this.handleSiteRateLimitSearchPerSecond
985 <div className="form-group row">
986 <h5 className="col-12">{i18n.t("taglines")}</h5>
987 <div className="table-responsive col-12">
990 className="table table-sm table-hover"
992 <thead className="pointer"></thead>
994 {this.state.siteForm.taglines
996 .map((cv, index) => (
1000 initialContent={Some(cv)}
1001 initialLanguageId={None}
1005 onContentChange={s =>
1006 this.handleTaglineChange(this, index, s)
1008 hideNavigationWarnings
1009 allLanguages={this.props.siteRes.all_languages}
1012 <td className="text-right">
1014 className="btn btn-link btn-animate text-muted"
1016 this.handleDeleteTaglineClick(this, index, e)
1018 data-tippy-content={i18n.t("delete")}
1019 aria-label={i18n.t("delete")}
1023 classes={`icon-inline text-danger`}
1032 className="btn btn-sm btn-secondary mr-2"
1033 onClick={e => this.handleAddTaglineClick(this, e)}
1035 {i18n.t("add_tagline")}
1040 <div className="form-group row">
1041 <div className="col-12">
1044 className="btn btn-secondary mr-2"
1045 disabled={this.state.loading}
1047 {this.state.loading ? (
1050 capitalizeFirstLetter(i18n.t("save"))
1052 capitalizeFirstLetter(i18n.t("create"))
1062 handleCreateSiteSubmit(i: SiteForm, event: any) {
1063 event.preventDefault();
1064 i.setState({ loading: true });
1065 i.setState(s => ((s.siteForm.auth = auth().unwrap()), s));
1066 if (i.props.siteRes.site_view.local_site.site_setup) {
1067 WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm));
1069 let sForm = i.state.siteForm;
1070 let form = new CreateSite({
1071 name: sForm.name.unwrapOr("My site"),
1072 sidebar: sForm.sidebar,
1073 description: sForm.description,
1075 banner: sForm.banner,
1076 community_creation_admin_only: sForm.community_creation_admin_only,
1077 enable_nsfw: sForm.enable_nsfw,
1078 enable_downvotes: sForm.enable_downvotes,
1079 require_application: sForm.require_application,
1080 application_question: sForm.application_question,
1081 open_registration: sForm.open_registration,
1082 require_email_verification: sForm.require_email_verification,
1083 private_instance: sForm.private_instance,
1084 default_theme: sForm.default_theme,
1085 default_post_listing_type: sForm.default_post_listing_type,
1086 application_email_admins: sForm.application_email_admins,
1087 auth: auth().unwrap(),
1088 hide_modlog_mod_names: sForm.hide_modlog_mod_names,
1089 legal_information: sForm.legal_information,
1090 slur_filter_regex: sForm.slur_filter_regex,
1091 actor_name_max_length: sForm.actor_name_max_length,
1092 rate_limit_message: sForm.rate_limit_message,
1093 rate_limit_message_per_second: sForm.rate_limit_message_per_second,
1094 rate_limit_comment: sForm.rate_limit_comment,
1095 rate_limit_comment_per_second: sForm.rate_limit_comment_per_second,
1096 rate_limit_image: sForm.rate_limit_image,
1097 rate_limit_image_per_second: sForm.rate_limit_image_per_second,
1098 rate_limit_post: sForm.rate_limit_post,
1099 rate_limit_post_per_second: sForm.rate_limit_post_per_second,
1100 rate_limit_register: sForm.rate_limit_register,
1101 rate_limit_register_per_second: sForm.rate_limit_register_per_second,
1102 rate_limit_search: sForm.rate_limit_search,
1103 rate_limit_search_per_second: sForm.rate_limit_search_per_second,
1104 federation_enabled: sForm.federation_enabled,
1105 federation_debug: sForm.federation_debug,
1106 federation_worker_count: sForm.federation_worker_count,
1107 captcha_enabled: sForm.captcha_enabled,
1108 captcha_difficulty: sForm.captcha_difficulty,
1109 allowed_instances: sForm.allowed_instances,
1110 blocked_instances: sForm.blocked_instances,
1111 discussion_languages: sForm.discussion_languages,
1113 WebSocketService.Instance.send(wsClient.createSite(form));
1115 i.setState(i.state);
1118 instancesToString(opt: Option<string[]>): string {
1119 return opt.map(list => list.join(",")).unwrapOr("");
1122 handleSiteAllowedInstances(i: SiteForm, event: any) {
1123 let list = splitToList(event.target.value);
1124 i.setState(s => ((s.siteForm.allowed_instances = list), s));
1127 handleSiteBlockedInstances(i: SiteForm, event: any) {
1128 let list = splitToList(event.target.value);
1129 i.setState(s => ((s.siteForm.blocked_instances = list), s));
1132 handleSiteNameChange(i: SiteForm, event: any) {
1133 i.state.siteForm.name = Some(event.target.value);
1134 i.setState(i.state);
1137 handleSiteSidebarChange(val: string) {
1138 this.setState(s => ((s.siteForm.sidebar = Some(val)), s));
1141 handleSiteLegalInfoChange(val: string) {
1142 this.setState(s => ((s.siteForm.legal_information = Some(val)), s));
1145 handleTaglineChange(i: SiteForm, index: number, val: string) {
1146 i.state.siteForm.taglines.match({
1152 i.setState(i.state);
1155 handleDeleteTaglineClick(
1158 event: InfernoMouseEvent<HTMLButtonElement>
1160 event.preventDefault();
1161 if (i.state.siteForm.taglines.isSome()) {
1162 let taglines = i.state.siteForm.taglines.unwrap();
1163 taglines.splice(index, 1);
1164 i.state.siteForm.taglines = None; // force rerender of table rows
1165 i.setState(i.state);
1166 i.state.siteForm.taglines = Some(taglines);
1167 i.setState(i.state);
1171 handleAddTaglineClick(
1173 event: InfernoMouseEvent<HTMLButtonElement>
1175 event.preventDefault();
1176 if (i.state.siteForm.taglines.isNone()) {
1177 i.state.siteForm.taglines = Some([]);
1179 i.state.siteForm.taglines.unwrap().push("");
1180 i.setState(i.state);
1183 handleSiteApplicationQuestionChange(val: string) {
1184 this.setState(s => ((s.siteForm.application_question = Some(val)), s));
1187 handleSiteDescChange(i: SiteForm, event: any) {
1188 i.state.siteForm.description = Some(event.target.value);
1189 i.setState(i.state);
1192 handleSiteEnableNsfwChange(i: SiteForm, event: any) {
1193 i.state.siteForm.enable_nsfw = Some(event.target.checked);
1194 i.setState(i.state);
1197 handleSiteOpenRegistrationChange(i: SiteForm, event: any) {
1198 i.state.siteForm.open_registration = Some(event.target.checked);
1199 i.setState(i.state);
1202 handleSiteCommunityCreationAdminOnly(i: SiteForm, event: any) {
1203 i.state.siteForm.community_creation_admin_only = Some(event.target.checked);
1204 i.setState(i.state);
1207 handleSiteEnableDownvotesChange(i: SiteForm, event: any) {
1208 i.state.siteForm.enable_downvotes = Some(event.target.checked);
1209 i.setState(i.state);
1212 handleSiteRequireApplication(i: SiteForm, event: any) {
1213 i.state.siteForm.require_application = Some(event.target.checked);
1214 i.setState(i.state);
1217 handleSiteRequireEmailVerification(i: SiteForm, event: any) {
1218 i.state.siteForm.require_email_verification = Some(event.target.checked);
1219 i.setState(i.state);
1222 handleSiteApplicationEmailAdmins(i: SiteForm, event: any) {
1223 i.state.siteForm.application_email_admins = Some(event.target.checked);
1224 i.setState(i.state);
1227 handleSitePrivateInstance(i: SiteForm, event: any) {
1228 i.state.siteForm.private_instance = Some(event.target.checked);
1229 i.setState(i.state);
1232 handleSiteHideModlogModNames(i: SiteForm, event: any) {
1233 i.state.siteForm.hide_modlog_mod_names = Some(event.target.checked);
1234 i.setState(i.state);
1237 handleSiteDefaultTheme(i: SiteForm, event: any) {
1238 i.state.siteForm.default_theme = Some(event.target.value);
1239 i.setState(i.state);
1242 handleIconUpload(url: string) {
1243 this.setState(s => ((s.siteForm.icon = Some(url)), s));
1246 handleIconRemove() {
1247 this.setState(s => ((s.siteForm.icon = Some("")), s));
1250 handleBannerUpload(url: string) {
1251 this.setState(s => ((s.siteForm.banner = Some(url)), s));
1254 handleBannerRemove() {
1255 this.setState(s => ((s.siteForm.banner = Some("")), s));
1258 handleSiteSlurFilterRegex(i: SiteForm, event: any) {
1260 s => ((s.siteForm.slur_filter_regex = Some(event.target.value)), s)
1264 handleSiteActorNameMaxLength(i: SiteForm, event: any) {
1267 (s.siteForm.actor_name_max_length = Some(Number(event.target.value))), s
1272 handleSiteRateLimitMessage(i: SiteForm, event: any) {
1275 (s.siteForm.rate_limit_message = Some(Number(event.target.value))), s
1280 handleSiteRateLimitMessagePerSecond(i: SiteForm, event: any) {
1283 (s.siteForm.rate_limit_message_per_second = Some(
1284 Number(event.target.value)
1291 handleSiteRateLimitPost(i: SiteForm, event: any) {
1293 s => ((s.siteForm.rate_limit_post = Some(Number(event.target.value))), s)
1297 handleSiteRateLimitPostPerSecond(i: SiteForm, event: any) {
1300 (s.siteForm.rate_limit_post_per_second = Some(
1301 Number(event.target.value)
1308 handleSiteRateLimitImage(i: SiteForm, event: any) {
1310 s => ((s.siteForm.rate_limit_image = Some(Number(event.target.value))), s)
1314 handleSiteRateLimitImagePerSecond(i: SiteForm, event: any) {
1317 (s.siteForm.rate_limit_image_per_second = Some(
1318 Number(event.target.value)
1325 handleSiteRateLimitComment(i: SiteForm, event: any) {
1328 (s.siteForm.rate_limit_comment = Some(Number(event.target.value))), s
1333 handleSiteRateLimitCommentPerSecond(i: SiteForm, event: any) {
1336 (s.siteForm.rate_limit_comment_per_second = Some(
1337 Number(event.target.value)
1344 handleSiteRateLimitSearch(i: SiteForm, event: any) {
1347 (s.siteForm.rate_limit_search = Some(Number(event.target.value))), s
1352 handleSiteRateLimitSearchPerSecond(i: SiteForm, event: any) {
1355 (s.siteForm.rate_limit_search_per_second = Some(
1356 Number(event.target.value)
1363 handleSiteRateLimitRegister(i: SiteForm, event: any) {
1366 (s.siteForm.rate_limit_register = Some(Number(event.target.value))), s
1371 handleSiteRateLimitRegisterPerSecond(i: SiteForm, event: any) {
1374 (s.siteForm.rate_limit_register_per_second = Some(
1375 Number(event.target.value)
1382 handleSiteFederationEnabled(i: SiteForm, event: any) {
1383 i.state.siteForm.federation_enabled = Some(event.target.checked);
1384 i.setState(i.state);
1387 handleSiteFederationDebug(i: SiteForm, event: any) {
1388 i.state.siteForm.federation_debug = Some(event.target.checked);
1389 i.setState(i.state);
1392 handleSiteFederationWorkerCount(i: SiteForm, event: any) {
1395 (s.siteForm.federation_worker_count = Some(Number(event.target.value))),
1401 handleSiteCaptchaEnabled(i: SiteForm, event: any) {
1402 i.state.siteForm.captcha_enabled = Some(event.target.checked);
1403 i.setState(i.state);
1406 handleSiteCaptchaDifficulty(i: SiteForm, event: any) {
1408 s => ((s.siteForm.captcha_difficulty = Some(event.target.value)), s)
1412 handleDiscussionLanguageChange(val: number[]) {
1413 this.setState(s => ((s.siteForm.discussion_languages = Some(val)), s));
1416 handleDefaultPostListingTypeChange(val: ListingType) {
1419 (s.siteForm.default_post_listing_type = Some(
1420 ListingType[ListingType[val]]
1428 function splitToList(commaList: string): Option<string[]> {
1429 if (commaList !== "") {
1430 let list = commaList.trim().split(",");