Commit Graph
479 Commits
Author SHA1 Message Date
Tanish MankuandClaude Opus 4.7 55e470d2ca pagescene: drop view-only mutation gates + rename selector
Visitors can now fully interact with someone else's scene — move objects,
add shapes, edit colors, etc. The previous strict view-only mode is gone.
Save remains the only auth/ownership-gated action; its rewiring lands in
a follow-up.

Renames computeIsViewOnly to computeIsVisitingOthersScene to reflect the
remaining role (it only drives the PreviewBox today; Save-copy label and
Reset button consume it next). Drops getIsViewOnly()/useIsViewOnly()
early-returns from engine actions, drag-drop, gizmo attach, keybinds,
and the Outliner row controls. Strips !isViewOnly wrappers from chrome
in Stage3DBody so the prompt box, controls, panel, and model selector
show for everyone.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 15:09:05 -07:00
Tanish Manku 5465aac4bc pagescene: silence webapp first-paint console errors
Two unrelated noise sources after wiring the editor into the webapp:

1. FontLoader was fetching /resources/fonts/CarterOneRegular.json,
   which exists in the Tauri public/ but not in the webapp's. Vite's
   SPA fallback returns index.html (200, HTML body), the FontLoader's
   progress callback fires "Font Loaded: 1" three times as it streams,
   then JSON.parse chokes on the leading `<` — surfaces as an
   unhandled promise rejection from LoadingPlaceHolderManager.
   Copy the same font asset into the webapp's public/ tree (same
   pattern Tauri and editor3d already use).

2. Editor.initialize() reads sceneContainerEl.offsetWidth/offsetHeight
   to size the WebGLRenderer + post-processing pipeline. On the
   webapp the flex chain (SidebarInset → wrapper → SceneContainer)
   isn't always laid out by first call, so the dimensions are
   transiently 0×0. setSize(0,0) then configureMain(0,0) allocates
   six post-process framebuffer attachments at 0 size, each emitting
   INVALID_FRAMEBUFFER_OPERATION until the next window.resize event
   cascades through and resizes them properly. Clamp the initial
   container offset to ≥1 (Math.max(1, ...)) and replace the
   `?? 0` fallbacks on the canvas dimensions with `|| 1`. First
   frame renders into a harmless 1×1, next resize fixes everything.
2026-05-13 14:37:30 -07:00
Tanish Manku 67d1e73208 promptbox: route webapp Generate through OmniGenApi (fix 404)
PromptBox3D's handleWebEnqueue was POSTing to /v1/image_studio/prompt
via PromptsApi.enqueueImageGeneration, but that endpoint does not exist
on the Rust backend — image_studio_routes.rs only registers
/scene_snapshot and /update_job_status under /v1/image_studio (the
remaining routes live under legacy_routes/). The webapp's /create-image
and other generation flows already use OmniGenApi.generateImage hitting
/v1/omni_gen/image/generate; this commit aligns the 3D editor with that
modern path.

- Snapshot upload still goes through PromptsApi.uploadSceneSnapshot
  (that endpoint is the one image_studio route still in use).
- The returned snapshot media token is prepended to image_media_tokens
  ahead of the user's reference images, matching how the Tauri path
  treats the scene snapshot as the primary input.
- aspect_ratio uses commonAspectRatio for models that support the new
  shape, falling back to getCurrentAspectRatio() otherwise.
- On success: toast "Image added to queue" plus the same
  __storeTaskEnqueueMeta telemetry the Tauri path fires.
- Failure path routes through the existing handleError modal.
- Drops a dead 2-second setTimeout that delayed the success toast.

Tauri path unchanged — IsDesktopApp() still gates handleTauriEnqueue,
which goes through Tauri IPC and bypasses storyteller-web entirely.
2026-05-13 13:53:03 -07:00
Tanish Manku 37723f8602 pagescene: fix color picker not opening in Safari
The Color section in ControlPanelSceneObject had two issues that
compounded into a "no picker shows up" symptom in Safari:

1. setColor(editorEngine?.selected?.userData.color) wrote `undefined`
   into React state for shapes that never had a color set, which made
   <input value={undefined}> uncontrolled and gave the Button no inline
   background color (it fell back to the primary variant, so the swatch
   looked like a generic button instead of a white swatch).
2. The hidden <input type="color"> was a sibling of the swatch
   <label htmlFor={id}>, with h-0 w-0 opacity-0. Safari refuses to open
   the native color picker when the label's target input has no layout
   box — Chrome/Firefox tolerate it, Safari doesn't.

Fixes:
- Default the color state to "#ffffff" when userData.color is unset
  (both at setColor time and at value={} time for belt-and-braces).
