-
Notifications
You must be signed in to change notification settings - Fork 448
feat: display and upload Civitai preview images in model upload flow #7274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a6b5ff1
9e53495
ab55e32
06ee181
3db5fff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,22 @@ | ||
| <template> | ||
| <div class="flex flex-col gap-4 text-sm text-muted-foreground"> | ||
| <!-- Model Info Section --> | ||
| <div class="flex flex-col gap-2"> | ||
| <p class="m-0"> | ||
| {{ $t('assetBrowser.modelAssociatedWithLink') }} | ||
| </p> | ||
| <p class="mt-0 text-base-foreground rounded-lg"> | ||
| {{ metadata?.filename || metadata?.name }} | ||
| </p> | ||
| <div | ||
| class="flex items-center gap-3 bg-secondary-background p-3 rounded-lg" | ||
| > | ||
| <img | ||
| v-if="previewImage" | ||
| :src="previewImage" | ||
| :alt="metadata?.filename || metadata?.name || 'Model preview'" | ||
| class="w-14 h-14 rounded object-cover flex-shrink-0" | ||
| /> | ||
| <p class="m-0 text-base-foreground"> | ||
| {{ metadata?.filename || metadata?.name }} | ||
| </p> | ||
| </div> | ||
|
Comment on lines
+7
to
+19
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preview thumbnail wiring looks good; localize fallback alt text The preview block and :alt="
metadata?.filename ||
metadata?.name ||
$t('assetBrowser.modelPreviewAlt', 'Model preview')
"and add Also applies to: 51-54 🤖 Prompt for AI Agents |
||
| </div> | ||
|
|
||
| <!-- Model Type Selection --> | ||
|
|
@@ -40,7 +49,8 @@ import { useModelTypes } from '@/platform/assets/composables/useModelTypes' | |
| import type { AssetMetadata } from '@/platform/assets/schemas/assetSchema' | ||
|
|
||
| defineProps<{ | ||
| metadata: AssetMetadata | null | ||
| metadata?: AssetMetadata | ||
| previewImage?: string | ||
| }>() | ||
|
|
||
| const modelValue = defineModel<string | undefined>() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,8 +25,14 @@ | |
| </p> | ||
|
|
||
| <div | ||
| class="flex flex-row items-start p-4 bg-modal-card-background rounded-lg" | ||
| class="flex flex-row items-center gap-3 p-4 bg-modal-card-background rounded-lg" | ||
| > | ||
| <img | ||
| v-if="previewImage" | ||
| :src="previewImage" | ||
| :alt="metadata?.filename || metadata?.name || 'Model preview'" | ||
| class="w-14 h-14 rounded object-cover flex-shrink-0" | ||
| /> | ||
|
Comment on lines
+28
to
+35
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Success preview behavior is good; localize alt fallback The success-state preview image is correctly wired and optional, and the new :alt="
metadata?.filename ||
metadata?.name ||
$t('assetBrowser.modelPreviewAlt', 'Model preview')
"with Also applies to: 69-75 🤖 Prompt for AI Agents |
||
| <div class="flex flex-col justify-center items-start gap-1 flex-1"> | ||
| <p class="text-base-foreground m-0"> | ||
| {{ metadata?.filename || metadata?.name }} | ||
|
|
@@ -63,7 +69,8 @@ import type { AssetMetadata } from '@/platform/assets/schemas/assetSchema' | |
| defineProps<{ | ||
| status: 'idle' | 'uploading' | 'success' | 'error' | ||
| error?: string | ||
| metadata: AssetMetadata | null | ||
| modelType: string | undefined | ||
| metadata?: AssetMetadata | ||
| modelType?: string | ||
| previewImage?: string | ||
| }>() | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,9 +9,10 @@ import { useModelToNodeStore } from '@/stores/modelToNodeStore' | |||||||
|
|
||||||||
| interface WizardData { | ||||||||
| url: string | ||||||||
| metadata: AssetMetadata | null | ||||||||
| metadata?: AssetMetadata | ||||||||
| name: string | ||||||||
| tags: string[] | ||||||||
| previewImage?: string | ||||||||
| } | ||||||||
|
|
||||||||
| interface ModelTypeOption { | ||||||||
|
|
@@ -30,7 +31,6 @@ export function useUploadModelWizard(modelTypes: Ref<ModelTypeOption[]>) { | |||||||
|
|
||||||||
| const wizardData = ref<WizardData>({ | ||||||||
| url: '', | ||||||||
| metadata: null, | ||||||||
| name: '', | ||||||||
| tags: [] | ||||||||
| }) | ||||||||
|
|
@@ -91,6 +91,9 @@ export function useUploadModelWizard(modelTypes: Ref<ModelTypeOption[]>) { | |||||||
| // Pre-fill name from metadata | ||||||||
| wizardData.value.name = metadata.filename || metadata.name || '' | ||||||||
|
|
||||||||
| // Store preview image if available | ||||||||
| wizardData.value.previewImage = metadata.preview_image | ||||||||
|
|
||||||||
| // Pre-fill model type from metadata tags if available | ||||||||
| if (metadata.tags && metadata.tags.length > 0) { | ||||||||
| wizardData.value.tags = metadata.tags | ||||||||
|
|
@@ -134,6 +137,34 @@ export function useUploadModelWizard(modelTypes: Ref<ModelTypeOption[]>) { | |||||||
| wizardData.value.metadata?.name || | ||||||||
| 'model' | ||||||||
|
|
||||||||
| let previewId: string | undefined | ||||||||
|
|
||||||||
| // Upload preview image first if available | ||||||||
| if (wizardData.value.previewImage) { | ||||||||
| try { | ||||||||
| const baseFilename = filename.split('.')[0] | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Consider more robust extension stripping.
Apply this diff to improve base filename extraction: - const baseFilename = filename.split('.')[0]
+ const lastDotIndex = filename.lastIndexOf('.')
+ const baseFilename = lastDotIndex !== -1 ? filename.slice(0, lastDotIndex) : filename📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||
|
|
||||||||
| // Extract extension from data URL MIME type | ||||||||
| let extension = 'png' | ||||||||
| const mimeMatch = wizardData.value.previewImage.match( | ||||||||
| /^data:image\/([^;]+);/ | ||||||||
| ) | ||||||||
| if (mimeMatch) { | ||||||||
| extension = mimeMatch[1] === 'jpeg' ? 'jpg' : mimeMatch[1] | ||||||||
| } | ||||||||
|
|
||||||||
| const previewAsset = await assetService.uploadAssetFromBase64({ | ||||||||
| data: wizardData.value.previewImage, | ||||||||
| name: `${baseFilename}_preview.${extension}`, | ||||||||
| tags: ['preview'] | ||||||||
| }) | ||||||||
| previewId = previewAsset.id | ||||||||
| } catch (error) { | ||||||||
| console.error('Failed to upload preview image:', error) | ||||||||
| // Continue with model upload even if preview fails | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| await assetService.uploadAssetFromUrl({ | ||||||||
| url: wizardData.value.url, | ||||||||
| name: filename, | ||||||||
|
|
@@ -142,7 +173,8 @@ export function useUploadModelWizard(modelTypes: Ref<ModelTypeOption[]>) { | |||||||
| source: 'civitai', | ||||||||
| source_url: wizardData.value.url, | ||||||||
| model_type: selectedModelType.value | ||||||||
| } | ||||||||
| }, | ||||||||
| preview_id: previewId | ||||||||
| }) | ||||||||
|
|
||||||||
| uploadStatus.value = 'success' | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -392,6 +392,59 @@ function createAssetService() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return await res.json() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Uploads an asset from base64 data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param params - Upload parameters | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param params.data - Base64 data URL (e.g., "data:image/png;base64,...") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param params.name - Display name (determines extension) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param params.tags - Optional freeform tags | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param params.user_metadata - Optional custom metadata object | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @returns Promise<AssetItem & { created_new: boolean }> - Asset object with created_new flag | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @throws Error if upload fails | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async function uploadAssetFromBase64(params: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tags?: string[] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user_metadata?: Record<string, any> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }): Promise<AssetItem & { created_new: boolean }> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Validate that data is a data URL | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!params.data || !params.data.startsWith('data:')) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'Invalid data URL: expected a string starting with "data:"' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Convert base64 data URL to Blob | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const blob = await fetch(params.data).then((r) => r.blob()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Create FormData and append the blob | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const formData = new FormData() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| formData.append('file', blob, params.name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (params.tags) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| formData.append('tags', JSON.stringify(params.tags)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (params.user_metadata) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| formData.append('user_metadata', JSON.stringify(params.user_metadata)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await api.fetchApi(ASSETS_ENDPOINT, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| method: 'POST', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| body: formData | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!res.ok) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `Failed to upload asset from base64: ${res.status} ${res.statusText}` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return await res.json() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+406
to
+446
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial uploadAssetFromBase64 implementation is solid; align error handling & i18n with uploadAssetFromUrl The data URL guard, Blob conversion, and FormData upload look correct. To keep UX and localization consistent with async function uploadAssetFromBase64(params: {
data: string
name: string
tags?: string[]
user_metadata?: Record<string, any>
}): Promise<AssetItem & { created_new: boolean }> {
- // Validate that data is a data URL
- if (!params.data || !params.data.startsWith('data:')) {
- throw new Error(
- 'Invalid data URL: expected a string starting with "data:"'
- )
- }
+ // Validate that data is a data URL
+ if (!params.data || !params.data.startsWith('data:')) {
+ throw new Error(
+ st(
+ 'assetBrowser.errorUploadFailed',
+ 'Failed to upload asset. Please try again.'
+ )
+ )
+ }
@@
- const res = await api.fetchApi(ASSETS_ENDPOINT, {
+ const res = await api.fetchApi(ASSETS_ENDPOINT, {
method: 'POST',
body: formData
})
- if (!res.ok) {
- throw new Error(
- `Failed to upload asset from base64: ${res.status} ${res.statusText}`
- )
- }
+ if (!res.ok) {
+ throw new Error(
+ st(
+ 'assetBrowser.errorUploadFailed',
+ 'Failed to upload asset. Please try again.'
+ )
+ )
+ }
return await res.json()
}This keeps failure behavior consistent across both upload paths and avoids leaking raw status text to end users while respecting the existing i18n pattern. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these are internal facing errors. The current error messages give us more detail about what actually went wrong
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @luke-mino-altherr Understood! That makes sense for internal tooling—keeping the detailed status information ( 🧠 Learnings used |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getAssetModelFolders, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getAssetModels, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -402,7 +455,8 @@ function createAssetService() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deleteAsset, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updateAsset, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getAssetMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uploadAssetFromUrl | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uploadAssetFromUrl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uploadAssetFromBase64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want a stretch goal: https://vueuse.org/core/useImage/#component-usage