Skip to content

Commit

Permalink
Add useToolBar hook
Browse files Browse the repository at this point in the history
  • Loading branch information
choidabom committed Sep 3, 2024
1 parent 3682417 commit 528d808
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 81 deletions.
96 changes: 15 additions & 81 deletions frontend/src/components/editor/Editor.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { markdown } from "@codemirror/lang-markdown";
import { EditorState } from "@codemirror/state";
import { keymap, ViewUpdate } from "@codemirror/view";
import { keymap } from "@codemirror/view";
import { xcodeDark, xcodeLight } from "@uiw/codemirror-theme-xcode";
import { basicSetup, EditorView } from "codemirror";
import { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { ScrollSyncPane } from "react-scroll-sync";
import { useCreateUploadUrlMutation, useUploadFileMutation } from "../../hooks/api/file";
import { useCurrentTheme } from "../../hooks/useCurrentTheme";
import { FormatType, ToolBarState, useFormatUtils } from "../../hooks/useFormatUtils";
import { useFormatUtils } from "../../hooks/useFormatUtils";
import { useToolBar } from "../../hooks/useToolBar";
import { selectEditor, setCmView } from "../../store/editorSlice";
import { selectSetting } from "../../store/settingSlice";
import { selectWorkspace } from "../../store/workspaceSlice";
Expand All @@ -26,77 +27,15 @@ function Editor() {
const workspaceStore = useSelector(selectWorkspace);
const { mutateAsync: createUploadUrl } = useCreateUploadUrlMutation();
const { mutateAsync: uploadFile } = useUploadFileMutation();

const [toolBarState, setToolBarState] = useState<ToolBarState>({
show: false,
position: { top: 0, left: 0 },
selectedFormats: new Set<FormatType>(),
});

const { getFormatMarkerLength, applyFormat, setKeymapConfig } = useFormatUtils();
const { applyFormat, setKeymapConfig } = useFormatUtils();
const { toolBarState, setToolBarState, updateFormatBar } = useToolBar();

const ref = useCallback((node: HTMLElement | null) => {
if (!node) return;
setElement(node);
}, []);

const updateFormatBar = useCallback(
(update: ViewUpdate) => {
const selection = update.state.selection.main;
if (!selection.empty) {
const coords = update.view.coordsAtPos(selection.from);
if (coords) {
const maxLength = getFormatMarkerLength(update.view.state, selection.from);

const selectedTextStart = update.state.sliceDoc(
selection.from - maxLength,
selection.from
);
const selectedTextEnd = update.state.sliceDoc(
selection.to,
selection.to + maxLength
);
const formats = new Set<FormatType>();

const checkAndAddFormat = (marker: string, format: FormatType) => {
if (
selectedTextStart.includes(marker) &&
selectedTextEnd.includes(marker)
) {
formats.add(format);
}
};

checkAndAddFormat("**", FormatType.BOLD);
checkAndAddFormat("_", FormatType.ITALIC);
checkAndAddFormat("`", FormatType.CODE);
checkAndAddFormat("~~", FormatType.STRIKETHROUGH);

// TODO: Modify the rendering method so that it is not affected by the size of the Toolbar
setToolBarState((prev) => ({
...prev,
show: true,
position: {
top: coords.top - 5,
left: coords.left,
},
selectedFormats: formats,
}));
}
} else {
setToolBarState((prev) => ({
...prev,
show: false,
selectedFormats: new Set(),
}));
}
},
[getFormatMarkerLength]
);

useEffect(() => {
let view: EditorView | undefined = undefined;

if (
!element ||
!editorStore.doc ||
Expand Down Expand Up @@ -126,44 +65,39 @@ function Editor() {
keymap.of(setKeymapConfig()),
basicSetup,
markdown(),
yorkieCodeMirror(editorStore.doc, editorStore.client),
themeMode == "light" ? xcodeLight : xcodeDark,
EditorView.theme({
"&": { width: "100%" },
}),
EditorView.theme({ "&": { width: "100%" } }),
EditorView.lineWrapping,
intelligencePivot,
...(settingStore.fileUpload.enable
? [imageUploader(handleUploadImage, editorStore.doc)]
: []),
EditorView.updateListener.of((update) => {
if (update.selectionSet) {
updateFormatBar(update);
}
}),
yorkieCodeMirror(editorStore.doc, editorStore.client),
intelligencePivot,
...(settingStore.fileUpload.enable
? [imageUploader(handleUploadImage, editorStore.doc)]
: []),
],
});

view = new EditorView({
state,
parent: element,
});
const view = new EditorView({ state, parent: element });

dispatch(setCmView(view));

return () => {
view?.destroy();
};
}, [
dispatch,
element,
editorStore.client,
editorStore.doc,
element,
themeMode,
workspaceStore.data,
settingStore.fileUpload?.enable,
dispatch,
createUploadUrl,
uploadFile,
settingStore.fileUpload?.enable,
applyFormat,
updateFormatBar,
setKeymapConfig,
Expand Down
68 changes: 68 additions & 0 deletions frontend/src/hooks/useToolBar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useCallback, useState } from "react";
import { FormatType, ToolBarState, useFormatUtils } from "./useFormatUtils";
import { ViewUpdate } from "@codemirror/view";

export const useToolBar = () => {
const [toolBarState, setToolBarState] = useState<ToolBarState>({
show: false,
position: { top: 0, left: 0 },
selectedFormats: new Set<FormatType>(),
});
const { getFormatMarkerLength } = useFormatUtils();

const updateFormatBar = useCallback(
(update: ViewUpdate) => {
const selection = update.state.selection.main;
if (!selection.empty) {
const coords = update.view.coordsAtPos(selection.from);
if (coords) {
const maxLength = getFormatMarkerLength(update.view.state, selection.from);

const selectedTextStart = update.state.sliceDoc(
selection.from - maxLength,
selection.from
);
const selectedTextEnd = update.state.sliceDoc(
selection.to,
selection.to + maxLength
);
const formats = new Set<FormatType>();

const checkAndAddFormat = (marker: string, format: FormatType) => {
if (
selectedTextStart.includes(marker) &&
selectedTextEnd.includes(marker)
) {
formats.add(format);
}
};

checkAndAddFormat("**", FormatType.BOLD);
checkAndAddFormat("_", FormatType.ITALIC);
checkAndAddFormat("`", FormatType.CODE);
checkAndAddFormat("~~", FormatType.STRIKETHROUGH);

// TODO: Modify the rendering method so that it is not affected by the size of the Toolbar
setToolBarState((prev) => ({
...prev,
show: true,
position: {
top: coords.top - 5,
left: coords.left,
},
selectedFormats: formats,
}));
}
} else {
setToolBarState((prev) => ({
...prev,
show: false,
selectedFormats: new Set(),
}));
}
},
[getFormatMarkerLength]
);

return { toolBarState, setToolBarState, updateFormatBar };
};

0 comments on commit 528d808

Please sign in to comment.