2023-05-13 12:15:18 +00:00
import React , { FC } from 'react' ;
2023-05-06 12:17:39 +00:00
import {
createTableColumn ,
DataGrid ,
DataGridBody ,
DataGridCell ,
DataGridHeader ,
DataGridHeaderCell ,
DataGridRow ,
TableCellLayout ,
TableColumnDefinition ,
Text ,
Textarea
} from '@fluentui/react-components' ;
2023-05-07 13:27:13 +00:00
import { ToolTipButton } from '../components/ToolTipButton' ;
2023-05-13 15:36:30 +00:00
import { ArrowClockwise20Regular , ArrowDownload20Regular , Folder20Regular , Open20Regular } from '@fluentui/react-icons' ;
2023-05-13 12:15:18 +00:00
import { observer } from 'mobx-react-lite' ;
2023-05-20 08:07:08 +00:00
import commonStore from '../stores/commonStore' ;
2023-05-13 12:15:18 +00:00
import { BrowserOpenURL } from '../../wailsjs/runtime' ;
2023-05-20 05:00:08 +00:00
import { AddToDownloadList , OpenFileFolder } from '../../wailsjs/go/backend_golang/App' ;
2023-05-13 15:36:30 +00:00
import manifest from '../../../manifest.json' ;
2023-05-15 13:55:57 +00:00
import { Page } from '../components/Page' ;
2023-05-20 06:53:52 +00:00
import { bytesToGb , refreshModels , saveConfigs , toastWithButton } from '../utils' ;
2023-05-18 12:48:53 +00:00
import { useTranslation } from 'react-i18next' ;
2023-05-20 06:53:52 +00:00
import { useNavigate } from 'react-router' ;
2023-05-06 12:17:39 +00:00
2023-05-20 08:07:08 +00:00
export type ModelSourceItem = {
name : string ;
size : number ;
lastUpdated : string ;
desc ? : { [ lang : string ] : string ; } ;
SHA256? : string ;
url? : string ;
downloadUrl? : string ;
isLocal? : boolean ;
lastUpdatedMs? : number ;
} ;
2023-05-13 12:15:18 +00:00
const columns : TableColumnDefinition < ModelSourceItem > [ ] = [
createTableColumn < ModelSourceItem > ( {
2023-05-06 12:17:39 +00:00
columnId : 'file' ,
compare : ( a , b ) = > {
2023-05-13 12:15:18 +00:00
return a . name . localeCompare ( b . name ) ;
2023-05-06 12:17:39 +00:00
} ,
renderHeaderCell : ( ) = > {
2023-05-18 12:48:53 +00:00
const { t } = useTranslation ( ) ;
return t ( 'File' ) ;
2023-05-06 12:17:39 +00:00
} ,
renderCell : ( item ) = > {
return (
< TableCellLayout className = "break-all" >
2023-05-13 12:15:18 +00:00
{ item . name }
2023-05-06 12:17:39 +00:00
< / TableCellLayout >
) ;
}
} ) ,
2023-05-13 12:15:18 +00:00
createTableColumn < ModelSourceItem > ( {
2023-05-06 12:17:39 +00:00
columnId : 'desc' ,
compare : ( a , b ) = > {
2023-05-19 14:18:38 +00:00
const lang : string = commonStore . settings . language ;
if ( a . desc && b . desc ) {
if ( lang in a . desc && lang in b . desc )
2023-05-19 14:37:11 +00:00
return b . desc [ lang ] . localeCompare ( a . desc [ lang ] ) ;
2023-05-19 14:18:38 +00:00
else if ( 'en' in a . desc && 'en' in b . desc )
2023-05-19 14:37:11 +00:00
return b . desc [ 'en' ] . localeCompare ( a . desc [ 'en' ] ) ;
2023-05-19 14:18:38 +00:00
}
return 0 ;
2023-05-06 12:17:39 +00:00
} ,
renderHeaderCell : ( ) = > {
2023-05-18 12:48:53 +00:00
const { t } = useTranslation ( ) ;
return t ( 'Desc' ) ;
2023-05-06 12:17:39 +00:00
} ,
renderCell : ( item ) = > {
2023-05-18 12:48:53 +00:00
const lang : string = commonStore . settings . language ;
2023-05-06 12:17:39 +00:00
return (
< TableCellLayout >
2023-05-18 12:48:53 +00:00
{ item . desc &&
( lang in item . desc ? item . desc [ lang ] :
( 'en' in item . desc && item . desc [ 'en' ] ) ) }
2023-05-06 12:17:39 +00:00
< / TableCellLayout >
) ;
}
} ) ,
2023-05-13 12:15:18 +00:00
createTableColumn < ModelSourceItem > ( {
2023-05-06 12:17:39 +00:00
columnId : 'size' ,
compare : ( a , b ) = > {
return a . size - b . size ;
} ,
renderHeaderCell : ( ) = > {
2023-05-18 12:48:53 +00:00
const { t } = useTranslation ( ) ;
return t ( 'Size' ) ;
2023-05-06 12:17:39 +00:00
} ,
renderCell : ( item ) = > {
return (
< TableCellLayout >
2023-05-20 05:46:33 +00:00
{ bytesToGb ( item . size ) + 'GB' }
2023-05-06 12:17:39 +00:00
< / TableCellLayout >
) ;
}
} ) ,
2023-05-13 12:15:18 +00:00
createTableColumn < ModelSourceItem > ( {
2023-05-06 12:17:39 +00:00
columnId : 'lastUpdated' ,
compare : ( a , b ) = > {
2023-05-13 12:15:18 +00:00
if ( ! a . lastUpdatedMs )
a . lastUpdatedMs = Date . parse ( a . lastUpdated ) ;
if ( ! b . lastUpdatedMs )
b . lastUpdatedMs = Date . parse ( b . lastUpdated ) ;
2023-05-13 15:36:30 +00:00
return b . lastUpdatedMs - a . lastUpdatedMs ;
2023-05-06 12:17:39 +00:00
} ,
renderHeaderCell : ( ) = > {
2023-05-18 12:48:53 +00:00
const { t } = useTranslation ( ) ;
return t ( 'Last updated' ) ;
2023-05-06 12:17:39 +00:00
} ,
renderCell : ( item ) = > {
return new Date ( item . lastUpdated ) . toLocaleString ( ) ;
}
} ) ,
2023-05-13 12:15:18 +00:00
createTableColumn < ModelSourceItem > ( {
2023-05-06 12:17:39 +00:00
columnId : 'actions' ,
compare : ( a , b ) = > {
2023-05-20 06:53:52 +00:00
return a . isLocal ? - 1 : 1 ;
2023-05-06 12:17:39 +00:00
} ,
renderHeaderCell : ( ) = > {
2023-05-18 12:48:53 +00:00
const { t } = useTranslation ( ) ;
return t ( 'Actions' ) ;
2023-05-06 12:17:39 +00:00
} ,
renderCell : ( item ) = > {
2023-05-18 12:48:53 +00:00
const { t } = useTranslation ( ) ;
2023-05-20 06:53:52 +00:00
const navigate = useNavigate ( ) ;
2023-05-18 12:48:53 +00:00
2023-05-06 12:17:39 +00:00
return (
< TableCellLayout >
2023-05-13 12:15:18 +00:00
< div className = "flex gap-1" >
2023-05-13 15:36:30 +00:00
{
item . isLocal &&
2023-05-18 12:48:53 +00:00
< ToolTipButton desc = { t ( 'Open Folder' ) } icon = { < Folder20Regular / > } onClick = { ( ) = > {
2023-05-17 13:20:41 +00:00
OpenFileFolder ( ` ./ ${ manifest . localModelDir } / ${ item . name } ` ) ;
2023-05-13 15:36:30 +00:00
} } / >
}
{ item . downloadUrl && ! item . isLocal &&
2023-05-18 12:48:53 +00:00
< ToolTipButton desc = { t ( 'Download' ) } icon = { < ArrowDownload20Regular / > } onClick = { ( ) = > {
2023-05-20 06:53:52 +00:00
toastWithButton ( ` ${ t ( 'Downloading' ) } ${ item . name } ` , t ( 'Check' ) , ( ) = > {
navigate ( { pathname : '/downloads' } ) ;
} ,
2023-05-20 07:15:49 +00:00
{ autoClose : 3000 } ) ;
2023-05-20 05:00:08 +00:00
AddToDownloadList ( ` ./ ${ manifest . localModelDir } / ${ item . name } ` , item . downloadUrl ! ) ;
2023-05-13 15:36:30 +00:00
} } / > }
2023-05-18 12:48:53 +00:00
{ item . url && < ToolTipButton desc = { t ( 'Open Url' ) } icon = { < Open20Regular / > } onClick = { ( ) = > {
2023-05-13 15:36:30 +00:00
BrowserOpenURL ( item . url ! ) ;
} } / > }
2023-05-13 12:15:18 +00:00
< / div >
2023-05-06 12:17:39 +00:00
< / TableCellLayout >
) ;
}
} )
] ;
2023-05-05 15:23:34 +00:00
2023-05-13 12:15:18 +00:00
export const Models : FC = observer ( ( ) = > {
2023-05-18 12:48:53 +00:00
const { t } = useTranslation ( ) ;
2023-05-05 15:23:34 +00:00
return (
2023-05-18 12:48:53 +00:00
< Page title = { t ( 'Models' ) } content = {
2023-05-15 13:55:57 +00:00
< div className = "flex flex-col gap-2 overflow-hidden" >
< div className = "flex flex-col gap-1" >
2023-05-19 02:08:28 +00:00
< div className = "flex justify-between items-center" >
2023-05-18 12:48:53 +00:00
< Text weight = "medium" > { t ( 'Model Source Manifest List' ) } < / Text >
< ToolTipButton desc = { t ( 'Refresh' ) } icon = { < ArrowClockwise20Regular / > } onClick = { ( ) = > {
2023-05-17 13:20:41 +00:00
refreshModels ( false ) ;
2023-05-17 15:27:52 +00:00
saveConfigs ( ) ;
2023-05-17 13:20:41 +00:00
} } / >
2023-05-13 12:15:18 +00:00
< / div >
2023-05-15 13:55:57 +00:00
< Text size = { 100 } >
2023-05-18 12:48:53 +00:00
{ 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.' ) }
2023-05-15 13:55:57 +00:00
< / Text >
< Textarea size = "large" resize = "vertical"
value = { commonStore . modelSourceManifestList }
onChange = { ( e , data ) = > commonStore . setModelSourceManifestList ( data . value ) } / >
< / div >
< div className = "flex grow overflow-hidden" >
< DataGrid
items = { commonStore . modelSourceList }
columns = { columns }
sortable = { true }
2023-05-17 13:20:41 +00:00
defaultSortState = { { sortColumn : 'actions' , sortDirection : 'ascending' } }
2023-05-15 13:55:57 +00:00
style = { { display : 'flex' } }
className = "flex-col w-full"
>
< DataGridHeader >
< DataGridRow >
{ ( { renderHeaderCell } ) = > (
< DataGridHeaderCell > { renderHeaderCell ( ) } < / DataGridHeaderCell >
) }
< / DataGridRow >
< / DataGridHeader >
< div className = "overflow-y-auto overflow-x-hidden" >
< DataGridBody < ModelSourceItem > >
{ ( { item , rowId } ) = > (
< DataGridRow < ModelSourceItem > key = { rowId } >
{ ( { renderCell } ) = > (
< DataGridCell > { renderCell ( item ) } < / DataGridCell >
) }
< / DataGridRow >
) }
< / DataGridBody >
< / div >
< / DataGrid >
< / div >
2023-05-13 12:15:18 +00:00
< / div >
2023-05-15 13:55:57 +00:00
} / >
2023-05-05 15:23:34 +00:00
) ;
2023-05-13 12:15:18 +00:00
} ) ;