file-tree-path.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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) => pathInFolder(fileTreeData, id),
  29. [fileTreeData]
  30. )
  31. const findEntityByPathInFileTree = useCallback(
  32. (path: string) => findEntityByPath(fileTreeData, path),
  33. [fileTreeData]
  34. )
  35. const previewByPathInFileTree = useCallback(
  36. (path: string) => previewByPath(fileTreeData, projectId, path),
  37. [fileTreeData, projectId]
  38. )
  39. const dirnameInFileTree = useCallback(
  40. (id: string) => dirname(fileTreeData, id),
  41. [fileTreeData]
  42. )
  43. const value = useMemo<FileTreePathContextValue>(
  44. () => ({
  45. pathInFolder: pathInFileTree,
  46. findEntityByPath: findEntityByPathInFileTree,
  47. previewByPath: previewByPathInFileTree,
  48. dirname: dirnameInFileTree,
  49. }),
  50. [
  51. pathInFileTree,
  52. findEntityByPathInFileTree,
  53. previewByPathInFileTree,
  54. dirnameInFileTree,
  55. ]
  56. )
  57. return (
  58. <FileTreePathContext.Provider value={value}>
  59. {children}
  60. </FileTreePathContext.Provider>
  61. )
  62. }
  63. export function useFileTreePathContext(): FileTreePathContextValue {
  64. const context = useContext(FileTreePathContext)
  65. if (!context) {
  66. throw new Error(
  67. 'useFileTreePathContext is only available inside FileTreePathProvider'
  68. )
  69. }
  70. return context
  71. }