Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions web-app/src/routes/hub/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useVirtualizer } from '@tanstack/react-virtual'
import { createFileRoute, useNavigate, useSearch } from '@tanstack/react-router'
import { route } from '@/constants/routes'
import { useModelSources } from '@/hooks/useModelSources'
import { cn } from '@/lib/utils'
import {

Check warning on line 7 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

2-7 lines are not covered with tests
useState,
useMemo,
useEffect,
Expand All @@ -12,48 +12,48 @@
useCallback,
useRef,
} from 'react'
import { Button } from '@/components/ui/button'
import { useModelProvider } from '@/hooks/useModelProvider'
import { Card, CardItem } from '@/containers/Card'
import { RenderMarkdown } from '@/containers/RenderMarkdown'
import { extractModelName, extractDescription } from '@/lib/models'
import {

Check warning on line 20 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

15-20 lines are not covered with tests
IconDownload,
IconFileCode,
IconEye,
IconSearch,
IconTool,
} from '@tabler/icons-react'
import { Switch } from '@/components/ui/switch'
import {

Check warning on line 28 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

27-28 lines are not covered with tests
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { ModelInfoHoverCard } from '@/containers/ModelInfoHoverCard'
import Joyride, { CallBackProps, STATUS } from 'react-joyride'
import { CustomTooltipJoyRide } from '@/containers/CustomeTooltipJoyRide'
import {

Check warning on line 37 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

34-37 lines are not covered with tests
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import {

Check warning on line 43 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

43 line is not covered with tests
CatalogModel,
pullModelWithMetadata,
fetchHuggingFaceRepo,
convertHfRepoToCatalogModel,
isModelSupported,
} from '@/services/models'
import { useDownloadStore } from '@/hooks/useDownloadStore'
import { Progress } from '@/components/ui/progress'
import HeaderPage from '@/containers/HeaderPage'
import { Loader } from 'lucide-react'
import { useTranslation } from '@/i18n/react-i18next-compat'
import Fuse from 'fuse.js'
import { useGeneralSetting } from '@/hooks/useGeneralSetting'

Check warning on line 56 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

50-56 lines are not covered with tests

type ModelProps = {
model: CatalogModel
Expand All @@ -61,27 +61,27 @@
type SearchParams = {
repo: string
}
const defaultModelQuantizations = ['iq4_xs', 'q4_k_m']

Check warning on line 64 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

64 line is not covered with tests

export const Route = createFileRoute(route.hub.index as any)({
component: Hub,
validateSearch: (search: Record<string, unknown>): SearchParams => ({
repo: search.repo as SearchParams['repo'],
}),
})

Check warning on line 71 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

66-71 lines are not covered with tests

function Hub() {
const parentRef = useRef(null)
const { huggingfaceToken } = useGeneralSetting()

Check warning on line 75 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

73-75 lines are not covered with tests

const { t } = useTranslation()
const sortOptions = [
{ value: 'newest', name: t('hub:sortNewest') },
{ value: 'most-downloaded', name: t('hub:sortMostDownloaded') },
]
const searchOptions = useMemo(() => {
return {
includeScore: true,

Check warning on line 84 in web-app/src/routes/hub/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

77-84 lines are not covered with tests
// Search in `author` and in `tags` array
keys: ['model_name', 'quants.model_id'],
}
Expand Down Expand Up @@ -205,7 +205,8 @@

if (
e.target.value.length &&
(e.target.value.includes('/') || e.target.value.startsWith('http'))
(e.target.value.includes('/') || e.target.value.startsWith('http')) &&
!showOnlyDownloaded
) {
setIsSearching(true)

Expand All @@ -222,7 +223,8 @@
!sources.some(
(s) =>
catalogModel.model_name.trim().split('/').pop() ===
s.model_name.trim()
s.model_name.trim() &&
catalogModel.developer.trim() === s.developer?.trim()
)
) {
setHuggingFaceRepo(catalogModel)
Expand Down Expand Up @@ -508,7 +510,46 @@
<div className="flex items-center gap-2">
<Switch
checked={showOnlyDownloaded}
onCheckedChange={setShowOnlyDownloaded}
onCheckedChange={(checked) => {
setShowOnlyDownloaded(checked)
if (checked) {
setHuggingFaceRepo(null)
} else if (
searchValue.length &&
(searchValue.includes('/') || searchValue.startsWith('http'))
) {
// Re-trigger HuggingFace search when switching back to "All models"
setIsSearching(true)
if (addModelSourceTimeoutRef.current) {
clearTimeout(addModelSourceTimeoutRef.current)
}
addModelSourceTimeoutRef.current = setTimeout(async () => {
try {
const repoInfo = await fetchHuggingFaceRepo(
searchValue,
huggingfaceToken
)
if (repoInfo) {
const catalogModel = convertHfRepoToCatalogModel(repoInfo)
if (
!sources.some(
(s) =>
catalogModel.model_name.trim().split('/').pop() ===
s.model_name.trim() &&
catalogModel.developer.trim() === s.developer?.trim()
)
) {
setHuggingFaceRepo(catalogModel)
}
}
} catch (error) {
console.error('Error fetching repository info:', error)
} finally {
setIsSearching(false)
}
}, 500)
}
}}
/>
<span className="text-xs text-main-view-fg/70 font-medium whitespace-nowrap">
{t('hub:downloaded')}
Expand Down
Loading