import { Component, InfernoKeyboardEvent, InfernoMouseEvent, linkEvent, } from "inferno"; import { CreateSite, EditSite, GetFederatedInstancesResponse, GetSiteResponse, ListingType, } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { WebSocketService } from "../../services"; import { capitalizeFirstLetter, fetchThemeList, myAuth, 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"; import NavigationPrompt from "../common/navigation-prompt"; interface SiteFormProps { siteRes: GetSiteResponse; instancesRes?: GetFederatedInstancesResponse; showLocal?: boolean; } interface SiteFormState { siteForm: EditSite; loading: boolean; themeList?: string[]; instance_select: { allowed_instances: string; blocked_instances: string; }; } type InstanceKey = "allowed_instances" | "blocked_instances"; export class SiteForm extends Component { state: SiteFormState = { siteForm: { auth: "TODO", }, loading: false, instance_select: { allowed_instances: "", blocked_instances: "", }, }; 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); const site = this.props.siteRes.site_view.site; const ls = this.props.siteRes.site_view.local_site; this.state = { ...this.state, siteForm: { 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, federation_debug: ls.federation_debug, federation_worker_count: ls.federation_worker_count, captcha_enabled: ls.captcha_enabled, captcha_difficulty: ls.captcha_difficulty, allowed_instances: this.props.instancesRes?.federated_instances?.allowed.map( i => i.domain ), blocked_instances: this.props.instancesRes?.federated_instances?.blocked.map( i => i.domain ), auth: "TODO", }, }; } async componentDidMount() { this.setState({ themeList: 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 = null; } } componentWillUnmount() { window.onbeforeunload = null; } render() { const 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.registration_mode == "RequireApplication" && (
)}
{this.props.showLocal && (
)}
{this.state.siteForm.federation_enabled && ( <>
{this.federatedInstanceSelect("allowed_instances")} {this.federatedInstanceSelect("blocked_instances")}
)}
{this.state.siteForm.captcha_enabled && (
)}
); } 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); } } handleCreateSiteSubmit(i: SiteForm, event: any) { event.preventDefault(); i.setState({ loading: true }); const auth = myAuth() ?? "TODO"; i.setState(s => ((s.siteForm.auth = auth), s)); if (i.props.siteRes.site_view.local_site.site_setup) { WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm)); } else { const sForm = i.state.siteForm; const form: CreateSite = { name: sForm.name ?? "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, application_question: sForm.application_question, registration_mode: sForm.registration_mode, 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, 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, federation_enabled: sForm.federation_enabled, federation_debug: sForm.federation_debug, federation_worker_count: sForm.federation_worker_count, 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, auth, }; WebSocketService.Instance.send(wsClient.createSite(form)); } i.setState(i.state); } handleAddInstance(key: InstanceKey) { const instance = this.state.instance_select[key].trim(); 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); } handleSiteFederationWorkerCount(i: SiteForm, event: any) { i.setState( s => ( (s.siteForm.federation_worker_count = Number(event.target.value)), s ) ); } 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)); } }