wip-restore-editor

This commit is contained in:
tonyrewin 2022-10-09 08:38:56 +03:00
parent 4570e50806
commit 56a82c0c6e
3 changed files with 53 additions and 67 deletions

View File

@ -24,7 +24,7 @@ const InvalidState = (props: { title: string }) => {
const onClick = () => ctrl.clean() const onClick = () => ctrl.clean()
return ( return (
<div class="error" data-tauri-drag-region="true"> <div class="error">
<div class="container"> <div class="container">
<h1>{props.title}</h1> <h1>{props.title}</h1>
<p> <p>
@ -48,12 +48,12 @@ const Other = () => {
const onClick = () => ctrl.discard() const onClick = () => ctrl.discard()
const getMessage = () => { const getMessage = () => {
const err = (store.error.props as any).error const { error } = store.error.props as any
return typeof err === 'string' ? err : err.message return typeof error === 'string' ? error : error.message
} }
return ( return (
<div class="error" data-tauri-drag-region="true"> <div class="error">
<div class="container"> <div class="container">
<h1>An error occurred.</h1> <h1>An error occurred.</h1>
<pre> <pre>

View File

@ -59,13 +59,5 @@ export const ProseMirror = (props: Props) => {
[props.text, props.extensions] [props.text, props.extensions]
) )
return ( return <div style={props.style} ref={editorRef} class={props.className} spell-check={false} />
<div
style={props.style}
ref={editorRef}
class={props.className}
spell-check={false}
data-tauri-drag-region="true"
/>
)
} }

View File

@ -1,9 +1,14 @@
import { Show, createEffect, createSignal, onCleanup } from 'solid-js' import { Show, createEffect, createSignal, onCleanup, For } from 'solid-js'
import { unwrap } from 'solid-js/store' import { unwrap } from 'solid-js/store'
import { undo, redo } from 'prosemirror-history' import { undo, redo } from 'prosemirror-history'
import { useState } from '../store' import { useState } from '../store'
import type { Styled } from './Layout' import type { Styled } from './Layout'
import '../styles/Sidebar.scss' import '../styles/Sidebar.scss'
import { router } from '../../../stores/router'
import { t } from '../../../utils/intl'
import { isEmpty } from '../prosemirror/helpers'
import type { EditorState } from 'prosemirror-state'
const Off = (props) => <div class="sidebar-off">{props.children}</div> const Off = (props) => <div class="sidebar-off">{props.children}</div>
@ -24,8 +29,19 @@ const Link = (
</button> </button>
) )
const mod = 'Ctrl'
const Keys = (props) => (
<span>
<For each={props.keys}>{(k: string) => <i>{k}</i>}</For>
</span>
)
interface SidebarProps {
error?: string
}
// eslint-disable-next-line sonarjs/cognitive-complexity // eslint-disable-next-line sonarjs/cognitive-complexity
export const Sidebar = (props) => { export const Sidebar = (_props: SidebarProps) => {
const [store, ctrl] = useState() const [store, ctrl] = useState()
const [lastAction, setLastAction] = createSignal<string | undefined>() const [lastAction, setLastAction] = createSignal<string | undefined>()
const toggleTheme = () => { const toggleTheme = () => {
@ -47,7 +63,11 @@ export const Sidebar = (props) => {
const onNew = () => ctrl.newFile() const onNew = () => ctrl.newFile()
const onDiscard = () => ctrl.discard() const onDiscard = () => ctrl.discard()
const [isHidden, setIsHidden] = createSignal<boolean | false>() const [isHidden, setIsHidden] = createSignal<boolean | false>()
// eslint-disable-next-line unicorn/consistent-function-scoping
const onHistory = () => {
console.log('[editor.sidebar] implement history handling')
router.open('/create/settings')
}
const toggleSidebar = () => setIsHidden(!isHidden()) const toggleSidebar = () => setIsHidden(!isHidden())
toggleSidebar() toggleSidebar()
@ -67,14 +87,22 @@ export const Sidebar = (props) => {
}, 1000) }, 1000)
onCleanup(() => clearTimeout(id)) onCleanup(() => clearTimeout(id))
}) })
const discardText = () => {
if (store.path) {
return 'Close'
} else if (store.drafts.length > 0 && isEmpty(store.text as EditorState)) {
return 'Delete ⚠️'
} else {
return 'Clear'
}
}
return ( return (
<div class={'sidebar-container' + (isHidden() ? ' sidebar-container--hidden' : '')}> <div class={'sidebar-container' + (isHidden() ? ' sidebar-container--hidden' : '')}>
<span class="sidebar-opener" onClick={toggleSidebar}> <span class="sidebar-opener" onClick={toggleSidebar}>
Советы и&nbsp;предложения {t('Tips and proposals')}
</span> </span>
<Off onClick={() => editorView().focus()} data-tauri-drag-region="true"> <Off onClick={() => editorView().focus()}>
<div class="sidebar-closer" onClick={toggleSidebar} /> <div class="sidebar-closer" onClick={toggleSidebar} />
<Show when={true}> <Show when={true}>
<div> <div>
@ -83,80 +111,46 @@ export const Sidebar = (props) => {
<i>({store.path.slice(Math.max(0, store.path.length - 24))})</i> <i>({store.path.slice(Math.max(0, store.path.length - 24))})</i>
</Label> </Label>
)} )}
<Link>Пригласить соавторов</Link> <Link onClick={onNew}>{t('Create')}</Link>
<Link>Настройки публикации</Link> <Link onClick={onCollab}>{t('Invite coauthors')}</Link>
<Link>История правок</Link> <Link onClick={() => router.open('/create/settings')}>{t('Publication settings')}</Link>
<Link onClick={onHistory}>{t('Changes history')}</Link>
<div class="theme-switcher"> <div class="theme-switcher">
Ночная тема
<input type="checkbox" name="theme" id="theme" onClick={toggleTheme} /> <input type="checkbox" name="theme" id="theme" onClick={toggleTheme} />
<label for="theme">Ночная тема</label>
</div> </div>
{/*
<Show when={isTauri && !store.path}>
<Link onClick={onSaveAs}>
Save to file <Keys keys={[mod, 's']} />
</Link>
</Show>
<Link onClick={onNew} data-testid='new'>
New <Keys keys={[mod, 'n']} />
</Link>
<Link <Link
onClick={onDiscard} onClick={onDiscard}
disabled={!store.path && store.files.length === 0 && isEmpty(store.text)} disabled={!store.path && store.drafts.length === 0 && isEmpty(store.text as EditorState)}
data-testid='discard' data-testid="discard"
> >
{store.path ? 'Close' : store.files.length > 0 && isEmpty(store.text) ? 'Delete ⚠️' : 'Clear'}{' '} {discardText()} <Keys keys={[mod, 'w']} />
<Keys keys={[mod, 'w']} />
</Link> </Link>
<Show when={isTauri}>
<Link onClick={onToggleFullscreen}>
Fullscreen {store.fullscreen && '✅'} <Keys keys={[alt, 'Enter']} />
</Link>
</Show>
<Link onClick={onUndo}> <Link onClick={onUndo}>
Undo <Keys keys={[mod, 'z']} /> Undo <Keys keys={[mod, 'z']} />
</Link> </Link>
<Link onClick={onRedo}> <Link onClick={onRedo}>
Redo <Keys keys={[mod, ...(isMac ? ['Shift', 'z'] : ['y'])]} /> Redo <Keys keys={[mod, 'Shift+z']} />
</Link> </Link>
<Show when={isTauri}> <Link onClick={onToggleMarkdown} data-testid="markdown">
<Link onClick={onToggleAlwaysOnTop}>Always on Top {store.config.alwaysOnTop && '✅'}</Link>
</Show>
<Show when={!isTauri && false}>
<Link onClick={onOpenInApp}>Open in App </Link>
</Show>
<Link onClick={onToggleMarkdown} data-testid='markdown'>
Markdown mode {store.markdown && '✅'} <Keys keys={[mod, 'm']} /> Markdown mode {store.markdown && '✅'} <Keys keys={[mod, 'm']} />
</Link> </Link>
<Link onClick={onCopyAllAsMd}>Copy all as MD {lastAction() === 'copy-md' && '📋'}</Link> <Show when={store.drafts.length > 0}>
<h4>{t('Drafts')}:</h4>
<Show when={store.files.length > 0}>
<h4>Files:</h4>
<p> <p>
<For each={store.files}>{(file) => <FileLink file={file} />}</For> <For each={store.drafts}>
{(draft) => <Link onClick={() => router.open(draft.path)}>{draft.path}</Link>}
</For>
</p> </p>
</Show> </Show>
<Link onClick={onCollab} title={store.collab?.error ? 'Connection error' : ''}> <Link onClick={onCollab} title={store.collab?.error ? 'Connection error' : ''}>
Collab {collabText()} Collab {collabText()}
</Link> </Link>
<Show when={collabUsers() > 0}> <Show when={collabUsers() > 0}>
<Link onClick={onCopyCollabLink}>
Copy Link {lastAction() === 'copy-collab-link' && '📋'}
</Link>
<Show when={false}>
<Link onClick={onCopyCollabAppLink}>
Copy App Link {lastAction() === 'copy-collab-app-link' && '📋'}
</Link>
</Show>
<span> <span>
{collabUsers()} {collabUsers() === 1 ? 'user' : 'users'} connected {collabUsers()} {collabUsers() === 1 ? 'user' : 'users'} connected
</span> </span>
</Show> </Show>
*/}
</div> </div>
</Show> </Show>
</Off> </Off>