- Seed userData.color = "#ffffff" at shape creation in addShape so
  the default carries through save/load roundtrips too.
- Move the <input type="color"> to be a CHILD of the Button label
  and position it absolute inset-0 over the swatch. Click lands
  directly on the input (no label[htmlFor] indirection Safari is
  flaky about) and the input now has a real full-size layout box.
2026-05-13 10:29:00 -07:00
Tanish Manku f977500553 Merge branch 'feature/webapp-pagescene' of github.com:storytold/storyteller-rust into feature/webapp-pagescene
# Conflicts:
#	frontend/apps/artcraft-webapp/src/pages/pagescene/pagescene.tsx
#	frontend/libs/components/pagescene/src/lib/Stage3DBody.tsx
#	frontend/libs/components/promptbox/src/lib/PromptBox3D.tsx
2026-05-13 09:36:17 -07:00
Tanish Manku 008fcfeaa7 pagescene: finish anonymous-use polish
- Gate File → Load my scene for anon: route through promptSignup
  instead of opening a dialog that would just error-toast on the
  silent listUserMediaFiles failure.
- Remove dead SettingsModal mount in Controls3D (no UI ever triggered
  it). Drops the @storyteller/ui-settings-modal import from this file.
- New AnonHintChip pill in the top-right corner of the playground
  ("Sign up to save"). Renders only when currentUserToken is undefined
  AND not in view-only mode; click routes to promptSignup. Tauri users
  never see it.
- Scaffolding for view-only PreviewBox: new component renders a small
  card with the author's generation result; returns null when no URL
  is supplied. Mounted in Stage3DBody under the isViewOnly guard,
  reading sceneMeta.previewImageUrl (new optional field). Data-path
  wiring (populating previewImageUrl from adapter.loadScene's
  response) is the next step — leaving the UI plumbing in place so
  that follow-up is purely data, not layout surgery.
2026-05-13 09:08:43 -07:00
bflatastic 52787c7fc0 add initial model selection on edit 3d 2026-05-13 21:57:09 +07:00
bflatastic 4deeb5e299 webapp: fix control panel sometimes renders overflowing right side 2026-05-13 20:41:10 +07:00
bflatastic cf95e4ce27 webapp: render model selector inside promptbox 2026-05-13 20:34:08 +07:00
bflatastic 572de13881 mobile gate edit 3d page, hold shift to boost movement speed 2026-05-13 20:22:43 +07:00
bflatastic e49c70b852 styling updates 2026-05-13 20:14:04 +07:00
bflatastic 076552fda4 webapp: fix flickering on threejs scene when sidebar collapsing/expanding, added edit 3d to homepage 2026-05-13 13:07:19 +07:00
Tanish Manku a9fa8d710a pagescene AssetMenu: fix featured Sets/Creatures never loading
useFeaturedObjects' auto-fetch effect synchronously flipped
firstFetch.current to IN_PROGRESS before calling fetchFeaturedObjects.
On AssetModal's first mount the EngineContext editor is null, so the
fetch bailed at `if (!editor) return`. When the editor later became
available the effect re-fired (editor is in fetchFeaturedObjects'
useCallback deps), but the IN_PROGRESS guard blocked it — the network
request never fired for any featured category. CHARACTER/OBJECT tabs
appeared populated only because they're merged with local demo arrays
inside AssetModal's assetTabs useMemo; Sets and Creatures have no demo
fallback so the bug was visible there.

Move the editor check into the auto-fetch effect itself and add editor
to its deps, so IN_PROGRESS isn't burned on the no-op call. Regression
from PR #1492.
2026-05-12 18:27:59 -07:00
Tanish Manku e120d009ae pagescene: add view-only mode + anon signup CTA
- view-only mode (driven by ownerToken !== currentUserToken): gates
  engine mutators (add/delete/toggle/transform/color), gizmo attach,
  delete/undo/redo keybinds, drag-to-add; hides editor chrome
  (OnboardingHelper, Controls3D, ControlsTopButtons, PromptBox3D,
  ControlPanelSceneObject, Outliner row toggles, model/cost buttons).
- new optional adapter.promptSignup; webapp adapter wires to existing
  useSignupCta modal. Save / Save-as-copy / Generate / Upload buttons
  call it when currentUserToken is undefined, so anon visitors hit a
  signup modal instead of silent failures.
- PromptBox3D gains onBeforeSubmit?: () => boolean hook; Stage3DBody
  uses it to route anon Generate clicks through promptSignup, since
  the Generate flow bypasses adapter.enqueueGeneration today.
