import autosize from "autosize"; import { Component, linkEvent } from "inferno"; import { Prompt } from "inferno-router"; import { CommunityView, CreatePost, EditPost, ListingType, PostResponse, PostView, Search, SearchResponse, SearchType, SortType, UserOperation, } from "lemmy-js-client"; import { Subscription } from "rxjs"; import { pictrsUri } from "../../env"; import { i18n } from "../../i18next"; import { PostFormParams } from "../../interfaces"; import { UserService, WebSocketService } from "../../services"; import { archiveTodayUrl, authField, capitalizeFirstLetter, choicesConfig, communitySelectName, communityToChoice, debounce, fetchCommunities, getSiteMetadata, ghostArchiveUrl, isBrowser, isImage, pictrsDeleteToast, relTags, setupTippy, toast, validTitle, validURL, webArchiveUrl, wsClient, wsJsonToRes, wsSubscribe, wsUserOp, } from "../../utils"; import { Icon, Spinner } from "../common/icon"; import { MarkdownTextArea } from "../common/markdown-textarea"; import { PostListings } from "./post-listings"; var Choices: any; if (isBrowser()) { Choices = require("choices.js"); } const MAX_POST_TITLE_LENGTH = 200; interface PostFormProps { post_view?: PostView; // If a post is given, that means this is an edit communities?: CommunityView[]; params?: PostFormParams; onCancel?(): any; onCreate?(post: PostView): any; onEdit?(post: PostView): any; enableNsfw: boolean; enableDownvotes: boolean; } interface PostFormState { postForm: CreatePost; loading: boolean; imageLoading: boolean; previewMode: boolean; suggestedTitle: string; suggestedPosts: PostView[]; crossPosts: PostView[]; } export class PostForm extends Component { private subscription: Subscription; private choices: any; private emptyState: PostFormState = { postForm: { community_id: null, name: null, nsfw: false, auth: authField(false), }, loading: false, imageLoading: false, previewMode: false, suggestedTitle: undefined, suggestedPosts: [], crossPosts: [], }; constructor(props: any, context: any) { super(props, context); this.fetchSimilarPosts = debounce(this.fetchSimilarPosts.bind(this)); this.fetchPageTitle = debounce(this.fetchPageTitle.bind(this)); this.handlePostBodyChange = this.handlePostBodyChange.bind(this); this.state = this.emptyState; // Means its an edit if (this.props.post_view) { this.state.postForm = { body: this.props.post_view.post.body, name: this.props.post_view.post.name, community_id: this.props.post_view.community.id, url: this.props.post_view.post.url, nsfw: this.props.post_view.post.nsfw, auth: authField(), }; } if (this.props.params) { this.state.postForm.name = this.props.params.name; if (this.props.params.url) { this.state.postForm.url = this.props.params.url; } if (this.props.params.body) { this.state.postForm.body = this.props.params.body; } } this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); } componentDidMount() { setupTippy(); this.setupCommunities(); let textarea: any = document.getElementById("post-title"); if (textarea) { autosize(textarea); } } componentDidUpdate() { if ( !this.state.loading && (this.state.postForm.name || this.state.postForm.url || this.state.postForm.body) ) { window.onbeforeunload = () => true; } else { window.onbeforeunload = undefined; } } componentWillUnmount() { this.subscription.unsubscribe(); /* this.choices && this.choices.destroy(); */ window.onbeforeunload = null; } render() { return (
{this.state.suggestedTitle && (
{i18n.t("copy_suggested_title", { title: this.state.suggestedTitle, })}
)} {this.state.postForm.url && validURL(this.state.postForm.url) && ( )} {this.state.imageLoading && } {isImage(this.state.postForm.url) && ( )} {this.state.crossPosts.length > 0 && ( <>
{i18n.t("cross_posts")}
)}