mirror of
https://github.com/hanzo-io/team.git
synced 2026-10-30 18:56:23 +00:00
164 lines
6.3 KiB
TypeScript
164 lines
6.3 KiB
TypeScript
import FullPageLoader from '@components/layout/FullPageLoader'
|
|
import { ChannelListContext, useChannelListProvider } from '@raven/lib/providers/ChannelListProvider'
|
|
import { UserListContext, useUserListProvider } from '@raven/lib/providers/UserListProvider'
|
|
import { PropsWithChildren, Suspense, useEffect } from 'react'
|
|
import { TouchableOpacity, View } from 'react-native'
|
|
import { ActiveUserProvider } from './UserInactivityProvider'
|
|
import ErrorBanner from '@components/common/ErrorBanner'
|
|
import useFetchWorkspaces from '@raven/lib/hooks/useFetchWorkspaces'
|
|
import { useAtom } from 'jotai'
|
|
import { selectedWorkspaceFamily } from '@hooks/useGetCurrentWorkspace'
|
|
import LogOutButton from '@components/features/profile/profile-settings/LogOutButton'
|
|
import useSiteContext from '@hooks/useSiteContext'
|
|
import { useFetchUnreadMessageCount } from '@hooks/useUnreadMessageCount'
|
|
import { useFrappeEventListener, useSWRConfig } from 'frappe-react-sdk'
|
|
import { useUnreadThreadsCountEventListener } from '@hooks/useUnreadThreadsCount'
|
|
import useCurrentRavenUser from '@raven/lib/hooks/useCurrentRavenUser'
|
|
import { useActiveSocketConnection } from '@hooks/useActiveSocketConnection'
|
|
import { useFetchActiveUsersRealtime } from '@hooks/useFetchActiveUsers'
|
|
import useFirebasePushTokenListener from '@hooks/useFirebasePushTokenListener'
|
|
import { Text } from '@components/nativewindui/Text'
|
|
import RefreshIcon from '@assets/icons/RefreshIcon.svg'
|
|
import { useColorScheme } from '@hooks/useColorScheme'
|
|
|
|
const Providers = (props: PropsWithChildren) => {
|
|
|
|
return (
|
|
<UserListProvider>
|
|
{props.children}
|
|
</UserListProvider>
|
|
)
|
|
}
|
|
|
|
const UserListProvider = ({ children }: PropsWithChildren) => {
|
|
const { users, enabledUsers, isLoading, error, hasData, mutate } = useUserListProvider()
|
|
|
|
useActiveSocketConnection()
|
|
|
|
const { colors } = useColorScheme()
|
|
|
|
if (isLoading) {
|
|
return <FullPageLoader />
|
|
}
|
|
|
|
if (!hasData && error) {
|
|
return <View className='bg-card px-2 gap-2 h-screen' style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
<ErrorBanner error={error} heading='There was an error while loading the user list.' />
|
|
<View className='flex w-full gap-2 pt-8'>
|
|
<TouchableOpacity onPress={() => mutate()}
|
|
activeOpacity={0.8}
|
|
hitSlop={10}
|
|
className="flex flex-row items-center py-3 px-4 rounded-xl justify-between bg-background">
|
|
<Text className="font-medium text-foreground">Reload App</Text>
|
|
<RefreshIcon height={20} width={20} fill={colors.icon} />
|
|
</TouchableOpacity>
|
|
<LogOutButton />
|
|
</View>
|
|
</View>
|
|
}
|
|
|
|
return (
|
|
<ActiveUserProvider>
|
|
<UserListContext.Provider value={{ users, enabledUsers }}>
|
|
<ChannelListProvider>
|
|
{children}
|
|
</ChannelListProvider>
|
|
</UserListContext.Provider>
|
|
</ActiveUserProvider>
|
|
)
|
|
}
|
|
|
|
const ChannelListProvider = ({ children }: PropsWithChildren) => {
|
|
|
|
const channelListContextData = useChannelListProvider()
|
|
|
|
const { colors } = useColorScheme()
|
|
|
|
if (channelListContextData.isLoading) {
|
|
return <FullPageLoader />
|
|
}
|
|
|
|
if (!channelListContextData.hasData && channelListContextData.error) {
|
|
return <View className='bg-card px-2 gap-2 h-screen' style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
<ErrorBanner error={channelListContextData.error} heading='There was an error while loading the channel list.' />
|
|
<View className='flex w-full gap-2 pt-8'>
|
|
<TouchableOpacity onPress={() => channelListContextData.mutate()}
|
|
activeOpacity={0.8}
|
|
hitSlop={10}
|
|
className="flex flex-row items-center py-3 px-4 rounded-xl justify-between bg-background">
|
|
<Text className="font-medium text-foreground">Reload App</Text>
|
|
<RefreshIcon height={20} width={20} fill={colors.icon} />
|
|
</TouchableOpacity>
|
|
<LogOutButton />
|
|
</View>
|
|
</View>
|
|
}
|
|
|
|
return <ChannelListContext.Provider value={channelListContextData}>
|
|
<Suspense>
|
|
<WorkspaceProvider>
|
|
{children}
|
|
</WorkspaceProvider>
|
|
</Suspense>
|
|
</ChannelListContext.Provider>
|
|
}
|
|
|
|
const WorkspaceProvider = ({ children }: PropsWithChildren) => {
|
|
|
|
const siteInfo = useSiteContext()
|
|
|
|
const [selectedWorkspace, setSelectedWorkspace] = useAtom(selectedWorkspaceFamily(siteInfo?.sitename || ''))
|
|
const { data } = useFetchWorkspaces()
|
|
|
|
useFetchUnreadMessageCount()
|
|
|
|
useFetchActiveUsersRealtime()
|
|
|
|
useFirebasePushTokenListener()
|
|
|
|
// Listen to channel members updated events and invalidate the channel members cache
|
|
const { mutate } = useSWRConfig()
|
|
|
|
useFrappeEventListener('channel_members_updated', (payload) => {
|
|
mutate(["channel_members", payload.channel_id])
|
|
})
|
|
|
|
const onThreadReplyEvent = useUnreadThreadsCountEventListener()
|
|
|
|
const { myProfile } = useCurrentRavenUser()
|
|
|
|
// Listen to realtime event for new message count
|
|
useFrappeEventListener('thread_reply', (event) => {
|
|
|
|
if (event.channel_id) {
|
|
mutate(["thread_reply_count", event.channel_id], {
|
|
message: event.number_of_replies
|
|
}, {
|
|
revalidate: false
|
|
})
|
|
}
|
|
|
|
// Unread count only needs to be fetched for certain conditions
|
|
|
|
// Ignore the event if the message is sent by the current user
|
|
if (event.sent_by === myProfile?.name) return
|
|
|
|
// Ignore the event if the message is in the current open thread
|
|
// if (threadID === event.channel_id) return
|
|
|
|
onThreadReplyEvent(event.channel_id)
|
|
})
|
|
|
|
useEffect(() => {
|
|
if (data && data.message.length > 0) {
|
|
if (!selectedWorkspace || !data.message.find((w) => w.name === selectedWorkspace)) {
|
|
// If there's no selected workspace, or if the selected workspace is not in the list of workspaces, set the first workspace as the selected workspace
|
|
setSelectedWorkspace(data.message[0].name)
|
|
}
|
|
}
|
|
}, [data])
|
|
|
|
return children
|
|
}
|
|
|
|
export default Providers |