2026-05-12 17:41:18 -07:00
Tanish MankuandClaude Opus 4.7 fcb0ddec56 webapp pagescene: fix top blank space; de-topbar shared lib layout
- styles.css: move .glass into @layer components so Tailwind's
  .absolute utility wins the cascade. OnboardingHelper was rendering
  position: relative and pushing the editor down on first paint until
  clicking dismissed it.
- SceneContainer + Stage3DBody: drop hardcoded calc(100vh - 68px) and
  height - 56 topbar offsets; the lib now fills its parent container.
- Webapp adapter: drop the +56 getViewportSize compensation now that
  the lib doesn't subtract a topbar from the supplied height.
- Tauri PageScene: wrap Stage3D in a calc(100vh - 56px) container
  (matching .topbar-spacer) so its shape is preserved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 14:20:27 -07:00
Tanish Manku 2178afd736 webapp: mount pagescene at /pagescene with sidebar-aware viewport
Adds /pagescene (and /pagescene/:sceneToken) under the webapp's public
chrome (inside ProtectedLayout, outside RequireAuth) so anonymous users
can view scenes too. Adapter implementation mirrors the website's, with
two webapp-specific tweaks: imports the local useSession / showToast /
invalidateSession helpers, and getViewportSize returns the wrapper's
live ResizeObserver-measured rect so DnD hit-testing matches the visible
canvas (not window.innerWidth).

Sidebar handling: the lib's position-fixed UI is scoped to a wrapper
div with transform: translateZ(0), which creates a new containing block.
The wrapper renders inside SidebarInset's flex flow, so the editor sits
naturally to the right of the sidebar and below the topbar; expanded-
sidebar behavior is deferred (currently shrinks the page further per the
flex layout).

Sidebar nav gets an "Edit 3D" entry between Image and Video. Tailwind
config gets brand-primary/secondary/tertiary, action color, red/green/
blue DEFAULTs; styles.css adds .bg-ui-panel-gradient, .prevent-select,
.dot-typing — same gap-fills landed on the website.

No new endpoints. tsconfig churn from nx sync.
2026-05-12 09:18:13 -07:00
Tanish Manku 2d6af20d0b ui-upload-modal: lift UploadModal3D/Image/Splat into shared lib
Hoists the three feature-specific upload modals out of the artcraft
Tauri host into @storyteller/ui-upload-modal so the website (and any
future host) can render the same flows through PageScene's adapter
slots. Replaces direct `~/Classes/ApiManager` calls with @storyteller/api's
MediaUploadApi/MediaFilesApi.

