feat: add search popup
This commit is contained in:
parent
9b7e2282fe
commit
2d46a4494e
@ -13,7 +13,6 @@ import { ThemeProvider } from './context/ThemeProvider'
|
|||||||
import AgentsPage from './pages/agents/AgentsPage'
|
import AgentsPage from './pages/agents/AgentsPage'
|
||||||
import AppsPage from './pages/apps/AppsPage'
|
import AppsPage from './pages/apps/AppsPage'
|
||||||
import FilesPage from './pages/files/FilesPage'
|
import FilesPage from './pages/files/FilesPage'
|
||||||
import HistoryPage from './pages/history/HistoryPage'
|
|
||||||
import HomePage from './pages/home/HomePage'
|
import HomePage from './pages/home/HomePage'
|
||||||
import PaintingsPage from './pages/paintings/PaintingsPage'
|
import PaintingsPage from './pages/paintings/PaintingsPage'
|
||||||
import SettingsPage from './pages/settings/SettingsPage'
|
import SettingsPage from './pages/settings/SettingsPage'
|
||||||
@ -36,7 +35,6 @@ function App(): JSX.Element {
|
|||||||
<Route path="/paintings" element={<PaintingsPage />} />
|
<Route path="/paintings" element={<PaintingsPage />} />
|
||||||
<Route path="/translate" element={<TranslatePage />} />
|
<Route path="/translate" element={<TranslatePage />} />
|
||||||
<Route path="/apps" element={<AppsPage />} />
|
<Route path="/apps" element={<AppsPage />} />
|
||||||
<Route path="/messages/*" element={<HistoryPage />} />
|
|
||||||
<Route path="/settings/*" element={<SettingsPage />} />
|
<Route path="/settings/*" element={<SettingsPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
|
|||||||
65
src/renderer/src/components/Popups/SearchPopup.tsx
Normal file
65
src/renderer/src/components/Popups/SearchPopup.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import HistoryPage from '@renderer/pages/history/HistoryPage'
|
||||||
|
import { Modal } from 'antd'
|
||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
import { TopView } from '../TopView'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
resolve: (data: any) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const PopupContainer: React.FC<Props> = ({ resolve }) => {
|
||||||
|
const [open, setOpen] = useState(true)
|
||||||
|
|
||||||
|
const onOk = () => {
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
resolve({})
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPopup.hide = onCancel
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
open={open}
|
||||||
|
onOk={onOk}
|
||||||
|
onCancel={onCancel}
|
||||||
|
afterClose={onClose}
|
||||||
|
title={null}
|
||||||
|
width="80vw"
|
||||||
|
transitionName="ant-move-down"
|
||||||
|
styles={{
|
||||||
|
content: { padding: 0, border: '1px solid var(--color-border)' },
|
||||||
|
body: { height: '80vh' }
|
||||||
|
}}
|
||||||
|
footer={null}>
|
||||||
|
<HistoryPage />
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class SearchPopup {
|
||||||
|
static topviewId = 0
|
||||||
|
static hide() {
|
||||||
|
TopView.hide('SearchPopup')
|
||||||
|
}
|
||||||
|
static show() {
|
||||||
|
return new Promise<any>((resolve) => {
|
||||||
|
TopView.show(
|
||||||
|
<PopupContainer
|
||||||
|
resolve={(v) => {
|
||||||
|
resolve(v)
|
||||||
|
TopView.hide('SearchPopup')
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
'SearchPopup'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -27,17 +27,27 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
|
|||||||
resolve({})
|
resolve({})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TemplatePopup.hide = onCancel
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal title={title} open={open} onOk={onOk} onCancel={onCancel} afterClose={onClose}>
|
<Modal
|
||||||
|
title={title}
|
||||||
|
open={open}
|
||||||
|
onOk={onOk}
|
||||||
|
onCancel={onCancel}
|
||||||
|
afterClose={onClose}
|
||||||
|
transitionName="ant-move-down">
|
||||||
<Box mb={8}>Name</Box>
|
<Box mb={8}>Name</Box>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TopViewKey = 'TemplatePopup'
|
||||||
|
|
||||||
export default class TemplatePopup {
|
export default class TemplatePopup {
|
||||||
static topviewId = 0
|
static topviewId = 0
|
||||||
static hide() {
|
static hide() {
|
||||||
TopView.hide('TemplatePopup')
|
TopView.hide(TopViewKey)
|
||||||
}
|
}
|
||||||
static show(props: ShowParams) {
|
static show(props: ShowParams) {
|
||||||
return new Promise<any>((resolve) => {
|
return new Promise<any>((resolve) => {
|
||||||
@ -46,10 +56,10 @@ export default class TemplatePopup {
|
|||||||
{...props}
|
{...props}
|
||||||
resolve={(v) => {
|
resolve={(v) => {
|
||||||
resolve(v)
|
resolve(v)
|
||||||
this.hide()
|
TopView.hide(TopViewKey)
|
||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
'TemplatePopup'
|
TopViewKey
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { FileSearchOutlined, FolderOutlined, PictureOutlined, TranslationOutlined } from '@ant-design/icons'
|
import { FolderOutlined, PictureOutlined, TranslationOutlined } from '@ant-design/icons'
|
||||||
import { isMac } from '@renderer/config/constant'
|
import { isMac } from '@renderer/config/constant'
|
||||||
import { isLocalAi, UserAvatar } from '@renderer/config/env'
|
import { isLocalAi, UserAvatar } from '@renderer/config/env'
|
||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||||
@ -93,13 +93,6 @@ const Sidebar: FC = () => {
|
|||||||
</Icon>
|
</Icon>
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={t('history.title')} mouseEnterDelay={0.5} placement="right">
|
|
||||||
<StyledLink onClick={() => to('/messages')}>
|
|
||||||
<Icon className={isRoutes('/messages')}>
|
|
||||||
<FileSearchOutlined />
|
|
||||||
</Icon>
|
|
||||||
</StyledLink>
|
|
||||||
</Tooltip>
|
|
||||||
</Menus>
|
</Menus>
|
||||||
</MainMenus>
|
</MainMenus>
|
||||||
<Menus onClick={MinApp.onClose}>
|
<Menus onClick={MinApp.onClose}>
|
||||||
|
|||||||
@ -31,6 +31,9 @@ const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
|
|||||||
Menu: {
|
Menu: {
|
||||||
activeBarBorderWidth: 0,
|
activeBarBorderWidth: 0,
|
||||||
darkItemBg: 'transparent'
|
darkItemBg: 'transparent'
|
||||||
|
},
|
||||||
|
Modal: {
|
||||||
|
colorBgMask: isDarkTheme ? 'rgba(0, 0, 0, 0.85)' : 'rgba(255, 255, 255, 0.9)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
token: {
|
token: {
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { ArrowLeftOutlined, EnterOutlined, SearchOutlined } from '@ant-design/icons'
|
import { ArrowLeftOutlined, EnterOutlined, SearchOutlined } from '@ant-design/icons'
|
||||||
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
|
|
||||||
import { Message, Topic } from '@renderer/types'
|
import { Message, Topic } from '@renderer/types'
|
||||||
import { Divider, Input } from 'antd'
|
import { Input } from 'antd'
|
||||||
import { last } from 'lodash'
|
import { last } from 'lodash'
|
||||||
import { FC, useState } from 'react'
|
import { FC, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -59,44 +58,38 @@ const TopicsPage: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Navbar>
|
<Header>
|
||||||
<NavbarCenter style={{ borderRight: 'none', justifyContent: 'flex-start' }}>{t('history.title')} </NavbarCenter>
|
{stack.length > 1 && (
|
||||||
</Navbar>
|
<HeaderLeft>
|
||||||
<ContentContainer id="content-container">
|
<MenuIcon onClick={goBack}>
|
||||||
<Header>
|
<ArrowLeftOutlined />
|
||||||
{stack.length > 1 && (
|
</MenuIcon>
|
||||||
<HeaderLeft>
|
</HeaderLeft>
|
||||||
<MenuIcon onClick={goBack}>
|
)}
|
||||||
<ArrowLeftOutlined />
|
<SearchInput
|
||||||
</MenuIcon>
|
placeholder={t('history.search.placeholder')}
|
||||||
</HeaderLeft>
|
type="search"
|
||||||
)}
|
value={search}
|
||||||
<SearchInput
|
allowClear
|
||||||
placeholder={t('history.search.placeholder')}
|
onChange={(e) => setSearch(e.target.value.trimStart())}
|
||||||
type="search"
|
suffix={search.length >= 2 ? <EnterOutlined /> : <SearchOutlined />}
|
||||||
value={search}
|
onPressEnter={onSearch}
|
||||||
allowClear
|
|
||||||
onChange={(e) => setSearch(e.target.value.trimStart())}
|
|
||||||
suffix={search.length >= 2 ? <EnterOutlined /> : <SearchOutlined />}
|
|
||||||
onPressEnter={onSearch}
|
|
||||||
/>
|
|
||||||
</Header>
|
|
||||||
<Divider style={{ margin: 0 }} />
|
|
||||||
<TopicsHistory
|
|
||||||
keywords={search}
|
|
||||||
onClick={onTopicClick as any}
|
|
||||||
onSearch={onSearch}
|
|
||||||
style={{ display: isShow('topics') }}
|
|
||||||
/>
|
/>
|
||||||
<TopicMessages topic={topic} style={{ display: isShow('topic') }} />
|
</Header>
|
||||||
<SearchResults
|
<TopicsHistory
|
||||||
keywords={isShow('search') ? search : ''}
|
keywords={search}
|
||||||
onMessageClick={onMessageClick}
|
onClick={onTopicClick as any}
|
||||||
onTopicClick={onTopicClick}
|
onSearch={onSearch}
|
||||||
style={{ display: isShow('search') }}
|
style={{ display: isShow('topics') }}
|
||||||
/>
|
/>
|
||||||
<SearchMessage message={message} style={{ display: isShow('message') }} />
|
<TopicMessages topic={topic} style={{ display: isShow('topic') }} />
|
||||||
</ContentContainer>
|
<SearchResults
|
||||||
|
keywords={isShow('search') ? search : ''}
|
||||||
|
onMessageClick={onMessageClick}
|
||||||
|
onTopicClick={onTopicClick}
|
||||||
|
style={{ display: isShow('search') }}
|
||||||
|
/>
|
||||||
|
<SearchMessage message={message} style={{ display: isShow('message') }} />
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -108,24 +101,17 @@ const Container = styled.div`
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
`
|
`
|
||||||
|
|
||||||
const ContentContainer = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: scroll;
|
|
||||||
`
|
|
||||||
|
|
||||||
const Header = styled.div`
|
const Header = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 8px 20px;
|
padding: 10px 0;
|
||||||
padding-top: 10px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background-color: var(--color-background-mute);
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const HeaderLeft = styled.div`
|
const HeaderLeft = styled.div`
|
||||||
|
|||||||
@ -2,11 +2,11 @@ import { ArrowRightOutlined } from '@ant-design/icons'
|
|||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import { default as MessageItem } from '@renderer/pages/home/Messages/Message'
|
import { default as MessageItem } from '@renderer/pages/home/Messages/Message'
|
||||||
import { locateToMessage } from '@renderer/services/MessagesService'
|
import { locateToMessage } from '@renderer/services/MessagesService'
|
||||||
|
import NavigationService from '@renderer/services/NavigationService'
|
||||||
import { Message } from '@renderer/types'
|
import { Message } from '@renderer/types'
|
||||||
import { Button } from 'antd'
|
import { Button } from 'antd'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useNavigate } from 'react-router'
|
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
@ -14,7 +14,7 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SearchMessage: FC<Props> = ({ message, ...props }) => {
|
const SearchMessage: FC<Props> = ({ message, ...props }) => {
|
||||||
const navigate = useNavigate()
|
const navigate = NavigationService.navigate!
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
if (!message) {
|
if (!message) {
|
||||||
|
|||||||
@ -1,15 +1,16 @@
|
|||||||
import { ArrowRightOutlined, MessageOutlined } from '@ant-design/icons'
|
import { ArrowRightOutlined, MessageOutlined } from '@ant-design/icons'
|
||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
|
import SearchPopup from '@renderer/components/Popups/SearchPopup'
|
||||||
import useScrollPosition from '@renderer/hooks/useScrollPosition'
|
import useScrollPosition from '@renderer/hooks/useScrollPosition'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
import { getAssistantById } from '@renderer/services/AssistantService'
|
import { getAssistantById } from '@renderer/services/AssistantService'
|
||||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
||||||
import { locateToMessage } from '@renderer/services/MessagesService'
|
import { locateToMessage } from '@renderer/services/MessagesService'
|
||||||
|
import NavigationService from '@renderer/services/NavigationService'
|
||||||
import { Topic } from '@renderer/types'
|
import { Topic } from '@renderer/types'
|
||||||
import { Button, Divider, Empty } from 'antd'
|
import { Button, Divider, Empty } from 'antd'
|
||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useNavigate } from 'react-router'
|
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import { default as MessageItem } from '../../home/Messages/Message'
|
import { default as MessageItem } from '../../home/Messages/Message'
|
||||||
@ -19,7 +20,7 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TopicMessages: FC<Props> = ({ topic, ...props }) => {
|
const TopicMessages: FC<Props> = ({ topic, ...props }) => {
|
||||||
const navigate = useNavigate()
|
const navigate = NavigationService.navigate!
|
||||||
const { handleScroll, containerRef } = useScrollPosition('TopicMessages')
|
const { handleScroll, containerRef } = useScrollPosition('TopicMessages')
|
||||||
const { messageStyle } = useSettings()
|
const { messageStyle } = useSettings()
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ const TopicMessages: FC<Props> = ({ topic, ...props }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onContinueChat = (topic: Topic) => {
|
const onContinueChat = (topic: Topic) => {
|
||||||
|
SearchPopup.hide()
|
||||||
const assistant = getAssistantById(topic.assistantId)
|
const assistant = getAssistantById(topic.assistantId)
|
||||||
navigate('/', { state: { assistant, topic } })
|
navigate('/', { state: { assistant, topic } })
|
||||||
setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 100)
|
setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 100)
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { useAssistants } from '@renderer/hooks/useAssistant'
|
import { useAssistants } from '@renderer/hooks/useAssistant'
|
||||||
import { useShowAssistants } from '@renderer/hooks/useStore'
|
import { useShowAssistants } from '@renderer/hooks/useStore'
|
||||||
import { useActiveTopic } from '@renderer/hooks/useTopic'
|
import { useActiveTopic } from '@renderer/hooks/useTopic'
|
||||||
|
import NavigationService from '@renderer/services/NavigationService'
|
||||||
import { Assistant } from '@renderer/types'
|
import { Assistant } from '@renderer/types'
|
||||||
import { FC, useState } from 'react'
|
import { FC, useEffect, useState } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import Chat from './Chat'
|
import Chat from './Chat'
|
||||||
@ -14,6 +15,7 @@ let _activeAssistant: Assistant
|
|||||||
|
|
||||||
const HomePage: FC = () => {
|
const HomePage: FC = () => {
|
||||||
const { assistants } = useAssistants()
|
const { assistants } = useAssistants()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const state = location.state
|
const state = location.state
|
||||||
@ -24,6 +26,15 @@ const HomePage: FC = () => {
|
|||||||
|
|
||||||
_activeAssistant = activeAssistant
|
_activeAssistant = activeAssistant
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
NavigationService.setNavigate(navigate)
|
||||||
|
}, [navigate])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
state?.assistant && setActiveAssistant(state?.assistant)
|
||||||
|
state?.topic && setActiveTopic(state?.topic)
|
||||||
|
}, [state])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Navbar activeAssistant={activeAssistant} activeTopic={activeTopic} setActiveTopic={setActiveTopic} />
|
<Navbar activeAssistant={activeAssistant} activeTopic={activeTopic} setActiveTopic={setActiveTopic} />
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { FormOutlined } from '@ant-design/icons'
|
import { SearchOutlined } from '@ant-design/icons'
|
||||||
import { Navbar, NavbarLeft, NavbarRight } from '@renderer/components/app/Navbar'
|
import { Navbar, NavbarLeft, NavbarRight } from '@renderer/components/app/Navbar'
|
||||||
import AssistantSettingsPopup from '@renderer/components/AssistantSettings'
|
import AssistantSettingsPopup from '@renderer/components/AssistantSettings'
|
||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
|
import SearchPopup from '@renderer/components/Popups/SearchPopup'
|
||||||
import { isMac, isWindows } from '@renderer/config/constant'
|
import { isMac, isWindows } from '@renderer/config/constant'
|
||||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore'
|
import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore'
|
||||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
|
||||||
import { Assistant, Topic } from '@renderer/types'
|
import { Assistant, Topic } from '@renderer/types'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
@ -25,8 +25,6 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
|
|||||||
const { topicPosition } = useSettings()
|
const { topicPosition } = useSettings()
|
||||||
const { showTopics, toggleShowTopics } = useShowTopics()
|
const { showTopics, toggleShowTopics } = useShowTopics()
|
||||||
|
|
||||||
const addNewTopic = () => EventEmitter.emit(EVENT_NAMES.ADD_NEW_TOPIC)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Navbar>
|
<Navbar>
|
||||||
{showAssistants && (
|
{showAssistants && (
|
||||||
@ -34,8 +32,8 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
|
|||||||
<NewButton onClick={toggleShowAssistants} style={{ marginLeft: isMac ? 8 : 0 }}>
|
<NewButton onClick={toggleShowAssistants} style={{ marginLeft: isMac ? 8 : 0 }}>
|
||||||
<i className="iconfont icon-hide-sidebar" />
|
<i className="iconfont icon-hide-sidebar" />
|
||||||
</NewButton>
|
</NewButton>
|
||||||
<NewButton onClick={addNewTopic}>
|
<NewButton onClick={() => SearchPopup.show()}>
|
||||||
<FormOutlined />
|
<SearchOutlined />
|
||||||
</NewButton>
|
</NewButton>
|
||||||
</NavbarLeft>
|
</NavbarLeft>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { CheckCircleFilled, CloseCircleFilled, LoadingOutlined } from '@ant-design/icons'
|
import { CheckCircleFilled, CloseCircleFilled, LoadingOutlined } from '@ant-design/icons'
|
||||||
import Scrollbar from '@renderer/components/Scrollbar'
|
import Scrollbar from '@renderer/components/Scrollbar'
|
||||||
import { TopView } from '@renderer/components/TopView'
|
import { TopView } from '@renderer/components/TopView'
|
||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
|
||||||
import { checkApi } from '@renderer/services/ApiService'
|
import { checkApi } from '@renderer/services/ApiService'
|
||||||
import { Button, List, Modal, Space, Spin, Typography } from 'antd'
|
import { Button, List, Modal, Space, Spin, Typography } from 'antd'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
@ -30,7 +29,6 @@ const PopupContainer: React.FC<Props> = ({ title, provider, apiKeys, resolve })
|
|||||||
return Array.from(uniqueKeys).map((key) => ({ key }))
|
return Array.from(uniqueKeys).map((key) => ({ key }))
|
||||||
})
|
})
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { theme } = useTheme()
|
|
||||||
const [isChecking, setIsChecking] = useState(false)
|
const [isChecking, setIsChecking] = useState(false)
|
||||||
|
|
||||||
const checkAllKeys = async () => {
|
const checkAllKeys = async () => {
|
||||||
@ -79,11 +77,6 @@ const PopupContainer: React.FC<Props> = ({ title, provider, apiKeys, resolve })
|
|||||||
afterClose={onClose}
|
afterClose={onClose}
|
||||||
centered
|
centered
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
maskProps={{
|
|
||||||
style: {
|
|
||||||
backgroundColor: theme === 'dark' ? 'rgba(0, 0, 0, 0.9)' : 'rgba(255, 255, 255, 0.9)'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
footer={
|
footer={
|
||||||
<Space style={{ display: 'flex', justifyContent: 'space-between' }}>
|
<Space style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||||
<Space>
|
<Space>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import SearchPopup from '@renderer/components/Popups/SearchPopup'
|
||||||
import { DEFAULT_CONTEXTCOUNT } from '@renderer/config/constant'
|
import { DEFAULT_CONTEXTCOUNT } from '@renderer/config/constant'
|
||||||
import { getTopicById } from '@renderer/hooks/useTopic'
|
import { getTopicById } from '@renderer/hooks/useTopic'
|
||||||
import { Assistant, Message, Topic } from '@renderer/types'
|
import { Assistant, Message, Topic } from '@renderer/types'
|
||||||
@ -43,6 +44,7 @@ export function deleteMessageFiles(message: Message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function locateToMessage(navigate: NavigateFunction, message: Message) {
|
export async function locateToMessage(navigate: NavigateFunction, message: Message) {
|
||||||
|
SearchPopup.hide()
|
||||||
const assistant = getAssistantById(message.assistantId)
|
const assistant = getAssistantById(message.assistantId)
|
||||||
const topic = await getTopicById(message.topicId)
|
const topic = await getTopicById(message.topicId)
|
||||||
navigate('/', { state: { assistant, topic } })
|
navigate('/', { state: { assistant, topic } })
|
||||||
|
|||||||
16
src/renderer/src/services/NavigationService.ts
Normal file
16
src/renderer/src/services/NavigationService.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { NavigateFunction } from 'react-router-dom'
|
||||||
|
|
||||||
|
interface INavigationService {
|
||||||
|
navigate: NavigateFunction | null
|
||||||
|
setNavigate: (navigateFunc: NavigateFunction) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavigationService: INavigationService = {
|
||||||
|
navigate: null,
|
||||||
|
|
||||||
|
setNavigate: (navigateFunc: NavigateFunction): void => {
|
||||||
|
NavigationService.navigate = navigateFunc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NavigationService
|
||||||
Loading…
x
Reference in New Issue
Block a user