import { myAuthRequired } from "@utils/app"; import { capitalizeFirstLetter, validInstanceTLD } from "@utils/helpers"; import { Component, InfernoKeyboardEvent, InfernoMouseEvent, InfernoNode, linkEvent, } from "inferno"; import { CreateSite, EditSite, GetSiteResponse, Instance, ListingType, } from "lemmy-js-client"; import deepEqual from "lodash.isequal"; import { I18NextService } from "../../services"; 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"; import NavigationPrompt from "../common/navigation-prompt"; interface SiteFormProps { blockedInstances?: Instance[]; allowedInstances?: Instance[]; showLocal?: boolean; themeList?: string[]; onSaveSite(form: EditSite): void; siteRes: GetSiteResponse; loading: boolean; } interface SiteFormState { siteForm: EditSite; instance_select: { allowed_instances: string; blocked_instances: string; }; submitted: boolean; } type InstanceKey = "allowed_instances" | "blocked_instances"; export class SiteForm extends Component { state: SiteFormState = { siteForm: this.initSiteForm(), instance_select: { allowed_instances: "", blocked_instances: "", }, submitted: false, }; initSiteForm(): EditSite { const site = this.props.siteRes.site_view.site; const ls = this.props.siteRes.site_view.local_site; return { name: site.name, sidebar: site.sidebar, description: site.description, enable_downvotes: ls.enable_downvotes, registration_mode: ls.registration_mode, enable_nsfw: ls.enable_nsfw, community_creation_admin_only: ls.community_creation_admin_only, icon: site.icon, banner: site.banner, require_email_verification: ls.require_email_verification, application_question: ls.application_question, private_instance: ls.private_instance, default_theme: ls.default_theme, default_post_listing_type: ls.default_post_listing_type, legal_information: ls.legal_information, application_email_admins: ls.application_email_admins, reports_email_admins: ls.reports_email_admins, hide_modlog_mod_names: ls.hide_modlog_mod_names, discussion_languages: this.props.siteRes.discussion_languages, slur_filter_regex: ls.slur_filter_regex, actor_name_max_length: ls.actor_name_max_length, federation_enabled: ls.federation_enabled, captcha_enabled: ls.captcha_enabled, captcha_difficulty: ls.captcha_difficulty, allowed_instances: this.props.allowedInstances?.map(i => i.domain), blocked_instances: this.props.blockedInstances?.map(i => i.domain), auth: "TODO", }; } constructor(props: any, context: any) { super(props, context); 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); this.handleAddInstance = this.handleAddInstance.bind(this); this.handleRemoveInstance = this.handleRemoveInstance.bind(this); this.handleInstanceEnterPress = this.handleInstanceEnterPress.bind(this); this.handleInstanceTextChange = this.handleInstanceTextChange.bind(this); } render() { const siteSetup = this.props.siteRes.site_view.local_site.site_setup; return (

{`${ siteSetup ? capitalizeFirstLetter(I18NextService.i18n.t("edit")) : capitalizeFirstLetter(I18NextService.i18n.t("setup")) } ${I18NextService.i18n.t("your_site")}`}

