mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
## Summary Stores and displays base64-encoded preview images from Civitai during the model upload flow, uploading the preview as a separate asset linked to the model. ## Changes - **Schema**: Added `preview_image` field to `AssetMetadata` schema - **Service**: Added `uploadAssetFromBase64` method to convert base64 data to blob and upload via FormData - **Upload Flow**: Modified wizard to first upload preview image as asset, then link it to model via `preview_id` - **UI**: Display 56x56px preview thumbnail alongside model filename in confirmation and success steps ## Review Focus - Base64 to blob conversion and FormData upload implementation - Sequential upload flow (preview first, then model with preview_id reference) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7274-feat-display-and-upload-Civitai-preview-images-in-model-upload-flow-2c46d73d365081ff9b74c1791d23f6dd) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude <noreply@anthropic.com>
113 lines
2.8 KiB
Vue
113 lines
2.8 KiB
Vue
<template>
|
|
<div
|
|
class="upload-model-dialog flex flex-col justify-between gap-6 p-4 pt-6 border-t border-border-default"
|
|
>
|
|
<!-- Step 1: Enter URL -->
|
|
<UploadModelUrlInput
|
|
v-if="currentStep === 1"
|
|
v-model="wizardData.url"
|
|
:error="uploadError"
|
|
/>
|
|
|
|
<!-- Step 2: Confirm Metadata -->
|
|
<UploadModelConfirmation
|
|
v-else-if="currentStep === 2"
|
|
v-model="selectedModelType"
|
|
:metadata="wizardData.metadata"
|
|
:preview-image="wizardData.previewImage"
|
|
/>
|
|
|
|
<!-- Step 3: Upload Progress -->
|
|
<UploadModelProgress
|
|
v-else-if="currentStep === 3"
|
|
:status="uploadStatus"
|
|
:error="uploadError"
|
|
:metadata="wizardData.metadata"
|
|
:model-type="selectedModelType"
|
|
:preview-image="wizardData.previewImage"
|
|
/>
|
|
|
|
<!-- Navigation Footer -->
|
|
<UploadModelFooter
|
|
:current-step="currentStep"
|
|
:is-fetching-metadata="isFetchingMetadata"
|
|
:is-uploading="isUploading"
|
|
:can-fetch-metadata="canFetchMetadata"
|
|
:can-upload-model="canUploadModel"
|
|
:upload-status="uploadStatus"
|
|
@back="goToPreviousStep"
|
|
@fetch-metadata="handleFetchMetadata"
|
|
@upload="handleUploadModel"
|
|
@close="handleClose"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { onMounted } from 'vue'
|
|
|
|
import UploadModelConfirmation from '@/platform/assets/components/UploadModelConfirmation.vue'
|
|
import UploadModelFooter from '@/platform/assets/components/UploadModelFooter.vue'
|
|
import UploadModelProgress from '@/platform/assets/components/UploadModelProgress.vue'
|
|
import UploadModelUrlInput from '@/platform/assets/components/UploadModelUrlInput.vue'
|
|
import { useModelTypes } from '@/platform/assets/composables/useModelTypes'
|
|
import { useUploadModelWizard } from '@/platform/assets/composables/useUploadModelWizard'
|
|
import { useDialogStore } from '@/stores/dialogStore'
|
|
|
|
const dialogStore = useDialogStore()
|
|
const { modelTypes, fetchModelTypes } = useModelTypes()
|
|
|
|
const emit = defineEmits<{
|
|
'upload-success': []
|
|
}>()
|
|
|
|
const {
|
|
currentStep,
|
|
isFetchingMetadata,
|
|
isUploading,
|
|
uploadStatus,
|
|
uploadError,
|
|
wizardData,
|
|
selectedModelType,
|
|
canFetchMetadata,
|
|
canUploadModel,
|
|
fetchMetadata,
|
|
uploadModel,
|
|
goToPreviousStep
|
|
} = useUploadModelWizard(modelTypes)
|
|
|
|
async function handleFetchMetadata() {
|
|
await fetchMetadata()
|
|
}
|
|
|
|
async function handleUploadModel() {
|
|
const success = await uploadModel()
|
|
if (success) {
|
|
emit('upload-success')
|
|
}
|
|
}
|
|
|
|
function handleClose() {
|
|
dialogStore.closeDialog({ key: 'upload-model' })
|
|
}
|
|
|
|
onMounted(() => {
|
|
fetchModelTypes()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.upload-model-dialog {
|
|
width: 90vw;
|
|
max-width: 800px;
|
|
min-height: 400px;
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.upload-model-dialog {
|
|
width: auto;
|
|
min-width: 600px;
|
|
}
|
|
}
|
|
</style>
|