From 2c4b997f683539bb542a41bcbf1c8e5d2d615c16 Mon Sep 17 00:00:00 2001 From: Murderlon Date: Wed, 27 Aug 2025 11:28:41 +0200 Subject: [PATCH] WIP --- packages/@uppy/image-generator/package.json | 27 ++++++++++- packages/@uppy/image-generator/src/index.tsx | 45 +++++++++++++------ packages/@uppy/image-generator/src/style.scss | 36 ++++++++++++--- packages/@uppy/locales/src/en_US.ts | 3 ++ .../@uppy/provider-views/src/SearchInput.tsx | 28 ++++++++++++ packages/@uppy/provider-views/src/style.scss | 20 +++++++++ packages/uppy/package.json | 1 + packages/uppy/src/style.scss | 1 + private/dev/Dashboard.js | 1 + private/dev/index.js | 2 +- yarn.lock | 5 +++ 11 files changed, 147 insertions(+), 22 deletions(-) diff --git a/packages/@uppy/image-generator/package.json b/packages/@uppy/image-generator/package.json index f36e6e0e6..3ee7f748c 100644 --- a/packages/@uppy/image-generator/package.json +++ b/packages/@uppy/image-generator/package.json @@ -3,8 +3,7 @@ "description": "AI-powered image generation for Uppy", "version": "0.0.0", "license": "MIT", - "main": "lib/index.js", - "style": "dist/style.min.css", + "sideEffects": false, "type": "module", "keywords": [ "file uploader", @@ -22,11 +21,35 @@ "type": "git", "url": "git+https://github.com/transloadit/uppy.git" }, + "files": [ + "src", + "lib", + "dist", + "CHANGELOG.md" + ], + "exports": { + ".": "./lib/index.js", + "./css/style.css": "./dist/style.css", + "./css/style.min.css": "./dist/style.min.css", + "./package.json": "./package.json" + }, + "scripts": { + "build": "tsc --build tsconfig.build.json", + "build:css": "sass --load-path=../../ src/style.scss dist/style.css && postcss dist/style.css -u cssnano -o dist/style.min.css", + "typecheck": "tsc --build" + }, "dependencies": { "@uppy/provider-views": "workspace:^", "@uppy/utils": "workspace:^", "preact": "^10.5.13" }, + "devDependencies": { + "@uppy/core": "workspace:^", + "cssnano": "^7.0.7", + "postcss": "^8.5.6", + "postcss-cli": "^11.0.1", + "sass": "^1.89.2" + }, "peerDependencies": { "@uppy/core": "workspace:^", "@uppy/transloadit": "workspace:^" diff --git a/packages/@uppy/image-generator/src/index.tsx b/packages/@uppy/image-generator/src/index.tsx index dd8d433b0..95129e777 100644 --- a/packages/@uppy/image-generator/src/index.tsx +++ b/packages/@uppy/image-generator/src/index.tsx @@ -12,8 +12,16 @@ interface PluginState extends Record { prompt: string results: AssemblyResult[] checkedResultIds: Set + loading: boolean } +const defaultState = { + prompt: '', + results: [], + checkedResultIds: new Set(), + loading: false, +} satisfies PluginState + export default class ImageGenerator< M extends Meta, B extends Body, @@ -27,11 +35,7 @@ export default class ImageGenerator< this.defaultLocale = locale - this.setPluginState({ - prompt: '', - results: [], - checkedResultIds: new Set(), - }) + this.setPluginState(defaultState) this.i18nInit() } @@ -57,15 +61,12 @@ export default class ImageGenerator< transloadit.setFields({ prompt: this.getPluginState().prompt }) this.uppy.on('transloadit:result', (stepName, result) => { - // TODO: this needs to be deterministic - // stepName is set by the implementer of the template - if (stepName === 'resized') { - const { results } = this.getPluginState() - this.setPluginState({ results: [...results, result] }) - } + const { results } = this.getPluginState() + this.setPluginState({ results: [...results, result] }) }) try { + this.setPluginState({ loading: true }) await this.uppy.upload() } catch { // TODO: inform the user @@ -75,6 +76,7 @@ export default class ImageGenerator< // 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 }) } } @@ -104,15 +106,30 @@ export default class ImageGenerator< })) this.uppy.addFiles(files) + this.setPluginState(defaultState) } render() { - const { prompt, results, checkedResultIds } = this.getPluginState() + const { prompt, results, checkedResultIds, loading } = this.getPluginState() const { i18n } = this.uppy if (results.length > 0) { return ( -
+
+
+ + this.setPluginState({ + prompt: (e.target as HTMLInputElement).value, + }) + } + /> + +
+
    {results.map((result) => (
  • @@ -124,7 +141,6 @@ export default class ImageGenerator< checked={checkedResultIds.has(result.id)} data-uppy-super-focusable /> - {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */} @@ -162,6 +178,7 @@ export default class ImageGenerator< return ( this.setPluginState({ prompt: str })} submitSearchString={this.search} diff --git a/packages/@uppy/image-generator/src/style.scss b/packages/@uppy/image-generator/src/style.scss index 649964eb0..5cd68b736 100644 --- a/packages/@uppy/image-generator/src/style.scss +++ b/packages/@uppy/image-generator/src/style.scss @@ -1,17 +1,37 @@ -@import '@uppy/core/src/_utils.scss'; -@import '@uppy/core/src/_variables.scss'; +@use '@uppy/core/src/_variables.scss' as *; +@use '@uppy/core/src/_utils.scss' as *; .uppy-ImageGenerator-root { height: 100%; + width: 100%; + display: flex; + flex-direction: column; +} + +.uppy-ImageGenerator-prompt { + width: 100%; + + input { + color: $gray-800; + border-radius: 10px; + border: none; + font-size: 1em; + padding: 0.5em 1em; + } + + label { + display: none; + } } .uppy-ImageGenerator-grid { display: grid; grid-template-columns: 1fr 1fr; - overflow-y: scroll; + overflow-y: auto; gap: 16px; margin: 0; padding: 16px; + flex: 1; li { margin: 0; @@ -27,12 +47,18 @@ } } - input[type='checkbox']:focus + label img { + input[type='checkbox']:focus+label img { box-shadow: $focus-shadow; } - input[type='checkbox']:checked + label img { + input[type='checkbox']:checked+label img { box-shadow: $focus-shadow; } + + img { + width: 100%; + height: 150px; + object-fit: cover; + } } } diff --git a/packages/@uppy/locales/src/en_US.ts b/packages/@uppy/locales/src/en_US.ts index ae34d9337..e9cd03cea 100644 --- a/packages/@uppy/locales/src/en_US.ts +++ b/packages/@uppy/locales/src/en_US.ts @@ -98,6 +98,9 @@ en_US.strings = { '1': 'Added %{smart_count} files from %{folder}', }, folderAlreadyAdded: 'The folder "%{folder}" was already added', + generateImage: 'Generate image', + generateImagePlaceholder: + 'A serene sunset over a mountain lake, with pine trees reflecting in the water', generatingThumbnails: 'Generating thumbnails...', import: 'Import', importFiles: 'Import files from:', diff --git a/packages/@uppy/provider-views/src/SearchInput.tsx b/packages/@uppy/provider-views/src/SearchInput.tsx index fe4a251f9..994b0234c 100644 --- a/packages/@uppy/provider-views/src/SearchInput.tsx +++ b/packages/@uppy/provider-views/src/SearchInput.tsx @@ -16,6 +16,8 @@ type Props = { showButton?: boolean buttonLabel?: string buttonCSSClassName?: string + + loading?: boolean } function SearchInput({ @@ -32,6 +34,8 @@ function SearchInput({ showButton = false, buttonLabel = '', buttonCSSClassName = '', + + loading = false, }: Props) { const onInput = (e: ChangeEvent) => { setSearchString((e.target as HTMLInputElement).value) @@ -73,6 +77,7 @@ function SearchInput({ value={searchString} onInput={onInput} form={form.id} + disabled={loading} data-uppy-super-focusable /> {!showButton && ( @@ -95,6 +100,7 @@ function SearchInput({ type="button" aria-label={clearSearchLabel} title={clearSearchLabel} + disabled={loading} onClick={() => setSearchString('')} > {buttonLabel} + + {loading && ( + + + + )} )} diff --git a/packages/@uppy/provider-views/src/style.scss b/packages/@uppy/provider-views/src/style.scss index 9fbd248d5..f7d4b4e2e 100644 --- a/packages/@uppy/provider-views/src/style.scss +++ b/packages/@uppy/provider-views/src/style.scss @@ -135,6 +135,7 @@ color: variables.$gray-200; } } + // ...uppy-Provider-breadcrumbs| .uppy-ProviderBrowser { @@ -287,6 +288,23 @@ } } +.uppy-SearchInput-spinner { + animation: uppy-SearchInput-spin 1s linear infinite; + margin-left: 1em; +} + +@keyframes uppy-SearchInput-spin { + from { + transform: rotate(0deg); + stroke-dashoffset: 31.416; + } + + to { + transform: rotate(360deg); + stroke-dashoffset: 0; + } +} + .uppy-ProviderBrowser-userLogout { @include utils.highlight-focus; // for focus @@ -376,6 +394,7 @@ flex-direction: column-reverse; align-items: stretch; } + .uppy-ProviderBrowser-footer-error { padding-bottom: 10px; } @@ -385,6 +404,7 @@ .picker-dialog-bg { z-index: 20000 !important; } + .picker-dialog { z-index: 20001 !important; } diff --git a/packages/uppy/package.json b/packages/uppy/package.json index c6a983360..cb0e3b4d9 100644 --- a/packages/uppy/package.json +++ b/packages/uppy/package.json @@ -53,6 +53,7 @@ "@uppy/google-drive-picker": "workspace:^", "@uppy/google-photos-picker": "workspace:^", "@uppy/image-editor": "workspace:^", + "@uppy/image-generator": "workspace:^", "@uppy/instagram": "workspace:^", "@uppy/locales": "workspace:^", "@uppy/onedrive": "workspace:^", diff --git a/packages/uppy/src/style.scss b/packages/uppy/src/style.scss index bfc142a44..b61127b96 100644 --- a/packages/uppy/src/style.scss +++ b/packages/uppy/src/style.scss @@ -6,4 +6,5 @@ @use '@uppy/audio/src/style.scss' as audio; @use '@uppy/screen-capture/src/style.scss' as screen-capture; @use '@uppy/image-editor/src/style.scss' as image-editor; +@use '@uppy/image-generator/src/style.scss' as image-generator; @use '@uppy/drop-target/src/style.scss' as drop-target; diff --git a/private/dev/Dashboard.js b/private/dev/Dashboard.js index 546aa7155..9593c7609 100644 --- a/private/dev/Dashboard.js +++ b/private/dev/Dashboard.js @@ -6,6 +6,7 @@ import Dashboard from '@uppy/dashboard' import DropTarget from '@uppy/drop-target' import Form from '@uppy/form' import GoldenRetriever from '@uppy/golden-retriever' +import ImageGenerator from '@uppy/image-generator' import GoogleDrive from '@uppy/google-drive' import GoogleDrivePicker from '@uppy/google-drive-picker' import GooglePhotosPicker from '@uppy/google-photos-picker' diff --git a/private/dev/index.js b/private/dev/index.js index 2feeefce2..a3ba4efd6 100644 --- a/private/dev/index.js +++ b/private/dev/index.js @@ -1,4 +1,4 @@ -import 'uppy/src/style.scss' +import 'uppy/dist/uppy.css' import Dashboard from './Dashboard.js' import DragDrop from './DragDrop.js' diff --git a/yarn.lock b/yarn.lock index c34f9a212..6cebcf984 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9420,9 +9420,14 @@ __metadata: version: 0.0.0-use.local resolution: "@uppy/image-generator@workspace:packages/@uppy/image-generator" dependencies: + "@uppy/core": "workspace:^" "@uppy/provider-views": "workspace:^" "@uppy/utils": "workspace:^" + cssnano: "npm:^7.0.7" + postcss: "npm:^8.5.6" + postcss-cli: "npm:^11.0.1" preact: "npm:^10.5.13" + sass: "npm:^1.89.2" peerDependencies: "@uppy/core": "workspace:^" "@uppy/transloadit": "workspace:^"