import { HtmlElementNode } from 'rehype-toc';
import useSWR, { Key, SWRResponse } from 'swr';
import useSWRImmutable from 'swr/immutable';
import { RendererConfig } from '~/interfaces/services/renderer';
import {
RendererOptions,
generateSimpleViewOptions, generatePreviewOptions, generateOthersOptions,
generateViewOptions, generateTocOptions,
} from '~/services/renderer/renderer';
import { getGrowiFacade } from '~/utils/growi-facade';
import {
useCurrentPagePath, useCurrentPageTocNode, useRendererConfig,
} from './context';
interface ReactMarkdownOptionsGenerator {
(config: RendererConfig): RendererOptions
}
// The base hook with common processes
const _useOptionsBase = (
rendererId: string, generator: ReactMarkdownOptionsGenerator,
): SWRResponse => {
const { data: rendererConfig } = useRendererConfig();
const isAllDataValid = rendererConfig != null;
const key = isAllDataValid
? [rendererId, rendererConfig]
: null;
const swrResult = useSWRImmutable(key);
if (isAllDataValid && swrResult.data == null) {
swrResult.mutate(generator(rendererConfig));
}
// call useSWRImmutable again to foce to update cache
return useSWRImmutable(key);
};
export const useViewOptions = (storeTocNodeHandler: (toc: HtmlElementNode) => void): SWRResponse => {
const { data: currentPagePath } = useCurrentPagePath();
const { data: rendererConfig } = useRendererConfig();
const isAllDataValid = currentPagePath != null && rendererConfig != null;
const key = isAllDataValid
? ['viewOptions', currentPagePath, rendererConfig]
: null;
return useSWR(
key,
(rendererId, currentPagePath, rendererConfig) => {
// determine options generator
const optionsGenerator = getGrowiFacade().markdownRenderer?.optionsGenerators?.customGenerateViewOptions ?? generateViewOptions;
return optionsGenerator(currentPagePath, rendererConfig, storeTocNodeHandler);
},
{
fallbackData: isAllDataValid ? generateViewOptions(currentPagePath, rendererConfig, storeTocNodeHandler) : undefined,
},
);
};
export const useTocOptions = (): SWRResponse => {
const { data: currentPagePath } = useCurrentPagePath();
const { data: rendererConfig } = useRendererConfig();
const { data: tocNode } = useCurrentPageTocNode();
const isAllDataValid = rendererConfig != null;
const key = isAllDataValid
? ['tocOptions', currentPagePath, tocNode, rendererConfig]
: null;
return useSWRImmutable(
key,
(rendererId, path, tocNode, rendererConfig) => generateTocOptions(rendererConfig, tocNode),
);
};
export const usePreviewOptions = (): SWRResponse => {
const { data: currentPagePath } = useCurrentPagePath();
const { data: rendererConfig } = useRendererConfig();
const isAllDataValid = currentPagePath != null && rendererConfig != null;
const key = isAllDataValid
? ['previewOptions', rendererConfig, currentPagePath]
: null;
return useSWR(
key,
(rendererId, rendererConfig, pagePath, highlightKeywords) => {
// determine options generator
const optionsGenerator = getGrowiFacade().markdownRenderer?.optionsGenerators?.customGeneratePreviewOptions ?? generatePreviewOptions;
return optionsGenerator(rendererConfig, pagePath, highlightKeywords);
},
{
fallbackData: isAllDataValid ? generatePreviewOptions(rendererConfig, currentPagePath) : undefined,
},
);
};
export const useCommentForCurrentPageOptions = (): SWRResponse => {
const { data: currentPagePath } = useCurrentPagePath();
const { data: rendererConfig } = useRendererConfig();
const isAllDataValid = currentPagePath != null && rendererConfig != null;
const key = isAllDataValid
? ['commentForCurrentPageOptions', rendererConfig, currentPagePath]
: null;
return useSWRImmutable(
key,
(rendererId, rendererConfig, currentPagePath) => generateSimpleViewOptions(rendererConfig, currentPagePath),
{
fallbackData: isAllDataValid ? generateSimpleViewOptions(rendererConfig, currentPagePath) : undefined,
},
);
};
export const useCommentPreviewOptions = useCommentForCurrentPageOptions;
export const useSelectedPagePreviewOptions = (pagePath: string, highlightKeywords?: string | string[]): SWRResponse => {
const { data: rendererConfig } = useRendererConfig();
const isAllDataValid = rendererConfig != null;
const key = isAllDataValid
? ['selectedPagePreviewOptions', rendererConfig, pagePath, highlightKeywords]
: null;
return useSWRImmutable(
key,
(rendererId, rendererConfig, pagePath, highlightKeywords) => generateSimpleViewOptions(rendererConfig, pagePath, highlightKeywords),
{
fallbackData: isAllDataValid ? generateSimpleViewOptions(rendererConfig, pagePath, highlightKeywords) : undefined,
},
);
};
export const useSearchResultOptions = useSelectedPagePreviewOptions;
export const useTimelineOptions = (): SWRResponse => {
const key = 'timelineOptions';
return _useOptionsBase(key, generateOthersOptions);
};
export const useDraftOptions = (): SWRResponse => {
const key = 'draftOptions';
return _useOptionsBase(key, generateOthersOptions);
};
export const useCustomSidebarOptions = (): SWRResponse => {
const key: Key = 'customSidebarOptions';
return _useOptionsBase(key, generateOthersOptions);
};