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