import React, { FC, useEffect, useState } from 'react'; import { Button, Checkbox, createTableColumn, DataGrid, DataGridBody, DataGridCell, DataGridHeader, DataGridHeaderCell, DataGridRow, TableCellLayout, TableColumnDefinition, Text, Textarea } from '@fluentui/react-components'; import { ToolTipButton } from '../components/ToolTipButton'; import { ArrowClockwise20Regular, ArrowDownload20Regular, Folder20Regular, Open20Regular } from '@fluentui/react-icons'; import { observer } from 'mobx-react-lite'; import commonStore from '../stores/commonStore'; import { BrowserOpenURL } from '../../wailsjs/runtime'; import { AddToDownloadList, OpenFileFolder } from '../../wailsjs/go/backend_golang/App'; import { Page } from '../components/Page'; import { bytesToGb, getHfDownloadUrl, refreshModels, saveConfigs, toastWithButton } from '../utils'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router'; import { ModelSourceItem } from '../types/models'; const columns: TableColumnDefinition[] = [ createTableColumn({ columnId: 'file', compare: (a, b) => { return a.name.localeCompare(b.name); }, renderHeaderCell: () => { const { t } = useTranslation(); return t('File'); }, renderCell: (item) => { return ( {item.name} ); } }), createTableColumn({ columnId: 'desc', compare: (a, b) => { const lang: string = commonStore.settings.language; if (a.desc && b.desc) { if (lang in a.desc && lang in b.desc && a.desc[lang] && b.desc[lang]) return b.desc[lang]!.localeCompare(a.desc[lang]!); else if ('en' in a.desc && 'en' in b.desc && a.desc['en'] && b.desc['en']) return b.desc['en']!.localeCompare(a.desc['en']!); } return 0; }, renderHeaderCell: () => { const { t } = useTranslation(); return t('Desc'); }, renderCell: (item) => { const lang: string = commonStore.settings.language; return ( {item.desc && (lang in item.desc ? item.desc[lang] : ('en' in item.desc && item.desc['en']))} ); } }), createTableColumn({ columnId: 'size', compare: (a, b) => { return a.size - b.size; }, renderHeaderCell: () => { const { t } = useTranslation(); return t('Size'); }, renderCell: (item) => { return ( {bytesToGb(item.size) + 'GB'} ); } }), createTableColumn({ columnId: 'lastUpdated', compare: (a, b) => { if (!a.lastUpdatedMs) a.lastUpdatedMs = Date.parse(a.lastUpdated); if (!b.lastUpdatedMs) b.lastUpdatedMs = Date.parse(b.lastUpdated); return b.lastUpdatedMs - a.lastUpdatedMs; }, renderHeaderCell: () => { const { t } = useTranslation(); return t('Last updated'); }, renderCell: (item) => { return new Date(item.lastUpdated).toLocaleString(); } }), createTableColumn({ columnId: 'actions', compare: (a, b) => { return a.isComplete ? -1 : 1; }, renderHeaderCell: () => { const { t } = useTranslation(); return t('Actions'); }, renderCell: (item) => { const { t } = useTranslation(); const navigate = useNavigate(); return (
{ item.isComplete && } onClick={() => { OpenFileFolder(`${commonStore.settings.customModelsPath}/${item.name}`); }} /> } {item.downloadUrl && !item.isComplete && } onClick={() => { toastWithButton(`${t('Downloading')} ${item.name}`, t('Check'), () => { navigate({ pathname: '/downloads' }); }, { autoClose: 3000 }); AddToDownloadList(`${commonStore.settings.customModelsPath}/${item.name}`, getHfDownloadUrl(item.downloadUrl!)); }} />} {item.url && } onClick={() => { BrowserOpenURL(item.url!); }} />}
); } }) ]; const getTags = () => { return Array.from(new Set( ['Recommended', 'Official', ...commonStore.modelSourceList.map(item => item.tags || []).flat() .filter(i => !i.includes('Other') && !i.includes('Local')) , 'Other', 'Local'])); }; const getCurrentModelList = () => { if (commonStore.activeModelListTags.length === 0) return commonStore.modelSourceList; else return commonStore.modelSourceList.filter(item => commonStore.activeModelListTags.some(tag => item.tags?.includes(tag))); }; const Models: FC = observer(() => { const { t } = useTranslation(); const [tags, setTags] = useState>(getTags()); const [modelSourceList, setModelSourceList] = useState(getCurrentModelList()); useEffect(() => { setTags(getTags()); }, [commonStore.modelSourceList]); useEffect(() => { setModelSourceList(getCurrentModelList()); }, [commonStore.modelSourceList, commonStore.activeModelListTags]); return (
{t('Model Source Manifest List')}
{commonStore.settings.language === 'zh' && { commonStore.setSettings({ useHfMirror: data.checked as boolean }); }} />} } onClick={() => { refreshModels(false); saveConfigs(); }} />
{t('Provide JSON file URLs for the models manifest. Separate URLs with semicolons. The "models" field in JSON files will be parsed into the following table.')}