|
|
@@ -1,4 +1,4 @@
|
|
|
-import { RefObject, useEffect } from 'react';
|
|
|
+import { RefObject, useCallback, useEffect } from 'react';
|
|
|
|
|
|
import {
|
|
|
isClient, isServer, pagePathUtils, Nullable, PageGrant,
|
|
|
@@ -72,29 +72,21 @@ export const useIsMobile = (): SWRResponse<boolean, Error> => {
|
|
|
return useStaticSWR<boolean, Error>(key, undefined, configuration);
|
|
|
};
|
|
|
|
|
|
-const updateBodyClassesByEditorMode = (newEditorMode: EditorMode, isSidebar = false) => {
|
|
|
- const bodyElement = document.getElementsByTagName('body')[0];
|
|
|
- if (bodyElement == null) {
|
|
|
- logger.warn('The body tag was not successfully obtained');
|
|
|
- return;
|
|
|
- }
|
|
|
- switch (newEditorMode) {
|
|
|
- case EditorMode.View:
|
|
|
- bodyElement.classList.remove('on-edit', 'builtin-editor', 'hackmd', 'editing-sidebar');
|
|
|
- break;
|
|
|
+const getClassNamesByEditorMode = (editorMode: EditorMode | undefined, isSidebar = false): string[] => {
|
|
|
+ const classNames: string[] = [];
|
|
|
+ switch (editorMode) {
|
|
|
case EditorMode.Editor:
|
|
|
- bodyElement.classList.add('on-edit', 'builtin-editor');
|
|
|
- bodyElement.classList.remove('hackmd');
|
|
|
- // editing /Sidebar
|
|
|
+ classNames.push('editing', 'builtin-editor');
|
|
|
if (isSidebar) {
|
|
|
- bodyElement.classList.add('editing-sidebar');
|
|
|
+ classNames.push('editing-sidebar');
|
|
|
}
|
|
|
break;
|
|
|
case EditorMode.HackMD:
|
|
|
- bodyElement.classList.add('on-edit', 'hackmd');
|
|
|
- bodyElement.classList.remove('builtin-editor', 'editing-sidebar');
|
|
|
+ classNames.push('editing', 'hackmd');
|
|
|
break;
|
|
|
}
|
|
|
+
|
|
|
+ return classNames;
|
|
|
};
|
|
|
|
|
|
const updateHashByEditorMode = (newEditorMode: EditorMode) => {
|
|
|
@@ -130,8 +122,11 @@ export const determineEditorModeByHash = (): EditorMode => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-let isEditorModeLoaded = false;
|
|
|
-export const useEditorMode = (): SWRResponse<EditorMode, Error> => {
|
|
|
+type EditorModeUtils = {
|
|
|
+ getClassNamesByEditorMode: (isEditingSidebar: boolean) => string[],
|
|
|
+}
|
|
|
+
|
|
|
+export const useEditorMode = (): SWRResponseWithUtils<EditorModeUtils, EditorMode> => {
|
|
|
const { data: _isEditable } = useIsEditable();
|
|
|
|
|
|
const editorModeByHash = determineEditorModeByHash();
|
|
|
@@ -140,36 +135,31 @@ export const useEditorMode = (): SWRResponse<EditorMode, Error> => {
|
|
|
const isEditable = !isLoading && _isEditable;
|
|
|
const initialData = isEditable ? editorModeByHash : EditorMode.View;
|
|
|
|
|
|
- const { data: currentPagePath } = useCurrentPagePath();
|
|
|
- const isSidebar = currentPagePath === '/Sidebar';
|
|
|
-
|
|
|
- const swrResponse = useSWRImmutable(
|
|
|
+ const swrResponse = useSWRImmutable<EditorMode>(
|
|
|
isLoading ? null : ['editorMode', isEditable],
|
|
|
null,
|
|
|
{ fallbackData: initialData },
|
|
|
);
|
|
|
|
|
|
- // initial updating
|
|
|
- if (!isEditorModeLoaded && !isLoading && swrResponse.data != null) {
|
|
|
- if (isEditable) {
|
|
|
- updateBodyClassesByEditorMode(swrResponse.data, isSidebar);
|
|
|
+ // construct overriding mutate method
|
|
|
+ const mutateOriginal = swrResponse.mutate;
|
|
|
+ const mutate = useCallback((editorMode: EditorMode, shouldRevalidate?: boolean) => {
|
|
|
+ if (!isEditable) {
|
|
|
+ return Promise.resolve(EditorMode.View); // fixed if not editable
|
|
|
}
|
|
|
- isEditorModeLoaded = true;
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- ...swrResponse,
|
|
|
-
|
|
|
- // overwrite mutate
|
|
|
- mutate: (editorMode: EditorMode, shouldRevalidate?: boolean) => {
|
|
|
- if (!isEditable) {
|
|
|
- return Promise.resolve(EditorMode.View); // fixed if not editable
|
|
|
- }
|
|
|
- updateBodyClassesByEditorMode(editorMode, isSidebar);
|
|
|
- updateHashByEditorMode(editorMode);
|
|
|
- return swrResponse.mutate(editorMode, shouldRevalidate);
|
|
|
- },
|
|
|
- };
|
|
|
+ updateHashByEditorMode(editorMode);
|
|
|
+ return mutateOriginal(editorMode, shouldRevalidate);
|
|
|
+ }, [isEditable, mutateOriginal]);
|
|
|
+
|
|
|
+ // construct getClassNamesByEditorMode method
|
|
|
+ const getClassNames = useCallback((isEditingSidebar: boolean) => {
|
|
|
+ return getClassNamesByEditorMode(swrResponse.data, isEditingSidebar);
|
|
|
+ }, [swrResponse.data]);
|
|
|
+
|
|
|
+ return Object.assign(swrResponse, {
|
|
|
+ mutate,
|
|
|
+ getClassNamesByEditorMode: getClassNames,
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
export const useIsDeviceSmallerThanMd = (): SWRResponse<boolean, Error> => {
|