* feat: desktop revamp * feat: refactor system monitor * fix linter CI * remove unused import component * added responsive and resizeable component * responsive and resizeable local server page * finalize responsive and resizeable component * fix scroll custom ui * remove react scroll to bottom from modal troubleshoot * fix modal troubleshoot ui * fix setting gpu list * text area custom scroll bar * fix padding message input * cleanup classname * update inference engine model dropdown * update loader style * update quick ask ui * prepare theme provider * update dark theme * remove update hotkey list model and navigation * fix: cleanup hardcode classname * fix: update feedback * Set native theme electron * update destop ui revamp from feedback * update button icon component insider icon chat input message * update model dropdown ui * update tranaparent baclground * update logo model provider * fix: set background material acrylic support to blur background windows * fix: update tranparent left and right panel * fix: linter CI * update app using frameless window * styling custom style minimize, maximize and close app * temporary hidden maximize window * fix: responsive left and right panel * fix: enable click outside when leftpanel responsive * fix: remove unused import * update transparent variable css windows * fix: ui import model * feat: Support Theme system (#2946) * feat: update support theme system * update select component * feat: add theme folder in root project * fix: padding left and right center panel * fix: update padding left and right * chore: migrate themes * fix: rmdirsync error * chore: update gitignore * fix: cp recursive * fix: files electron package json * fix: migration * fix: update fgit ignore --------- Co-authored-by: Louis <louis@jan.ai> * fix: update feedback missing state when refrash app * fix: error test CI * chore: refactor useLoadThemes * chore: cleanup unused vars * fix: revert back menubar windows * fix minor ui * fix: minor ui --------- Co-authored-by: Louis <louis@jan.ai>
112 lines
3.3 KiB
TypeScript
112 lines
3.3 KiB
TypeScript
import { useCallback, useState } from 'react'
|
|
|
|
import Image from 'next/image'
|
|
|
|
import { ScrollArea, Button, Select } from '@janhq/joi'
|
|
|
|
import { useAtomValue, useSetAtom } from 'jotai'
|
|
import { UploadIcon } from 'lucide-react'
|
|
|
|
import CenterPanelContainer from '@/containers/CenterPanelContainer'
|
|
import ModelSearch from '@/containers/ModelSearch'
|
|
|
|
import { setImportModelStageAtom } from '@/hooks/useImportModel'
|
|
|
|
import ModelList from '@/screens/Hub/ModelList'
|
|
|
|
import {
|
|
configuredModelsAtom,
|
|
downloadedModelsAtom,
|
|
} from '@/helpers/atoms/Model.atom'
|
|
|
|
const sortMenus = [
|
|
{
|
|
name: 'All Models',
|
|
value: 'all-models',
|
|
},
|
|
{
|
|
name: 'Featured',
|
|
value: 'featured',
|
|
},
|
|
{
|
|
name: 'Downloaded',
|
|
value: 'downloaded',
|
|
},
|
|
]
|
|
|
|
const HubScreen = () => {
|
|
const configuredModels = useAtomValue(configuredModelsAtom)
|
|
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
|
const [searchValue, setsearchValue] = useState('')
|
|
const [sortSelected, setSortSelected] = useState('all-models')
|
|
|
|
const setImportModelStage = useSetAtom(setImportModelStageAtom)
|
|
|
|
const filteredModels = configuredModels.filter((x) => {
|
|
if (sortSelected === 'downloaded') {
|
|
return (
|
|
x.name.toLowerCase().includes(searchValue.toLowerCase()) &&
|
|
downloadedModels.some((y) => y.id === x.id)
|
|
)
|
|
} else if (sortSelected === 'featured') {
|
|
return (
|
|
x.name.toLowerCase().includes(searchValue.toLowerCase()) &&
|
|
x.metadata.tags.includes('Featured')
|
|
)
|
|
} else {
|
|
return x.name.toLowerCase().includes(searchValue.toLowerCase())
|
|
}
|
|
})
|
|
|
|
const onImportModelClick = useCallback(() => {
|
|
setImportModelStage('SELECTING_MODEL')
|
|
}, [setImportModelStage])
|
|
|
|
const onSearchUpdate = useCallback((input: string) => {
|
|
setsearchValue(input)
|
|
}, [])
|
|
|
|
return (
|
|
<CenterPanelContainer>
|
|
<ScrollArea data-testid="hub-container-test-id" className="h-full w-full">
|
|
<div className="relative h-40 p-4 sm:h-auto">
|
|
<Image
|
|
src="./images/hub-banner.png"
|
|
alt="Hub Banner"
|
|
width={800}
|
|
height={800}
|
|
className="h-full w-full rounded-lg object-cover"
|
|
/>
|
|
<div className="absolute left-1/2 top-1/2 mx-auto w-4/5 -translate-x-1/2 -translate-y-1/2 rounded-xl bg-[hsla(var(--app-bg))] p-4 sm:w-1/2">
|
|
<div className="flex flex-col items-center justify-between gap-2 sm:flex-row">
|
|
<div className="w-full">
|
|
<ModelSearch onSearchLocal={onSearchUpdate} />
|
|
</div>
|
|
<div className="flex-shrink-0">
|
|
<Button onClick={onImportModelClick}>
|
|
<UploadIcon size={16} className="mr-2" />
|
|
<span>Import Model</span>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="p-4 py-0 sm:px-16">
|
|
<div className="mb-4 flex w-full justify-end">
|
|
<Select
|
|
value={sortSelected}
|
|
onValueChange={(value) => {
|
|
setSortSelected(value)
|
|
}}
|
|
options={sortMenus}
|
|
/>
|
|
</div>
|
|
<ModelList models={filteredModels} />
|
|
</div>
|
|
</ScrollArea>
|
|
</CenterPanelContainer>
|
|
)
|
|
}
|
|
|
|
export default HubScreen
|