renderer.tsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import { useCallback } from 'react';
  2. import type { HtmlElementNode } from 'rehype-toc';
  3. import useSWR, { type SWRConfiguration, type SWRResponse } from 'swr';
  4. import { getGrowiFacade } from '~/features/growi-plugin/client/utils/growi-facade-utils';
  5. import type { RendererOptions } from '~/interfaces/renderer-options';
  6. import {
  7. useRendererConfig,
  8. } from './context';
  9. import { useCurrentPagePath } from './page';
  10. import { useCurrentPageTocNode } from './ui';
  11. export const useViewOptions = (): SWRResponse<RendererOptions, Error> => {
  12. const { data: currentPagePath } = useCurrentPagePath();
  13. const { data: rendererConfig } = useRendererConfig();
  14. const { mutate: mutateCurrentPageTocNode } = useCurrentPageTocNode();
  15. const storeTocNodeHandler = useCallback((toc: HtmlElementNode) => {
  16. mutateCurrentPageTocNode(toc, { revalidate: false });
  17. }, [mutateCurrentPageTocNode]);
  18. const isAllDataValid = currentPagePath != null && rendererConfig != null;
  19. const customGenerater = getGrowiFacade().markdownRenderer?.optionsGenerators?.customGenerateViewOptions;
  20. return useSWR(
  21. isAllDataValid
  22. ? ['viewOptions', currentPagePath, rendererConfig, customGenerater]
  23. : null,
  24. async([, currentPagePath, rendererConfig]) => {
  25. if (customGenerater != null) {
  26. return customGenerater(currentPagePath, rendererConfig, storeTocNodeHandler);
  27. }
  28. const { generateViewOptions } = await import('~/client/services/renderer/renderer');
  29. return generateViewOptions(currentPagePath, rendererConfig, storeTocNodeHandler);
  30. },
  31. {
  32. keepPreviousData: true,
  33. revalidateOnFocus: false,
  34. revalidateOnReconnect: false,
  35. },
  36. );
  37. };
  38. export const useTocOptions = (): SWRResponse<RendererOptions, Error> => {
  39. const { data: currentPagePath } = useCurrentPagePath();
  40. const { data: rendererConfig } = useRendererConfig();
  41. const { data: tocNode } = useCurrentPageTocNode();
  42. const isAllDataValid = currentPagePath != null && rendererConfig != null && tocNode != null;
  43. return useSWR(
  44. isAllDataValid
  45. ? ['tocOptions', currentPagePath, tocNode, rendererConfig]
  46. : null,
  47. async([, , tocNode, rendererConfig]) => {
  48. const { generateTocOptions } = await import('~/client/services/renderer/renderer');
  49. return generateTocOptions(rendererConfig, tocNode);
  50. },
  51. {
  52. keepPreviousData: true,
  53. revalidateOnFocus: false,
  54. revalidateOnReconnect: false,
  55. },
  56. );
  57. };
  58. export const usePreviewOptions = (): SWRResponse<RendererOptions, Error> => {
  59. const { data: currentPagePath } = useCurrentPagePath();
  60. const { data: rendererConfig } = useRendererConfig();
  61. const isAllDataValid = currentPagePath != null && rendererConfig != null;
  62. const customGenerater = getGrowiFacade().markdownRenderer?.optionsGenerators?.customGeneratePreviewOptions;
  63. return useSWR(
  64. isAllDataValid
  65. ? ['previewOptions', rendererConfig, currentPagePath, customGenerater]
  66. : null,
  67. async([, rendererConfig, pagePath]) => {
  68. if (customGenerater != null) {
  69. return customGenerater(rendererConfig, pagePath);
  70. }
  71. const { generatePreviewOptions } = await import('~/client/services/renderer/renderer');
  72. return generatePreviewOptions(rendererConfig, pagePath);
  73. },
  74. {
  75. keepPreviousData: true,
  76. revalidateOnFocus: false,
  77. revalidateOnReconnect: false,
  78. },
  79. );
  80. };
  81. export const useCommentForCurrentPageOptions = (): SWRResponse<RendererOptions, Error> => {
  82. const { data: currentPagePath } = useCurrentPagePath();
  83. const { data: rendererConfig } = useRendererConfig();
  84. const isAllDataValid = currentPagePath != null && rendererConfig != null;
  85. return useSWR(
  86. isAllDataValid
  87. ? ['commentPreviewOptions', rendererConfig, currentPagePath]
  88. : null,
  89. async([, rendererConfig, currentPagePath]) => {
  90. const { generateSimpleViewOptions } = await import('~/client/services/renderer/renderer');
  91. return generateSimpleViewOptions(
  92. rendererConfig,
  93. currentPagePath,
  94. undefined,
  95. rendererConfig.isEnabledLinebreaksInComments,
  96. );
  97. },
  98. {
  99. keepPreviousData: true,
  100. revalidateOnFocus: false,
  101. revalidateOnReconnect: false,
  102. },
  103. );
  104. };
  105. export const useCommentPreviewOptions = useCommentForCurrentPageOptions;
  106. export const useSelectedPagePreviewOptions = (pagePath: string, highlightKeywords?: string | string[]): SWRResponse<RendererOptions, Error> => {
  107. const { data: rendererConfig } = useRendererConfig();
  108. const isAllDataValid = rendererConfig != null;
  109. return useSWR(
  110. isAllDataValid
  111. ? ['selectedPagePreviewOptions', rendererConfig, pagePath, highlightKeywords]
  112. : null,
  113. async([, rendererConfig, pagePath, highlightKeywords]) => {
  114. const { generateSimpleViewOptions } = await import('~/client/services/renderer/renderer');
  115. return generateSimpleViewOptions(rendererConfig, pagePath, highlightKeywords);
  116. },
  117. {
  118. revalidateOnFocus: false,
  119. revalidateOnReconnect: false,
  120. },
  121. );
  122. };
  123. export const useSearchResultOptions = useSelectedPagePreviewOptions;
  124. export const useTimelineOptions = useSelectedPagePreviewOptions;
  125. export const useCustomSidebarOptions = (config?: SWRConfiguration): SWRResponse<RendererOptions, Error> => {
  126. const { data: rendererConfig } = useRendererConfig();
  127. const isAllDataValid = rendererConfig != null;
  128. return useSWR(
  129. isAllDataValid
  130. ? ['customSidebarOptions', rendererConfig]
  131. : null,
  132. async([, rendererConfig]) => {
  133. const { generateSimpleViewOptions } = await import('~/client/services/renderer/renderer');
  134. return generateSimpleViewOptions(rendererConfig, '/');
  135. },
  136. {
  137. ...config,
  138. keepPreviousData: true,
  139. revalidateOnFocus: false,
  140. revalidateOnReconnect: false,
  141. },
  142. );
  143. };
  144. export const usePresentationViewOptions = (): SWRResponse<RendererOptions, Error> => {
  145. const { data: currentPagePath } = useCurrentPagePath();
  146. const { data: rendererConfig } = useRendererConfig();
  147. const isAllDataValid = currentPagePath != null && rendererConfig != null;
  148. return useSWR(
  149. isAllDataValid
  150. ? ['presentationViewOptions', currentPagePath, rendererConfig]
  151. : null,
  152. async([, currentPagePath, rendererConfig]) => {
  153. const { generatePresentationViewOptions } = await import('~/client/services/renderer/renderer');
  154. return generatePresentationViewOptions(rendererConfig, currentPagePath);
  155. },
  156. {
  157. revalidateOnFocus: false,
  158. revalidateOnReconnect: false,
  159. },
  160. );
  161. };