import React, { FC } from 'react'; import { 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 manifest from '../../../manifest.json'; import { Page } from '../components/Page'; import { bytesToGb, refreshModels, saveConfigs, toastWithButton } from '../utils'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router'; export type ModelSourceItem = { name: string; size: number; lastUpdated: string; desc?: { [lang: string]: string; }; SHA256?: string; url?: string; downloadUrl?: string; isLocal?: boolean; lastUpdatedMs?: number; }; 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) return b.desc[lang].localeCompare(a.desc[lang]); else if ('en' in a.desc && 'en' in b.desc) 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.isLocal ? -1 : 1; }, renderHeaderCell: () => { const { t } = useTranslation(); return t('Actions'); }, renderCell: (item) => { const { t } = useTranslation(); const navigate = useNavigate(); return (
{ item.isLocal && } onClick={() => { OpenFileFolder(`./${manifest.localModelDir}/${item.name}`); }} /> } {item.downloadUrl && !item.isLocal && } onClick={() => { toastWithButton(`${t('Downloading')} ${item.name}`, t('Check'), () => { navigate({ pathname: '/downloads' }); }, { autoClose: 3000 }); AddToDownloadList(`./${manifest.localModelDir}/${item.name}`, item.downloadUrl!); }} />} {item.url && } onClick={() => { BrowserOpenURL(item.url!); }} />}
); } }) ]; export const Models: FC = observer(() => { const { t } = useTranslation(); return (
{t('Model Source Manifest List')} } 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.')}