{this.state.siteForm.registration_mode == "RequireApplication" && (
)}
{this.props.showLocal && (
)}
{this.state.siteForm.federation_enabled && ( <>
{this.federatedInstanceSelect("allowed_instances")} {this.federatedInstanceSelect("blocked_instances")}
)}
{this.state.siteForm.captcha_enabled && (
)}
); } componentDidUpdate( prevProps: Readonly<{ children?: InfernoNode } & SiteFormProps> ) { if ( !( deepEqual(prevProps.allowedInstances, this.props.allowedInstances) || deepEqual(prevProps.blockedInstances, this.props.blockedInstances) ) ) { this.setState({ siteForm: this.initSiteForm() }); } } federatedInstanceSelect(key: InstanceKey) { const id = `create_site_${key}`; const value = this.state.instance_select[key]; const selectedInstances = this.state.siteForm[key]; return (
{selectedInstances && selectedInstances.length > 0 && (
    {selectedInstances.map(instance => (
  • ))}
)}
); } handleInstanceTextChange(type: InstanceKey, event: any) { this.setState(s => ({ ...s, instance_select: { ...s.instance_select, [type]: event.target.value, }, })); } handleInstanceEnterPress( key: InstanceKey, event: InfernoKeyboardEvent ) { if (event.code.toLowerCase() === "enter") { event.preventDefault(); this.handleAddInstance(key); } } handleSaveSiteSubmit(i: SiteForm, event: any) { event.preventDefault(); const auth = myAuthRequired(); i.setState(s => ((s.siteForm.auth = auth), s)); i.setState({ submitted: true }); const stateSiteForm = i.state.siteForm; let form: EditSite | CreateSite; if (i.props.siteRes.site_view.local_site.site_setup) { form = stateSiteForm; } else { form = { name: stateSiteForm.name ?? "My site", sidebar: stateSiteForm.sidebar, description: stateSiteForm.description, icon: stateSiteForm.icon, banner: stateSiteForm.banner, community_creation_admin_only: stateSiteForm.community_creation_admin_only, enable_nsfw: stateSiteForm.enable_nsfw, enable_downvotes: stateSiteForm.enable_downvotes, application_question: stateSiteForm.application_question, registration_mode: stateSiteForm.registration_mode, require_email_verification: stateSiteForm.require_email_verification, private_instance: stateSiteForm.private_instance, default_theme: stateSiteForm.default_theme, default_post_listing_type: stateSiteForm.default_post_listing_type, application_email_admins: stateSiteForm.application_email_admins, hide_modlog_mod_names: stateSiteForm.hide_modlog_mod_names, legal_information: stateSiteForm.legal_information, slur_filter_regex: stateSiteForm.slur_filter_regex, actor_name_max_length: stateSiteForm.actor_name_max_length, rate_limit_message: stateSiteForm.rate_limit_message, rate_limit_message_per_second: stateSiteForm.rate_limit_message_per_second, rate_limit_comment: stateSiteForm.rate_limit_comment, rate_limit_comment_per_second: stateSiteForm.rate_limit_comment_per_second, rate_limit_image: stateSiteForm.rate_limit_image, rate_limit_image_per_second: stateSiteForm.rate_limit_image_per_second, rate_limit_post: stateSiteForm.rate_limit_post, rate_limit_post_per_second: stateSiteForm.rate_limit_post_per_second, rate_limit_register: stateSiteForm.rate_limit_register, rate_limit_register_per_second: stateSiteForm.rate_limit_register_per_second, rate_limit_search: stateSiteForm.rate_limit_search, rate_limit_search_per_second: stateSiteForm.rate_limit_search_per_second, federation_enabled: stateSiteForm.federation_enabled, federation_debug: stateSiteForm.federation_debug, captcha_enabled: stateSiteForm.captcha_enabled, captcha_difficulty: stateSiteForm.captcha_difficulty, allowed_instances: stateSiteForm.allowed_instances, blocked_instances: stateSiteForm.blocked_instances, discussion_languages: stateSiteForm.discussion_languages, auth, }; } i.props.onSaveSite(form); } handleAddInstance(key: InstanceKey) { const instance = this.state.instance_select[key].trim(); if (!validInstanceTLD(instance)) { return; } if (!this.state.siteForm[key]?.includes(instance)) { this.setState(s => ({ ...s, siteForm: { ...s.siteForm, [key]: [...(s.siteForm[key] ?? []), instance], }, instance_select: { ...s.instance_select, [key]: "", }, })); const oppositeKey: InstanceKey = key === "allowed_instances" ? "blocked_instances" : "allowed_instances"; if (this.state.siteForm[oppositeKey]?.includes(instance)) { this.handleRemoveInstance({ key: oppositeKey, instance }); } } } handleRemoveInstance({ key, instance, }: { key: InstanceKey; instance: string; }) { this.setState(s => ({ ...s, siteForm: { ...s.siteForm, [key]: s.siteForm[key]?.filter(i => i !== instance), }, })); } handleSiteNameChange(i: SiteForm, event: any) { i.state.siteForm.name = event.target.value; i.setState(i.state); } handleSiteSidebarChange(val: string) { this.setState(s => ((s.siteForm.sidebar = val), s)); } handleSiteLegalInfoChange(val: string) { this.setState(s => ((s.siteForm.legal_information = val), s)); } handleTaglineChange(i: SiteForm, index: number, val: string) { const taglines = i.state.siteForm.taglines; if (taglines) { taglines[index] = val; i.setState(i.state); } } handleDeleteTaglineClick( i: SiteForm, index: number, event: InfernoMouseEvent ) { event.preventDefault(); const taglines = i.state.siteForm.taglines; if (taglines) { taglines.splice(index, 1); i.state.siteForm.taglines = undefined; i.setState(i.state); i.state.siteForm.taglines = taglines; i.setState(i.state); } } handleAddTaglineClick( i: SiteForm, event: InfernoMouseEvent ) { event.preventDefault(); if (!i.state.siteForm.taglines) { i.state.siteForm.taglines = []; } i.state.siteForm.taglines.push(""); i.setState(i.state); } handleSiteApplicationQuestionChange(val: string) { this.setState(s => ((s.siteForm.application_question = val), s)); } handleSiteDescChange(i: SiteForm, event: any) { i.state.siteForm.description = event.target.value; i.setState(i.state); } handleSiteEnableNsfwChange(i: SiteForm, event: any) { i.state.siteForm.enable_nsfw = event.target.checked; i.setState(i.state); } handleSiteRegistrationModeChange(i: SiteForm, event: any) { i.state.siteForm.registration_mode = event.target.value; i.setState(i.state); } handleSiteCommunityCreationAdminOnly(i: SiteForm, event: any) { i.state.siteForm.community_creation_admin_only = event.target.checked; i.setState(i.state); } handleSiteEnableDownvotesChange(i: SiteForm, event: any) { i.state.siteForm.enable_downvotes = event.target.checked; i.setState(i.state); } handleSiteRequireEmailVerification(i: SiteForm, event: any) { i.state.siteForm.require_email_verification = event.target.checked; i.setState(i.state); } handleSiteApplicationEmailAdmins(i: SiteForm, event: any) { i.state.siteForm.application_email_admins = event.target.checked; i.setState(i.state); } handleSiteReportsEmailAdmins(i: SiteForm, event: any) { i.state.siteForm.reports_email_admins = event.target.checked; i.setState(i.state); } handleSitePrivateInstance(i: SiteForm, event: any) { i.state.siteForm.private_instance = event.target.checked; i.setState(i.state); } handleSiteHideModlogModNames(i: SiteForm, event: any) { i.state.siteForm.hide_modlog_mod_names = event.target.checked; i.setState(i.state); } handleSiteDefaultTheme(i: SiteForm, event: any) { i.state.siteForm.default_theme = event.target.value; i.setState(i.state); } handleIconUpload(url: string) { this.setState(s => ((s.siteForm.icon = url), s)); } handleIconRemove() { this.setState(s => ((s.siteForm.icon = ""), s)); } handleBannerUpload(url: string) { this.setState(s => ((s.siteForm.banner = url), s)); } handleBannerRemove() { this.setState(s => ((s.siteForm.banner = ""), s)); } handleSiteSlurFilterRegex(i: SiteForm, event: any) { i.setState(s => ((s.siteForm.slur_filter_regex = event.target.value), s)); } handleSiteActorNameMaxLength(i: SiteForm, event: any) { i.setState( s => ((s.siteForm.actor_name_max_length = Number(event.target.value)), s) ); } handleSiteFederationEnabled(i: SiteForm, event: any) { i.state.siteForm.federation_enabled = event.target.checked; i.setState(i.state); } handleSiteFederationDebug(i: SiteForm, event: any) { i.state.siteForm.federation_debug = event.target.checked; i.setState(i.state); } handleSiteCaptchaEnabled(i: SiteForm, event: any) { i.state.siteForm.captcha_enabled = event.target.checked; i.setState(i.state); } handleSiteCaptchaDifficulty(i: SiteForm, event: any) { i.setState(s => ((s.siteForm.captcha_difficulty = event.target.value), s)); } handleDiscussionLanguageChange(val: number[]) { this.setState(s => ((s.siteForm.discussion_languages = val), s)); } handleDefaultPostListingTypeChange(val: ListingType) { this.setState(s => ((s.siteForm.default_post_listing_type = val), s)); } }