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 federation_strict_allowlist: None,
76 federation_http_fetch_retry_limit: None,
77 captcha_enabled: None,
78 captcha_difficulty: None,
79 allowed_instances: None,
80 blocked_instances: None,
88 constructor(props: any, context: any) {
89 super(props, context);
91 this.state = this.emptyState;
92 this.handleSiteSidebarChange = this.handleSiteSidebarChange.bind(this);
93 this.handleSiteLegalInfoChange = this.handleSiteLegalInfoChange.bind(this);
94 this.handleSiteApplicationQuestionChange =
95 this.handleSiteApplicationQuestionChange.bind(this);
97 this.handleIconUpload = this.handleIconUpload.bind(this);
98 this.handleIconRemove = this.handleIconRemove.bind(this);
100 this.handleBannerUpload = this.handleBannerUpload.bind(this);
101 this.handleBannerRemove = this.handleBannerRemove.bind(this);
103 this.handleDefaultPostListingTypeChange =
104 this.handleDefaultPostListingTypeChange.bind(this);
106 this.handleDiscussionLanguageChange =
107 this.handleDiscussionLanguageChange.bind(this);
109 let site = this.props.siteRes.site_view.site;
110 let ls = this.props.siteRes.site_view.local_site;
111 let lsrl = this.props.siteRes.site_view.local_site_rate_limit;
114 siteForm: new EditSite({
115 name: Some(site.name),
116 sidebar: site.sidebar,
117 description: site.description,
118 enable_downvotes: Some(ls.enable_downvotes),
119 open_registration: Some(ls.open_registration),
120 enable_nsfw: Some(ls.enable_nsfw),
121 community_creation_admin_only: Some(ls.community_creation_admin_only),
124 require_email_verification: Some(ls.require_email_verification),
125 require_application: Some(ls.require_application),
126 application_question: ls.application_question,
127 private_instance: Some(ls.private_instance),
128 default_theme: Some(ls.default_theme),
129 default_post_listing_type: Some(ls.default_post_listing_type),
130 legal_information: ls.legal_information,
131 application_email_admins: Some(ls.application_email_admins),
132 hide_modlog_mod_names: Some(ls.hide_modlog_mod_names),
133 discussion_languages: Some(this.props.siteRes.discussion_languages),
134 slur_filter_regex: ls.slur_filter_regex,
135 actor_name_max_length: Some(ls.actor_name_max_length),
136 rate_limit_message: Some(lsrl.message),
137 rate_limit_message_per_second: Some(lsrl.message_per_second),
138 rate_limit_comment: Some(lsrl.comment),
139 rate_limit_comment_per_second: Some(lsrl.comment_per_second),
140 rate_limit_image: Some(lsrl.image),
141 rate_limit_image_per_second: Some(lsrl.image_per_second),
142 rate_limit_post: Some(lsrl.post),
143 rate_limit_post_per_second: Some(lsrl.post_per_second),
144 rate_limit_register: Some(lsrl.register),
145 rate_limit_register_per_second: Some(lsrl.register_per_second),
146 rate_limit_search: Some(lsrl.search),
147 rate_limit_search_per_second: Some(lsrl.search_per_second),
148 federation_enabled: Some(ls.federation_enabled),
149 federation_debug: Some(ls.federation_debug),
150 federation_worker_count: Some(ls.federation_worker_count),
151 federation_strict_allowlist: Some(ls.federation_strict_allowlist),
152 federation_http_fetch_retry_limit: Some(
153 ls.federation_http_fetch_retry_limit
155 captcha_enabled: Some(ls.captcha_enabled),
156 captcha_difficulty: Some(ls.captcha_difficulty),
157 allowed_instances: this.props.siteRes.federated_instances.andThen(
160 blocked_instances: this.props.siteRes.federated_instances.andThen(
163 taglines: this.props.siteRes.taglines.map(x => x.map(y => y.content)),
169 async componentDidMount() {
170 this.setState({ themeList: Some(await fetchThemeList()) });
173 // Necessary to stop the loading
174 componentWillReceiveProps() {
175 this.setState({ loading: false });
178 componentDidUpdate() {
180 !this.state.loading &&
181 !this.props.siteRes.site_view.local_site.site_setup &&
182 (this.state.siteForm.name ||
183 this.state.siteForm.sidebar ||
184 this.state.siteForm.application_question ||
185 this.state.siteForm.description)
187 window.onbeforeunload = () => true;
189 window.onbeforeunload = undefined;
193 componentWillUnmount() {
194 window.onbeforeunload = null;
198 let siteSetup = this.props.siteRes.site_view.local_site.site_setup;
203 !this.state.loading &&
205 (this.state.siteForm.name ||
206 this.state.siteForm.sidebar ||
207 this.state.siteForm.application_question ||
208 this.state.siteForm.description)
210 message={i18n.t("block_leaving")}
212 <form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
215 ? capitalizeFirstLetter(i18n.t("save"))
216 : capitalizeFirstLetter(i18n.t("name"))
217 } ${i18n.t("your_site")}`}</h5>
218 <div className="form-group row">
219 <label className="col-12 col-form-label" htmlFor="create-site-name">
222 <div className="col-12">
225 id="create-site-name"
226 className="form-control"
227 value={toUndefined(this.state.siteForm.name)}
228 onInput={linkEvent(this, this.handleSiteNameChange)}
235 <div className="form-group">
236 <label>{i18n.t("icon")}</label>
238 uploadTitle={i18n.t("upload_icon")}
239 imageSrc={this.state.siteForm.icon}
240 onUpload={this.handleIconUpload}
241 onRemove={this.handleIconRemove}
245 <div className="form-group">
246 <label>{i18n.t("banner")}</label>
248 uploadTitle={i18n.t("upload_banner")}
249 imageSrc={this.state.siteForm.banner}
250 onUpload={this.handleBannerUpload}
251 onRemove={this.handleBannerRemove}
254 <div className="form-group row">
255 <label className="col-12 col-form-label" htmlFor="site-desc">
256 {i18n.t("description")}
258 <div className="col-12">
261 className="form-control"
263 value={toUndefined(this.state.siteForm.description)}
264 onInput={linkEvent(this, this.handleSiteDescChange)}
269 <div className="form-group row">
270 <label className="col-12 col-form-label">{i18n.t("sidebar")}</label>
271 <div className="col-12">
273 initialContent={this.state.siteForm.sidebar}
274 initialLanguageId={None}
278 onContentChange={this.handleSiteSidebarChange}
279 hideNavigationWarnings
284 <div className="form-group row">
285 <label className="col-12 col-form-label">
286 {i18n.t("legal_information")}
288 <div className="col-12">
290 initialContent={this.state.siteForm.legal_information}
291 initialLanguageId={None}
295 onContentChange={this.handleSiteLegalInfoChange}
296 hideNavigationWarnings
301 {this.state.siteForm.require_application.unwrapOr(false) && (
302 <div className="form-group row">
303 <label className="col-12 col-form-label">
304 {i18n.t("application_questionnaire")}
306 <div className="col-12">
308 initialContent={this.state.siteForm.application_question}
309 initialLanguageId={None}
313 onContentChange={this.handleSiteApplicationQuestionChange}
314 hideNavigationWarnings
320 <div className="form-group row">
321 <div className="col-12">
322 <div className="form-check">
324 className="form-check-input"
325 id="create-site-downvotes"
327 checked={toUndefined(this.state.siteForm.enable_downvotes)}
330 this.handleSiteEnableDownvotesChange
334 className="form-check-label"
335 htmlFor="create-site-downvotes"
337 {i18n.t("enable_downvotes")}
342 <div className="form-group row">
343 <div className="col-12">
344 <div className="form-check">
346 className="form-check-input"
347 id="create-site-enable-nsfw"
349 checked={toUndefined(this.state.siteForm.enable_nsfw)}
350 onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
353 className="form-check-label"
354 htmlFor="create-site-enable-nsfw"
356 {i18n.t("enable_nsfw")}
361 <div className="form-group row">
362 <div className="col-12">
363 <div className="form-check">
365 className="form-check-input"
366 id="create-site-open-registration"
368 checked={toUndefined(this.state.siteForm.open_registration)}
371 this.handleSiteOpenRegistrationChange
375 className="form-check-label"
376 htmlFor="create-site-open-registration"
378 {i18n.t("open_registration")}
383 <div className="form-group row">
384 <div className="col-12">
385 <div className="form-check">
387 className="form-check-input"
388 id="create-site-community-creation-admin-only"
390 checked={toUndefined(
391 this.state.siteForm.community_creation_admin_only
395 this.handleSiteCommunityCreationAdminOnly
399 className="form-check-label"
400 htmlFor="create-site-community-creation-admin-only"
402 {i18n.t("community_creation_admin_only")}
407 <div className="form-group row">
408 <div className="col-12">
409 <div className="form-check">
411 className="form-check-input"
412 id="create-site-require-email-verification"
414 checked={toUndefined(
415 this.state.siteForm.require_email_verification
419 this.handleSiteRequireEmailVerification
423 className="form-check-label"
424 htmlFor="create-site-require-email-verification"
426 {i18n.t("require_email_verification")}
431 <div className="form-group row">
432 <div className="col-12">
433 <div className="form-check">
435 className="form-check-input"
436 id="create-site-require-application"
438 checked={toUndefined(this.state.siteForm.require_application)}
439 onChange={linkEvent(this, this.handleSiteRequireApplication)}
442 className="form-check-label"
443 htmlFor="create-site-require-application"
445 {i18n.t("require_registration_application")}
450 <div className="form-group row">
451 <div className="col-12">
452 <div className="form-check">
454 className="form-check-input"
455 id="create-site-application-email-admins"
457 checked={toUndefined(
458 this.state.siteForm.application_email_admins
462 this.handleSiteApplicationEmailAdmins
466 className="form-check-label"
467 htmlFor="create-site-email-admins"
469 {i18n.t("application_email_admins")}
474 <div className="form-group row">
475 <div className="col-12">
477 className="form-check-label mr-2"
478 htmlFor="create-site-default-theme"
483 id="create-site-default-theme"
484 value={toUndefined(this.state.siteForm.default_theme)}
485 onChange={linkEvent(this, this.handleSiteDefaultTheme)}
486 className="custom-select w-auto"
488 <option value="browser">{i18n.t("browser_default")}</option>
489 {this.state.themeList.unwrapOr([]).map(theme => (
490 <option key={theme} value={theme}>
497 {this.props.showLocal && (
498 <form className="form-group row">
499 <label className="col-sm-3">{i18n.t("listing_type")}</label>
500 <div className="col-sm-9">
504 this.state.siteForm.default_post_listing_type.unwrapOr(
510 showSubscribed={false}
511 onChange={this.handleDefaultPostListingTypeChange}
516 <div className="form-group row">
517 <div className="col-12">
518 <div className="form-check">
520 className="form-check-input"
521 id="create-site-private-instance"
523 checked={toUndefined(this.state.siteForm.private_instance)}
524 onChange={linkEvent(this, this.handleSitePrivateInstance)}
527 className="form-check-label"
528 htmlFor="create-site-private-instance"
530 {i18n.t("private_instance")}
535 <div className="form-group row">
536 <div className="col-12">
537 <div className="form-check">
539 className="form-check-input"
540 id="create-site-hide-modlog-mod-names"
542 checked={toUndefined(
543 this.state.siteForm.hide_modlog_mod_names
545 onChange={linkEvent(this, this.handleSiteHideModlogModNames)}
548 className="form-check-label"
549 htmlFor="create-site-hide-modlog-mod-names"
551 {i18n.t("hide_modlog_mod_names")}
556 <div className="form-group row">
558 className="col-12 col-form-label"
559 htmlFor="create-site-slur-filter-regex"
561 {i18n.t("slur_filter_regex")}
563 <div className="col-12">
566 id="create-site-slur-filter-regex"
567 placeholder="(word1|word2)"
568 className="form-control"
569 value={toUndefined(this.state.siteForm.slur_filter_regex)}
570 onInput={linkEvent(this, this.handleSiteSlurFilterRegex)}
576 allLanguages={this.props.siteRes.all_languages}
577 selectedLanguageIds={this.state.siteForm.discussion_languages}
579 onChange={this.handleDiscussionLanguageChange}
581 <div className="form-group row">
583 className="col-12 col-form-label"
584 htmlFor="create-site-actor-name"
586 {i18n.t("actor_name_max_length")}
588 <div className="col-12">
591 id="create-site-actor-name"
592 className="form-control"
594 value={toUndefined(this.state.siteForm.actor_name_max_length)}
595 onInput={linkEvent(this, this.handleSiteActorNameMaxLength)}
599 <div className="form-group row">
600 <div className="col-12">
601 <div className="form-check">
603 className="form-check-input"
604 id="create-site-federation-enabled"
606 checked={toUndefined(this.state.siteForm.federation_enabled)}
607 onChange={linkEvent(this, this.handleSiteFederationEnabled)}
610 className="form-check-label"
611 htmlFor="create-site-federation-enabled"
613 {i18n.t("federation_enabled")}
618 {this.state.siteForm.federation_enabled.unwrapOr(false) && (
620 <div className="form-group row">
622 className="col-12 col-form-label"
623 htmlFor="create-site-allowed-instances"
625 {i18n.t("allowed_instances")}
627 <div className="col-12">
630 placeholder="instance1.tld,instance2.tld"
631 id="create-site-allowed-instances"
632 className="form-control"
633 value={this.instancesToString(
634 this.state.siteForm.allowed_instances
636 onInput={linkEvent(this, this.handleSiteAllowedInstances)}
640 <div className="form-group row">
642 className="col-12 col-form-label"
643 htmlFor="create-site-blocked-instances"
645 {i18n.t("blocked_instances")}
647 <div className="col-12">
650 placeholder="instance1.tld,instance2.tld"
651 id="create-site-blocked-instances"
652 className="form-control"
653 value={this.instancesToString(
654 this.state.siteForm.blocked_instances
656 onInput={linkEvent(this, this.handleSiteBlockedInstances)}
660 <div className="form-group row">
661 <div className="col-12">
662 <div className="form-check">
664 className="form-check-input"
665 id="create-site-federation-debug"
667 checked={toUndefined(
668 this.state.siteForm.federation_debug
670 onChange={linkEvent(this, this.handleSiteFederationDebug)}
673 className="form-check-label"
674 htmlFor="create-site-federation-debug"
676 {i18n.t("federation_debug")}
681 <div className="form-group row">
682 <div className="col-12">
683 <div className="form-check">
685 className="form-check-input"
686 id="create-site-federation-strict-allowlist"
688 checked={toUndefined(
689 this.state.siteForm.federation_strict_allowlist
693 this.handleSiteFederationStrictAllowList
697 className="form-check-label"
698 htmlFor="create-site-federation-strict-allowlist"
700 {i18n.t("federation_strict_allowlist")}
705 <div className="form-group row">
707 className="col-12 col-form-label"
708 htmlFor="create-site-federation-http-fetch-retry-limit"
710 {i18n.t("federation_http_fetch_retry_limit")}
712 <div className="col-12">
715 id="create-site-federation-http-fetch-retry-limit"
716 className="form-control"
719 this.state.siteForm.federation_http_fetch_retry_limit
723 this.handleSiteFederationHttpFetchRetryLimit
728 <div className="form-group row">
730 className="col-12 col-form-label"
731 htmlFor="create-site-federation-worker-count"
733 {i18n.t("federation_worker_count")}
735 <div className="col-12">
738 id="create-site-federation-worker-count"
739 className="form-control"
742 this.state.siteForm.federation_worker_count
746 this.handleSiteFederationWorkerCount
753 <div className="form-group row">
754 <div className="col-12">
755 <div className="form-check">
757 className="form-check-input"
758 id="create-site-captcha-enabled"
760 checked={toUndefined(this.state.siteForm.captcha_enabled)}
761 onChange={linkEvent(this, this.handleSiteCaptchaEnabled)}
764 className="form-check-label"
765 htmlFor="create-site-captcha-enabled"
767 {i18n.t("captcha_enabled")}
772 {this.state.siteForm.captcha_enabled.unwrapOr(false) && (
773 <div className="form-group row">
774 <div className="col-12">
776 className="form-check-label mr-2"
777 htmlFor="create-site-captcha-difficulty"
779 {i18n.t("captcha_difficulty")}
782 id="create-site-captcha-difficulty"
783 value={toUndefined(this.state.siteForm.captcha_difficulty)}
784 onChange={linkEvent(this, this.handleSiteCaptchaDifficulty)}
785 className="custom-select w-auto"
787 <option value="easy">{i18n.t("easy")}</option>
788 <option value="medium">{i18n.t("medium")}</option>
789 <option value="hard">{i18n.t("hard")}</option>
794 <div className="form-group row">
796 className="col-12 col-form-label"
797 htmlFor="create-site-rate-limit-message"
799 {i18n.t("rate_limit_message")}
801 <div className="col-12">
804 id="create-site-rate-limit-message"
805 className="form-control"
807 value={toUndefined(this.state.siteForm.rate_limit_message)}
808 onInput={linkEvent(this, this.handleSiteRateLimitMessage)}
812 <div className="form-group row">
814 className="col-12 col-form-label"
815 htmlFor="create-site-rate-limit-message-per-second"
817 {i18n.t("per_second")}
819 <div className="col-12">
822 id="create-site-rate-limit-message-per-second"
823 className="form-control"
826 this.state.siteForm.rate_limit_message_per_second
830 this.handleSiteRateLimitMessagePerSecond
835 <div className="form-group row">
837 className="col-12 col-form-label"
838 htmlFor="create-site-rate-limit-post"
840 {i18n.t("rate_limit_post")}
842 <div className="col-12">
845 id="create-site-rate-limit-post"
846 className="form-control"
848 value={toUndefined(this.state.siteForm.rate_limit_post)}
849 onInput={linkEvent(this, this.handleSiteRateLimitPost)}
853 <div className="form-group row">
855 className="col-12 col-form-label"
856 htmlFor="create-site-rate-limit-post-per-second"
858 {i18n.t("per_second")}
860 <div className="col-12">
863 id="create-site-rate-limit-post-per-second"
864 className="form-control"
867 this.state.siteForm.rate_limit_post_per_second
869 onInput={linkEvent(this, this.handleSiteRateLimitPostPerSecond)}
873 <div className="form-group row">
875 className="col-12 col-form-label"
876 htmlFor="create-site-rate-limit-register"
878 {i18n.t("rate_limit_register")}
880 <div className="col-12">
883 id="create-site-rate-limit-register"
884 className="form-control"
886 value={toUndefined(this.state.siteForm.rate_limit_register)}
887 onInput={linkEvent(this, this.handleSiteRateLimitRegister)}
891 <div className="form-group row">
893 className="col-12 col-form-label"
894 htmlFor="create-site-rate-limit-register-per-second"
896 {i18n.t("per_second")}
898 <div className="col-12">
901 id="create-site-rate-limit-register-per-second"
902 className="form-control"
905 this.state.siteForm.rate_limit_register_per_second
909 this.handleSiteRateLimitRegisterPerSecond
914 <div className="form-group row">
916 className="col-12 col-form-label"
917 htmlFor="create-site-rate-limit-image"
919 {i18n.t("rate_limit_image")}
921 <div className="col-12">
924 id="create-site-rate-limit-image"
925 className="form-control"
927 value={toUndefined(this.state.siteForm.rate_limit_image)}
928 onInput={linkEvent(this, this.handleSiteRateLimitImage)}
932 <div className="form-group row">
934 className="col-12 col-form-label"
935 htmlFor="create-site-rate-limit-image-per-second"
937 {i18n.t("per_second")}
939 <div className="col-12">
942 id="create-site-rate-limit-image-per-second"
943 className="form-control"
946 this.state.siteForm.rate_limit_image_per_second
950 this.handleSiteRateLimitImagePerSecond
955 <div className="form-group row">
957 className="col-12 col-form-label"
958 htmlFor="create-site-rate-limit-comment"
960 {i18n.t("rate_limit_comment")}
962 <div className="col-12">
965 id="create-site-rate-limit-comment"
966 className="form-control"
968 value={toUndefined(this.state.siteForm.rate_limit_comment)}
969 onInput={linkEvent(this, this.handleSiteRateLimitComment)}
973 <div className="form-group row">
975 className="col-12 col-form-label"
976 htmlFor="create-site-rate-limit-comment-per-second"
978 {i18n.t("per_second")}
980 <div className="col-12">
983 id="create-site-rate-limit-comment-per-second"
984 className="form-control"
987 this.state.siteForm.rate_limit_comment_per_second
991 this.handleSiteRateLimitCommentPerSecond
996 <div className="form-group row">
998 className="col-12 col-form-label"
999 htmlFor="create-site-rate-limit-search"
1001 {i18n.t("rate_limit_search")}
1003 <div className="col-12">
1006 id="create-site-rate-limit-search"
1007 className="form-control"
1009 value={toUndefined(this.state.siteForm.rate_limit_search)}
1010 onInput={linkEvent(this, this.handleSiteRateLimitSearch)}
1014 <div className="form-group row">
1016 className="col-12 col-form-label"
1017 htmlFor="create-site-rate-limit-search-per-second"
1019 {i18n.t("per_second")}
1021 <div className="col-12">
1024 id="create-site-rate-limit-search-per-second"
1025 className="form-control"
1028 this.state.siteForm.rate_limit_search_per_second
1032 this.handleSiteRateLimitSearchPerSecond
1037 {siteSetup && <div className="form-group row">
1038 <h5 className="col-12">{i18n.t("taglines")}</h5>
1039 <div className="table-responsive col-12">
1040 <table id="taglines_table" className="table table-sm table-hover">
1041 <thead className="pointer"></thead>
1043 {this.state.siteForm.taglines
1045 .map((cv, index) => (
1049 initialContent={Some(cv)}
1050 initialLanguageId={None}
1054 onContentChange={s =>
1055 this.handleTaglineChange(this, index, s)
1057 hideNavigationWarnings
1058 allLanguages={this.props.siteRes.all_languages}
1061 <td className="text-right">
1063 className="btn btn-link btn-animate text-muted"
1065 this.handleDeleteTaglineClick(this, index, e)
1067 data-tippy-content={i18n.t("delete")}
1068 aria-label={i18n.t("delete")}
1072 classes={`icon-inline text-danger`}
1081 className="btn btn-sm btn-secondary mr-2"
1082 onClick={e => this.handleAddTaglineClick(this, e)}
1084 {i18n.t("add_tagline")}
1088 <div className="form-group row">
1089 <div className="col-12">
1092 className="btn btn-secondary mr-2"
1093 disabled={this.state.loading}
1095 {this.state.loading ? (
1098 capitalizeFirstLetter(i18n.t("save"))
1100 capitalizeFirstLetter(i18n.t("create"))
1110 handleCreateSiteSubmit(i: SiteForm, event: any) {
1111 event.preventDefault();
1112 i.setState({ loading: true });
1113 i.setState(s => ((s.siteForm.auth = auth().unwrap()), s));
1114 if (i.props.siteRes.site_view.local_site.site_setup) {
1115 WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm));
1117 let sForm = i.state.siteForm;
1118 let form = new CreateSite({
1119 name: sForm.name.unwrapOr("My site"),
1120 sidebar: sForm.sidebar,
1121 description: sForm.description,
1123 banner: sForm.banner,
1124 community_creation_admin_only: sForm.community_creation_admin_only,
1125 enable_nsfw: sForm.enable_nsfw,
1126 enable_downvotes: sForm.enable_downvotes,
1127 require_application: sForm.require_application,
1128 application_question: sForm.application_question,
1129 open_registration: sForm.open_registration,
1130 require_email_verification: sForm.require_email_verification,
1131 private_instance: sForm.private_instance,
1132 default_theme: sForm.default_theme,
1133 default_post_listing_type: sForm.default_post_listing_type,
1134 application_email_admins: sForm.application_email_admins,
1135 auth: auth().unwrap(),
1136 hide_modlog_mod_names: sForm.hide_modlog_mod_names,
1137 legal_information: sForm.legal_information,
1138 slur_filter_regex: sForm.slur_filter_regex,
1139 actor_name_max_length: sForm.actor_name_max_length,
1140 rate_limit_message: sForm.rate_limit_message,
1141 rate_limit_message_per_second: sForm.rate_limit_message_per_second,
1142 rate_limit_comment: sForm.rate_limit_comment,
1143 rate_limit_comment_per_second: sForm.rate_limit_comment_per_second,
1144 rate_limit_image: sForm.rate_limit_image,
1145 rate_limit_image_per_second: sForm.rate_limit_image_per_second,
1146 rate_limit_post: sForm.rate_limit_post,
1147 rate_limit_post_per_second: sForm.rate_limit_post_per_second,
1148 rate_limit_register: sForm.rate_limit_register,
1149 rate_limit_register_per_second: sForm.rate_limit_register_per_second,
1150 rate_limit_search: sForm.rate_limit_search,
1151 rate_limit_search_per_second: sForm.rate_limit_search_per_second,
1152 federation_enabled: sForm.federation_enabled,
1153 federation_debug: sForm.federation_debug,
1154 federation_worker_count: sForm.federation_worker_count,
1155 federation_strict_allowlist: sForm.federation_strict_allowlist,
1156 federation_http_fetch_retry_limit:
1157 sForm.federation_http_fetch_retry_limit,
1158 captcha_enabled: sForm.captcha_enabled,
1159 captcha_difficulty: sForm.captcha_difficulty,
1160 allowed_instances: sForm.allowed_instances,
1161 blocked_instances: sForm.blocked_instances,
1162 discussion_languages: sForm.discussion_languages,
1164 WebSocketService.Instance.send(wsClient.createSite(form));
1166 i.setState(i.state);
1169 instancesToString(opt: Option<string[]>): string {
1170 return opt.map(list => list.join(",")).unwrapOr("");
1173 handleSiteAllowedInstances(i: SiteForm, event: any) {
1174 let list = splitToList(event.target.value);
1175 i.setState(s => ((s.siteForm.allowed_instances = list), s));
1178 handleSiteBlockedInstances(i: SiteForm, event: any) {
1179 let list = splitToList(event.target.value);
1180 i.setState(s => ((s.siteForm.blocked_instances = list), s));
1183 handleSiteNameChange(i: SiteForm, event: any) {
1184 i.state.siteForm.name = Some(event.target.value);
1185 i.setState(i.state);
1188 handleSiteSidebarChange(val: string) {
1189 this.setState(s => ((s.siteForm.sidebar = Some(val)), s));
1192 handleSiteLegalInfoChange(val: string) {
1193 this.setState(s => ((s.siteForm.legal_information = Some(val)), s));
1196 handleTaglineChange(i: SiteForm, index: number, val: string) {
1197 i.state.siteForm.taglines.match({
1198 some: tls => { tls[index] = val; },
1201 i.setState(i.state);
1204 handleDeleteTaglineClick(
1207 event: InfernoMouseEvent<HTMLButtonElement>
1209 event.preventDefault();
1210 if (i.state.siteForm.taglines.isSome()){
1211 let taglines = i.state.siteForm.taglines.unwrap();
1212 taglines.splice(index, 1);
1213 i.state.siteForm.taglines = None; // force rerender of table rows
1214 i.setState(i.state);
1215 i.state.siteForm.taglines = Some(taglines);
1216 i.setState(i.state);
1220 handleAddTaglineClick(
1222 event: InfernoMouseEvent<HTMLButtonElement>
1224 event.preventDefault();
1225 if (i.state.siteForm.taglines.isNone()){
1226 i.state.siteForm.taglines = Some([]);
1228 i.state.siteForm.taglines.unwrap().push("");
1229 i.setState(i.state);
1232 handleSiteApplicationQuestionChange(val: string) {
1233 this.setState(s => ((s.siteForm.application_question = Some(val)), s));
1236 handleSiteDescChange(i: SiteForm, event: any) {
1237 i.state.siteForm.description = Some(event.target.value);
1238 i.setState(i.state);
1241 handleSiteEnableNsfwChange(i: SiteForm, event: any) {
1242 i.state.siteForm.enable_nsfw = Some(event.target.checked);
1243 i.setState(i.state);
1246 handleSiteOpenRegistrationChange(i: SiteForm, event: any) {
1247 i.state.siteForm.open_registration = Some(event.target.checked);
1248 i.setState(i.state);
1251 handleSiteCommunityCreationAdminOnly(i: SiteForm, event: any) {
1252 i.state.siteForm.community_creation_admin_only = Some(event.target.checked);
1253 i.setState(i.state);
1256 handleSiteEnableDownvotesChange(i: SiteForm, event: any) {
1257 i.state.siteForm.enable_downvotes = Some(event.target.checked);
1258 i.setState(i.state);
1261 handleSiteRequireApplication(i: SiteForm, event: any) {
1262 i.state.siteForm.require_application = Some(event.target.checked);
1263 i.setState(i.state);
1266 handleSiteRequireEmailVerification(i: SiteForm, event: any) {
1267 i.state.siteForm.require_email_verification = Some(event.target.checked);
1268 i.setState(i.state);
1271 handleSiteApplicationEmailAdmins(i: SiteForm, event: any) {
1272 i.state.siteForm.application_email_admins = Some(event.target.checked);
1273 i.setState(i.state);
1276 handleSitePrivateInstance(i: SiteForm, event: any) {
1277 i.state.siteForm.private_instance = Some(event.target.checked);
1278 i.setState(i.state);
1281 handleSiteHideModlogModNames(i: SiteForm, event: any) {
1282 i.state.siteForm.hide_modlog_mod_names = Some(event.target.checked);
1283 i.setState(i.state);
1286 handleSiteDefaultTheme(i: SiteForm, event: any) {
1287 i.state.siteForm.default_theme = Some(event.target.value);
1288 i.setState(i.state);
1291 handleIconUpload(url: string) {
1292 this.setState(s => ((s.siteForm.icon = Some(url)), s));
1295 handleIconRemove() {
1296 this.setState(s => ((s.siteForm.icon = Some("")), s));
1299 handleBannerUpload(url: string) {
1300 this.setState(s => ((s.siteForm.banner = Some(url)), s));
1303 handleBannerRemove() {
1304 this.setState(s => ((s.siteForm.banner = Some("")), s));
1307 handleSiteSlurFilterRegex(i: SiteForm, event: any) {
1309 s => ((s.siteForm.slur_filter_regex = Some(event.target.value)), s)
1313 handleSiteActorNameMaxLength(i: SiteForm, event: any) {
1316 (s.siteForm.actor_name_max_length = Some(Number(event.target.value))), s
1321 handleSiteRateLimitMessage(i: SiteForm, event: any) {
1324 (s.siteForm.rate_limit_message = Some(Number(event.target.value))), s
1329 handleSiteRateLimitMessagePerSecond(i: SiteForm, event: any) {
1332 (s.siteForm.rate_limit_message_per_second = Some(
1333 Number(event.target.value)
1340 handleSiteRateLimitPost(i: SiteForm, event: any) {
1342 s => ((s.siteForm.rate_limit_post = Some(Number(event.target.value))), s)
1346 handleSiteRateLimitPostPerSecond(i: SiteForm, event: any) {
1349 (s.siteForm.rate_limit_post_per_second = Some(
1350 Number(event.target.value)
1357 handleSiteRateLimitImage(i: SiteForm, event: any) {
1359 s => ((s.siteForm.rate_limit_image = Some(Number(event.target.value))), s)
1363 handleSiteRateLimitImagePerSecond(i: SiteForm, event: any) {
1366 (s.siteForm.rate_limit_image_per_second = Some(
1367 Number(event.target.value)
1374 handleSiteRateLimitComment(i: SiteForm, event: any) {
1377 (s.siteForm.rate_limit_comment = Some(Number(event.target.value))), s
1382 handleSiteRateLimitCommentPerSecond(i: SiteForm, event: any) {
1385 (s.siteForm.rate_limit_comment_per_second = Some(
1386 Number(event.target.value)
1393 handleSiteRateLimitSearch(i: SiteForm, event: any) {
1396 (s.siteForm.rate_limit_search = Some(Number(event.target.value))), s
1401 handleSiteRateLimitSearchPerSecond(i: SiteForm, event: any) {
1404 (s.siteForm.rate_limit_search_per_second = Some(
1405 Number(event.target.value)
1412 handleSiteRateLimitRegister(i: SiteForm, event: any) {
1415 (s.siteForm.rate_limit_register = Some(Number(event.target.value))), s
1420 handleSiteRateLimitRegisterPerSecond(i: SiteForm, event: any) {
1423 (s.siteForm.rate_limit_register_per_second = Some(
1424 Number(event.target.value)
1431 handleSiteFederationEnabled(i: SiteForm, event: any) {
1432 i.state.siteForm.federation_enabled = Some(event.target.checked);
1433 i.setState(i.state);
1436 handleSiteFederationDebug(i: SiteForm, event: any) {
1437 i.state.siteForm.federation_debug = Some(event.target.checked);
1438 i.setState(i.state);
1441 handleSiteFederationStrictAllowList(i: SiteForm, event: any) {
1442 i.state.siteForm.federation_strict_allowlist = Some(event.target.checked);
1443 i.setState(i.state);
1446 handleSiteFederationWorkerCount(i: SiteForm, event: any) {
1449 (s.siteForm.federation_worker_count = Some(Number(event.target.value))),
1455 handleSiteFederationHttpFetchRetryLimit(i: SiteForm, event: any) {
1458 (s.siteForm.federation_http_fetch_retry_limit = Some(
1459 Number(event.target.value)
1466 handleSiteCaptchaEnabled(i: SiteForm, event: any) {
1467 i.state.siteForm.captcha_enabled = Some(event.target.checked);
1468 i.setState(i.state);
1471 handleSiteCaptchaDifficulty(i: SiteForm, event: any) {
1473 s => ((s.siteForm.captcha_difficulty = Some(event.target.value)), s)
1477 handleDiscussionLanguageChange(val: number[]) {
1478 this.setState(s => ((s.siteForm.discussion_languages = Some(val)), s));
1481 handleDefaultPostListingTypeChange(val: ListingType) {
1484 (s.siteForm.default_post_listing_type = Some(
1485 ListingType[ListingType[val]]
1493 function splitToList(commaList: string): Option<string[]> {
1494 if (commaList !== "") {
1495 let list = commaList.trim().split(",");