From 05cdf42c05fafd557aa02d81f8fc5b01309284c6 Mon Sep 17 00:00:00 2001 From: tonyrewin Date: Tue, 18 Oct 2022 18:50:49 +0300 Subject: [PATCH] fix-state --- CHANGELOG.txt | 3 + public/icons/checkbox.svg | 3 - src/components/Editor/components/Editor.tsx | 2 +- src/components/Editor/components/Sidebar.tsx | 6 +- src/components/Editor/index.tsx | 25 ------- src/components/Editor/prosemirror/p2p.ts | 31 +++++---- src/components/Editor/store/ctrl.ts | 72 +++++++++++--------- src/components/Pages/CreatePage.tsx | 3 +- src/components/Views/Create.tsx | 16 +++-- src/locales/ru.json | 7 +- 10 files changed, 77 insertions(+), 91 deletions(-) delete mode 100644 public/icons/checkbox.svg delete mode 100644 src/components/Editor/index.tsx diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 31eb7487..e4fcaba0 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,6 @@ +[0.6.0] +[+] editor enabled + [0.5.1] [+] nanostores-base global store [-] Root.tsx components diff --git a/public/icons/checkbox.svg b/public/icons/checkbox.svg deleted file mode 100644 index 61dd1216..00000000 --- a/public/icons/checkbox.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/Editor/components/Editor.tsx b/src/components/Editor/components/Editor.tsx index a19dfc1e..9b9a5415 100644 --- a/src/components/Editor/components/Editor.tsx +++ b/src/components/Editor/components/Editor.tsx @@ -5,7 +5,7 @@ import { ProseMirror } from '../components/ProseMirror' import '../styles/Editor.scss' import type { ProseMirrorExtension, ProseMirrorState } from '../prosemirror/helpers' -export default () => { +export const Editor = () => { const [store, ctrl] = useState() const onInit = (text: EditorState, editorView: EditorView) => ctrl.setState({ editorView, text }) const onReconfigure = (text: EditorState) => ctrl.setState({ text }) diff --git a/src/components/Editor/components/Sidebar.tsx b/src/components/Editor/components/Sidebar.tsx index dfeb93ee..68082ea0 100644 --- a/src/components/Editor/components/Sidebar.tsx +++ b/src/components/Editor/components/Sidebar.tsx @@ -51,9 +51,9 @@ export const Sidebar = (_props: SidebarProps) => { } const collabText = () => { if (store.collab?.started) { - return 'Stop' + return t('Stop collab') } else { - return store.collab?.error ? t('Restart') : t('Start') + return store.collab?.error ? t('Restart collab') : t('Start collab') } } const editorView = () => unwrap(store.editorView) @@ -142,7 +142,7 @@ export const Sidebar = (_props: SidebarProps) => { - {t('Collab')} {collabText()} + {collabText()} 0}> diff --git a/src/components/Editor/index.tsx b/src/components/Editor/index.tsx deleted file mode 100644 index 1cf25a22..00000000 --- a/src/components/Editor/index.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import './styles/Editor.scss' -import type { EditorView } from 'prosemirror-view' -import type { EditorState } from 'prosemirror-state' -import { useState } from './store' -import { ProseMirror } from './components/ProseMirror' - -export const Editor = () => { - const [store, ctrl] = useState() - const onInit = (text: EditorState, editorView: EditorView) => ctrl.setState({ editorView, text }) - const onReconfigure = (text: EditorState) => ctrl.setState({ text }) - const onChange = (text: EditorState) => ctrl.setState({ text, lastModified: new Date() }) - return ( - - ) -} diff --git a/src/components/Editor/prosemirror/p2p.ts b/src/components/Editor/prosemirror/p2p.ts index 0349315a..3c9d1f80 100644 --- a/src/components/Editor/prosemirror/p2p.ts +++ b/src/components/Editor/prosemirror/p2p.ts @@ -8,6 +8,10 @@ import { setReactions } from '../../../stores/editor' export const roomConnect = (room, username = '', keyname = 'collab'): [XmlFragment, WebrtcProvider] => { const ydoc = new Doc() const yarr = ydoc.getArray(keyname + '-reactions') + yarr.observeDeep(() => { + console.debug('[p2p] yarray updated', yarr.toArray()) + setReactions(yarr.toArray() as Reaction[]) + }) const yXmlFragment = ydoc.getXmlFragment(keyname) const webrtcOptions = { awareness: new Awareness(ydoc), @@ -22,23 +26,20 @@ export const roomConnect = (room, username = '', keyname = 'collab'): [XmlFragme peerOpts: {}, password: '' } + // connect with provider const provider = new WebrtcProvider(room, ydoc, webrtcOptions) - let name = username - - yarr.observeDeep(() => { - console.debug('yarray updated:', yarr.toArray()) - setReactions(yarr.toArray() as Reaction[]) + console.debug('[p2p] provider', provider) + // setting username + provider.awareness.setLocalStateField('user', { + name: + username ?? + uniqueNamesGenerator({ + dictionaries: [adjectives, animals], + style: 'capital', + separator: ' ', + length: 2 + }) }) - if (Boolean(name) === false) { - name = uniqueNamesGenerator({ - dictionaries: [adjectives, animals], - style: 'capital', - separator: ' ', - length: 2 - }) - } - - provider.awareness.setLocalStateField('user', { name }) return [yXmlFragment, provider] } diff --git a/src/components/Editor/store/ctrl.ts b/src/components/Editor/store/ctrl.ts index e698f752..9d6e18a8 100644 --- a/src/components/Editor/store/ctrl.ts +++ b/src/components/Editor/store/ctrl.ts @@ -176,7 +176,7 @@ export const createCtrl = (initial): [Store, { [key: string]: any }] => { } } - const getTheme = (state: State) => ({ theme: state.config.theme }) + const getTheme = (state: State) => ({ theme: state.config?.theme || '' }) const clean = () => { setState({ @@ -204,7 +204,7 @@ export const createCtrl = (initial): [Store, { [key: string]: any }] => { let state = await readStoredState() console.log('[editor] init with state', state) try { - if (state.args.room) { + if (state.args?.room) { state = await doStartCollab(state) } else if (state.args.text) { state = await doOpenDraft(state, { @@ -354,43 +354,51 @@ export const createCtrl = (initial): [Store, { [key: string]: any }] => { } const doStartCollab = async (state: State): Promise => { - const backup = state.args?.room && state.collab?.room !== state.args.room + const restoredRoom = state.args?.room && state.collab?.room !== state.args.room const room = state.args?.room ?? uuidv4() - state.args.room = room - window.history.replaceState(null, '', `/${room}`) - const { roomConnect } = await import('../prosemirror/p2p') - const [type, provider] = roomConnect(room) - - const extensions = createExtensions({ - config: state.config, - markdown: state.markdown, - path: state.path, - keymap, - y: { type, provider }, - collab: true - }) - + state.args = { ...state.args, room } let newst = state - if ((backup && !isEmpty(state.text as EditorState)) || state.path) { - let drafts = state.drafts - if (!state.error) { - drafts = addToDrafts(drafts, { lastModified: new Date(), text: state.text } as Draft) + try { + const { roomConnect } = await import('../prosemirror/p2p') + const [type, provider] = roomConnect(room) + + const extensions = createExtensions({ + config: state.config, + markdown: state.markdown, + path: state.path, + keymap, + y: { type, provider }, + collab: true + }) + + if ((restoredRoom && !isEmpty(state.text as EditorState)) || state.path) { + let drafts = state.drafts + if (!state.error) { + drafts = addToDrafts(drafts, { lastModified: new Date(), text: state.text } as Draft) + } + + newst = { + ...state, + drafts, + lastModified: undefined, + path: undefined, + error: undefined + } + window.history.replaceState(null, '', `/${room}`) } - newst = { + return { + ...newst, + extensions, + collab: { started: true, room, y: { type, provider } } + } + } catch (error) { + console.error(error) + return { ...state, - drafts, - lastModified: undefined, - path: undefined, - error: undefined + collab: { error } } } - - return { - ...newst, - extensions, - collab: { started: true, room, y: { type, provider } } - } } const stopCollab = (state: State) => { diff --git a/src/components/Pages/CreatePage.tsx b/src/components/Pages/CreatePage.tsx index 1c82fb95..a7cb6943 100644 --- a/src/components/Pages/CreatePage.tsx +++ b/src/components/Pages/CreatePage.tsx @@ -1,10 +1,11 @@ +import { newState } from '../Editor/store' import { MainLayout } from '../Layouts/MainLayout' import { CreateView } from '../Views/Create' export const CreatePage = () => { return ( - + ) } diff --git a/src/components/Views/Create.tsx b/src/components/Views/Create.tsx index f133bd26..063e5b38 100644 --- a/src/components/Views/Create.tsx +++ b/src/components/Views/Create.tsx @@ -1,14 +1,16 @@ import { Show, onCleanup, createEffect, onError, onMount, untrack } from 'solid-js' import { createMutable, unwrap } from 'solid-js/store' -import { State, StateContext, newState } from '../Editor/store' +import { State, StateContext } from '../Editor/store' import { createCtrl } from '../Editor/store/ctrl' import { Layout } from '../Editor/components/Layout' -import { Editor } from '../Editor' +import { Editor } from '../Editor/components/Editor' import { Sidebar } from '../Editor/components/Sidebar' import ErrorView from '../Editor/components/Error' -export const CreateView = () => { - const [store, ctrl] = createCtrl(newState()) +const matchDark = () => window.matchMedia('(prefers-color-scheme: dark)') + +export const CreateView = (props: { state: State }) => { + const [store, ctrl] = createCtrl(props.state) const mouseEnterCoords = createMutable({ x: 0, y: 0 }) const onMouseEnter = (e: MouseEvent) => { @@ -25,10 +27,10 @@ export const CreateView = () => { await ctrl.init() }) + const onChangeTheme = () => ctrl.updateTheme() onMount(() => { - const mediaQuery = '(prefers-color-scheme: dark)' - window.matchMedia(mediaQuery).addEventListener('change', ctrl.updateTheme) - onCleanup(() => window.matchMedia(mediaQuery).removeEventListener('change', ctrl.updateTheme)) + matchDark().addEventListener('change', onChangeTheme) + onCleanup(() => matchDark().removeEventListener('change', onChangeTheme)) }) onError((error) => { diff --git a/src/locales/ru.json b/src/locales/ru.json index d137cb79..faf52a3a 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -157,10 +157,9 @@ "History of changes": "История правок", "Undo": "Откат", "Redo": "Повторить действие", - "Start": "Начать", - "Stop": "Остановить", - "Restart": "Перезапустить", + "Stop collab": "Индивидуальный режим", + "Restart collab": "Перезапустить коллаборацию", + "Start collab": "Коллаборативный режим", "Clear": "Сбросить", - "Collab": "Совместно", "Режим": "Theme" }