permissions-context.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import { createContext, useContext, useEffect } from 'react'
  2. import { useConnectionContext } from '@/features/ide-react/context/connection-context'
  3. import { useEditorContext } from '@/shared/context/editor-context'
  4. import getMeta from '@/utils/meta'
  5. import {
  6. Permissions,
  7. PermissionsLevel,
  8. } from '@/features/ide-react/types/permissions'
  9. import useScopeValue from '@/shared/hooks/use-scope-value'
  10. import { DeepReadonly } from '../../../../../types/utils'
  11. import useViewerPermissions from '@/shared/hooks/use-viewer-permissions'
  12. export const PermissionsContext = createContext<Permissions | undefined>(
  13. undefined
  14. )
  15. const permissionsMap: DeepReadonly<Record<PermissionsLevel, Permissions>> = {
  16. readOnly: {
  17. read: true,
  18. write: false,
  19. admin: false,
  20. comment: true,
  21. },
  22. readAndWrite: {
  23. read: true,
  24. write: true,
  25. admin: false,
  26. comment: true,
  27. },
  28. owner: {
  29. read: true,
  30. write: true,
  31. admin: true,
  32. comment: true,
  33. },
  34. }
  35. const anonymousPermissionsMap: typeof permissionsMap = {
  36. readOnly: { ...permissionsMap.readOnly, comment: false },
  37. readAndWrite: { ...permissionsMap.readAndWrite, comment: false },
  38. owner: { ...permissionsMap.owner, comment: false },
  39. }
  40. const linkSharingWarningPermissionsMap: typeof permissionsMap = {
  41. readOnly: { ...permissionsMap.readOnly, comment: false },
  42. readAndWrite: permissionsMap.readAndWrite,
  43. owner: permissionsMap.owner,
  44. }
  45. export const PermissionsProvider: React.FC = ({ children }) => {
  46. const [permissions, setPermissions] =
  47. useScopeValue<Readonly<Permissions>>('permissions')
  48. const { connectionState } = useConnectionContext()
  49. const { permissionsLevel } = useEditorContext() as {
  50. permissionsLevel: PermissionsLevel
  51. }
  52. const hasViewerPermissions = useViewerPermissions()
  53. const anonymous = getMeta('ol-anonymous')
  54. useEffect(() => {
  55. let activePermissionsMap
  56. if (hasViewerPermissions) {
  57. activePermissionsMap = linkSharingWarningPermissionsMap
  58. } else {
  59. activePermissionsMap = anonymous
  60. ? anonymousPermissionsMap
  61. : permissionsMap
  62. }
  63. setPermissions(activePermissionsMap[permissionsLevel])
  64. }, [anonymous, permissionsLevel, setPermissions, hasViewerPermissions])
  65. useEffect(() => {
  66. if (connectionState.forceDisconnected) {
  67. setPermissions(prevState => ({ ...prevState, write: false }))
  68. }
  69. }, [connectionState.forceDisconnected, setPermissions])
  70. return (
  71. <PermissionsContext.Provider value={permissions}>
  72. {children}
  73. </PermissionsContext.Provider>
  74. )
  75. }
  76. export function usePermissionsContext() {
  77. const context = useContext(PermissionsContext)
  78. if (!context) {
  79. throw new Error(
  80. 'usePermissionsContext is only available inside PermissionsProvider'
  81. )
  82. }
  83. return context
  84. }