diff --git a/extensions/yarn.lock b/extensions/yarn.lock
index 586a57dec..8a542694a 100644
--- a/extensions/yarn.lock
+++ b/extensions/yarn.lock
@@ -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
diff --git a/joi/src/core/ScrollArea/styles.scss b/joi/src/core/ScrollArea/styles.scss
index fd8a43e53..99ee7de87 100644
--- a/joi/src/core/ScrollArea/styles.scss
+++ b/joi/src/core/ScrollArea/styles.scss
@@ -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;
-}
diff --git a/web/containers/Layout/index.tsx b/web/containers/Layout/index.tsx
index d29647029..024ddfca4 100644
--- a/web/containers/Layout/index.tsx
+++ b/web/containers/Layout/index.tsx
@@ -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 = () => {
)}
>
-
+
diff --git a/web/containers/LeftPanelContainer/index.tsx b/web/containers/LeftPanelContainer/index.tsx
index 523af5ddb..ac4b8893f 100644
--- a/web/containers/LeftPanelContainer/index.tsx
+++ b/web/containers/LeftPanelContainer/index.tsx
@@ -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()}
>
-
+
{children}
{showLeftPanel && !matches && (
diff --git a/web/containers/ListContainer/index.tsx b/web/containers/ListContainer/index.tsx
index 44e5b2527..3184c171b 100644
--- a/web/containers/ListContainer/index.tsx
+++ b/web/containers/ListContainer/index.tsx
@@ -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 (
-
+
{engineList
.filter((e) => e.type === searchFilter)
.filter(
diff --git a/web/containers/RightPanelContainer/index.tsx b/web/containers/RightPanelContainer/index.tsx
index 7443ab61a..6d474d557 100644
--- a/web/containers/RightPanelContainer/index.tsx
+++ b/web/containers/RightPanelContainer/index.tsx
@@ -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()}
>
-
+
{children}
{showRightPanel && !matches && (
diff --git a/web/containers/ServerLogs/index.tsx b/web/containers/ServerLogs/index.tsx
index b89a4c237..c9074808c 100644
--- a/web/containers/ServerLogs/index.tsx
+++ b/web/containers/ServerLogs/index.tsx
@@ -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(null)
const prevScrollTop = useRef(0)
const isUserManuallyScrollingUp = useRef(false)
+ const showScrollBar = useAtomValue(showScrollBarAtom)
const updateLogs = useCallback(
() =>
@@ -136,6 +138,7 @@ const ServerLogs = (props: ServerLogsProps) => {
)}
([])
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(
undefined,
{ getOnInit: true }
)
+export const showScrollBarAtom = atomWithStorage(
+ SCROLL_BAR,
+ false,
+ undefined,
+ { getOnInit: true }
+)
export const productAnalyticAtom = atomWithStorage(
PRODUCT_ANALYTIC,
false,
diff --git a/web/screens/Hub/ModelPage/index.tsx b/web/screens/Hub/ModelPage/index.tsx
index e0288c687..8bded0a4f 100644
--- a/web/screens/Hub/ModelPage/index.tsx
+++ b/web/screens/Hub/ModelPage/index.tsx
@@ -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 (
-
+
diff --git a/web/screens/Hub/index.tsx b/web/screens/Hub/index.tsx
index 56d4b7836..15f2b2bbe 100644
--- a/web/screens/Hub/index.tsx
+++ b/web/screens/Hub/index.tsx
@@ -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(
undefined
)
+ const showScrollBar = useAtomValue(showScrollBarAtom)
const [modelDetail, setModelDetail] = useAtom(modelDetailAtom)
const setImportModelStage = useSetAtom(setImportModelStageAtom)
const dropdownRef = useRef(null)
@@ -260,6 +262,7 @@ const HubScreen = () => {
>
{!selectedModel && (
@@ -311,7 +314,10 @@ const HubScreen = () => {
/>
{hubBannerOption === 'gallery' && (
-
+
{Array.from({ length: 30 }, (_, i) => i + 1).map(
(e) => {
return (
diff --git a/web/screens/Settings/Advanced/ProxySettings/index.tsx b/web/screens/Settings/Advanced/ProxySettings/index.tsx
index 446738ea2..7d5723ca8 100644
--- a/web/screens/Settings/Advanced/ProxySettings/index.tsx
+++ b/web/screens/Settings/Advanced/ProxySettings/index.tsx
@@ -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 (
-
+
{/* Header */}
diff --git a/web/screens/Settings/Advanced/index.tsx b/web/screens/Settings/Advanced/index.tsx
index cb10a1778..9cb940171 100644
--- a/web/screens/Settings/Advanced/index.tsx
+++ b/web/screens/Settings/Advanced/index.tsx
@@ -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 (
-
+
{/* Experimental */}
diff --git a/web/screens/Settings/Appearance/index.tsx b/web/screens/Settings/Appearance/index.tsx
index d7008552e..873ad9e13 100644
--- a/web/screens/Settings/Appearance/index.tsx
+++ b/web/screens/Settings/Appearance/index.tsx
@@ -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() {
/>
+
+
+
+
Scrolling Bar
+
+
+ Turn on to make scrolling bar visible across windows.
+
+
+
+ setShowScrollBar(e.target.checked)}
+ />
+
+
)
}
diff --git a/web/screens/Settings/CoreExtensions/index.tsx b/web/screens/Settings/CoreExtensions/index.tsx
index b1d11db9a..030df24c2 100644
--- a/web/screens/Settings/CoreExtensions/index.tsx
+++ b/web/screens/Settings/CoreExtensions/index.tsx
@@ -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
(
[]
)
-
+ const showScrollBar = useAtomValue(showScrollBarAtom)
const [searchText, setSearchText] = useState('')
const [showLoading, setShowLoading] = useState(false)
const fileInputRef = useRef(null)
@@ -103,7 +105,10 @@ const ExtensionCatalog = () => {
return (
<>
-
+
{
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
>(new Map())
@@ -169,7 +171,10 @@ const LocalEngineSettings = ({ engine }: { engine: InferenceEngine }) => {
}
return (
-
+
diff --git a/web/screens/Settings/Engines/RemoteEngineSettings.tsx b/web/screens/Settings/Engines/RemoteEngineSettings.tsx
index f9197b157..991b5889e 100644
--- a/web/screens/Settings/Engines/RemoteEngineSettings.tsx
+++ b/web/screens/Settings/Engines/RemoteEngineSettings.tsx
@@ -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 (
-
+
diff --git a/web/screens/Settings/Engines/index.tsx b/web/screens/Settings/Engines/index.tsx
index ded8b5a90..1375d4d29 100644
--- a/web/screens/Settings/Engines/index.tsx
+++ b/web/screens/Settings/Engines/index.tsx
@@ -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 (
-
+
diff --git a/web/screens/Settings/Hardware/index.tsx b/web/screens/Settings/Hardware/index.tsx
index dbc4354d1..e0c25971b 100644
--- a/web/screens/Settings/Hardware/index.tsx
+++ b/web/screens/Settings/Hardware/index.tsx
@@ -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 (
-
+
{/* CPU */}
diff --git a/web/screens/Settings/Hotkeys/index.tsx b/web/screens/Settings/Hotkeys/index.tsx
index 7e18c9c34..363001aee 100644
--- a/web/screens/Settings/Hotkeys/index.tsx
+++ b/web/screens/Settings/Hotkeys/index.tsx
@@ -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 (
-
+
diff --git a/web/screens/Settings/MyModels/index.tsx b/web/screens/Settings/MyModels/index.tsx
index 0254be6d7..0f70e1950 100644
--- a/web/screens/Settings/MyModels/index.tsx
+++ b/web/screens/Settings/MyModels/index.tsx
@@ -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 (
-
+
{isDragActive && (
{
/**
@@ -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 (
-
+
We prioritize your control over your data. Learn more about our
diff --git a/web/screens/Thread/ThreadCenterPanel/ChatBody/OnDeviceStarterScreen/index.tsx b/web/screens/Thread/ThreadCenterPanel/ChatBody/OnDeviceStarterScreen/index.tsx
index 20a7216bc..25875dc2a 100644
--- a/web/screens/Thread/ThreadCenterPanel/ChatBody/OnDeviceStarterScreen/index.tsx
+++ b/web/screens/Thread/ThreadCenterPanel/ChatBody/OnDeviceStarterScreen/index.tsx
@@ -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 (
diff --git a/web/styles/base/global.scss b/web/styles/base/global.scss
index 965819d72..8aad051b2 100644
--- a/web/styles/base/global.scss
+++ b/web/styles/base/global.scss
@@ -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;
+ }
+}