import { None, Option, Some } from "@sniptt/monads"; import { Component, InfernoMouseEvent, linkEvent } from "inferno"; import { Prompt } from "inferno-router"; import { CreateSite, EditSite, GetSiteResponse, ListingType, toUndefined, } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { WebSocketService } from "../../services"; import { auth, capitalizeFirstLetter, fetchThemeList, wsClient, } from "../../utils"; import { Icon, Spinner } from "../common/icon"; import { ImageUploadForm } from "../common/image-upload-form"; import { LanguageSelect } from "../common/language-select"; import { ListingTypeSelect } from "../common/listing-type-select"; import { MarkdownTextArea } from "../common/markdown-textarea"; interface SiteFormProps { siteRes: GetSiteResponse; showLocal?: boolean; } interface SiteFormState { siteForm: EditSite; loading: boolean; themeList: Option; } export class SiteForm extends Component { private emptyState: SiteFormState = { siteForm: new EditSite({ enable_downvotes: None, open_registration: None, enable_nsfw: None, name: None, icon: None, banner: None, require_email_verification: None, require_application: None, application_question: None, private_instance: None, default_theme: None, sidebar: None, default_post_listing_type: None, legal_information: None, description: None, community_creation_admin_only: None, application_email_admins: None, hide_modlog_mod_names: None, discussion_languages: None, slur_filter_regex: None, actor_name_max_length: None, rate_limit_message: None, rate_limit_message_per_second: None, rate_limit_comment: None, rate_limit_comment_per_second: None, rate_limit_image: None, rate_limit_image_per_second: None, rate_limit_post: None, rate_limit_post_per_second: None, rate_limit_register: None, rate_limit_register_per_second: None, rate_limit_search: None, rate_limit_search_per_second: None, federation_enabled: None, federation_debug: None, federation_worker_count: None, federation_strict_allowlist: None, federation_http_fetch_retry_limit: None, captcha_enabled: None, captcha_difficulty: None, allowed_instances: None, blocked_instances: None, taglines: None, auth: undefined, }), loading: false, themeList: None, }; constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; this.handleSiteSidebarChange = this.handleSiteSidebarChange.bind(this); this.handleSiteLegalInfoChange = this.handleSiteLegalInfoChange.bind(this); this.handleSiteApplicationQuestionChange = this.handleSiteApplicationQuestionChange.bind(this); this.handleIconUpload = this.handleIconUpload.bind(this); this.handleIconRemove = this.handleIconRemove.bind(this); this.handleBannerUpload = this.handleBannerUpload.bind(this); this.handleBannerRemove = this.handleBannerRemove.bind(this); this.handleDefaultPostListingTypeChange = this.handleDefaultPostListingTypeChange.bind(this); this.handleDiscussionLanguageChange = this.handleDiscussionLanguageChange.bind(this); let site = this.props.siteRes.site_view.site; let ls = this.props.siteRes.site_view.local_site; let lsrl = this.props.siteRes.site_view.local_site_rate_limit; this.state = { ...this.state, siteForm: new EditSite({ name: Some(site.name), sidebar: site.sidebar, description: site.description, enable_downvotes: Some(ls.enable_downvotes), open_registration: Some(ls.open_registration), enable_nsfw: Some(ls.enable_nsfw), community_creation_admin_only: Some(ls.community_creation_admin_only), icon: site.icon, banner: site.banner, require_email_verification: Some(ls.require_email_verification), require_application: Some(ls.require_application), application_question: ls.application_question, private_instance: Some(ls.private_instance), default_theme: Some(ls.default_theme), default_post_listing_type: Some(ls.default_post_listing_type), legal_information: ls.legal_information, application_email_admins: Some(ls.application_email_admins), hide_modlog_mod_names: Some(ls.hide_modlog_mod_names), discussion_languages: Some(this.props.siteRes.discussion_languages), slur_filter_regex: ls.slur_filter_regex, actor_name_max_length: Some(ls.actor_name_max_length), rate_limit_message: Some(lsrl.message), rate_limit_message_per_second: Some(lsrl.message_per_second), rate_limit_comment: Some(lsrl.comment), rate_limit_comment_per_second: Some(lsrl.comment_per_second), rate_limit_image: Some(lsrl.image), rate_limit_image_per_second: Some(lsrl.image_per_second), rate_limit_post: Some(lsrl.post), rate_limit_post_per_second: Some(lsrl.post_per_second), rate_limit_register: Some(lsrl.register), rate_limit_register_per_second: Some(lsrl.register_per_second), rate_limit_search: Some(lsrl.search), rate_limit_search_per_second: Some(lsrl.search_per_second), federation_enabled: Some(ls.federation_enabled), federation_debug: Some(ls.federation_debug), federation_worker_count: Some(ls.federation_worker_count), federation_strict_allowlist: Some(ls.federation_strict_allowlist), federation_http_fetch_retry_limit: Some( ls.federation_http_fetch_retry_limit ), captcha_enabled: Some(ls.captcha_enabled), captcha_difficulty: Some(ls.captcha_difficulty), allowed_instances: this.props.siteRes.federated_instances.andThen( f => f.allowed ), blocked_instances: this.props.siteRes.federated_instances.andThen( f => f.blocked ), taglines: this.props.siteRes.taglines.map(x => x.map(y => y.content)), auth: undefined, }), }; } async componentDidMount() { this.setState({ themeList: Some(await fetchThemeList()) }); } // Necessary to stop the loading componentWillReceiveProps() { this.setState({ loading: false }); } componentDidUpdate() { if ( !this.state.loading && !this.props.siteRes.site_view.local_site.site_setup && (this.state.siteForm.name || this.state.siteForm.sidebar || this.state.siteForm.application_question || this.state.siteForm.description) ) { window.onbeforeunload = () => true; } else { window.onbeforeunload = undefined; } } componentWillUnmount() { window.onbeforeunload = null; } render() { let siteSetup = this.props.siteRes.site_view.local_site.site_setup; return ( <>
{`${ siteSetup ? capitalizeFirstLetter(i18n.t("save")) : capitalizeFirstLetter(i18n.t("name")) } ${i18n.t("your_site")}`}
{this.state.siteForm.require_application.unwrapOr(false) && (
)}
{this.props.showLocal && (
)}
{this.state.siteForm.federation_enabled.unwrapOr(false) && ( <>
)}
{this.state.siteForm.captcha_enabled.unwrapOr(false) && (
)}
{siteSetup &&
{i18n.t("taglines")}
{this.state.siteForm.taglines .unwrapOr([]) .map((cv, index) => ( ))}
this.handleTaglineChange(this, index, s) } hideNavigationWarnings allLanguages={this.props.siteRes.all_languages} />
}
); } handleCreateSiteSubmit(i: SiteForm, event: any) { event.preventDefault(); i.setState({ loading: true }); i.setState(s => ((s.siteForm.auth = auth().unwrap()), s)); if (i.props.siteRes.site_view.local_site.site_setup) { WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm)); } else { let sForm = i.state.siteForm; let form = new CreateSite({ name: sForm.name.unwrapOr("My site"), sidebar: sForm.sidebar, description: sForm.description, icon: sForm.icon, banner: sForm.banner, community_creation_admin_only: sForm.community_creation_admin_only, enable_nsfw: sForm.enable_nsfw, enable_downvotes: sForm.enable_downvotes, require_application: sForm.require_application, application_question: sForm.application_question, open_registration: sForm.open_registration, require_email_verification: sForm.require_email_verification, private_instance: sForm.private_instance, default_theme: sForm.default_theme, default_post_listing_type: sForm.default_post_listing_type, application_email_admins: sForm.application_email_admins, auth: auth().unwrap(), hide_modlog_mod_names: sForm.hide_modlog_mod_names, legal_information: sForm.legal_information, slur_filter_regex: sForm.slur_filter_regex, actor_name_max_length: sForm.actor_name_max_length, rate_limit_message: sForm.rate_limit_message, rate_limit_message_per_second: sForm.rate_limit_message_per_second, rate_limit_comment: sForm.rate_limit_comment, rate_limit_comment_per_second: sForm.rate_limit_comment_per_second, rate_limit_image: sForm.rate_limit_image, rate_limit_image_per_second: sForm.rate_limit_image_per_second, rate_limit_post: sForm.rate_limit_post, rate_limit_post_per_second: sForm.rate_limit_post_per_second, rate_limit_register: sForm.rate_limit_register, rate_limit_register_per_second: sForm.rate_limit_register_per_second, rate_limit_search: sForm.rate_limit_search, rate_limit_search_per_second: sForm.rate_limit_search_per_second, federation_enabled: sForm.federation_enabled, federation_debug: sForm.federation_debug, federation_worker_count: sForm.federation_worker_count, federation_strict_allowlist: sForm.federation_strict_allowlist, federation_http_fetch_retry_limit: sForm.federation_http_fetch_retry_limit, captcha_enabled: sForm.captcha_enabled, captcha_difficulty: sForm.captcha_difficulty, allowed_instances: sForm.allowed_instances, blocked_instances: sForm.blocked_instances, discussion_languages: sForm.discussion_languages, }); WebSocketService.Instance.send(wsClient.createSite(form)); } i.setState(i.state); } instancesToString(opt: Option): string { return opt.map(list => list.join(",")).unwrapOr(""); } handleSiteAllowedInstances(i: SiteForm, event: any) { let list = splitToList(event.target.value); i.setState(s => ((s.siteForm.allowed_instances = list), s)); } handleSiteBlockedInstances(i: SiteForm, event: any) { let list = splitToList(event.target.value); i.setState(s => ((s.siteForm.blocked_instances = list), s)); } handleSiteNameChange(i: SiteForm, event: any) { i.state.siteForm.name = Some(event.target.value); i.setState(i.state); } handleSiteSidebarChange(val: string) { this.setState(s => ((s.siteForm.sidebar = Some(val)), s)); } handleSiteLegalInfoChange(val: string) { this.setState(s => ((s.siteForm.legal_information = Some(val)), s)); } handleTaglineChange(i: SiteForm, index: number, val: string) { i.state.siteForm.taglines.match({ some: tls => { tls[index] = val; }, none: void 0 }); i.setState(i.state); } handleDeleteTaglineClick( i: SiteForm, index: number, event: InfernoMouseEvent ) { event.preventDefault(); if (i.state.siteForm.taglines.isSome()){ let taglines = i.state.siteForm.taglines.unwrap(); taglines.splice(index, 1); i.state.siteForm.taglines = None; // force rerender of table rows i.setState(i.state); i.state.siteForm.taglines = Some(taglines); i.setState(i.state); } } handleAddTaglineClick( i: SiteForm, event: InfernoMouseEvent ) { event.preventDefault(); if (i.state.siteForm.taglines.isNone()){ i.state.siteForm.taglines = Some([]); } i.state.siteForm.taglines.unwrap().push(""); i.setState(i.state); } handleSiteApplicationQuestionChange(val: string) { this.setState(s => ((s.siteForm.application_question = Some(val)), s)); } handleSiteDescChange(i: SiteForm, event: any) { i.state.siteForm.description = Some(event.target.value); i.setState(i.state); } handleSiteEnableNsfwChange(i: SiteForm, event: any) { i.state.siteForm.enable_nsfw = Some(event.target.checked); i.setState(i.state); } handleSiteOpenRegistrationChange(i: SiteForm, event: any) { i.state.siteForm.open_registration = Some(event.target.checked); i.setState(i.state); } handleSiteCommunityCreationAdminOnly(i: SiteForm, event: any) { i.state.siteForm.community_creation_admin_only = Some(event.target.checked); i.setState(i.state); } handleSiteEnableDownvotesChange(i: SiteForm, event: any) { i.state.siteForm.enable_downvotes = Some(event.target.checked); i.setState(i.state); } handleSiteRequireApplication(i: SiteForm, event: any) { i.state.siteForm.require_application = Some(event.target.checked); i.setState(i.state); } handleSiteRequireEmailVerification(i: SiteForm, event: any) { i.state.siteForm.require_email_verification = Some(event.target.checked); i.setState(i.state); } handleSiteApplicationEmailAdmins(i: SiteForm, event: any) { i.state.siteForm.application_email_admins = Some(event.target.checked); i.setState(i.state); } handleSitePrivateInstance(i: SiteForm, event: any) { i.state.siteForm.private_instance = Some(event.target.checked); i.setState(i.state); } handleSiteHideModlogModNames(i: SiteForm, event: any) { i.state.siteForm.hide_modlog_mod_names = Some(event.target.checked); i.setState(i.state); } handleSiteDefaultTheme(i: SiteForm, event: any) { i.state.siteForm.default_theme = Some(event.target.value); i.setState(i.state); } handleIconUpload(url: string) { this.setState(s => ((s.siteForm.icon = Some(url)), s)); } handleIconRemove() { this.setState(s => ((s.siteForm.icon = Some("")), s)); } handleBannerUpload(url: string) { this.setState(s => ((s.siteForm.banner = Some(url)), s)); } handleBannerRemove() { this.setState(s => ((s.siteForm.banner = Some("")), s)); } handleSiteSlurFilterRegex(i: SiteForm, event: any) { i.setState( s => ((s.siteForm.slur_filter_regex = Some(event.target.value)), s) ); } handleSiteActorNameMaxLength(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.actor_name_max_length = Some(Number(event.target.value))), s ) ); } handleSiteRateLimitMessage(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_message = Some(Number(event.target.value))), s ) ); } handleSiteRateLimitMessagePerSecond(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_message_per_second = Some( Number(event.target.value) )), s ) ); } handleSiteRateLimitPost(i: SiteForm, event: any) { i.setState( s => ((s.siteForm.rate_limit_post = Some(Number(event.target.value))), s) ); } handleSiteRateLimitPostPerSecond(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_post_per_second = Some( Number(event.target.value) )), s ) ); } handleSiteRateLimitImage(i: SiteForm, event: any) { i.setState( s => ((s.siteForm.rate_limit_image = Some(Number(event.target.value))), s) ); } handleSiteRateLimitImagePerSecond(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_image_per_second = Some( Number(event.target.value) )), s ) ); } handleSiteRateLimitComment(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_comment = Some(Number(event.target.value))), s ) ); } handleSiteRateLimitCommentPerSecond(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_comment_per_second = Some( Number(event.target.value) )), s ) ); } handleSiteRateLimitSearch(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_search = Some(Number(event.target.value))), s ) ); } handleSiteRateLimitSearchPerSecond(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_search_per_second = Some( Number(event.target.value) )), s ) ); } handleSiteRateLimitRegister(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_register = Some(Number(event.target.value))), s ) ); } handleSiteRateLimitRegisterPerSecond(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.rate_limit_register_per_second = Some( Number(event.target.value) )), s ) ); } handleSiteFederationEnabled(i: SiteForm, event: any) { i.state.siteForm.federation_enabled = Some(event.target.checked); i.setState(i.state); } handleSiteFederationDebug(i: SiteForm, event: any) { i.state.siteForm.federation_debug = Some(event.target.checked); i.setState(i.state); } handleSiteFederationStrictAllowList(i: SiteForm, event: any) { i.state.siteForm.federation_strict_allowlist = Some(event.target.checked); i.setState(i.state); } handleSiteFederationWorkerCount(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.federation_worker_count = Some(Number(event.target.value))), s ) ); } handleSiteFederationHttpFetchRetryLimit(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.federation_http_fetch_retry_limit = Some( Number(event.target.value) )), s ) ); } handleSiteCaptchaEnabled(i: SiteForm, event: any) { i.state.siteForm.captcha_enabled = Some(event.target.checked); i.setState(i.state); } handleSiteCaptchaDifficulty(i: SiteForm, event: any) { i.setState( s => ((s.siteForm.captcha_difficulty = Some(event.target.value)), s) ); } handleDiscussionLanguageChange(val: number[]) { this.setState(s => ((s.siteForm.discussion_languages = Some(val)), s)); } handleDefaultPostListingTypeChange(val: ListingType) { this.setState( s => ( (s.siteForm.default_post_listing_type = Some( ListingType[ListingType[val]] )), s ) ); } } function splitToList(commaList: string): Option { if (commaList !== "") { let list = commaList.trim().split(","); return Some(list); } else { return Some([]); } }