fix: quick ask improvement (#2543)

* docs: Update README.md

* fix: quick ask improvement

Signed-off-by: James <james@jan.ai>

---------

Signed-off-by: James <james@jan.ai>
Co-authored-by: hieu-jan <150573299+henryh0x1@users.noreply.github.com>
Co-authored-by: James <james@jan.ai>
This commit is contained in:
NamH 2024-03-30 08:59:52 +07:00 committed by GitHub
parent 53b572029b
commit 96af5fb85a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 111 additions and 91 deletions

View File

@ -44,31 +44,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute
<td style="text-align:center"><b>Stable (Recommended)</b></td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-win-x64-0.4.9.exe'>
<img src='./docs/static/img/windows.png' style="height:14px; width: 14px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/windows.png' style="height:14px; width: 14px" />
<b>jan.exe</b>
</a>
</td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-mac-x64-0.4.9.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/mac.png' style="height:15px; width: 15px" />
<b>Intel</b>
</a>
</td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-mac-arm64-0.4.9.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/mac.png' style="height:15px; width: 15px" />
<b>M1/M2</b>
</a>
</td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-linux-amd64-0.4.9.deb'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.deb</b>
</a>
</td>
<td style="text-align:center">
<a href='https://github.com/janhq/jan/releases/download/v0.4.9/jan-linux-x86_64-0.4.9.AppImage'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.AppImage</b>
</a>
</td>
@ -77,31 +77,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute
<td style="text-align:center"><b>Experimental (Nightly Build)</b></td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-win-x64-0.4.9-351.exe'>
<img src='./docs/static/img/windows.png' style="height:14px; width: 14px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/windows.png' style="height:14px; width: 14px" />
<b>jan.exe</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-mac-x64-0.4.9-351.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/mac.png' style="height:15px; width: 15px" />
<b>Intel</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-mac-arm64-0.4.9-351.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/mac.png' style="height:15px; width: 15px" />
<b>M1/M2</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-linux-amd64-0.4.9-351.deb'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.deb</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/latest/jan-linux-x86_64-0.4.9-351.AppImage'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<img src='https://github.com/janhq/docs/blob/main/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.AppImage</b>
</a>
</td>

View File

@ -2,8 +2,6 @@ import { PropsWithChildren } from 'react'
import { Metadata } from 'next'
import Providers from '@/containers/Providers'
import '@/styles/main.scss'
export const metadata: Metadata = {
@ -16,8 +14,7 @@ export default function RootLayout({ children }: PropsWithChildren) {
return (
<html lang="en" suppressHydrationWarning>
<body className="bg-white font-sans text-sm antialiased dark:bg-background">
<div className="title-bar" />
<Providers>{children}</Providers>
{children}
</body>
</html>
)

View File

@ -1,40 +1,11 @@
'use client'
import { useAtomValue } from 'jotai'
import BaseLayout from '@/containers/Layout'
import { MainViewState } from '@/constants/screens'
import ChatScreen from '@/screens/Chat'
import ExploreModelsScreen from '@/screens/ExploreModels'
import LocalServerScreen from '@/screens/LocalServer'
import SettingsScreen from '@/screens/Settings'
import { mainViewStateAtom } from '@/helpers/atoms/App.atom'
import Providers from '@/containers/Providers'
export default function Page() {
const mainViewState = useAtomValue(mainViewStateAtom)
let children = null
switch (mainViewState) {
case MainViewState.Hub:
children = <ExploreModelsScreen />
break
case MainViewState.Settings:
children = <SettingsScreen />
break
case MainViewState.LocalServer:
children = <LocalServerScreen />
break
default:
children = <ChatScreen />
break
}
return <BaseLayout>{children}</BaseLayout>
return (
<Providers>
<BaseLayout />
</Providers>
)
}

View File

@ -10,6 +10,7 @@ const SelectedText = ({ onCleared }: { onCleared?: () => void }) => {
const containerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
if (window.core?.api?.quickAskSizeUpdated !== 'function') return
if (text.trim().length === 0) {
window.core?.api?.quickAskSizeUpdated(0)
} else {

32
web/app/search/layout.tsx Normal file
View File

@ -0,0 +1,32 @@
'use client'
import { useEffect } from 'react'
import ClipboardListener from '@/containers/Providers/ClipboardListener'
import JotaiWrapper from '@/containers/Providers/Jotai'
import ThemeWrapper from '@/containers/Providers/Theme'
import { setupCoreServices } from '@/services/coreService'
import Search from './page'
export default function RootLayout() {
useEffect(() => {
setupCoreServices()
}, [])
return (
<html lang="en" suppressHydrationWarning>
<body className="bg-white font-sans text-sm antialiased dark:bg-background">
<JotaiWrapper>
<ThemeWrapper>
<ClipboardListener>
<Search />
</ClipboardListener>
</ThemeWrapper>
</JotaiWrapper>
</body>
</html>
)
}

View File

@ -68,7 +68,7 @@ const TopBar = () => {
}
return (
<div className="fixed left-0 top-0 z-20 flex h-12 w-full border-b border-border bg-background/80 backdrop-blur-md">
<div className="title-bar fixed left-0 top-0 z-20 flex h-12 w-full border-b border-border bg-background/80 backdrop-blur-md">
{mainViewState !== MainViewState.Thread &&
mainViewState !== MainViewState.LocalServer ? (
<div className="relative left-16 flex w-[calc(100%-64px)] items-center justify-between space-x-4 pl-6 pr-2">

View File

@ -1,4 +1,5 @@
import React, { PropsWithChildren, useEffect } from 'react'
'use client'
import React, { useEffect } from 'react'
import { useTheme } from 'next-themes'
@ -23,12 +24,13 @@ import ImportModelOptionModal from '@/screens/Settings/ImportModelOptionModal'
import ImportingModelModal from '@/screens/Settings/ImportingModelModal'
import SelectingModelModal from '@/screens/Settings/SelectingModelModal'
import MainViewContainer from '../MainViewContainer'
import InstallingExtensionModal from './BottomBar/InstallingExtension/InstallingExtensionModal'
import { mainViewStateAtom } from '@/helpers/atoms/App.atom'
const BaseLayout = (props: PropsWithChildren) => {
const { children } = props
const BaseLayout = () => {
const [mainViewState, setMainViewState] = useAtom(mainViewStateAtom)
const importModelStage = useAtomValue(getImportModelStageAtom)
const { theme, setTheme } = useTheme()
@ -61,7 +63,7 @@ const BaseLayout = (props: PropsWithChildren) => {
},
}}
>
{children}
<MainViewContainer />
</m.div>
<BottomBar />
</div>

View File

@ -0,0 +1,37 @@
import { useAtomValue } from 'jotai'
import { MainViewState } from '@/constants/screens'
import ChatScreen from '@/screens/Chat'
import ExploreModelsScreen from '@/screens/ExploreModels'
import LocalServerScreen from '@/screens/LocalServer'
import SettingsScreen from '@/screens/Settings'
import { mainViewStateAtom } from '@/helpers/atoms/App.atom'
const MainViewContainer: React.FC = () => {
const mainViewState = useAtomValue(mainViewStateAtom)
let children = null
switch (mainViewState) {
case MainViewState.Hub:
children = <ExploreModelsScreen />
break
case MainViewState.Settings:
children = <SettingsScreen />
break
case MainViewState.LocalServer:
children = <LocalServerScreen />
break
default:
children = <ChatScreen />
break
}
return children
}
export default MainViewContainer

View File

@ -7,9 +7,11 @@ import { selectedTextAtom } from './Jotai'
const ClipboardListener = ({ children }: PropsWithChildren) => {
const setSelectedText = useSetAtom(selectedTextAtom)
window?.electronAPI?.onSelectedText((_event: string, text: string) => {
setSelectedText(text)
})
if (typeof window !== 'undefined') {
window?.electronAPI?.onSelectedText((_event: string, text: string) => {
setSelectedText(text)
})
}
return <Fragment>{children}</Fragment>
}

View File

@ -1,15 +1,13 @@
import { Fragment, ReactNode, useRef } from 'react'
import { Fragment, ReactNode } from 'react'
import { useSetAtom } from 'jotai'
import { useDebouncedCallback } from 'use-debounce'
import { MainViewState } from '@/constants/screens'
import useSendChatMessage from '@/hooks/useSendChatMessage'
import { showRightSideBarAtom } from '@/screens/Chat/Sidebar'
import { showLeftSideBarAtom } from './KeyListener'
import { mainViewStateAtom } from '@/helpers/atoms/App.atom'
type Props = {
@ -18,19 +16,15 @@ type Props = {
const QuickAskListener: React.FC<Props> = ({ children }) => {
const { sendChatMessage } = useSendChatMessage()
const setShowRightSideBar = useSetAtom(showRightSideBarAtom)
const setShowLeftSideBar = useSetAtom(showLeftSideBarAtom)
const setMainState = useSetAtom(mainViewStateAtom)
const previousMessage = useRef('')
const debounced = useDebouncedCallback((value) => {
setMainState(MainViewState.Thread)
sendChatMessage(value)
}, 300)
window.electronAPI?.onUserSubmitQuickAsk((_event: string, input: string) => {
if (previousMessage.current === input) return
setMainState(MainViewState.Thread)
setShowRightSideBar(false)
setShowLeftSideBar(false)
sendChatMessage(input)
previousMessage.current = input
debounced(input)
})
return <Fragment>{children}</Fragment>

View File

@ -4,8 +4,6 @@ import { PropsWithChildren, useCallback, useEffect, useState } from 'react'
import { Toaster } from 'react-hot-toast'
import { usePathname } from 'next/navigation'
import { TooltipProvider } from '@janhq/uikit'
import GPUDriverPrompt from '@/containers/GPUDriverPromptModal'
@ -29,10 +27,7 @@ import KeyListener from './KeyListener'
import { extensionManager } from '@/extension'
const Providers = (props: PropsWithChildren) => {
const { children } = props
const pathname = usePathname()
const Providers = ({ children }: PropsWithChildren) => {
const [setupCore, setSetupCore] = useState(false)
const [activated, setActivated] = useState(false)
const [settingUp, setSettingUp] = useState(false)
@ -43,11 +38,6 @@ const Providers = (props: PropsWithChildren) => {
setTimeout(async () => {
if (!isCoreExtensionInstalled()) {
// TODO: Proper window handle
// Do not migrate extension from quick ask window
if (pathname === '/search') {
return
}
setSettingUp(true)
await setupBaseExtensions()
return
@ -57,7 +47,7 @@ const Providers = (props: PropsWithChildren) => {
setSettingUp(false)
setActivated(true)
}, 500)
}, [pathname])
}, [])
// Services Setup
useEffect(() => {

View File

@ -46,6 +46,7 @@
"tailwindcss": "3.3.5",
"ulidx": "^2.3.0",
"uuid": "^9.0.1",
"use-debounce": "^10.0.0",
"zod": "^3.22.4"
},
"devDependencies": {

View File

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
import { ExtensionTypeEnum } from '@janhq/core'
import { extensionManager } from '@/extension/ExtensionManager'
@ -13,6 +11,7 @@ export const isCoreExtensionInstalled = () => {
}
return true
}
export const setupBaseExtensions = async () => {
if (typeof window === 'undefined') {
return

View File

@ -8,12 +8,6 @@
}
.title-bar {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 24px;
user-select: none;
-webkit-app-region: drag;
}