import { redirectPage } from '@nanostores/router' import { clsx } from 'clsx' import { Show, createEffect, createMemo, createSignal, lazy, onMount } from 'solid-js' import { createStore } from 'solid-js/store' import { ShoutForm, useEditorContext } from '../../../context/editor' import { useLocalize } from '../../../context/localize' import { useSession } from '../../../context/session' import { useTopics } from '../../../context/topics' import { Topic } from '../../../graphql/schema/core.gen' import { UploadedFile } from '../../../pages/types' import { router } from '../../../stores/router' import { hideModal, showModal } from '../../../stores/ui' import { TopicSelect, UploadModalContent } from '../../Editor' import { Modal } from '../../Nav/Modal' import { Button } from '../../_shared/Button' import { Icon } from '../../_shared/Icon' import { Image } from '../../_shared/Image' import { useSnackbar } from '../../../context/snackbar' import stylesBeside from '../../Feed/Beside.module.scss' import styles from './PublishSettings.module.scss' const SimplifiedEditor = lazy(() => import('../../Editor/SimplifiedEditor')) const GrowingTextarea = lazy(() => import('../../_shared/GrowingTextarea/GrowingTextarea')) const DESCRIPTION_MAX_LENGTH = 400 type Props = { shoutId: number form: ShoutForm } const shorten = (str: string, maxLen: number) => { if (str.length <= maxLen) return str const result = str.slice(0, Math.max(0, str.lastIndexOf(' ', maxLen))).trim() return `${result}...` } const EMPTY_TOPIC: Topic = { id: -1, slug: '', } const emptyConfig = { coverImageUrl: '', mainTopic: EMPTY_TOPIC, slug: '', title: '', subtitle: '', description: '', selectedTopics: [], } export const PublishSettings = (props: Props) => { const { t } = useLocalize() const { author } = useSession() const { sortedTopics } = useTopics() const { showSnackbar } = useSnackbar() const [topics, setTopics] = createSignal(sortedTopics()) const composeDescription = () => { if (!props.form.description) { const cleanFootnotes = props.form.body.replaceAll(/(.*?)<\/footnote>/g, '') const leadText = cleanFootnotes.replaceAll(/<\/?[^>]+(>|$)/gi, ' ') return shorten(leadText, DESCRIPTION_MAX_LENGTH).trim() } return props.form.description } const initialData = createMemo(() => { return { coverImageUrl: props.form?.coverImageUrl, mainTopic: props.form?.mainTopic || EMPTY_TOPIC, slug: props.form?.slug || '', title: props.form?.title || '', subtitle: props.form?.subtitle || '', description: composeDescription() || '', selectedTopics: [], } }) const [settingsForm, setSettingsForm] = createStore(emptyConfig) onMount(() => { setSettingsForm(initialData()) }) createEffect(() => setTopics(sortedTopics())) const { formErrors, setForm, setFormErrors, saveShout, publishShout } = useEditorContext() const handleUploadModalContentCloseSetCover = (image: UploadedFile) => { hideModal() setSettingsForm('coverImageUrl', image.url) } const handleDeleteCoverImage = () => { setSettingsForm('coverImageUrl', '') } const handleTopicSelectChange = (newSelectedTopics) => { if ( props.form.selectedTopics.length === 0 || newSelectedTopics.every((topic) => topic.id !== props.form.mainTopic?.id) ) { setSettingsForm((prev) => { return { ...prev, mainTopic: newSelectedTopics[0], } }) } if (newSelectedTopics.length > 0) { setFormErrors('selectedTopics', '') } setForm('selectedTopics', newSelectedTopics) } const handleBackClick = () => { redirectPage(router, 'edit', { shoutId: props.shoutId.toString(), }) } const handleCancelClick = () => { setSettingsForm(initialData()) handleBackClick() } const handlePublishSubmit = () => { const shoutData = { ...props.form, ...settingsForm } if (shoutData?.mainTopic) { publishShout(shoutData) } else { showSnackbar({ body: t('Please, set the main topic first') }) } } const handleSaveDraft = () => { saveShout({ ...props.form, ...settingsForm }) } return (

{t('Publish Settings')}

{t('Material card')}

{initialData().title}
{settingsForm.mainTopic.title}
{settingsForm.title}
{settingsForm.subtitle || ''}
{author()?.name}

{t( 'Choose a title image for the article. You can immediately see how the publication card will look like.', )}

setSettingsForm('title', value)} allowEnterKey={false} maxLength={100} /> setSettingsForm('subtitle', value)} allowEnterKey={false} maxLength={100} /> setForm('description', value)} maxLength={DESCRIPTION_MAX_LENGTH} />

{t('Slug')}

{t('Topics')}

{t( 'Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title', )}

0}> setForm('mainTopic', mainTopic)} mainTopic={props.form.mainTopic} />
{formErrors.selectedTopics}

{t('Collaborators')}

handleUploadModalContentCloseSetCover(value)} />
) }