permissions-context.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. review: {
  23. read: true,
  24. write: true,
  25. admin: false,
  26. comment: true,
  27. },
  28. readAndWrite: {
  29. read: true,
  30. write: true,
  31. admin: false,
  32. comment: true,
  33. },
  34. owner: {
  35. read: true,
  36. write: true,
  37. admin: true,
  38. comment: true,
  39. },
  40. }
  41. const anonymousPermissionsMap: typeof permissionsMap = {
  42. readOnly: { ...permissionsMap.readOnly, comment: false },
  43. readAndWrite: { ...permissionsMap.readAndWrite, comment: false },
  44. review: { ...permissionsMap.review, comment: false },
  45. owner: { ...permissionsMap.owner, comment: false },
  46. }
  47. const linkSharingWarningPermissionsMap: typeof permissionsMap = {
  48. readOnly: { ...permissionsMap.readOnly, comment: false },
  49. readAndWrite: permissionsMap.readAndWrite,
  50. review: permissionsMap.review,
  51. owner: permissionsMap.owner,
  52. }
  53. export const PermissionsProvider: React.FC = ({ children }) => {
  54. const [permissions, setPermissions] =
  55. useScopeValue<Readonly<Permissions>>('permissions')
  56. const { connectionState } = useConnectionContext()
  57. const { permissionsLevel } = useEditorContext() as {
  58. permissionsLevel: PermissionsLevel
  59. }
  60. const hasViewerPermissions = useViewerPermissions()
  61. const anonymous = getMeta('ol-anonymous')
  62. useEffect(() => {
  63. let activePermissionsMap
  64. if (hasViewerPermissions) {
  65. activePermissionsMap = linkSharingWarningPermissionsMap
  66. } else {
  67. activePermissionsMap = anonymous
  68. ? anonymousPermissionsMap
  69. : permissionsMap
  70. }
  71. setPermissions(activePermissionsMap[permissionsLevel])
  72. }, [anonymous, permissionsLevel, setPermissions, hasViewerPermissions])
  73. useEffect(() => {
  74. if (connectionState.forceDisconnected) {
  75. setPermissions(prevState => ({ ...prevState, write: false }))
  76. }
  77. }, [connectionState.forceDisconnected, setPermissions])
  78. return (
  79. <PermissionsContext.Provider value={permissions}>
  80. {children}
  81. </PermissionsContext.Provider>
  82. )
  83. }
  84. export function usePermissionsContext() {
  85. const context = useContext(PermissionsContext)
  86. if (!context) {
  87. throw new Error(
  88. 'usePermissionsContext is only available inside PermissionsProvider'
  89. )
  90. }
  91. return context
  92. }