import { Component, linkEvent } from "inferno"; import { CommunityResponse, CommunityView, CreateCommunity, EditCommunity, Language, UserOperation, wsJsonToRes, wsUserOp, } from "lemmy-js-client"; import { Subscription } from "rxjs"; import { i18n } from "../../i18next"; import { UserService, WebSocketService } from "../../services"; import { capitalizeFirstLetter, myAuth, randomStr, wsClient, wsSubscribe, } from "../../utils"; import { Icon, Spinner } from "../common/icon"; import { ImageUploadForm } from "../common/image-upload-form"; import { LanguageSelect } from "../common/language-select"; import { MarkdownTextArea } from "../common/markdown-textarea"; import NavigationPrompt from "../common/navigation-prompt"; interface CommunityFormProps { community_view?: CommunityView; // If a community is given, that means this is an edit allLanguages: Language[]; siteLanguages: number[]; communityLanguages?: number[]; onCancel?(): any; onCreate?(community: CommunityView): any; onEdit?(community: CommunityView): any; enableNsfw?: boolean; } interface CommunityFormState { form: { name?: string; title?: string; description?: string; icon?: string; banner?: string; nsfw?: boolean; posting_restricted_to_mods?: boolean; discussion_languages?: number[]; }; loading: boolean; } export class CommunityForm extends Component< CommunityFormProps, CommunityFormState > { private id = `community-form-${randomStr()}`; private subscription?: Subscription; state: CommunityFormState = { form: {}, loading: false, }; constructor(props: any, context: any) { super(props, context); this.handleCommunityDescriptionChange = this.handleCommunityDescriptionChange.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.handleDiscussionLanguageChange = this.handleDiscussionLanguageChange.bind(this); this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); const cv = this.props.community_view; if (cv) { this.state = { form: { name: cv.community.name, title: cv.community.title, description: cv.community.description, nsfw: cv.community.nsfw, icon: cv.community.icon, banner: cv.community.banner, posting_restricted_to_mods: cv.community.posting_restricted_to_mods, discussion_languages: this.props.communityLanguages, }, loading: false, }; } } componentDidUpdate() { if ( !this.state.loading && (this.state.form.name || this.state.form.title || this.state.form.description) ) { window.onbeforeunload = () => true; } else { window.onbeforeunload = null; } } componentWillUnmount() { this.subscription?.unsubscribe(); window.onbeforeunload = null; } render() { return ( <>
{!this.props.community_view && (
)}
{this.props.enableNsfw && (
{i18n.t("nsfw")}
)}
{i18n.t("only_mods_can_post_in_community")}
{this.props.community_view && ( )}
); } handleCreateCommunitySubmit(i: CommunityForm, event: any) { event.preventDefault(); i.setState({ loading: true }); const cForm = i.state.form; const auth = myAuth(); const cv = i.props.community_view; if (auth) { if (cv) { const form: EditCommunity = { community_id: cv.community.id, title: cForm.title, description: cForm.description, icon: cForm.icon, banner: cForm.banner, nsfw: cForm.nsfw, posting_restricted_to_mods: cForm.posting_restricted_to_mods, discussion_languages: cForm.discussion_languages, auth, }; WebSocketService.Instance.send(wsClient.editCommunity(form)); } else { if (cForm.title && cForm.name) { const form: CreateCommunity = { name: cForm.name, title: cForm.title, description: cForm.description, icon: cForm.icon, banner: cForm.banner, nsfw: cForm.nsfw, posting_restricted_to_mods: cForm.posting_restricted_to_mods, discussion_languages: cForm.discussion_languages, auth, }; WebSocketService.Instance.send(wsClient.createCommunity(form)); } } } i.setState(i.state); } handleCommunityNameChange(i: CommunityForm, event: any) { i.state.form.name = event.target.value; i.setState(i.state); } handleCommunityTitleChange(i: CommunityForm, event: any) { i.state.form.title = event.target.value; i.setState(i.state); } handleCommunityDescriptionChange(val: string) { this.setState(s => ((s.form.description = val), s)); } handleCommunityNsfwChange(i: CommunityForm, event: any) { i.state.form.nsfw = event.target.checked; i.setState(i.state); } handleCommunityPostingRestrictedToMods(i: CommunityForm, event: any) { i.state.form.posting_restricted_to_mods = event.target.checked; i.setState(i.state); } handleCancel(i: CommunityForm) { i.props.onCancel?.(); } handleIconUpload(url: string) { this.setState(s => ((s.form.icon = url), s)); } handleIconRemove() { this.setState(s => ((s.form.icon = ""), s)); } handleBannerUpload(url: string) { this.setState(s => ((s.form.banner = url), s)); } handleBannerRemove() { this.setState(s => ((s.form.banner = ""), s)); } handleDiscussionLanguageChange(val: number[]) { this.setState(s => ((s.form.discussion_languages = val), s)); } parseMessage(msg: any) { const op = wsUserOp(msg); console.log(msg); if (msg.error) { // Errors handled by top level pages // toast(i18n.t(msg.error), "danger"); this.setState({ loading: false }); return; } else if (op == UserOperation.CreateCommunity) { const data = wsJsonToRes(msg); this.props.onCreate?.(data.community_view); // Update myUserInfo const community = data.community_view.community; const mui = UserService.Instance.myUserInfo; if (mui) { const person = mui.local_user_view.person; mui.follows.push({ community, follower: person, }); mui.moderates.push({ community, moderator: person, }); } } else if (op == UserOperation.EditCommunity) { const data = wsJsonToRes(msg); this.setState({ loading: false }); this.props.onEdit?.(data.community_view); const community = data.community_view.community; const mui = UserService.Instance.myUserInfo; if (mui) { const followFound = mui.follows.findIndex( f => f.community.id == community.id ); if (followFound) { mui.follows[followFound].community = community; } const moderatesFound = mui.moderates.findIndex( f => f.community.id == community.id ); if (moderatesFound) { mui.moderates[moderatesFound].community = community; } } } } }