file-tree-path.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import { createContext, FC, useCallback, useContext, useMemo } from 'react'
  2. import { Folder } from '../../../../../types/folder'
  3. import { useFileTreeData } from '@/shared/context/file-tree-data-context'
  4. import getMeta from '@/utils/meta'
  5. import {
  6. findEntityByPath,
  7. previewByPath,
  8. dirname,
  9. FindResult,
  10. pathInFolder,
  11. } from '@/features/file-tree/util/path'
  12. import { PreviewPath } from '../../../../../types/preview-path'
  13. type FileTreePathContextValue = {
  14. pathInFolder: (id: string) => string | null
  15. findEntityByPath: (path: string) => FindResult | null
  16. previewByPath: (path: string) => PreviewPath | null
  17. dirname: (id: string) => string | null
  18. }
  19. export const FileTreePathContext = createContext<
  20. FileTreePathContextValue | undefined
  21. >(undefined)
  22. export const FileTreePathProvider: FC<React.PropsWithChildren> = ({
  23. children,
  24. }) => {
  25. const { fileTreeData }: { fileTreeData: Folder } = useFileTreeData()
  26. const projectId = getMeta('ol-project_id')
  27. const pathInFileTree = useCallback(
  28. (id: string) => {
  29. if (!fileTreeData) return null
  30. return pathInFolder(fileTreeData, id)
  31. },
  32. [fileTreeData]
  33. )
  34. const findEntityByPathInFileTree = useCallback(
  35. (path: string) => {
  36. if (!fileTreeData) return null
  37. return findEntityByPath(fileTreeData, path)
  38. },
  39. [fileTreeData]
  40. )
  41. const previewByPathInFileTree = useCallback(
  42. (path: string) => {
  43. if (!fileTreeData) return null
  44. return previewByPath(fileTreeData, projectId, path)
  45. },
  46. [fileTreeData, projectId]
  47. )
  48. const dirnameInFileTree = useCallback(
  49. (id: string) => {
  50. if (!fileTreeData) return null
  51. return dirname(fileTreeData, id)
  52. },
  53. [fileTreeData]
  54. )
  55. const value = useMemo<FileTreePathContextValue>(
  56. () => ({
  57. pathInFolder: pathInFileTree,
  58. findEntityByPath: findEntityByPathInFileTree,
  59. previewByPath: previewByPathInFileTree,
  60. dirname: dirnameInFileTree,
  61. }),
  62. [
  63. pathInFileTree,
  64. findEntityByPathInFileTree,
  65. previewByPathInFileTree,
  66. dirnameInFileTree,
  67. ]
  68. )
  69. return (
  70. <FileTreePathContext.Provider value={value}>
  71. {children}
  72. </FileTreePathContext.Provider>
  73. )
  74. }
  75. export function useFileTreePathContext(): FileTreePathContextValue {
  76. const context = useContext(FileTreePathContext)
  77. if (!context) {
  78. throw new Error(
  79. 'useFileTreePathContext is only available inside FileTreePathProvider'
  80. )
  81. }
  82. return context
  83. }