From 000b8c9052d0d7c6d41bfb1a413ea79f934d506e Mon Sep 17 00:00:00 2001 From: Murderlon Date: Wed, 1 Oct 2025 11:51:54 +0200 Subject: [PATCH] Update --- packages/@uppy/image-generator/src/icons.tsx | 119 ++++++++++++ packages/@uppy/image-generator/src/index.tsx | 181 +++--------------- packages/@uppy/image-generator/src/style.scss | 36 +++- 3 files changed, 179 insertions(+), 157 deletions(-) create mode 100644 packages/@uppy/image-generator/src/icons.tsx diff --git a/packages/@uppy/image-generator/src/icons.tsx b/packages/@uppy/image-generator/src/icons.tsx new file mode 100644 index 000000000..d93e68aae --- /dev/null +++ b/packages/@uppy/image-generator/src/icons.tsx @@ -0,0 +1,119 @@ +export function EmptyStateIcon() { + return ( + + image + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/packages/@uppy/image-generator/src/index.tsx b/packages/@uppy/image-generator/src/index.tsx index 8887d44ff..c30a31147 100644 --- a/packages/@uppy/image-generator/src/index.tsx +++ b/packages/@uppy/image-generator/src/index.tsx @@ -1,8 +1,9 @@ -import type { Body, Meta, UIPluginOptions, Uppy } from '@uppy/core' +import Uppy from '@uppy/core' +import type { Body, Meta, UIPluginOptions } from '@uppy/core' import { UIPlugin } from '@uppy/core' -import { SearchInput } from '@uppy/provider-views' -import type Transloadit from '@uppy/transloadit' +import Transloadit from '@uppy/transloadit' import type { AssemblyResult } from '@uppy/transloadit' +import { EmptyStateIcon } from './icons.js' import locale from './locale.js' export interface ImageGeneratorOptions extends UIPluginOptions {} @@ -56,10 +57,14 @@ export default class ImageGenerator< if (!transloadit) { throw new Error('ImageGenerator requires the Transloadit plugin') } + // TODO: override the template_id + const localUppy = new Uppy().use(Transloadit, transloadit.opts) + const localTransloadit = + localUppy.getPlugin>('Transloadit')! - transloadit.setFields({ prompt: this.getPluginState().prompt }) + localTransloadit.setFields({ prompt: this.getPluginState().prompt }) - this.uppy.on('transloadit:result', (step, result) => { + localUppy.on('transloadit:result', (step, result) => { console.log('transloadit:result', step, result) const { results } = this.getPluginState() // For some reason this event can be called twice with the same result @@ -70,16 +75,15 @@ export default class ImageGenerator< }) try { - this.setPluginState({ loading: true, results: [] }) - await this.uppy.upload() + this.setPluginState({ + loading: true, + results: [], + checkedResultIds: new Set(), + }) + await localUppy.upload() } catch { // TODO: inform the user? } finally { - // Normally uppy.upload() is only used to upload your files - // but here we need it to _get_ the results from the AI image generator Robot. - // That means users who set `allowMultipleUploadBatches: false` will not - // be able to actually upload their files, so we reset the state here. - this.uppy.setState({ allowNewUpload: true }) this.setPluginState({ loading: false }) } } @@ -101,7 +105,7 @@ export default class ImageGenerator< const files = results .filter((result) => checkedResultIds.has(result.id)) .map((result) => ({ - name: result.name, + name: `ai-image-${new Date().toISOString()}`, type: result.mime, isRemote: true, source: 'Transloadit', @@ -148,26 +152,17 @@ export default class ImageGenerator< data-uppy-super-focusable > Generate - {/* */} - {/* */} - {/* */} {results.length > 0 ? ( -
    +
      {results.map((result) => ( -
    • +
    • this.onCheckboxChange(result)} @@ -185,135 +180,9 @@ export default class ImageGenerator< ) : (
      - - image - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + {loading ? ( -

      Generating

      +

      Generating

      ) : (

      Generate a new image using Transloadit AI

      )} diff --git a/packages/@uppy/image-generator/src/style.scss b/packages/@uppy/image-generator/src/style.scss index 41a6f1034..098a3fa12 100644 --- a/packages/@uppy/image-generator/src/style.scss +++ b/packages/@uppy/image-generator/src/style.scss @@ -8,6 +8,13 @@ width: 100%; display: flex; flex-direction: column; + + // Ensure the footer sticks to the bottom when using uppy-ProviderBrowser-footer + .uppy-ProviderBrowser-footer { + position: sticky; + bottom: 0; + z-index: 2; + } } .uppy-ImageGenerator-prompt { @@ -65,6 +72,12 @@ padding: 16px; flex: 1; + &.uppy-ImageGenerator-grid--single { + grid-template-columns: 1fr; + max-width: 400px; + margin: 0 auto; + } + li { margin: 0; padding: 0; @@ -89,8 +102,10 @@ img { width: 100%; - height: 150px; + height: 50%; + min-height: 200px; object-fit: cover; + border-radius: 6px; } } } @@ -110,5 +125,24 @@ p { font-size: 14px; color: $gray-600; + + &.uppy-ImageGenerator-generating { + background: linear-gradient(90deg, $gray-400, $gray-600, $gray-400); + background-size: 200% 100%; + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + animation: uppy-gradient-slide 2s ease-in-out infinite; + } + } +} + +@keyframes uppy-gradient-slide { + 0% { + background-position: -200% 0; + } + + 100% { + background-position: 200% 0; } }