import autosize from "autosize"; import { Component, InfernoNode, linkEvent } from "inferno"; import { CommunityView, CreatePost, EditPost, GetSiteMetadataResponse, Language, PostView, SearchResponse, } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { PostFormParams } from "../../interfaces"; import { UserService } from "../../services"; import { HttpService, RequestState } from "../../services/HttpService"; import { Choice, archiveTodayUrl, capitalizeFirstLetter, communityToChoice, debounce, fetchCommunities, getIdFromString, ghostArchiveUrl, isImage, myAuth, myAuthRequired, relTags, setupTippy, toast, trendingFetchLimit, validTitle, validURL, webArchiveUrl, } from "../../utils"; import { Icon, Spinner } from "../common/icon"; import { LanguageSelect } from "../common/language-select"; import { MarkdownTextArea } from "../common/markdown-textarea"; import NavigationPrompt from "../common/navigation-prompt"; import { SearchableSelect } from "../common/searchable-select"; import { PostListings } from "./post-listings"; const MAX_POST_TITLE_LENGTH = 200; interface PostFormProps { post_view?: PostView; // If a post is given, that means this is an edit crossPosts?: PostView[]; allLanguages: Language[]; siteLanguages: number[]; params?: PostFormParams; onCancel?(): void; onCreate?(form: CreatePost): void; onEdit?(form: EditPost): void; enableNsfw?: boolean; enableDownvotes?: boolean; selectedCommunityChoice?: Choice; onSelectCommunity?: (choice: Choice) => void; initialCommunities?: CommunityView[]; } interface PostFormState { form: { name?: string; url?: string; body?: string; nsfw?: boolean; language_id?: number; community_id?: number; honeypot?: string; }; loading: boolean; suggestedPostsRes: RequestState; metadataRes: RequestState; imageLoading: boolean; imageDeleteUrl: string; communitySearchLoading: boolean; communitySearchOptions: Choice[]; previewMode: boolean; submitted: boolean; } export class PostForm extends Component { state: PostFormState = { suggestedPostsRes: { state: "empty" }, metadataRes: { state: "empty" }, form: {}, loading: false, imageLoading: false, imageDeleteUrl: "", communitySearchLoading: false, previewMode: false, communitySearchOptions: [], submitted: false, }; constructor(props: PostFormProps, 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.handleLanguageChange = this.handleLanguageChange.bind(this); this.handleCommunitySelect = this.handleCommunitySelect.bind(this); const { post_view, selectedCommunityChoice, params } = this.props; // Means its an edit if (post_view) { this.state = { ...this.state, form: { body: post_view.post.body, name: post_view.post.name, community_id: post_view.community.id, url: post_view.post.url, nsfw: post_view.post.nsfw, language_id: post_view.post.language_id, }, }; } else if (selectedCommunityChoice) { this.state = { ...this.state, form: { ...this.state.form, community_id: getIdFromString(selectedCommunityChoice.value), }, communitySearchOptions: [selectedCommunityChoice] .concat( this.props.initialCommunities?.map( ({ community: { id, title } }) => ({ label: title, value: id.toString(), }) ) ?? [] ) .filter(option => option.value !== selectedCommunityChoice.value), }; } else { this.state = { ...this.state, communitySearchOptions: this.props.initialCommunities?.map( ({ community: { id, title } }) => ({ label: title, value: id.toString(), }) ) ?? [], }; } if (params) { this.state = { ...this.state, form: { ...this.state.form, ...params, }, }; } } componentDidMount() { setupTippy(); const textarea: any = document.getElementById("post-title"); if (textarea) { autosize(textarea); } } componentWillReceiveProps( nextProps: Readonly<{ children?: InfernoNode } & PostFormProps> ): void { if (this.props != nextProps) { this.setState( s => ( (s.form.community_id = getIdFromString( nextProps.selectedCommunityChoice?.value )), s ) ); } } render() { const firstLang = this.state.form.language_id; const selectedLangs = firstLang ? Array.of(firstLang) : undefined; const url = this.state.form.url; // TODO // const promptCheck = // !!this.state.form.name || !!this.state.form.url || !!this.state.form.body; // return (
{this.renderSuggestedTitleCopy()} {url && validURL(url) && ( )} {this.state.imageLoading && } {url && isImage(url) && ( )} {this.state.imageDeleteUrl && ( )} {this.props.crossPosts && this.props.crossPosts.length > 0 && ( <>
{i18n.t("cross_posts")}
{}} onPostVote={() => {}} onPostReport={() => {}} onBlockPerson={() => {}} onLockPost={() => {}} onDeletePost={() => {}} onRemovePost={() => {}} onSavePost={() => {}} onFeaturePost={() => {}} onPurgePerson={() => {}} onPurgePost={() => {}} onBanPersonFromCommunity={() => {}} onBanPerson={() => {}} onAddModToCommunity={() => {}} onAddAdmin={() => {}} onTransferCommunity={() => {}} /> )}