renderer.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { HtmlElementNode } from 'rehype-toc';
  2. import { Key, SWRResponse } from 'swr';
  3. import useSWRImmutable from 'swr/immutable';
  4. import { RendererConfig } from '~/interfaces/services/renderer';
  5. import {
  6. RendererOptions,
  7. generatePreviewOptions, generateCommentPreviewOptions, generateOthersOptions,
  8. generateViewOptions, generateTocOptions,
  9. } from '~/services/renderer/renderer';
  10. import {
  11. useCurrentPagePath, useCurrentPageTocNode, useRendererConfig,
  12. } from './context';
  13. interface ReactMarkdownOptionsGenerator {
  14. (config: RendererConfig): RendererOptions
  15. }
  16. // The base hook with common processes
  17. const _useOptionsBase = (
  18. rendererId: string, generator: ReactMarkdownOptionsGenerator,
  19. ): SWRResponse<RendererOptions, Error> => {
  20. const { data: rendererConfig } = useRendererConfig();
  21. const isAllDataValid = rendererConfig != null;
  22. const key = isAllDataValid
  23. ? [rendererId, rendererConfig]
  24. : null;
  25. const swrResult = useSWRImmutable<RendererOptions, Error>(key);
  26. if (isAllDataValid && swrResult.data == null) {
  27. swrResult.mutate(generator(rendererConfig));
  28. }
  29. // call useSWRImmutable again to foce to update cache
  30. return useSWRImmutable<RendererOptions, Error>(key);
  31. };
  32. export const useViewOptions = (storeTocNodeHandler: (toc: HtmlElementNode) => void): SWRResponse<RendererOptions, Error> => {
  33. const { data: currentPagePath } = useCurrentPagePath();
  34. const { data: rendererConfig } = useRendererConfig();
  35. const isAllDataValid = currentPagePath != null && rendererConfig != null;
  36. const key = isAllDataValid
  37. ? ['viewOptions', currentPagePath, rendererConfig]
  38. : null;
  39. return useSWRImmutable<RendererOptions, Error>(
  40. key,
  41. (rendererId, currentPagePath, rendererConfig) => generateViewOptions(currentPagePath, rendererConfig, storeTocNodeHandler),
  42. {
  43. fallbackData: isAllDataValid ? generateViewOptions(currentPagePath, rendererConfig, storeTocNodeHandler) : undefined,
  44. },
  45. );
  46. };
  47. export const useTocOptions = (): SWRResponse<RendererOptions, Error> => {
  48. const { data: currentPagePath } = useCurrentPagePath();
  49. const { data: rendererConfig } = useRendererConfig();
  50. const { data: tocNode } = useCurrentPageTocNode();
  51. const isAllDataValid = rendererConfig != null;
  52. const key = isAllDataValid
  53. ? ['tocOptions', currentPagePath, tocNode, rendererConfig]
  54. : null;
  55. return useSWRImmutable<RendererOptions, Error>(
  56. key,
  57. (rendererId, path, tocNode, rendererConfig) => generateTocOptions(rendererConfig, tocNode),
  58. );
  59. };
  60. export const usePreviewOptions = (): SWRResponse<RendererOptions, Error> => {
  61. const { data: currentPagePath } = useCurrentPagePath();
  62. const { data: rendererConfig } = useRendererConfig();
  63. const isAllDataValid = currentPagePath != null && rendererConfig != null;
  64. const key = isAllDataValid
  65. ? ['previewOptions', currentPagePath, rendererConfig]
  66. : null;
  67. return useSWRImmutable<RendererOptions, Error>(
  68. key,
  69. (rendererId, currentPagePath, rendererConfig) => generatePreviewOptions(currentPagePath, rendererConfig),
  70. {
  71. fallbackData: isAllDataValid ? generatePreviewOptions(currentPagePath, rendererConfig) : undefined,
  72. },
  73. );
  74. };
  75. export const useCommentPreviewOptions = (): SWRResponse<RendererOptions, Error> => {
  76. const key = 'commentPreviewOptions';
  77. return _useOptionsBase(key, generateCommentPreviewOptions);
  78. };
  79. export const useSearchResultOptions = (): SWRResponse<RendererOptions, Error> => {
  80. const key = 'searchResultOptions';
  81. return _useOptionsBase(key, generateOthersOptions);
  82. };
  83. export const useTimelineOptions = (): SWRResponse<RendererOptions, Error> => {
  84. const key = 'timelineOptions';
  85. return _useOptionsBase(key, generateOthersOptions);
  86. };
  87. export const useDraftOptions = (): SWRResponse<RendererOptions, Error> => {
  88. const key = 'draftOptions';
  89. return _useOptionsBase(key, generateOthersOptions);
  90. };
  91. export const useCustomSidebarOptions = (): SWRResponse<RendererOptions, Error> => {
  92. const key: Key = 'customSidebarOptions';
  93. return _useOptionsBase(key, generateOthersOptions);
  94. };