Skip to content

Commit

Permalink
fix project data and get code to editor
Browse files Browse the repository at this point in the history
  • Loading branch information
sytabaresa committed Jul 9, 2023
1 parent 7fb76a6 commit f8f466b
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 129 deletions.
38 changes: 10 additions & 28 deletions src/common/components/molecules/publishProjectForm.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { useCallback, useEffect, useState } from "react";
import { SmithProject } from "@localtypes/smith";
import { useTranslation } from "@modules/i18n"
import { useDataProvider } from "@hooks/useDataProvider";
import { savingServiceAtom } from "@core/atoms/smith";
import { useAtomValue } from "jotai";
import { projectDataAtom, savingServiceAtom } from "@core/atoms/smith";
import { useAtom, } from "jotai";
// import { Timestamp } from "firebase/firestore";

type PublishProjectFormProps = {
Expand All @@ -12,47 +10,31 @@ type PublishProjectFormProps = {

const PublishProjectForm = ({ }: PublishProjectFormProps) => {
const { t } = useTranslation()
const current = useAtomValue(savingServiceAtom)
const projectData = current.context.projectData
const { data } = useDataProvider()
const [publicState, setPublicState] = useState(false)
const [projectData, setProjectData] = useAtom(projectDataAtom)
const [error, setError] = useState("")
const [info, setInfo] = useState("")

useEffect(() => {
// console.log(projectData)
setPublicState(!!projectData?.isPublic)
}, [projectData])

const updatePublicState = useCallback(async (e) => {
const { update } = data
const newPublicState = !publicState
const newPublicState = !projectData?.project.isPublic
console.log(newPublicState, `making ${newPublicState ? 'public' : 'private'} project: ${projectData.id}`)
setError("")
setInfo("")

try {
setError("")
setInfo("")
const res = await update({
resource: 'projects',
id: projectData.id,
variables: {
isPublic: newPublicState,
// updatedAt: new Date()
} as SmithProject
})
const res = await setProjectData({ isPublic: newPublicState }, {})
console.log('changed sucessfully')
setInfo('ok!')
setPublicState(newPublicState)
} catch (err) {
console.log("Error adding document: ", err);
setError(err.code)
}
}, [publicState])
}, [projectData])

return (
<form className="flex flex-col justify-start md:px-20 min-h-16">
<label className="label cursor-pointer">
<span className="label-text uppercase font-bold">{t.settings.make_public()}?</span>
<input type="checkbox" className="toggle" onChange={updatePublicState} checked={publicState} />
<input type="checkbox" className="toggle" onChange={updatePublicState} checked={!!projectData?.project?.isPublic} disabled={projectData?.readOnly ?? true} />
</label>
{error != "" && <span className="text-red-500">{error?.toString()}</span>}
{info != "" && <span className="text-green-600">{info?.toString()}</span>}
Expand Down
5 changes: 3 additions & 2 deletions src/common/components/organisms/codeToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import SmithButton from "@components/atoms/smithButton";
import EditorMobile from "./editorMobile";
import EditorDesktop from "./editorDesktop";
import { cn } from "@utils/styles";
import { EditorProvider } from "@editor/components/editorProvider";

interface CodeToolbarProps extends HTMLAttributes<HTMLDivElement> {

Expand All @@ -25,7 +26,7 @@ const CodeToolbar = (props: CodeToolbarProps) => {
}, [mobile])

// console.log(screen)
return (
return <EditorProvider>
<div className={cn(className)} {...rest}>
<div id="code-desktop" className="flex">
{!mobile && <EditorDesktop className={cn('transition-all duration-300', mobile2 ? 'w-0 p-0 opacity-0' : '')} />}
Expand All @@ -43,7 +44,7 @@ const CodeToolbar = (props: CodeToolbarProps) => {
<PrimitivesMenu />
</div>
</div>
);
</EditorProvider>
};

export default CodeToolbar;
4 changes: 2 additions & 2 deletions src/common/components/organisms/primitivesMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import { useAtom, useAtomValue } from "jotai";
import { drawServiceAtom } from "@core/atoms/smith";
import createModal from "@components/molecules/createModal";
import CircleRadiusForm from "@components/molecules/circleRadiusForm";
import { editorAtom } from "@editor/common/atoms";
import { cn } from "@utils/styles";
import { usePlateEditorRef } from "@udecode/plate-common";

interface PrimitivesMenuProps extends React.HTMLAttributes<HTMLDivElement> {
};
Expand All @@ -28,7 +28,7 @@ const PrimitivesMenu = (props: PrimitivesMenuProps) => {
const { className, ...rest } = props
const { t } = useTranslation()
const [current, send] = useAtom(drawServiceAtom)
const editor = useAtomValue(editorAtom)
const editor = usePlateEditorRef()
const [offset, setOffset] = useState(0)

const ref = useRef()
Expand Down
19 changes: 1 addition & 18 deletions src/common/editor/common/atoms.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
import { MyValue, createMyPlugins } from "@editor/types";
import { PlateEditor, createPlateEditor } from "@udecode/plate-common";
import { MyValue, } from "@editor/types";
import { WritableAtom, atom } from "jotai";

// plugins
import { basicNodesPlugins } from "./basicNodesPlugin";
import { createClipboardPlugin } from "@editor/clipboard/createClipboardPlugin";

export const plugins = createMyPlugins(
[
...basicNodesPlugins,
createClipboardPlugin(),
]
);

export const editorAtom = atom<PlateEditor<MyValue>>(
createPlateEditor({
id: '',
plugins: plugins
}))

export const changeAtom = atom<MyValue>(null) as WritableAtom<MyValue, [MyValue], void>
export const selectionAtom = atom<object>({}) as WritableAtom<object, [object], void>
10 changes: 10 additions & 0 deletions src/common/editor/common/plugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createMyPlugins } from "@editor/types";
import { basicNodesPlugins } from "./basicNodesPlugin";
import { createClipboardPlugin } from "@editor/clipboard/createClipboardPlugin";

export const plugins = createMyPlugins(
[
...basicNodesPlugins,
createClipboardPlugin(),
]
);
62 changes: 62 additions & 0 deletions src/common/editor/components/editorProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { codeAtom, editorServiceAtom, savingServiceAtom } from "@core/atoms/smith"
import { plugins } from "@editor/common/plugins"
import { deserializeCode, serializeCode } from "@editor/serializers/serializers"
import { MyValue } from "@editor/types"
import { PlateEditor, PlateProvider } from "@udecode/plate-common"
import { useAtomValue, useSetAtom } from "jotai"
import { useCallback, useMemo, useRef } from "react"
import { debounce } from "lodash"
import { changeAtom, selectionAtom } from "@editor/common/atoms"

export const EditorProvider = ({ children }) => {
const code = useAtomValue(codeAtom)
const editorRef = useRef<PlateEditor<MyValue> | null>(null);

// machines
const sendEditor = useSetAtom(editorServiceAtom)
const sendSave = useSetAtom(savingServiceAtom)

// FSM actions
const setSelection = useSetAtom(selectionAtom)
const setChange = useSetAtom(changeAtom)


const saveCode = debounce((value) => {
// console.log("code")
const code = serializeCode(value)
sendEditor({ type: "CODE", value: code })
if (code != '') {
sendSave({ type: 'SAVE' })
}
}, 1000)

const onEditorChanged = useCallback(
(value: MyValue) => {
const editor = editorRef.current;
// setChange(editor.operations)
const isAstChange = editor.operations.some(
op => 'set_selection' !== op.type
)
// console.log(editor.operations)
if (isAstChange) {
// console.log('changed')
// Serialize the value and save the string value
saveCode(value)
} else {
setSelection({})
}
}, [])

const editorValue = useMemo(() => deserializeCode(code), [code])

return <PlateProvider<MyValue>
// id={id}
editorRef={editorRef}
plugins={plugins}
value={editorValue}
onChange={onEditorChanged}
>
{children}
</PlateProvider>

}
62 changes: 15 additions & 47 deletions src/common/editor/editor.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { debounce } from "lodash";
import { useAtomValue, useSetAtom } from "jotai"
import { HTMLAttributes, ReactNode, useCallback, useEffect, useMemo } from "react";
import { Plate, PlateEditor, PlateProvider } from '@udecode/plate-common';
import { deserializeCode, serializeCode } from '@editor/serializers/serializers'
import { codeAtom, editorServiceAtom, savingServiceAtom } from "@core/atoms/smith";
import { changeAtom, editorAtom, selectionAtom } from "@editor/common/atoms";
import { Plate, PlateEditor, usePlateEditorRef } from '@udecode/plate-common';
import { serializeCode } from '@editor/serializers/serializers'
import { codeAtom, editorServiceAtom, projectDataAtom, savingServiceAtom } from "@core/atoms/smith";
import { changeAtom, selectionAtom } from "@editor/common/atoms";
import { cn } from "@utils/styles";
// import { SearcherPopup } from "@components/molecules/editor/searcher";
import { useCutomEditableProps } from './common/useCustomEditableProps';
Expand All @@ -17,56 +17,24 @@ export interface CodeEditor extends HTMLAttributes<HTMLDivElement> {
};

const CodeEditor = ({ className, toolbar, footer, id = '', ...rest }: CodeEditor) => {

// machines
const editor = useAtomValue(editorAtom)
const sendEditor = useSetAtom(editorServiceAtom)
const code = useAtomValue(codeAtom)
const sendSave = useSetAtom(savingServiceAtom)

// FSM actions
const setSelection = useSetAtom(selectionAtom)
const setChange = useSetAtom(changeAtom)

const onEditorChanged = useCallback((value: MyValue) => {
setChange(editor.operations)
const isAstChange = editor.operations.some(
op => 'set_selection' !== op.type
)
if (isAstChange) {
// Serialize the value and save the string value
debounce(() => {
const code = serializeCode(value)
sendEditor({ type: "CODE", value: code })
}, 1000)
} else {
setSelection({})
}
}, [])

const editorValue = useMemo(() => deserializeCode(code), [code])
// console.log(initialValue)

// useAtom(useMemo(() => atom((get) => get(editorServiceAtom).context.counter), []))
const editor = usePlateEditorRef<MyValue>()
const projectData = useAtomValue(projectDataAtom)
const editorService = useAtomValue(editorServiceAtom)

const editableProps = useCutomEditableProps()

useEffect(() => {
// for get new initialValue in editor
editor.reset()
}, [projectData])

if (code != '') {
sendSave({ type: 'SAVE' })
}
}, [code])
useEffect(() => {
// for get new initialValue in editor
if (editorService.name == 'parsing')
editor.reset()
}, [editorService.name])

return <PlateProvider<MyValue>
// id={id}
editor={editor}
plugins={editor.plugins}
value={editorValue}
onChange={onEditorChanged}
>
return <>
<div className={cn('border border-neutral bg-base-100 p-2 flex flex-col relative', className)} {...rest}>
<div className="absolute top-0 right-0 mt-2 mr-6 flex z-10 opacity-50">
{toolbar?.(editor)}
Expand All @@ -80,7 +48,7 @@ const CodeEditor = ({ className, toolbar, footer, id = '', ...rest }: CodeEditor
{footer?.(editor)}
</div >
<div id="code-end"></div>
</PlateProvider>
</>
}

export default CodeEditor;
5 changes: 5 additions & 0 deletions src/common/types/smith.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ export type SmithProject = {
userId?: string
readonly: boolean;
}

export type RuntimeProject = {
readOnly: boolean;
project: SmithProject
}
42 changes: 37 additions & 5 deletions src/modules/core/atoms/smith.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import ReCircleTooltip from "@tooltips/reCircle";
import ImCircleTooltip from "@tooltips/imCircle";
import ReCircleAdTooltip from "@tooltips/reCircleAd";
import ImCircleAdTooltip from "@tooltips/imCircleAd";
import { Getter, Setter, WritableAtom, atom } from "jotai";
import { Getter, PrimitiveAtom, Setter, WritableAtom, atom } from "jotai";
import { initBoard } from "@core/jxg/initBoard";
import { getCurrentBreakpoint } from "@hooks/useScreen";
import { atomWithReset, atomWithStorage } from "jotai/utils";
import { _dataRxdbProviderAtom } from "./db";
import { Board } from "jsxgraph";
import { RuntimeProject, SmithProject } from "@localtypes/smith";
import { DataProvider } from "@db/db";

export const editorServiceAtom = atomWithMachine(editorFSM, (get) => ({
menuService: drawServiceAtom,
Expand Down Expand Up @@ -153,13 +155,36 @@ export const boardDataAtom = atomWithStorage('config', {
coordsPresition: 3
})

// read only atom
export const codeAtom = atom<string>(
(get) => {
return get(_codeAtom)

export const _projectDataAtom = atom(null) as PrimitiveAtom<RuntimeProject>
export const projectDataAtom = atom<RuntimeProject, [Partial<SmithProject>, Partial<RuntimeProject>], void>(
(get) => get(_projectDataAtom),
async (get, set, project, runtime) => {
const oldData = get(_projectDataAtom)
set(_projectDataAtom, {
...oldData,
...runtime,
project: {
...oldData.project,
...project
}
})

if (!oldData?.readOnly) {
const { update } = await get(_dataRxdbProviderAtom) as DataProvider

await update({
resource: 'projects',
id: oldData.project.id,
variables: {
...project
} as SmithProject
})
}
}
)


export const _codeAtom = atomWithReset<string>(
`/**
* My smith design
Expand All @@ -168,6 +193,13 @@ export const _codeAtom = atomWithReset<string>(
**/
Zo = 50;`)

// read only atom
export const codeAtom = atom<string>(
(get) => {
return get(_codeAtom)
}
)

export const infoboxAtom = atom<{
x: number,
y: number,
Expand Down
Loading

0 comments on commit f8f466b

Please sign in to comment.