wip-restore-editor
This commit is contained in:
parent
4570e50806
commit
56a82c0c6e
|
@ -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>
|
||||||
|
|
|
@ -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"
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}>
|
||||||
Советы и предложения
|
{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>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user