enhancement: scrollbar setting options (#4726)
* enhancement: scrollbar setting options * chore: fix linter
This commit is contained in:
parent
81fea5665b
commit
2ea8083ad7
@ -684,61 +684,61 @@ __metadata:
|
|||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=ff5479&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=b51c7a&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/a9f5cc6b3e90eecef539a2036385dcdcb5988304a4c78d1bff4fe9e7e9910b319aa1efd92c395a0dabee98821a9bc274f45958a345441204f3dafbeec76ba658
|
checksum: 10c0/14c61c6f50f09da8202fec64a46e3b5b81927872ee25695da209a2cc1cf7638049c9cd981a0be0cd51034479dfd3d921b851b0fa2809a4823095977b41954e6e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=ff5479&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=b51c7a&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/a9f5cc6b3e90eecef539a2036385dcdcb5988304a4c78d1bff4fe9e7e9910b319aa1efd92c395a0dabee98821a9bc274f45958a345441204f3dafbeec76ba658
|
checksum: 10c0/14c61c6f50f09da8202fec64a46e3b5b81927872ee25695da209a2cc1cf7638049c9cd981a0be0cd51034479dfd3d921b851b0fa2809a4823095977b41954e6e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=ff5479&locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=b51c7a&locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/a9f5cc6b3e90eecef539a2036385dcdcb5988304a4c78d1bff4fe9e7e9910b319aa1efd92c395a0dabee98821a9bc274f45958a345441204f3dafbeec76ba658
|
checksum: 10c0/14c61c6f50f09da8202fec64a46e3b5b81927872ee25695da209a2cc1cf7638049c9cd981a0be0cd51034479dfd3d921b851b0fa2809a4823095977b41954e6e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fhardware-management-extension%40workspace%3Ahardware-management-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fhardware-management-extension%40workspace%3Ahardware-management-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=ff5479&locator=%40janhq%2Fhardware-management-extension%40workspace%3Ahardware-management-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=b51c7a&locator=%40janhq%2Fhardware-management-extension%40workspace%3Ahardware-management-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/a9f5cc6b3e90eecef539a2036385dcdcb5988304a4c78d1bff4fe9e7e9910b319aa1efd92c395a0dabee98821a9bc274f45958a345441204f3dafbeec76ba658
|
checksum: 10c0/14c61c6f50f09da8202fec64a46e3b5b81927872ee25695da209a2cc1cf7638049c9cd981a0be0cd51034479dfd3d921b851b0fa2809a4823095977b41954e6e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=ff5479&locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=b51c7a&locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/a9f5cc6b3e90eecef539a2036385dcdcb5988304a4c78d1bff4fe9e7e9910b319aa1efd92c395a0dabee98821a9bc274f45958a345441204f3dafbeec76ba658
|
checksum: 10c0/14c61c6f50f09da8202fec64a46e3b5b81927872ee25695da209a2cc1cf7638049c9cd981a0be0cd51034479dfd3d921b851b0fa2809a4823095977b41954e6e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension":
|
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension":
|
||||||
version: 0.1.10
|
version: 0.1.10
|
||||||
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=ff5479&locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension"
|
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=b51c7a&locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension"
|
||||||
dependencies:
|
dependencies:
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
ulidx: "npm:^2.3.0"
|
ulidx: "npm:^2.3.0"
|
||||||
checksum: 10c0/a9f5cc6b3e90eecef539a2036385dcdcb5988304a4c78d1bff4fe9e7e9910b319aa1efd92c395a0dabee98821a9bc274f45958a345441204f3dafbeec76ba658
|
checksum: 10c0/14c61c6f50f09da8202fec64a46e3b5b81927872ee25695da209a2cc1cf7638049c9cd981a0be0cd51034479dfd3d921b851b0fa2809a4823095977b41954e6e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -755,6 +755,7 @@ __metadata:
|
|||||||
run-script-os: "npm:^1.1.6"
|
run-script-os: "npm:^1.1.6"
|
||||||
ts-loader: "npm:^9.5.0"
|
ts-loader: "npm:^9.5.0"
|
||||||
typescript: "npm:^5.3.3"
|
typescript: "npm:^5.3.3"
|
||||||
|
vitest: "npm:^3.0.6"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
|||||||
@ -51,20 +51,3 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-track,
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background-clip: content-box;
|
|
||||||
border-radius: inherit;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: hsla(var(--scrollbar-tracker));
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: hsla(var(--scrollbar-thumb));
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import {
|
|||||||
productAnalyticAtom,
|
productAnalyticAtom,
|
||||||
productAnalyticPromptAtom,
|
productAnalyticPromptAtom,
|
||||||
reduceTransparentAtom,
|
reduceTransparentAtom,
|
||||||
|
showScrollBarAtom,
|
||||||
} from '@/helpers/atoms/Setting.atom'
|
} from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
const BaseLayout = () => {
|
const BaseLayout = () => {
|
||||||
@ -52,6 +53,7 @@ const BaseLayout = () => {
|
|||||||
const [productAnalyticPrompt, setProductAnalyticPrompt] = useAtom(
|
const [productAnalyticPrompt, setProductAnalyticPrompt] = useAtom(
|
||||||
productAnalyticPromptAtom
|
productAnalyticPromptAtom
|
||||||
)
|
)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
const [showProductAnalyticPrompt, setShowProductAnalyticPrompt] =
|
const [showProductAnalyticPrompt, setShowProductAnalyticPrompt] =
|
||||||
useState(false)
|
useState(false)
|
||||||
|
|
||||||
@ -150,7 +152,12 @@ const BaseLayout = () => {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<TopPanel />
|
<TopPanel />
|
||||||
<div className="relative top-9 flex h-[calc(100vh-(36px+36px))] w-screen">
|
<div
|
||||||
|
className={twMerge(
|
||||||
|
'relative top-9 flex h-[calc(100vh-(36px+36px))] w-screen',
|
||||||
|
showScrollBar && 'show-scroll-bar'
|
||||||
|
)}
|
||||||
|
>
|
||||||
<RibbonPanel />
|
<RibbonPanel />
|
||||||
<MainViewContainer />
|
<MainViewContainer />
|
||||||
<LoadingModal />
|
<LoadingModal />
|
||||||
|
|||||||
@ -12,7 +12,10 @@ import { atom, useAtom, useAtomValue } from 'jotai'
|
|||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
import { showLeftPanelAtom } from '@/helpers/atoms/App.atom'
|
import { showLeftPanelAtom } from '@/helpers/atoms/App.atom'
|
||||||
import { reduceTransparentAtom } from '@/helpers/atoms/Setting.atom'
|
import {
|
||||||
|
reduceTransparentAtom,
|
||||||
|
showScrollBarAtom,
|
||||||
|
} from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
type Props = PropsWithChildren
|
type Props = PropsWithChildren
|
||||||
|
|
||||||
@ -27,6 +30,7 @@ const LeftPanelContainer = ({ children }: Props) => {
|
|||||||
const [showLeftPanel, setShowLeftPanel] = useAtom(showLeftPanelAtom)
|
const [showLeftPanel, setShowLeftPanel] = useAtom(showLeftPanelAtom)
|
||||||
const matches = useMediaQuery('(max-width: 880px)')
|
const matches = useMediaQuery('(max-width: 880px)')
|
||||||
const reduceTransparent = useAtomValue(reduceTransparentAtom)
|
const reduceTransparent = useAtomValue(reduceTransparentAtom)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
useClickOutside(
|
useClickOutside(
|
||||||
() => matches && showLeftPanel && setShowLeftPanel(false),
|
() => matches && showLeftPanel && setShowLeftPanel(false),
|
||||||
@ -101,7 +105,10 @@ const LeftPanelContainer = ({ children }: Props) => {
|
|||||||
style={{ width: showLeftPanel ? leftPanelWidth : 0 }}
|
style={{ width: showLeftPanel ? leftPanelWidth : 0 }}
|
||||||
onMouseDown={(e) => isResizing && e.stopPropagation()}
|
onMouseDown={(e) => isResizing && e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
{showLeftPanel && !matches && (
|
{showLeftPanel && !matches && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { ScrollArea } from '@janhq/joi'
|
|||||||
|
|
||||||
import { useAtomValue } from 'jotai'
|
import { useAtomValue } from 'jotai'
|
||||||
|
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
const ListContainer = ({ children }: PropsWithChildren) => {
|
const ListContainer = ({ children }: PropsWithChildren) => {
|
||||||
@ -12,6 +13,7 @@ const ListContainer = ({ children }: PropsWithChildren) => {
|
|||||||
const isUserManuallyScrollingUp = useRef(false)
|
const isUserManuallyScrollingUp = useRef(false)
|
||||||
const activeThread = useAtomValue(activeThreadAtom)
|
const activeThread = useAtomValue(activeThreadAtom)
|
||||||
const prevActiveThread = useRef(activeThread)
|
const prevActiveThread = useRef(activeThread)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
// Handle active thread changes
|
// Handle active thread changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -59,6 +61,7 @@ const ListContainer = ({ children }: PropsWithChildren) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
className="flex h-full w-full flex-col overflow-x-hidden"
|
className="flex h-full w-full flex-col overflow-x-hidden"
|
||||||
ref={listRef}
|
ref={listRef}
|
||||||
onScroll={handleScroll}
|
onScroll={handleScroll}
|
||||||
|
|||||||
@ -55,6 +55,7 @@ import {
|
|||||||
showEngineListModelAtom,
|
showEngineListModelAtom,
|
||||||
} from '@/helpers/atoms/Model.atom'
|
} from '@/helpers/atoms/Model.atom'
|
||||||
|
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
import {
|
import {
|
||||||
activeThreadAtom,
|
activeThreadAtom,
|
||||||
setThreadModelParamsAtom,
|
setThreadModelParamsAtom,
|
||||||
@ -77,6 +78,7 @@ const ModelDropdown = ({
|
|||||||
const [modelDropdownState, setModelDropdownState] = useAtom(
|
const [modelDropdownState, setModelDropdownState] = useAtom(
|
||||||
modelDropdownStateAtom
|
modelDropdownStateAtom
|
||||||
)
|
)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
const [searchFilter, setSearchFilter] = useState('local')
|
const [searchFilter, setSearchFilter] = useState('local')
|
||||||
const [searchText, setSearchText] = useState('')
|
const [searchText, setSearchText] = useState('')
|
||||||
@ -385,7 +387,10 @@ const ModelDropdown = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ScrollArea className="h-[calc(100%-90px)] w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-[calc(100%-90px)] w-full"
|
||||||
|
>
|
||||||
{engineList
|
{engineList
|
||||||
.filter((e) => e.type === searchFilter)
|
.filter((e) => e.type === searchFilter)
|
||||||
.filter(
|
.filter(
|
||||||
|
|||||||
@ -12,7 +12,10 @@ import { atom, useAtom, useAtomValue } from 'jotai'
|
|||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
import { showRightPanelAtom } from '@/helpers/atoms/App.atom'
|
import { showRightPanelAtom } from '@/helpers/atoms/App.atom'
|
||||||
import { reduceTransparentAtom } from '@/helpers/atoms/Setting.atom'
|
import {
|
||||||
|
reduceTransparentAtom,
|
||||||
|
showScrollBarAtom,
|
||||||
|
} from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
type Props = PropsWithChildren
|
type Props = PropsWithChildren
|
||||||
|
|
||||||
@ -28,6 +31,7 @@ const RightPanelContainer = ({ children }: Props) => {
|
|||||||
null
|
null
|
||||||
)
|
)
|
||||||
const reduceTransparent = useAtomValue(reduceTransparentAtom)
|
const reduceTransparent = useAtomValue(reduceTransparentAtom)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
const [showRightPanel, setShowRightPanel] = useAtom(showRightPanelAtom)
|
const [showRightPanel, setShowRightPanel] = useAtom(showRightPanelAtom)
|
||||||
const matches = useMediaQuery('(max-width: 880px)')
|
const matches = useMediaQuery('(max-width: 880px)')
|
||||||
@ -105,7 +109,10 @@ const RightPanelContainer = ({ children }: Props) => {
|
|||||||
style={{ width: showRightPanel ? rightPanelWidth : 0 }}
|
style={{ width: showRightPanel ? rightPanelWidth : 0 }}
|
||||||
onMouseDown={(e) => isResizing && e.preventDefault()}
|
onMouseDown={(e) => isResizing && e.preventDefault()}
|
||||||
>
|
>
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
{showRightPanel && !matches && (
|
{showRightPanel && !matches && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { useLogs } from '@/hooks/useLogs'
|
|||||||
import { usePath } from '@/hooks/usePath'
|
import { usePath } from '@/hooks/usePath'
|
||||||
|
|
||||||
import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
|
import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
type ServerLogsProps = { limit?: number; withCopy?: boolean }
|
type ServerLogsProps = { limit?: number; withCopy?: boolean }
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ const ServerLogs = (props: ServerLogsProps) => {
|
|||||||
const listRef = useRef<HTMLDivElement>(null)
|
const listRef = useRef<HTMLDivElement>(null)
|
||||||
const prevScrollTop = useRef(0)
|
const prevScrollTop = useRef(0)
|
||||||
const isUserManuallyScrollingUp = useRef(false)
|
const isUserManuallyScrollingUp = useRef(false)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
const updateLogs = useCallback(
|
const updateLogs = useCallback(
|
||||||
() =>
|
() =>
|
||||||
@ -136,6 +138,7 @@ const ServerLogs = (props: ServerLogsProps) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
ref={listRef}
|
ref={listRef}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
'h-[calc(100%-49px)] w-full p-4 py-0',
|
'h-[calc(100%-49px)] w-full p-4 py-0',
|
||||||
|
|||||||
@ -11,6 +11,7 @@ export const janSettingScreenAtom = atom<SettingScreen[]>([])
|
|||||||
export const THEME = 'themeAppearance'
|
export const THEME = 'themeAppearance'
|
||||||
export const REDUCE_TRANSPARENT = 'reduceTransparent'
|
export const REDUCE_TRANSPARENT = 'reduceTransparent'
|
||||||
export const SPELL_CHECKING = 'spellChecking'
|
export const SPELL_CHECKING = 'spellChecking'
|
||||||
|
export const SCROLL_BAR = 'scrollBar'
|
||||||
export const PRODUCT_ANALYTIC = 'productAnalytic'
|
export const PRODUCT_ANALYTIC = 'productAnalytic'
|
||||||
export const PRODUCT_ANALYTIC_PROMPT = 'productAnalyticPrompt'
|
export const PRODUCT_ANALYTIC_PROMPT = 'productAnalyticPrompt'
|
||||||
export const THEME_DATA = 'themeData'
|
export const THEME_DATA = 'themeData'
|
||||||
@ -45,6 +46,12 @@ export const spellCheckAtom = atomWithStorage<boolean>(
|
|||||||
undefined,
|
undefined,
|
||||||
{ getOnInit: true }
|
{ getOnInit: true }
|
||||||
)
|
)
|
||||||
|
export const showScrollBarAtom = atomWithStorage<boolean>(
|
||||||
|
SCROLL_BAR,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
{ getOnInit: true }
|
||||||
|
)
|
||||||
export const productAnalyticAtom = atomWithStorage<boolean>(
|
export const productAnalyticAtom = atomWithStorage<boolean>(
|
||||||
PRODUCT_ANALYTIC,
|
PRODUCT_ANALYTIC,
|
||||||
false,
|
false,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import Image from 'next/image'
|
|||||||
|
|
||||||
import { ModelSource } from '@janhq/core'
|
import { ModelSource } from '@janhq/core'
|
||||||
import { Badge, Button, ScrollArea } from '@janhq/joi'
|
import { Badge, Button, ScrollArea } from '@janhq/joi'
|
||||||
import { useSetAtom } from 'jotai'
|
import { useAtomValue, useSetAtom } from 'jotai'
|
||||||
import {
|
import {
|
||||||
ArrowLeftIcon,
|
ArrowLeftIcon,
|
||||||
DownloadIcon,
|
DownloadIcon,
|
||||||
@ -24,7 +24,10 @@ import { toGigabytes } from '@/utils/converter'
|
|||||||
import { extractModelName } from '@/utils/modelSource'
|
import { extractModelName } from '@/utils/modelSource'
|
||||||
|
|
||||||
import { mainViewStateAtom } from '@/helpers/atoms/App.atom'
|
import { mainViewStateAtom } from '@/helpers/atoms/App.atom'
|
||||||
import { selectedSettingAtom } from '@/helpers/atoms/Setting.atom'
|
import {
|
||||||
|
selectedSettingAtom,
|
||||||
|
showScrollBarAtom,
|
||||||
|
} from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
model: ModelSource
|
model: ModelSource
|
||||||
@ -35,9 +38,14 @@ const ModelPage = ({ model, onGoBack }: Props) => {
|
|||||||
const setSelectedSetting = useSetAtom(selectedSettingAtom)
|
const setSelectedSetting = useSetAtom(selectedSettingAtom)
|
||||||
const setMainViewState = useSetAtom(mainViewStateAtom)
|
const setMainViewState = useSetAtom(mainViewStateAtom)
|
||||||
const { refreshingModels, refreshModels } = useRefreshModelList(model.id)
|
const { refreshingModels, refreshModels } = useRefreshModelList(model.id)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea data-testid="hub-container-test-id" className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
data-testid="hub-container-test-id"
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
<div className="flex h-full w-full justify-center">
|
<div className="flex h-full w-full justify-center">
|
||||||
<div className="flex w-full max-w-[800px] flex-col ">
|
<div className="flex w-full max-w-[800px] flex-col ">
|
||||||
<div className="sticky top-0 flex h-12 items-center bg-[hsla(var(--app-bg))] px-4">
|
<div className="sticky top-0 flex h-12 items-center bg-[hsla(var(--app-bg))] px-4">
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import {
|
|||||||
} from '@/helpers/atoms/App.atom'
|
} from '@/helpers/atoms/App.atom'
|
||||||
import { modelDetailAtom } from '@/helpers/atoms/Model.atom'
|
import { modelDetailAtom } from '@/helpers/atoms/Model.atom'
|
||||||
|
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
import { totalRamAtom } from '@/helpers/atoms/SystemBar.atom'
|
import { totalRamAtom } from '@/helpers/atoms/SystemBar.atom'
|
||||||
|
|
||||||
const sortMenus = [
|
const sortMenus = [
|
||||||
@ -94,6 +95,7 @@ const HubScreen = () => {
|
|||||||
const [selectedModel, setSelectedModel] = useState<ModelSource | undefined>(
|
const [selectedModel, setSelectedModel] = useState<ModelSource | undefined>(
|
||||||
undefined
|
undefined
|
||||||
)
|
)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
const [modelDetail, setModelDetail] = useAtom(modelDetailAtom)
|
const [modelDetail, setModelDetail] = useAtom(modelDetailAtom)
|
||||||
const setImportModelStage = useSetAtom(setImportModelStageAtom)
|
const setImportModelStage = useSetAtom(setImportModelStageAtom)
|
||||||
const dropdownRef = useRef<HTMLDivElement>(null)
|
const dropdownRef = useRef<HTMLDivElement>(null)
|
||||||
@ -260,6 +262,7 @@ const HubScreen = () => {
|
|||||||
>
|
>
|
||||||
{!selectedModel && (
|
{!selectedModel && (
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
data-testid="hub-container-test-id"
|
data-testid="hub-container-test-id"
|
||||||
className="h-full w-full"
|
className="h-full w-full"
|
||||||
>
|
>
|
||||||
@ -311,7 +314,10 @@ const HubScreen = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{hubBannerOption === 'gallery' && (
|
{hubBannerOption === 'gallery' && (
|
||||||
<ScrollArea className="h-[350px] w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-[350px] w-full"
|
||||||
|
>
|
||||||
{Array.from({ length: 30 }, (_, i) => i + 1).map(
|
{Array.from({ length: 30 }, (_, i) => i + 1).map(
|
||||||
(e) => {
|
(e) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useCallback, useState } from 'react'
|
import { useCallback, useState } from 'react'
|
||||||
|
|
||||||
import { Input, ScrollArea, Switch } from '@janhq/joi'
|
import { Input, ScrollArea, Switch } from '@janhq/joi'
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom, useAtomValue } from 'jotai'
|
||||||
import { EyeIcon, EyeOffIcon, XIcon, ArrowLeftIcon } from 'lucide-react'
|
import { EyeIcon, EyeOffIcon, XIcon, ArrowLeftIcon } from 'lucide-react'
|
||||||
import { useDebouncedCallback } from 'use-debounce'
|
import { useDebouncedCallback } from 'use-debounce'
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ import {
|
|||||||
proxyUsernameAtom,
|
proxyUsernameAtom,
|
||||||
proxyPasswordAtom,
|
proxyPasswordAtom,
|
||||||
} from '@/helpers/atoms/AppConfig.atom'
|
} from '@/helpers/atoms/AppConfig.atom'
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
const ProxySettings = ({ onBack }: { onBack: () => void }) => {
|
const ProxySettings = ({ onBack }: { onBack: () => void }) => {
|
||||||
const [proxy, setProxy] = useAtom(proxyAtom)
|
const [proxy, setProxy] = useAtom(proxyAtom)
|
||||||
@ -38,6 +39,7 @@ const ProxySettings = ({ onBack }: { onBack: () => void }) => {
|
|||||||
const [verifyPeerSSL, setVerifyPeerSSL] = useAtom(verifyPeerSslAtom)
|
const [verifyPeerSSL, setVerifyPeerSSL] = useAtom(verifyPeerSslAtom)
|
||||||
const [verifyHostSSL, setVerifyHostSSL] = useAtom(verifyHostSslAtom)
|
const [verifyHostSSL, setVerifyHostSSL] = useAtom(verifyHostSslAtom)
|
||||||
const [showPassword, setShowPassword] = useState(false)
|
const [showPassword, setShowPassword] = useState(false)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
const updatePullOptions = useDebouncedCallback(
|
const updatePullOptions = useDebouncedCallback(
|
||||||
() => configurePullOptions(),
|
() => configurePullOptions(),
|
||||||
@ -102,7 +104,10 @@ const ProxySettings = ({ onBack }: { onBack: () => void }) => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="sticky top-0 z-10 flex h-12 items-center border-b border-[hsla(var(--app-border))] bg-[hsla(var(--app-bg))] px-4">
|
<div className="sticky top-0 z-10 flex h-12 items-center border-b border-[hsla(var(--app-border))] bg-[hsla(var(--app-bg))] px-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import {
|
|||||||
quickAskEnabledAtom,
|
quickAskEnabledAtom,
|
||||||
} from '@/helpers/atoms/AppConfig.atom'
|
} from '@/helpers/atoms/AppConfig.atom'
|
||||||
|
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
import { ThreadModalAction } from '@/helpers/atoms/Thread.atom'
|
import { ThreadModalAction } from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
import { modalActionThreadAtom } from '@/helpers/atoms/Thread.atom'
|
import { modalActionThreadAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
@ -38,6 +39,7 @@ const Advanced = ({ setSubdir }: { setSubdir: (subdir: string) => void }) => {
|
|||||||
const [experimentalEnabled, setExperimentalEnabled] = useAtom(
|
const [experimentalEnabled, setExperimentalEnabled] = useAtom(
|
||||||
experimentalFeatureEnabledAtom
|
experimentalFeatureEnabledAtom
|
||||||
)
|
)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
const [proxyEnabled, setProxyEnabled] = useAtom(proxyEnabledAtom)
|
const [proxyEnabled, setProxyEnabled] = useAtom(proxyEnabledAtom)
|
||||||
const quickAskEnabled = useAtomValue(quickAskEnabledAtom)
|
const quickAskEnabled = useAtomValue(quickAskEnabledAtom)
|
||||||
@ -94,7 +96,10 @@ const Advanced = ({ setSubdir }: { setSubdir: (subdir: string) => void }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full w-full px-4">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full px-4"
|
||||||
|
>
|
||||||
<div className="block w-full py-4">
|
<div className="block w-full py-4">
|
||||||
{/* Experimental */}
|
{/* Experimental */}
|
||||||
<div className="flex w-full flex-row items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none">
|
<div className="flex w-full flex-row items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none">
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import {
|
|||||||
chatWidthAtom,
|
chatWidthAtom,
|
||||||
reduceTransparentAtom,
|
reduceTransparentAtom,
|
||||||
selectedThemeIdAtom,
|
selectedThemeIdAtom,
|
||||||
|
showScrollBarAtom,
|
||||||
spellCheckAtom,
|
spellCheckAtom,
|
||||||
themeDataAtom,
|
themeDataAtom,
|
||||||
themesOptionsAtom,
|
themesOptionsAtom,
|
||||||
@ -29,6 +30,7 @@ export default function AppearanceOptions() {
|
|||||||
reduceTransparentAtom
|
reduceTransparentAtom
|
||||||
)
|
)
|
||||||
const [spellCheck, setSpellCheck] = useAtom(spellCheckAtom)
|
const [spellCheck, setSpellCheck] = useAtom(spellCheckAtom)
|
||||||
|
const [showScrollBar, setShowScrollBar] = useAtom(showScrollBarAtom)
|
||||||
const [chatWidth, setChatWidth] = useAtom(chatWidthAtom)
|
const [chatWidth, setChatWidth] = useAtom(chatWidthAtom)
|
||||||
|
|
||||||
const chatWidthOption = [
|
const chatWidthOption = [
|
||||||
@ -194,6 +196,22 @@ export default function AppearanceOptions() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row">
|
||||||
|
<div className="w-full space-y-1 lg:w-3/4">
|
||||||
|
<div className="flex gap-x-2">
|
||||||
|
<h6 className="font-semibold capitalize">Scrolling Bar</h6>
|
||||||
|
</div>
|
||||||
|
<p className=" font-medium leading-relaxed text-[hsla(var(--text-secondary))]">
|
||||||
|
Turn on to make scrolling bar visible across windows.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex-shrink-0">
|
||||||
|
<Switch
|
||||||
|
checked={showScrollBar}
|
||||||
|
onChange={(e) => setShowScrollBar(e.target.checked)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import React, { useState, useEffect, useRef } from 'react'
|
|||||||
|
|
||||||
import { Button, ScrollArea, Badge, Input } from '@janhq/joi'
|
import { Button, ScrollArea, Badge, Input } from '@janhq/joi'
|
||||||
|
|
||||||
|
import { useAtomValue } from 'jotai'
|
||||||
import { SearchIcon } from 'lucide-react'
|
import { SearchIcon } from 'lucide-react'
|
||||||
import { Marked, Renderer } from 'marked'
|
import { Marked, Renderer } from 'marked'
|
||||||
|
|
||||||
@ -12,12 +13,13 @@ import { formatExtensionsName } from '@/utils/converter'
|
|||||||
|
|
||||||
import { extensionManager } from '@/extension'
|
import { extensionManager } from '@/extension'
|
||||||
import Extension from '@/extension/Extension'
|
import Extension from '@/extension/Extension'
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
const ExtensionCatalog = () => {
|
const ExtensionCatalog = () => {
|
||||||
const [coreActiveExtensions, setCoreActiveExtensions] = useState<Extension[]>(
|
const [coreActiveExtensions, setCoreActiveExtensions] = useState<Extension[]>(
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
const [searchText, setSearchText] = useState('')
|
const [searchText, setSearchText] = useState('')
|
||||||
const [showLoading, setShowLoading] = useState(false)
|
const [showLoading, setShowLoading] = useState(false)
|
||||||
const fileInputRef = useRef<HTMLInputElement | null>(null)
|
const fileInputRef = useRef<HTMLInputElement | null>(null)
|
||||||
@ -103,7 +105,10 @@ const ExtensionCatalog = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
<div className="flex w-full flex-col items-start justify-between gap-y-2 p-4 sm:flex-row">
|
<div className="flex w-full flex-col items-start justify-between gap-y-2 p-4 sm:flex-row">
|
||||||
<div className="w-full sm:w-[300px]">
|
<div className="w-full sm:w-[300px]">
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
} from '@janhq/core'
|
} from '@janhq/core'
|
||||||
import { Button, ScrollArea, Badge, Select, Progress } from '@janhq/joi'
|
import { Button, ScrollArea, Badge, Select, Progress } from '@janhq/joi'
|
||||||
|
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom, useAtomValue } from 'jotai'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
import { useActiveModel } from '@/hooks/useActiveModel'
|
import { useActiveModel } from '@/hooks/useActiveModel'
|
||||||
@ -30,6 +30,7 @@ import ExtensionSetting from '../ExtensionSetting'
|
|||||||
import DeleteEngineVariant from './DeleteEngineVariant'
|
import DeleteEngineVariant from './DeleteEngineVariant'
|
||||||
|
|
||||||
import { LocalEngineDefaultVariantAtom } from '@/helpers/atoms/App.atom'
|
import { LocalEngineDefaultVariantAtom } from '@/helpers/atoms/App.atom'
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
const os = () => {
|
const os = () => {
|
||||||
switch (PLATFORM) {
|
switch (PLATFORM) {
|
||||||
case 'win32':
|
case 'win32':
|
||||||
@ -53,6 +54,7 @@ const LocalEngineSettings = ({ engine }: { engine: InferenceEngine }) => {
|
|||||||
defaultEngineVariant?.version as string,
|
defaultEngineVariant?.version as string,
|
||||||
os()
|
os()
|
||||||
)
|
)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
const [installingEngines, setInstallingEngines] = useState<
|
const [installingEngines, setInstallingEngines] = useState<
|
||||||
Map<string, number>
|
Map<string, number>
|
||||||
>(new Map())
|
>(new Map())
|
||||||
@ -169,7 +171,10 @@ const LocalEngineSettings = ({ engine }: { engine: InferenceEngine }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
<div className="block w-full px-4">
|
<div className="block w-full px-4">
|
||||||
<div className="mb-3 mt-4 border-b border-[hsla(var(--app-border))] pb-4">
|
<div className="mb-3 mt-4 border-b border-[hsla(var(--app-border))] pb-4">
|
||||||
<div className="flex w-full flex-col items-start justify-between sm:flex-row">
|
<div className="flex w-full flex-col items-start justify-between sm:flex-row">
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import {
|
|||||||
downloadedModelsAtom,
|
downloadedModelsAtom,
|
||||||
selectedModelAtom,
|
selectedModelAtom,
|
||||||
} from '@/helpers/atoms/Model.atom'
|
} from '@/helpers/atoms/Model.atom'
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
import { threadsAtom } from '@/helpers/atoms/Thread.atom'
|
import { threadsAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
const RemoteEngineSettings = ({
|
const RemoteEngineSettings = ({
|
||||||
@ -64,6 +65,7 @@ const RemoteEngineSettings = ({
|
|||||||
const customEngineLogo = getLogoEngine(name)
|
const customEngineLogo = getLogoEngine(name)
|
||||||
const threads = useAtomValue(threadsAtom)
|
const threads = useAtomValue(threadsAtom)
|
||||||
const { refreshingModels, refreshModels } = useRefreshModelList(name)
|
const { refreshingModels, refreshModels } = useRefreshModelList(name)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
const engine =
|
const engine =
|
||||||
engines &&
|
engines &&
|
||||||
@ -150,7 +152,10 @@ const RemoteEngineSettings = ({
|
|||||||
if (!engine) return null
|
if (!engine) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
<div className="block w-full px-4">
|
<div className="block w-full px-4">
|
||||||
<div className="mb-3 mt-4 border-b border-[hsla(var(--app-border))] pb-4">
|
<div className="mb-3 mt-4 border-b border-[hsla(var(--app-border))] pb-4">
|
||||||
<div className="flex w-full flex-col items-start justify-between sm:flex-row">
|
<div className="flex w-full flex-col items-start justify-between sm:flex-row">
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import React from 'react'
|
|||||||
import { InferenceEngine } from '@janhq/core'
|
import { InferenceEngine } from '@janhq/core'
|
||||||
import { ScrollArea } from '@janhq/joi'
|
import { ScrollArea } from '@janhq/joi'
|
||||||
|
|
||||||
|
import { useAtomValue } from 'jotai'
|
||||||
|
|
||||||
import { useGetEngines } from '@/hooks/useEngineManagement'
|
import { useGetEngines } from '@/hooks/useEngineManagement'
|
||||||
|
|
||||||
import { isLocalEngine } from '@/utils/modelEngine'
|
import { isLocalEngine } from '@/utils/modelEngine'
|
||||||
@ -11,11 +13,17 @@ import LocalEngineItems from './LocalEngineItem'
|
|||||||
import ModalAddRemoteEngine from './ModalAddRemoteEngine'
|
import ModalAddRemoteEngine from './ModalAddRemoteEngine'
|
||||||
import RemoteEngineItems from './RemoteEngineItem'
|
import RemoteEngineItems from './RemoteEngineItem'
|
||||||
|
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
const Engines = () => {
|
const Engines = () => {
|
||||||
const { engines } = useGetEngines()
|
const { engines } = useGetEngines()
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
<div className="block w-full px-4">
|
<div className="block w-full px-4">
|
||||||
<div className="mb-3 mt-4 pb-4">
|
<div className="mb-3 mt-4 pb-4">
|
||||||
<h6 className="text-xs text-[hsla(var(--text-secondary))]">
|
<h6 className="text-xs text-[hsla(var(--text-secondary))]">
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import { toGigabytes } from '@/utils/converter'
|
|||||||
|
|
||||||
import { utilizedMemory } from '@/utils/memory'
|
import { utilizedMemory } from '@/utils/memory'
|
||||||
|
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
import {
|
import {
|
||||||
cpuUsageAtom,
|
cpuUsageAtom,
|
||||||
ramUtilitizedAtom,
|
ramUtilitizedAtom,
|
||||||
@ -44,7 +45,7 @@ const Hardware = () => {
|
|||||||
const totalRam = useAtomValue(totalRamAtom)
|
const totalRam = useAtomValue(totalRamAtom)
|
||||||
const usedRam = useAtomValue(usedRamAtom)
|
const usedRam = useAtomValue(usedRamAtom)
|
||||||
const ramUtilitized = useAtomValue(ramUtilitizedAtom)
|
const ramUtilitized = useAtomValue(ramUtilitizedAtom)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
const [gpus, setGpus] = useAtom(gpusAtom)
|
const [gpus, setGpus] = useAtom(gpusAtom)
|
||||||
|
|
||||||
const [orderGpus, setOrderGpus] = useAtom(orderGpusAtom)
|
const [orderGpus, setOrderGpus] = useAtom(orderGpusAtom)
|
||||||
@ -133,7 +134,10 @@ const Hardware = () => {
|
|||||||
}, [hardware?.gpus, setGpus])
|
}, [hardware?.gpus, setGpus])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full w-full px-4">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full px-4"
|
||||||
|
>
|
||||||
<div className="block w-full py-4">
|
<div className="block w-full py-4">
|
||||||
{/* CPU */}
|
{/* CPU */}
|
||||||
<div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row">
|
<div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row">
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
import { ScrollArea, Badge } from '@janhq/joi'
|
import { ScrollArea, Badge } from '@janhq/joi'
|
||||||
|
import { useAtomValue } from 'jotai'
|
||||||
|
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
const availableHotkeys = [
|
const availableHotkeys = [
|
||||||
{
|
{
|
||||||
@ -42,8 +45,12 @@ const availableHotkeys = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const Hotkeys = () => {
|
const Hotkeys = () => {
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full w-full p-4">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full p-4"
|
||||||
|
>
|
||||||
<div className="mb-2 flex flex-col items-center justify-center gap-2">
|
<div className="mb-2 flex flex-col items-center justify-center gap-2">
|
||||||
<div className="hidden w-full gap-x-4 border-b border-[hsla(var(--app-border))] pb-2 sm:flex">
|
<div className="hidden w-full gap-x-4 border-b border-[hsla(var(--app-border))] pb-2 sm:flex">
|
||||||
<div className="w-1/2 pb-2">
|
<div className="w-1/2 pb-2">
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import {
|
|||||||
downloadedModelsAtom,
|
downloadedModelsAtom,
|
||||||
showEngineListModelAtom,
|
showEngineListModelAtom,
|
||||||
} from '@/helpers/atoms/Model.atom'
|
} from '@/helpers/atoms/Model.atom'
|
||||||
|
import { showScrollBarAtom } from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
const MyModels = () => {
|
const MyModels = () => {
|
||||||
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
||||||
@ -49,6 +50,7 @@ const MyModels = () => {
|
|||||||
const [showEngineListModel, setShowEngineListModel] = useAtom(
|
const [showEngineListModel, setShowEngineListModel] = useAtom(
|
||||||
showEngineListModelAtom
|
showEngineListModelAtom
|
||||||
)
|
)
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
const { engines } = useGetEngines()
|
const { engines } = useGetEngines()
|
||||||
|
|
||||||
@ -124,7 +126,10 @@ const MyModels = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...getRootProps()} className="h-full w-full">
|
<div {...getRootProps()} className="h-full w-full">
|
||||||
<ScrollArea className="h-full w-full">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
{isDragActive && (
|
{isDragActive && (
|
||||||
<div className="absolute z-50 mx-auto h-full w-full bg-[hsla(var(--app-bg))]/50 p-8 backdrop-blur-lg">
|
<div className="absolute z-50 mx-auto h-full w-full bg-[hsla(var(--app-bg))]/50 p-8 backdrop-blur-lg">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -10,7 +10,10 @@ import { toaster } from '@/containers/Toast'
|
|||||||
import { usePath } from '@/hooks/usePath'
|
import { usePath } from '@/hooks/usePath'
|
||||||
|
|
||||||
import { janDataFolderPathAtom } from '@/helpers/atoms/AppConfig.atom'
|
import { janDataFolderPathAtom } from '@/helpers/atoms/AppConfig.atom'
|
||||||
import { productAnalyticAtom } from '@/helpers/atoms/Setting.atom'
|
import {
|
||||||
|
productAnalyticAtom,
|
||||||
|
showScrollBarAtom,
|
||||||
|
} from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
const Privacy = () => {
|
const Privacy = () => {
|
||||||
/**
|
/**
|
||||||
@ -30,13 +33,16 @@ const Privacy = () => {
|
|||||||
type: 'success',
|
type: 'success',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
const janDataFolderPath = useAtomValue(janDataFolderPathAtom)
|
const janDataFolderPath = useAtomValue(janDataFolderPathAtom)
|
||||||
const { onRevealInFinder } = usePath()
|
const { onRevealInFinder } = usePath()
|
||||||
const [productAnalytic, setProductAnalytic] = useAtom(productAnalyticAtom)
|
const [productAnalytic, setProductAnalytic] = useAtom(productAnalyticAtom)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="h-full w-full px-4">
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
|
className="h-full w-full px-4"
|
||||||
|
>
|
||||||
<div className="mb-4 mt-8 rounded-xl bg-[hsla(var(--tertiary-bg))] px-4 py-2 text-[hsla(var(--text-secondary))]">
|
<div className="mb-4 mt-8 rounded-xl bg-[hsla(var(--tertiary-bg))] px-4 py-2 text-[hsla(var(--text-secondary))]">
|
||||||
<p>
|
<p>
|
||||||
We prioritize your control over your data. Learn more about our
|
We prioritize your control over your data. Learn more about our
|
||||||
|
|||||||
@ -43,7 +43,10 @@ import {
|
|||||||
configuredModelsAtom,
|
configuredModelsAtom,
|
||||||
getDownloadingModelAtom,
|
getDownloadingModelAtom,
|
||||||
} from '@/helpers/atoms/Model.atom'
|
} from '@/helpers/atoms/Model.atom'
|
||||||
import { selectedSettingAtom } from '@/helpers/atoms/Setting.atom'
|
import {
|
||||||
|
selectedSettingAtom,
|
||||||
|
showScrollBarAtom,
|
||||||
|
} from '@/helpers/atoms/Setting.atom'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isShowStarterScreen?: boolean
|
isShowStarterScreen?: boolean
|
||||||
@ -57,6 +60,7 @@ const OnDeviceStarterScreen = ({ isShowStarterScreen }: Props) => {
|
|||||||
const downloadStates = useAtomValue(modelDownloadStateAtom)
|
const downloadStates = useAtomValue(modelDownloadStateAtom)
|
||||||
const setSelectedSetting = useSetAtom(selectedSettingAtom)
|
const setSelectedSetting = useSetAtom(selectedSettingAtom)
|
||||||
const { engines } = useGetEngines()
|
const { engines } = useGetEngines()
|
||||||
|
const showScrollBar = useAtomValue(showScrollBarAtom)
|
||||||
|
|
||||||
const configuredModels = useAtomValue(configuredModelsAtom)
|
const configuredModels = useAtomValue(configuredModelsAtom)
|
||||||
const { sources } = useGetModelSources()
|
const { sources } = useGetModelSources()
|
||||||
@ -98,6 +102,7 @@ const OnDeviceStarterScreen = ({ isShowStarterScreen }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<CenterPanelContainer isShowStarterScreen={isShowStarterScreen}>
|
<CenterPanelContainer isShowStarterScreen={isShowStarterScreen}>
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
|
type={showScrollBar ? 'always' : 'scroll'}
|
||||||
className="flex h-full w-full items-center"
|
className="flex h-full w-full items-center"
|
||||||
data-testid="onboard-screen"
|
data-testid="onboard-screen"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
input[type='number'] {
|
input[type='number'] {
|
||||||
|
appearance: textfield;
|
||||||
-moz-appearance: textfield;
|
-moz-appearance: textfield;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,3 +43,22 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.show-scroll-bar {
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track,
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-clip: content-box;
|
||||||
|
border-radius: inherit;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: hsla(var(--scrollbar-tracker));
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: hsla(var(--scrollbar-thumb));
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user