jan/web-app/src/providers/DataProvider.tsx

105 lines
3.3 KiB
TypeScript

import { useMessages } from '@/hooks/useMessages'
import { useModelProvider } from '@/hooks/useModelProvider'
import { useAppUpdater } from '@/hooks/useAppUpdater'
import { fetchMessages } from '@/services/messages'
import { getProviders } from '@/services/providers'
import { fetchThreads } from '@/services/threads'
import { useEffect } from 'react'
import { useMCPServers } from '@/hooks/useMCPServers'
import { getMCPConfig } from '@/services/mcp'
import { useAssistant } from '@/hooks/useAssistant'
import { getAssistants } from '@/services/assistants'
import {
onOpenUrl,
getCurrent as getCurrentDeepLinkUrls,
} from '@tauri-apps/plugin-deep-link'
import { useNavigate } from '@tanstack/react-router'
import { route } from '@/constants/routes'
import { useThreads } from '@/hooks/useThreads'
import { AppEvent, events } from '@janhq/core'
export function DataProvider() {
const { setProviders } = useModelProvider()
const { setMessages } = useMessages()
const { checkForUpdate } = useAppUpdater()
const { setServers } = useMCPServers()
const { setAssistants, initializeWithLastUsed } = useAssistant()
const { setThreads } = useThreads()
const navigate = useNavigate()
useEffect(() => {
console.log('Initializing DataProvider...')
getProviders().then(setProviders)
getMCPConfig().then((data) => setServers(data.mcpServers ?? []))
getAssistants()
.then((data) => {
// Only update assistants if we have valid data
if (data && Array.isArray(data) && data.length > 0) {
setAssistants(data as unknown as Assistant[])
initializeWithLastUsed()
}
})
.catch((error) => {
console.warn('Failed to load assistants, keeping default:', error)
})
getCurrentDeepLinkUrls().then(handleDeepLink)
onOpenUrl(handleDeepLink)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useEffect(() => {
fetchThreads().then((threads) => {
setThreads(threads)
threads.forEach((thread) =>
fetchMessages(thread.id).then((messages) =>
setMessages(thread.id, messages)
)
)
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
// Check for app updates
useEffect(() => {
// Only check for updates if the auto updater is not disabled
// App might be distributed via other package managers
// or methods that handle updates differently
if (!AUTO_UPDATER_DISABLED) {
checkForUpdate()
}
}, [checkForUpdate])
useEffect(() => {
events.on(AppEvent.onModelImported, () => {
getProviders().then(setProviders)
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const handleDeepLink = (urls: string[] | null) => {
if (!urls) return
console.log('Received deeplink:', urls)
const deeplink = urls[0]
if (deeplink) {
const url = new URL(deeplink)
const params = url.pathname.split('/').filter((str) => str.length > 0)
if (params.length < 3) return undefined
// const action = params[0]
// const provider = params[1]
const resource = params.slice(1).join('/')
// return { action, provider, resource }
navigate({
to: route.hub.model,
search: {
repo: resource,
},
})
}
}
return null
}