Removes the old lib-internal UploadModal/UploadFiles/uploadAssets
placeholders (unused) and inlines the host-local enums
(MediaFileAnimationType, UploaderState/States, file-type enums) into
Types.ts. Adds UploadSpzFile to @storyteller/api's MediaUploadApi and
the SPLAT variant to FilterEngineCategories.
2026-05-12 09:11:11 -07:00
Brandon Thomas d2dbef249c tauri providers - fal api key support (#1502) 2026-05-12 00:02:41 -04:00
BFlat 89f6015e3f Fix aspect ratio picker losing label after model switch (#1499)
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`.
2026-05-11 20:24:01 +07:00
Tanish Manku 2d18a07843 3D PageScene: Componentize and big refactor (#1492) 2026-05-09 14:26:42 -07:00
Tanish Manku 369c552096 PageDraw: Generate fixes and performance boost (#1494) 2026-05-09 13:51:25 -07:00
bflatastic f8be6ea4c9 website: hide resolution picker, progress timer 5 mins 2026-05-09 16:35:18 +07:00
Brandon Thomas d0e5a05253 frontend api stuff (#1491) 2026-05-08 22:01:21 -04:00
Brandon Thomas 7471259d28 fix frontend errors (missing vite config, type errors) (#1490) 2026-05-08 21:40:46 -04:00
BFlat b4da753346 video background change feature (#1480)
- both app and website
2026-05-09 02:31:54 +07:00
Brandon ThomasandTanish Manku 58b64b694c Big tauri refactor: new consolidated commands, deprecate and remove duplication (#1486)
Co-authored-by: Tanish Manku <tanish2k09.dev@gmail.com>
2026-05-08 09:29:25 -04:00
BFlat f666e68dcd app: ask location before download (#1483)
- toggle in settings to enable disable ask location on download button
pressed
2026-05-08 16:25:27 +07:00
BFlat 9b6b0175ea desktop app: unblock object generations, styling cleanup, model selector (#1478) 2026-05-06 22:51:39 +07:00
BFlat ac9a0c2172 show more media info on desktop app lightbox (#1474)
- 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.
2026-05-05 21:23:07 +07:00
BFlat 551f4fbae3 batch prompt update 2026-05-01 15:30:20 +07:00
BFlat 122b2464fc batch prompt api and show prompt on job cards (#1464)
- show prompts and job details on the gallery cards
- task queue too
2026-05-01 15:26:46 +07:00
Tanish Manku f90d928f33 Surface credits-fetch state on top bar coin icon + 60s poll (#1458)
Customers occasionally saw "0 Credits" with no signal that the fetch had
failed silently. Add a status badge on the coin (slow/failed/ recovered,
hidden in the happy path), a 60s background refresh, and gate the
initial fetch on AUTH_STATUS.LOGGED_IN to remove the 1s setTimeout
band-aid that was racing intermediate auth states.
2026-04-30 16:24:49 -07:00
BFlat 8f9607cc5d promptbox: default both Enter and Shift+Enter to newline (#1454)
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.
2026-04-30 10:02:10 +07:00
BFlat 13f1fb4f63 bug fixes for character and video ref uploads on website, show error … (#1451)
…toasts
2026-04-30 01:16:41 +07:00
Brandon Thomas 967828ec2f tauri changes to support artcraft_router v2 (happy horse, seedance 2, etc.) (#1448) 2026-04-29 13:53:30 -04:00
BFlat ae8fd30b4b shift enter to generate by default, toggleable via settings panel in app (#1440)
- 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
2026-04-26 21:34:08 +07:00
bflatastic d37a732d60 name mappings for happy horse 1.0 2026-04-24 16:15:17 +07:00
bflatastic 5535d50ec3 website: image ref selection limit fixed, gallery item active focus outline blinking fixed 2026-04-24 13:25:17 +07:00
BFlat 9166148701 website error messages (#1431)
artcraft website now shows error messages on the failed cards and task
queue
2026-04-23 13:43:17 +07:00
Brandon Thomas 1f53b6a4cf tauri: seedance 2.0 fast, seedance 2.0 1080p (#1427) 2026-04-22 19:45:58 -04:00
Brandon Thomas 5eb2abf112 artcraft desktop gpt-image cost estimates + quality arg (#1425) 2026-04-22 19:17:07 -04:00
bflatastic 02676680b1 fixed quality field name 2026-04-23 01:56:45 +07:00
BFlat ba19e9ae40 gpt image 2 quality selector (#1422) 2026-04-23 01:37:50 +07:00
Brandon Thomas 00499252a1 gpt-image-2 desktop support for quality (#1421) 2026-04-22 14:18:55 -04:00
Brandon Thomas c2ca096099 desktop frontend support for gpt-image-2 (#1418) 2026-04-22 10:40:47 -04:00
bflatastic 8bc552c450 add gpt image 2 to name mapping 2026-04-22 18:44:24 +07:00
BFlat 128d3e43c5 reuse gallery modal for the artcraft website and app styling aligned (#1415)
- website to reuse shared app lib's gallery modal for image selection
- styling alignments with the desktop app
- new checkbox shared component
2026-04-22 18:38:02 +07:00
BFlat fc0f4b7f5c fix: prevent character mention from matching wrong character 2026-04-21 23:20:00 +07:00
BFlat 6883b64276 website: unified lightbox, recreate, desktop CTA, prompt fixes (#1404)
## Artcraft website: unified lightbox, recreate, desktop CTA, prompt
fixes

**Lightbox**
- Gallery modal and `/media/:id` page now share one details component -
no more drift.
- Author sticks to the top when you scroll; `X` moved to the details
panel; "Show more" prompt toggle added to the media page.
- Shows aspect ratio, resolution, duration, and audio on/off.

**Recreate (new)**
- Button in the lightbox restores prompt, refs (image / end-frame /
video / audio), model, aspect, resolution, duration, audio toggle, and
input mode from a past generation.
- Routes to Create Image vs Create Video based on the saved model class,
not URL guessing.
- Does not auto-generate.

**Desktop CTA**
- Dismissible banner above the promptbox linking to the desktop app.
Hidden on mobile, reappears 24h after dismissal.

**Model names**
- Model selector uses `full_name` from the OmniGen API so new models
show up correctly without a code change.
- Added Seedance 2.0 Fast to the shared model list for the lightbox
details panel.

**Promptbox `@mentions`**
- Triggers correctly after Chinese, punctuation, or emoji - not just
whitespace.
- Case-insensitive: `@image1` highlights as `@Image1`.
2026-04-20 21:20:27 +07:00
BFlat 6542834336 fix: video promptbox layout bugs (#1403)
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
2026-04-20 07:36:47 +07:00