file-tree-path.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. import { useSnapshotContext } from '@/features/ide-react/context/snapshot-context'
  14. type FileTreePathContextValue = {
  15. pathInFolder: (id: string) => string | null
  16. findEntityByPath: (path: string) => FindResult | null
  17. previewByPath: (path: string) => PreviewPath | null
  18. dirname: (id: string) => string | null
  19. }
  20. export const FileTreePathContext = createContext<
  21. FileTreePathContextValue | undefined
  22. >(undefined)
  23. export const FileTreePathProvider: FC = ({ children }) => {
  24. const { fileTreeData }: { fileTreeData: Folder } = useFileTreeData()
  25. const { fileTreeFromHistory } = useSnapshotContext()
  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) =>
  37. previewByPath(fileTreeData, projectId, path, fileTreeFromHistory),
  38. [fileTreeData, projectId, fileTreeFromHistory]
  39. )
  40. const dirnameInFileTree = useCallback(
  41. (id: string) => dirname(fileTreeData, id),
  42. [fileTreeData]
  43. )
  44. const value = useMemo<FileTreePathContextValue>(
  45. () => ({
  46. pathInFolder: pathInFileTree,
  47. findEntityByPath: findEntityByPathInFileTree,
  48. previewByPath: previewByPathInFileTree,
  49. dirname: dirnameInFileTree,
  50. }),
  51. [
  52. pathInFileTree,
  53. findEntityByPathInFileTree,
  54. previewByPathInFileTree,
  55. dirnameInFileTree,
  56. ]
  57. )
  58. return (
  59. <FileTreePathContext.Provider value={value}>
  60. {children}
  61. </FileTreePathContext.Provider>
  62. )
  63. }
  64. export function useFileTreePathContext(): FileTreePathContextValue {
  65. const context = useContext(FileTreePathContext)
  66. if (!context) {
  67. throw new Error(
  68. 'useFileTreePathContext is only available inside FileTreePathProvider'
  69. )
  70. }
  71. return context
  72. }