2023-11-14 15:10:00 +00:00
|
|
|
import { clsx } from 'clsx'
|
2024-02-04 11:25:21 +00:00
|
|
|
import { Show, createSignal } from 'solid-js'
|
2023-05-12 13:03:46 +00:00
|
|
|
import { useEditorHTML } from 'solid-tiptap'
|
|
|
|
import Typograf from 'typograf'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
import { useUI } from '~/context/ui'
|
2023-11-14 15:10:00 +00:00
|
|
|
import { useEditorContext } from '../../../context/editor'
|
|
|
|
import { useLocalize } from '../../../context/localize'
|
|
|
|
import { useEscKeyDownHandler } from '../../../utils/useEscKeyDownHandler'
|
|
|
|
import { useOutsideClickHandler } from '../../../utils/useOutsideClickHandler'
|
|
|
|
import { Button } from '../../_shared/Button'
|
2023-05-29 04:40:17 +00:00
|
|
|
import { DarkModeToggle } from '../../_shared/DarkModeToggle'
|
2023-11-14 15:10:00 +00:00
|
|
|
import { Icon } from '../../_shared/Icon'
|
2024-06-24 17:50:27 +00:00
|
|
|
|
|
|
|
import { A } from '@solidjs/router'
|
2023-11-14 15:10:00 +00:00
|
|
|
import styles from './Panel.module.scss'
|
2023-05-12 13:03:46 +00:00
|
|
|
|
|
|
|
const typograf = new Typograf({ locale: ['ru', 'en-US'] })
|
2023-04-26 02:37:29 +00:00
|
|
|
|
2023-05-04 04:43:52 +00:00
|
|
|
type Props = {
|
2023-05-08 17:21:06 +00:00
|
|
|
shoutId: number
|
2023-05-03 16:13:48 +00:00
|
|
|
}
|
2023-04-26 02:37:29 +00:00
|
|
|
|
2023-05-04 04:43:52 +00:00
|
|
|
export const Panel = (props: Props) => {
|
2023-04-26 02:37:29 +00:00
|
|
|
const { t } = useLocalize()
|
2024-06-24 17:50:27 +00:00
|
|
|
const { showModal } = useUI()
|
2024-05-03 08:36:15 +00:00
|
|
|
const {
|
|
|
|
isEditorPanelVisible,
|
|
|
|
wordCounter,
|
2024-06-24 17:50:27 +00:00
|
|
|
editor,
|
2024-05-03 08:36:15 +00:00
|
|
|
form,
|
|
|
|
toggleEditorPanel,
|
|
|
|
saveShout,
|
|
|
|
saveDraft,
|
|
|
|
publishShout,
|
|
|
|
} = useEditorContext()
|
2023-05-03 16:13:48 +00:00
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
let containerRef: HTMLElement | undefined
|
2023-05-29 04:40:17 +00:00
|
|
|
const [isShortcutsVisible, setIsShortcutsVisible] = createSignal(false)
|
|
|
|
const [isTypographyFixed, setIsTypographyFixed] = createSignal(false)
|
|
|
|
|
2023-05-03 16:13:48 +00:00
|
|
|
useOutsideClickHandler({
|
|
|
|
containerRef,
|
|
|
|
predicate: () => isEditorPanelVisible(),
|
2023-11-14 15:10:00 +00:00
|
|
|
handler: () => toggleEditorPanel(),
|
2023-05-03 16:13:48 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
useEscKeyDownHandler(() => {
|
|
|
|
if (isEditorPanelVisible()) {
|
|
|
|
toggleEditorPanel()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2023-05-12 13:45:31 +00:00
|
|
|
const handleSaveClick = () => {
|
2024-05-03 08:36:15 +00:00
|
|
|
const hasTopics = form.selectedTopics?.length > 0
|
|
|
|
if (hasTopics) {
|
|
|
|
saveShout(form)
|
|
|
|
} else {
|
|
|
|
saveDraft(form)
|
|
|
|
}
|
2023-05-08 17:21:06 +00:00
|
|
|
}
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
const html = useEditorHTML(() => editor()) // FIXME: lost current() call
|
2024-02-05 15:49:08 +00:00
|
|
|
|
2023-05-12 13:45:31 +00:00
|
|
|
const handleFixTypographyClick = () => {
|
2024-06-24 17:50:27 +00:00
|
|
|
editor()?.commands.setContent(typograf.execute(html() || '')) // here too
|
2023-05-29 04:40:17 +00:00
|
|
|
setIsTypographyFixed(true)
|
2023-05-12 13:03:46 +00:00
|
|
|
}
|
|
|
|
|
2023-04-26 02:37:29 +00:00
|
|
|
return (
|
2023-05-03 16:13:48 +00:00
|
|
|
<aside
|
2024-06-24 17:50:27 +00:00
|
|
|
ref={(el) => (containerRef = el)}
|
2023-05-03 16:13:48 +00:00
|
|
|
class={clsx('col-md-6', styles.Panel, { [styles.hidden]: !isEditorPanelVisible() })}
|
|
|
|
>
|
2023-05-29 04:40:17 +00:00
|
|
|
<Button
|
|
|
|
value={<Icon name="close" />}
|
|
|
|
variant={'inline'}
|
|
|
|
class={styles.close}
|
|
|
|
onClick={() => toggleEditorPanel()}
|
|
|
|
/>
|
|
|
|
<div class={clsx(styles.actionsHolder, styles.scrolled, { hidden: isShortcutsVisible() })}>
|
2023-04-26 02:37:29 +00:00
|
|
|
<section>
|
2023-05-03 16:13:48 +00:00
|
|
|
<p>
|
2024-02-12 08:12:23 +00:00
|
|
|
<span class={styles.link} onClick={() => publishShout(form)}>
|
2023-05-08 17:21:06 +00:00
|
|
|
{t('Publish')}
|
2023-05-12 13:45:31 +00:00
|
|
|
</span>
|
2023-05-03 16:13:48 +00:00
|
|
|
</p>
|
|
|
|
<p>
|
2023-05-12 13:45:31 +00:00
|
|
|
<span class={styles.link} onClick={handleSaveClick}>
|
2023-05-08 17:21:06 +00:00
|
|
|
{t('Save draft')}
|
2023-05-12 13:45:31 +00:00
|
|
|
</span>
|
2023-05-03 16:13:48 +00:00
|
|
|
</p>
|
2023-04-26 02:37:29 +00:00
|
|
|
</section>
|
|
|
|
|
|
|
|
<section>
|
2023-05-03 16:13:48 +00:00
|
|
|
<p>
|
2024-01-25 09:57:57 +00:00
|
|
|
<span class={styles.link} onClick={() => showModal('inviteMembers')}>
|
2023-12-20 16:06:42 +00:00
|
|
|
{t('Invite co-authors')}
|
|
|
|
</span>
|
2023-05-03 16:13:48 +00:00
|
|
|
</p>
|
|
|
|
<p>
|
2024-06-24 17:50:27 +00:00
|
|
|
<A
|
2023-05-12 13:45:31 +00:00
|
|
|
class={styles.link}
|
2023-05-10 01:46:39 +00:00
|
|
|
onClick={() => toggleEditorPanel()}
|
2024-06-24 17:50:27 +00:00
|
|
|
href={`/edit/${props.shoutId}/settings`}
|
2023-05-10 01:46:39 +00:00
|
|
|
>
|
2023-05-03 16:13:48 +00:00
|
|
|
{t('Publication settings')}
|
2024-06-24 17:50:27 +00:00
|
|
|
</A>
|
2023-05-03 16:13:48 +00:00
|
|
|
</p>
|
2023-05-12 13:03:46 +00:00
|
|
|
<p>
|
2023-05-29 04:40:17 +00:00
|
|
|
<span class={styles.link}>{t('Corrections history')}</span>
|
2023-05-03 16:13:48 +00:00
|
|
|
</p>
|
2023-04-26 02:37:29 +00:00
|
|
|
</section>
|
|
|
|
|
2023-05-29 04:40:17 +00:00
|
|
|
<section>
|
|
|
|
<div class={styles.typograph}>
|
|
|
|
<div>
|
|
|
|
<span class={styles.link} onClick={handleFixTypographyClick}>
|
|
|
|
{t('Autotypograph')}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
<Show when={isTypographyFixed()}>
|
|
|
|
<div class={clsx(styles.typographStatus, styles.typographStatusSuccess)}>{t('Fixed')}</div>
|
|
|
|
</Show>
|
|
|
|
</div>
|
|
|
|
<p>{t('Text checking')}</p>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section>
|
|
|
|
<DarkModeToggle />
|
|
|
|
</section>
|
|
|
|
|
2023-04-26 02:37:29 +00:00
|
|
|
<section>
|
|
|
|
<p>
|
2023-05-12 13:45:31 +00:00
|
|
|
<a class={styles.link} href="/how-to-write-a-good-article">
|
|
|
|
{t('How to write a good article')}
|
|
|
|
</a>
|
2023-04-26 02:37:29 +00:00
|
|
|
</p>
|
|
|
|
<p>
|
2023-05-29 04:40:17 +00:00
|
|
|
<button class={styles.link} onClick={() => setIsShortcutsVisible(true)}>
|
2023-05-12 13:45:31 +00:00
|
|
|
{t('Hotkeys')}
|
2023-05-29 04:40:17 +00:00
|
|
|
</button>
|
2023-04-26 02:37:29 +00:00
|
|
|
</p>
|
|
|
|
<p>
|
2023-05-12 13:45:31 +00:00
|
|
|
<a class={styles.link} href="#">
|
|
|
|
{t('Help')}
|
|
|
|
</a>
|
2023-04-26 02:37:29 +00:00
|
|
|
</p>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<div class={styles.stats}>
|
|
|
|
<div>
|
|
|
|
{t('Characters')}: <em>{wordCounter().characters}</em>
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
{t('Words')}: <em>{wordCounter().words}</em>
|
|
|
|
</div>
|
2023-05-03 16:13:48 +00:00
|
|
|
{/*<div>*/}
|
|
|
|
{/* {t('Last rev.')}: <em>22.03.22 в 18:20</em>*/}
|
|
|
|
{/*</div>*/}
|
2023-04-26 02:37:29 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2023-05-29 04:40:17 +00:00
|
|
|
|
|
|
|
<div class={clsx(styles.actionsHolder, styles.scrolled, { hidden: !isShortcutsVisible() })}>
|
|
|
|
<p>
|
|
|
|
<button class={styles.backToMenuControl} onClick={() => setIsShortcutsVisible(false)}>
|
|
|
|
{t('back to menu"')}
|
|
|
|
</button>
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<section class={styles.shortcutList}>
|
|
|
|
<p>
|
|
|
|
{t('bold')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>Ctrl</span>
|
|
|
|
<span class={styles.shortcutButton}>B</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
{t('italic')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>Ctrl</span>
|
|
|
|
<span class={styles.shortcutButton}>I</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
{t('add link')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>Ctrl</span>
|
|
|
|
<span class={styles.shortcutButton}>K</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section class={styles.shortcutList}>
|
|
|
|
<p>
|
|
|
|
{t('header 1')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>Ctrl</span>
|
|
|
|
<span class={styles.shortcutButton}>Alt</span>
|
|
|
|
<span class={styles.shortcutButton}>1</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
{t('header 2')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>Ctrl</span>
|
|
|
|
<span class={styles.shortcutButton}>Alt</span>
|
|
|
|
<span class={styles.shortcutButton}>2</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
{t('header 3')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>Ctrl</span>
|
|
|
|
<span class={styles.shortcutButton}>Alt</span>
|
|
|
|
<span class={styles.shortcutButton}>3</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section class={styles.shortcutList}>
|
|
|
|
<p>
|
|
|
|
{t('marker list')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>*</span>
|
|
|
|
<span class={styles.shortcutButton}>Space</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
{t('number list')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>1</span>
|
|
|
|
<span class={styles.shortcutButton}>Space</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
{t('delimiter')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>***</span>
|
|
|
|
<span class={styles.shortcutButton}>Enter</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section class={styles.shortcutList}>
|
|
|
|
<p>
|
2023-07-28 09:47:19 +00:00
|
|
|
{t('cancel')}
|
2023-05-29 04:40:17 +00:00
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>Ctrl</span>
|
|
|
|
<span class={styles.shortcutButton}>Z</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
{t('repeat')}
|
|
|
|
<span class={styles.shortcut}>
|
|
|
|
<span class={styles.shortcutButton}>Ctrl</span>
|
|
|
|
<span class={styles.shortcutButton}>Shift</span>
|
|
|
|
<span class={styles.shortcutButton}>Z</span>
|
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
</section>
|
|
|
|
</div>
|
2023-04-26 02:37:29 +00:00
|
|
|
</aside>
|
|
|
|
)
|
|
|
|
}
|