chore: add functional use button when download complete
This commit is contained in:
parent
53f5729674
commit
1435cd3162
@ -125,7 +125,7 @@ export function DownloadManagement() {
|
|||||||
<div className="mt-2 flex items-center justify-between space-x-2">
|
<div className="mt-2 flex items-center justify-between space-x-2">
|
||||||
<Progress value={overallProgress * 100} />
|
<Progress value={overallProgress * 100} />
|
||||||
<span className="text-xs font-medium text-main-view-fg/80 shrink-0">
|
<span className="text-xs font-medium text-main-view-fg/80 shrink-0">
|
||||||
{overallProgress.toFixed(2)}%
|
{Math.round(overallProgress * 100)}%
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -175,7 +175,7 @@ export function DownloadManagement() {
|
|||||||
/>
|
/>
|
||||||
<p className="text-main-view-fg/60 text-xs">
|
<p className="text-main-view-fg/60 text-xs">
|
||||||
{`${renderGB(download.current)} / ${renderGB(download.total)}`}{' '}
|
{`${renderGB(download.current)} / ${renderGB(download.total)}`}{' '}
|
||||||
GB ({download.progress.toFixed(2)}%)
|
GB ({Math.round(download.progress * 100)}%)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { createFileRoute, Link } from '@tanstack/react-router'
|
import { createFileRoute, Link, useNavigate } from '@tanstack/react-router'
|
||||||
import { route } from '@/constants/routes'
|
import { route } from '@/constants/routes'
|
||||||
import { useModelSources } from '@/hooks/useModelSources'
|
import { useModelSources } from '@/hooks/useModelSources'
|
||||||
import { cn, fuzzySearch, toGigabytes } from '@/lib/utils'
|
import { cn, fuzzySearch, toGigabytes } from '@/lib/utils'
|
||||||
import { useState, useMemo, useEffect, ChangeEvent } from 'react'
|
import { useState, useMemo, useEffect, ChangeEvent, useCallback } from 'react'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { useModelProvider } from '@/hooks/useModelProvider'
|
||||||
import { Card, CardItem } from '@/containers/Card'
|
import { Card, CardItem } from '@/containers/Card'
|
||||||
import { RenderMarkdown } from '@/containers/RenderMarkdown'
|
import { RenderMarkdown } from '@/containers/RenderMarkdown'
|
||||||
import { extractModelName, extractDescription } from '@/lib/models'
|
import { extractModelName, extractDescription } from '@/lib/models'
|
||||||
@ -19,6 +20,15 @@ import { downloadModel } from '@/services/models'
|
|||||||
import { useDownloadStore } from '@/hooks/useDownloadStore'
|
import { useDownloadStore } from '@/hooks/useDownloadStore'
|
||||||
import { Progress } from '@/components/ui/progress'
|
import { Progress } from '@/components/ui/progress'
|
||||||
|
|
||||||
|
type ModelProps = {
|
||||||
|
model: {
|
||||||
|
id: string
|
||||||
|
models: {
|
||||||
|
id: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export const Route = createFileRoute(route.hub as any)({
|
export const Route = createFileRoute(route.hub as any)({
|
||||||
component: Hub,
|
component: Hub,
|
||||||
@ -93,14 +103,26 @@ function Hub() {
|
|||||||
[downloads]
|
[downloads]
|
||||||
)
|
)
|
||||||
|
|
||||||
interface ModelProps {
|
const { getProviderByName } = useModelProvider()
|
||||||
model: {
|
const llamaProvider = getProviderByName('llama.cpp')
|
||||||
id: string
|
|
||||||
models: {
|
const navigate = useNavigate()
|
||||||
id: string
|
|
||||||
}[]
|
const handleUseModel = useCallback(
|
||||||
}
|
(modelId: string) => {
|
||||||
}
|
navigate({
|
||||||
|
to: route.home,
|
||||||
|
params: {},
|
||||||
|
search: {
|
||||||
|
model: {
|
||||||
|
id: modelId,
|
||||||
|
provider: 'llama.cpp',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
[navigate]
|
||||||
|
)
|
||||||
|
|
||||||
const DownloadButtonPlaceholder = useMemo(() => {
|
const DownloadButtonPlaceholder = useMemo(() => {
|
||||||
return ({ model }: ModelProps) => {
|
return ({ model }: ModelProps) => {
|
||||||
@ -108,6 +130,9 @@ function Hub() {
|
|||||||
const isDownloading = downloadProcesses.some((e) => e.id === modelId)
|
const isDownloading = downloadProcesses.some((e) => e.id === modelId)
|
||||||
const downloadProgress =
|
const downloadProgress =
|
||||||
downloadProcesses.find((e) => e.id === modelId)?.progress || 0
|
downloadProcesses.find((e) => e.id === modelId)?.progress || 0
|
||||||
|
const isDownloaded = llamaProvider?.models.some(
|
||||||
|
(m: { id: string }) => m.id === modelId
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -118,13 +143,19 @@ function Hub() {
|
|||||||
{Math.round(downloadProgress * 100)}%
|
{Math.round(downloadProgress * 100)}%
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
) : isDownloaded ? (
|
||||||
|
<Button size="sm" onClick={() => handleUseModel(modelId)}>
|
||||||
|
Use
|
||||||
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button onClick={() => downloadModel(modelId)}>Download</Button>
|
<Button size="sm" onClick={() => downloadModel(modelId)}>
|
||||||
|
Download
|
||||||
|
</Button>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, [downloadProcesses])
|
}, [downloadProcesses, llamaProvider?.models, handleUseModel])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full w-full">
|
<div className="flex h-full w-full">
|
||||||
@ -282,20 +313,50 @@ function Hub() {
|
|||||||
downloadProcesses.find(
|
downloadProcesses.find(
|
||||||
(e) => e.id === variant.id
|
(e) => e.id === variant.id
|
||||||
)?.progress || 0
|
)?.progress || 0
|
||||||
|
const isDownloaded =
|
||||||
|
llamaProvider?.models.some(
|
||||||
|
(m: { id: string }) =>
|
||||||
|
m.id === variant.id
|
||||||
|
)
|
||||||
|
|
||||||
return isDownloading ? (
|
if (isDownloading) {
|
||||||
<>
|
return (
|
||||||
<div className="flex items-center gap-2 w-20">
|
<>
|
||||||
<Progress
|
<div className="flex items-center gap-2 w-20">
|
||||||
value={downloadProgress * 100}
|
<Progress
|
||||||
/>
|
value={downloadProgress * 100}
|
||||||
<span className="text-xs text-center text-main-view-fg/70">
|
/>
|
||||||
{Math.round(downloadProgress * 100)}
|
<span className="text-xs text-center text-main-view-fg/70">
|
||||||
%
|
{Math.round(
|
||||||
</span>
|
downloadProgress * 100
|
||||||
|
)}
|
||||||
|
%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDownloaded) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex items-center justify-center rounded bg-main-view-fg/10"
|
||||||
|
title="Use this model"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
size="sm"
|
||||||
|
onClick={() =>
|
||||||
|
handleUseModel(variant.id)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Use
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
)
|
||||||
) : (
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<div
|
<div
|
||||||
className="size-6 cursor-pointer flex items-center justify-center rounded hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out"
|
className="size-6 cursor-pointer flex items-center justify-center rounded hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out"
|
||||||
title="Download model"
|
title="Download model"
|
||||||
|
|||||||
@ -1,20 +1,32 @@
|
|||||||
import { createFileRoute } from '@tanstack/react-router'
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { route } from '@/constants/routes'
|
import { createFileRoute, useSearch } from '@tanstack/react-router'
|
||||||
import ChatInput from '@/containers/ChatInput'
|
import ChatInput from '@/containers/ChatInput'
|
||||||
import HeaderPage from '@/containers/HeaderPage'
|
import HeaderPage from '@/containers/HeaderPage'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import DropdownModelProvider from '@/containers/DropdownModelProvider'
|
import DropdownModelProvider from '@/containers/DropdownModelProvider'
|
||||||
import { useModelProvider } from '@/hooks/useModelProvider'
|
import { useModelProvider } from '@/hooks/useModelProvider'
|
||||||
import SetupScreen from '@/containers/SetupScreen'
|
import SetupScreen from '@/containers/SetupScreen'
|
||||||
|
import { route } from '@/constants/routes'
|
||||||
|
|
||||||
|
type SearchParams = {
|
||||||
|
model?: {
|
||||||
|
id: string
|
||||||
|
provider: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
export const Route = createFileRoute(route.home as any)({
|
export const Route = createFileRoute(route.home as any)({
|
||||||
component: Index,
|
component: Index,
|
||||||
|
validateSearch: (search: Record<string, unknown>): SearchParams => ({
|
||||||
|
model: search.model as SearchParams['model'],
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
function Index() {
|
function Index() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { providers } = useModelProvider()
|
const { providers } = useModelProvider()
|
||||||
|
const search = useSearch({ from: route.home as any })
|
||||||
|
const selectedModel = search.model
|
||||||
|
|
||||||
// Conditional to check if there are any valid providers
|
// Conditional to check if there are any valid providers
|
||||||
// required min 1 api_key or 1 model in llama.cpp
|
// required min 1 api_key or 1 model in llama.cpp
|
||||||
@ -31,7 +43,7 @@ function Index() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex h-full flex-col flex-justify-center">
|
<div className="flex h-full flex-col flex-justify-center">
|
||||||
<HeaderPage>
|
<HeaderPage>
|
||||||
<DropdownModelProvider />
|
<DropdownModelProvider model={selectedModel} />
|
||||||
</HeaderPage>
|
</HeaderPage>
|
||||||
<div className="h-full px-8 overflow-y-auto flex flex-col gap-2 justify-center">
|
<div className="h-full px-8 overflow-y-auto flex flex-col gap-2 justify-center">
|
||||||
<div className="w-4/6 mx-auto">
|
<div className="w-4/6 mx-auto">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user