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