* fix: reduce the number of api call Signed-off-by: James <james@jan.ai> * fix: download progress Signed-off-by: James <james@jan.ai> * chore: save blob * fix: server boot up * fix: download state not updating Signed-off-by: James <james@jan.ai> * fix: copy assets * Add Dockerfile CPU for Jan Server and Jan Web * Add Dockerfile GPU for Jan Server and Jan Web * feat: S3 adapter * Update check find count from ./pre-install and correct copy:asserts command * server add bundleDependencies @janhq/core * server add bundleDependencies @janhq/core * fix: update success/failed download state (#1945) * fix: update success/failed download state Signed-off-by: James <james@jan.ai> * fix: download model progress and state handling for both Desktop and Web --------- Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai> Co-authored-by: Louis <louis@jan.ai> * chore: refactor * fix: load models empty first time open * Add Docker compose * fix: assistants onUpdate --------- Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai> Co-authored-by: Hien To <tominhhien97@gmail.com> Co-authored-by: NamH <NamNh0122@gmail.com>
102 lines
2.8 KiB
TypeScript
102 lines
2.8 KiB
TypeScript
import { useMemo } from 'react'
|
|
|
|
import { Model } from '@janhq/core'
|
|
|
|
import {
|
|
Modal,
|
|
ModalTrigger,
|
|
ModalClose,
|
|
ModalFooter,
|
|
ModalContent,
|
|
ModalHeader,
|
|
Button,
|
|
ModalTitle,
|
|
Progress,
|
|
} from '@janhq/uikit'
|
|
|
|
import { atom, useAtomValue } from 'jotai'
|
|
|
|
import useDownloadModel from '@/hooks/useDownloadModel'
|
|
|
|
import { modelDownloadStateAtom } from '@/hooks/useDownloadState'
|
|
|
|
import { formatDownloadPercentage } from '@/utils/converter'
|
|
|
|
import { getDownloadingModelAtom } from '@/helpers/atoms/Model.atom'
|
|
|
|
type Props = {
|
|
model: Model
|
|
isFromList?: boolean
|
|
}
|
|
|
|
const ModalCancelDownload: React.FC<Props> = ({ model, isFromList }) => {
|
|
const downloadingModels = useAtomValue(getDownloadingModelAtom)
|
|
const downloadAtom = useMemo(
|
|
() => atom((get) => get(modelDownloadStateAtom)[model.id]),
|
|
[model.id]
|
|
)
|
|
const downloadState = useAtomValue(downloadAtom)
|
|
const cancelText = `Cancel ${formatDownloadPercentage(downloadState.percent)}`
|
|
const { abortModelDownload } = useDownloadModel()
|
|
|
|
return (
|
|
<Modal>
|
|
<ModalTrigger asChild>
|
|
{isFromList ? (
|
|
<Button themes="outline" size="sm">
|
|
{cancelText}
|
|
</Button>
|
|
) : (
|
|
<Button themes="secondaryBlue">
|
|
<div className="flex items-center space-x-2">
|
|
<span className="inline-block">Cancel</span>
|
|
<Progress
|
|
className="inline-block h-2 w-[80px] bg-blue-100"
|
|
value={
|
|
formatDownloadPercentage(downloadState?.percent, {
|
|
hidePercentage: true,
|
|
}) as number
|
|
}
|
|
/>
|
|
<span>{formatDownloadPercentage(downloadState.percent)}</span>
|
|
</div>
|
|
</Button>
|
|
)}
|
|
</ModalTrigger>
|
|
<ModalContent>
|
|
<ModalHeader>
|
|
<ModalTitle>Cancel Download</ModalTitle>
|
|
</ModalHeader>
|
|
<p>
|
|
Are you sure you want to cancel the download of
|
|
{downloadState?.modelId}?
|
|
</p>
|
|
<ModalFooter>
|
|
<div className="flex gap-x-2">
|
|
<ModalClose asChild>
|
|
<Button themes="ghost">No</Button>
|
|
</ModalClose>
|
|
<ModalClose asChild>
|
|
<Button
|
|
themes="danger"
|
|
onClick={() => {
|
|
if (downloadState?.modelId) {
|
|
const model = downloadingModels.find(
|
|
(model) => model.id === downloadState.modelId
|
|
)
|
|
if (model) abortModelDownload(model)
|
|
}
|
|
}}
|
|
>
|
|
Yes
|
|
</Button>
|
|
</ModalClose>
|
|
</div>
|
|
</ModalFooter>
|
|
</ModalContent>
|
|
</Modal>
|
|
)
|
|
}
|
|
|
|
export default ModalCancelDownload
|