…perf
- Add desktop-style marquee drag selection on the webapp library: drag
on blank space to select covered tiles, click blank space to deselect
all
- Multi-select: clicking anywhere on a tile toggles it (fixes a
double-fire that cancelled the toggle so only the checkbox worked);
selection persists across tabs and folder navigation
- Gallery item menus show "View image" / "View video" / "View 3D" above
Add to Folder; menu panels size to content so labels no longer wrap
- Mobile/touch: no tile dragging or marquee (finger drags scroll),
checkbox and menu buttons always visible (no hover on touch), and the
Add to Folder submenu expands inline as an accordion instead of
overflowing the screen
- Select-mode gallery modal: folder cards hide the options menu and
ignore right-click (picker is browse-only)
- Perf: bulk selection moved to a module store with per-tile
subscriptions so selection changes re-render only flipped tiles, never
the page; marquee rectangle is positioned imperatively with cached tile
rects and commits only when coverage changes; webapp date groups
virtualized via the shared LazyDateGroup for smooth scrolling on large
libraries
- Bulk selection bar extracted to its own component, fixed to the
viewport bottom and centered within the content area
- Redesigned the gallery modal with a sidebar replacing the old filter
dropdown - filters now show as a list with item counts
- Added a Folders system - create, rename, and delete folders to
organize assets
- Users can drag items onto folders in the sidebar, including
multi-selected items
- Added "Add to Folder" option in the item right-click menu with a
folder picker submenu
- Added "Add to folder" button in the bulk selection bar with a folder
picker popup
- Clicking a folder in the sidebar opens a folder view with its own
content area and empty state
- Folder names are editable - click the title in the header or
right-click a folder in the sidebar to rename
- Videos are now draggable - previously only images and 3D objects could
be dragged
- Folder data is mocked locally for now - ready for API integration
## Signup, credits, and pricing polish
A round of UX improvements around signing up, running out of credits,
and the pricing page.
**Signup**
- Refreshed the signup prompt copy and added a "Continue with Google"
option (same flow as the login/signup pages)
- Added a "Sign up to create" button on the image and video pages for
logged-out visitors
**Create pages**
- Punchier empty-state headlines ("Describe anything. See it in
seconds." for images, "Describe a scene. See it in motion." for video)
- Added a subtle background pattern behind the empty state
**Out of credits**
- New modal that appears when a generation is blocked by not enough
credits
- Subscribers see "Upgrade plan" (hidden if they're already on the top
plan) plus "Buy credits"
- People without a plan get a "Choose a plan" prompt instead
**Pricing page**
- Existing subscribers get a "Buy more credits" shortcut at the top of
the page
- "Contact Us" now opens a small menu to copy the email or open your
mail app
**Cleanup**
- Removed the "Seedance 2.0 is in Early Alpha" warning from the task
queue
**Buy credits modal**
- Restyled the buy credits modal to be more appealing
- remove small plan text on pricing page
- persist prompt/settings across reloads, add frontend lightbox
references media (audio/video)
- remove topbar for edit 3d page, reclaim vertical space and relocate
scene title rename/right topbar actions
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Add an `aboveStackSlot` prop to PromptBox3D rendered as the first
child of its `bottom-4 flex-col` stack, and thread a
`promptboxAboveStackSlot` prop through Stage3D / Stage3DBody. The lib
now owns the vertical math, so the webapp's button never overlaps the
prompt input regardless of textarea height — replaces the host-side
ResizeObserver/MutationObserver positioning that was unreliable in
production builds.
…s scenes
Adds an inline overlay above the promptbox in /edit-3d (visible only
when `?output=` is in the URL) for swapping to another curated example
scene. The grid reuses SceneSplashCard + EXAMPLE_SCENES and filters out
the current scene. Position tracks the promptbox stack via Resize- and
MutationObserver so the pill sits 12px above it at any height.
Also resets the lib's camera Zustand state (cameras, selectedCameraId,
focalLengthDragging) on every sceneToken change. save_manager.load-
FromJson only emits CamerasReplacedEvent when scene_json carries a
`cameras` field, so navigating from a scene whose JSON had cameras (e.g.
60mm) into one that omits them left the prior cameras array in the store
and the per-frame tick kept applying its FOV to the new viewport.
OnboardingHelper: nudge the WASD/Look chip up to bottom-72 and drop its
background tint so it stacks cleanly above the new pill.
feature: add high-res image preview modal to prompt box
- Added click-to-preview functionality for reference and end frame
images in `ImagePromptRow`.
- Updated `RefImage` interface to include `fullUrl` for fetching
high-resolution library images.
- Populated `fullUrl` for library selections in `create-image` and
`create-video` pages.
- Configured the preview modal to tightly wrap the image so the close
button anchors correctly to the corner.
- Updated the image uploading indicator to use the standardized
`spinner-third` icon.
## Summary
- Regression from PR #1492. After the refactor, `useFeaturedObjects`
auto-fetch effect was racing the `EngineContext` editor instance: on
AssetModal's first mount `editor` is `null`, the effect synchronously
flipped `firstFetch.current` to `IN_PROGRESS` and then called
`fetchFeaturedObjects()` which immediately bailed at `if (!editor)
return`. When the editor became available the effect re-fired (editor is
in the `useCallback` deps), but the `IN_PROGRESS` guard then blocked it
— so **the network request never fired** for any featured category.
- Visible only on Sets and Creatures tabs because
Characters/Objects/Memes are merged with local demo arrays in
`assetTabs` and looked populated despite the same fetch breakage.
- Fix: gate the auto-fetch effect on `editor` (early-return when null,
add `editor` to deps) so `IN_PROGRESS` isn't burned on the no-op call.
## Test plan
- [ ] Open `/edit-3d` in artcraft-webapp with DevTools Network panel +
"Disable cache" on.
- [ ] Open the AssetModal — confirm exactly 5 GETs to
`/v1/media_files/list_featured` (one each for `character`, `object`,
`location`, `creature`, `image_plane`).
- [ ] Switch to Sets and Creatures tabs — items render.
- [ ] Drag a Set into the 3D scene — loads via `addObject` (LOCATION
maps to `AssetType.OBJECT` in `responseMapping`).
- [ ] Tauri smoke: open the 3D page in the desktop app, AssetModal
Sets/Creatures tabs populate.
- [ ] `nx typecheck @storyteller/ui-pagescene` (no new errors).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
When the stored `commonAspectRatio` (e.g. `SquareHd`) isn't in the
newly-selected model's `aspectRatios`, `PopoverMenu` toggle mode found
no selected item and collapsed the trigger to icon-only.
Reset to `model.defaultAspectRatio` from inside `AspectRatioPicker` so
the fix applies to all three callers (image/edit/3D). Drops the
duplicate workaround from `PromptBox3D`.
- Lightbox now shows full media metadata: Aspect Ratio, Resolution,
Size, Duration, Audio, and Created (with timestamp).
- Added Author header at the top so the close button no longer overlaps
the Prompt copy button.
- Extracted aspect ratio / resolution / duration formatters into
`@storyteller/common` so the website and desktop app share them.
Only the submit button triggers generation by default. The "Enter to
generate" toggle (available in both app and website settings top right
nav) still allows opting into Enter-to-submit.
- Pressing **Enter** in any prompt box now adds a new line instead of
submitting - fixes complaints about accidental generations
- **Shift+Enter** is the new submit shortcut
- Desktop app gets an "Enter to generate" toggle in Settings → General
(off by default) for users who prefer the old behavior
- Applies to all prompt boxes in the Artcraft desktop app and the
website
fixes:
- prompt box no longer overlaps bottom buttons or wastes space on big
screens
- long unbroken text wraps instead of escaping the box
- resizing the window updates the layout without needing to refocus
getCurrentAspectRatioIcon() was reading from aspectRatioList (useState),
which is only updated on manual picker clicks, not external store
writes. Reading aspectRatio from the store directly fixes the stale
icon.
## Video reference library picker
- Added "Pick from library" option to the Video Ref slot, with gallery
filtered to videos
- Added loading state to "Use selected" button in gallery modal
- Enforced seedance-2 limits (max 3 videos / 15s total) for both upload
and library flows, with a deduped video-ref-limit toast so users see a
warning on count overflow, duration overflow, or submitting when already
at max
Two bugs were preventing @image / @video / @character references from
being tagged in prompts written with Chinese, Japanese, or Korean text:
1. The mention-highlight regex was built with just the "g" flag, so a
user-typed "@image6" never matched the canonical label "@Image6" and the
reference was rendered as plain text. Make the regex case-insensitive
and do the colorMap lookup via a lowercase-keyed table so "@image6"
still finds the color for "@Image6".
2. detectMention required the character immediately before "@" to match
/\s/, which never matches CJK characters. Typing "@" right after a
Chinese character like "从" therefore never opened the autocomplete
dropdown, leaving users to type the mention by hand (which then hit bug
1). Replace the whitespace check with a "not an ASCII identifier char"
check so CJK, quotes, and punctuation all count as valid word boundaries
before an @mention.