Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

web-app-context.tsx 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. 'use client'
  2. import type { ChatConfig } from '@/app/components/base/chat/types'
  3. import Loading from '@/app/components/base/loading'
  4. import { checkOrSetAccessToken } from '@/app/components/share/utils'
  5. import { AccessMode } from '@/models/access-control'
  6. import type { AppData, AppMeta } from '@/models/share'
  7. import { useGetWebAppAccessModeByCode } from '@/service/use-share'
  8. import { usePathname, useSearchParams } from 'next/navigation'
  9. import type { FC, PropsWithChildren } from 'react'
  10. import { useEffect } from 'react'
  11. import { useState } from 'react'
  12. import { create } from 'zustand'
  13. type WebAppStore = {
  14. shareCode: string | null
  15. updateShareCode: (shareCode: string | null) => void
  16. appInfo: AppData | null
  17. updateAppInfo: (appInfo: AppData | null) => void
  18. appParams: ChatConfig | null
  19. updateAppParams: (appParams: ChatConfig | null) => void
  20. webAppAccessMode: AccessMode
  21. updateWebAppAccessMode: (accessMode: AccessMode) => void
  22. appMeta: AppMeta | null
  23. updateWebAppMeta: (appMeta: AppMeta | null) => void
  24. userCanAccessApp: boolean
  25. updateUserCanAccessApp: (canAccess: boolean) => void
  26. }
  27. export const useWebAppStore = create<WebAppStore>(set => ({
  28. shareCode: null,
  29. updateShareCode: (shareCode: string | null) => set(() => ({ shareCode })),
  30. appInfo: null,
  31. updateAppInfo: (appInfo: AppData | null) => set(() => ({ appInfo })),
  32. appParams: null,
  33. updateAppParams: (appParams: ChatConfig | null) => set(() => ({ appParams })),
  34. webAppAccessMode: AccessMode.SPECIFIC_GROUPS_MEMBERS,
  35. updateWebAppAccessMode: (accessMode: AccessMode) => set(() => ({ webAppAccessMode: accessMode })),
  36. appMeta: null,
  37. updateWebAppMeta: (appMeta: AppMeta | null) => set(() => ({ appMeta })),
  38. userCanAccessApp: false,
  39. updateUserCanAccessApp: (canAccess: boolean) => set(() => ({ userCanAccessApp: canAccess })),
  40. }))
  41. const getShareCodeFromRedirectUrl = (redirectUrl: string | null): string | null => {
  42. if (!redirectUrl || redirectUrl.length === 0)
  43. return null
  44. const url = new URL(`${window.location.origin}${decodeURIComponent(redirectUrl)}`)
  45. return url.pathname.split('/').pop() || null
  46. }
  47. const getShareCodeFromPathname = (pathname: string): string | null => {
  48. const code = pathname.split('/').pop() || null
  49. if (code === 'webapp-signin')
  50. return null
  51. return code
  52. }
  53. const WebAppStoreProvider: FC<PropsWithChildren> = ({ children }) => {
  54. const updateWebAppAccessMode = useWebAppStore(state => state.updateWebAppAccessMode)
  55. const updateShareCode = useWebAppStore(state => state.updateShareCode)
  56. const pathname = usePathname()
  57. const searchParams = useSearchParams()
  58. const redirectUrlParam = searchParams.get('redirect_url')
  59. const session = searchParams.get('session')
  60. const sysUserId = searchParams.get('sys.user_id')
  61. const [shareCode, setShareCode] = useState<string | null>(null)
  62. useEffect(() => {
  63. const shareCodeFromRedirect = getShareCodeFromRedirectUrl(redirectUrlParam)
  64. const shareCodeFromPathname = getShareCodeFromPathname(pathname)
  65. const newShareCode = shareCodeFromRedirect || shareCodeFromPathname
  66. setShareCode(newShareCode)
  67. updateShareCode(newShareCode)
  68. }, [pathname, redirectUrlParam, updateShareCode])
  69. const { isFetching, data: accessModeResult } = useGetWebAppAccessModeByCode(shareCode)
  70. const [isFetchingAccessToken, setIsFetchingAccessToken] = useState(true)
  71. useEffect(() => {
  72. if (accessModeResult?.accessMode) {
  73. updateWebAppAccessMode(accessModeResult.accessMode)
  74. if (accessModeResult?.accessMode === AccessMode.PUBLIC && session && sysUserId) {
  75. setIsFetchingAccessToken(true)
  76. checkOrSetAccessToken(shareCode).finally(() => {
  77. setIsFetchingAccessToken(false)
  78. })
  79. }
  80. else {
  81. setIsFetchingAccessToken(false)
  82. }
  83. }
  84. }, [accessModeResult, updateWebAppAccessMode, setIsFetchingAccessToken, shareCode, session, sysUserId])
  85. if (isFetching || isFetchingAccessToken) {
  86. return <div className='flex h-full w-full items-center justify-center'>
  87. <Loading />
  88. </div>
  89. }
  90. return (
  91. <>
  92. {children}
  93. </>
  94. )
  95. }
  96. export default WebAppStoreProvider