Skip to content

feat: creators tools dashboard for Worlds - #571

Open
gonpombo8 wants to merge 14 commits into
masterfrom
feat/creators-tools
Open

feat: creators tools dashboard for Worlds#571
gonpombo8 wants to merge 14 commits into
masterfrom
feat/creators-tools

Conversation

@gonpombo8

Copy link
Copy Markdown

Summary

Adds the Creators Tools dashboard — a Roblox-style management surface for the Worlds a connected wallet owns or collaborates on, as a heavy lazy-loaded DappsShell route group under /creators.

  • /creators — Creations grid (worlds owned/contributable), enriched with places-api thumbnails + live user counts.
  • /creators/world/:name — routed left-rail layout, each tab its own page:
    • Overview (deployment info + Jump in), Preview (single-click bevy scene-viewer iframe, credentialless), Events, Auth Server (signed /logs SSE stream + embedded scene/player/env storage managers; gated on authoritativeMultiplayer), Streaming (OBS/RTMP key), Scene admins, Access (world ACL), Bans, and Analytics/Monetization placeholders.
  • New gatekeeperClient RTK Query base + authServer / sceneGatekeeper / worldPermissions / bans / creators feature folders. Shared components/storage/managers/* now back both /storage and /creators.

Stacks on the /discover commits already on this branch (not yet in master); those land with this PR.

What could break

  • Log streaming needs a backend deploy. The /logs SSE endpoint requires CORS on the multiplayer-server (sdk-multiplayer-server#94). It already passes on .zone; prod needs that PR deployed before logs stream.
  • COEP credentialless is set per-route in vercel.json for /creators (same as /discover) so the bevy Preview iframe becomes crossOriginIsolated — a misconfigured header would break Preview only.
  • Auth Server tabs are gated on authoritativeMultiplayer; worlds without it show an enable-in-scene.json message instead of managers.
  • All gatekeeper mutations are signed-fetch — unauthenticated users see sign-in prompts, not errors.

How to test

  1. npm run dev, connect a wallet that owns ≥1 World, open /creators.
  2. Enter a world and walk each tab: Overview, Preview (click Launch), Events, Auth Server → Logs (Stream) + Storage, Streaming, Scene admins, Access, Bans.
  3. Verify Streaming Expires shows ~4 days out (not a far-future date).
  4. npm run build && npm run preview and load /creators/world/<name> to confirm the prod lazy chunk renders.

Validated in-browser against live .zone data; gate green: tsc, eslint, lint:pkg, 2247 tests, build, prod-preview. Coverage ≥95% on all new logic files.

gonpombo8 added 10 commits May 21, 2026 09:45
Renames the heavy-route components and pages from `social/` to `discover/`
to match the URL rename, and brings every /discover surface in line with
the sites design system. Top-level fixes:

- Eliminate "two loaders" cold-load: home/communities/scene-detail now
  short-circuit to a bare CenteredBox so the DappsShell Suspense → page
  loader handoff anchors at the same viewport Y on mobile
- Mobile bevy fallback: detect touch UA, skip iframe mount, show a
  Decentraland-Web card with the same App Store / Google Play badge
  art used by landing Hero (no more clipped bevy template)
- Hide SceneChatDock loading state on tablet/mobile so the chat spinner
  doesn't stack below the watcher spinner
- Seed PEOPLE IN-WORLD pill from places-api user_count so it paints a
  real number before LiveKit finishes connecting
- Filter "Road at X,Y" placeholders out of LIVE NOW + BROWSE grids
- Community detail: white-pill primary CTA + ABOUT section label so the
  page matches the scene-detail vocabulary
- vercel.json: COOP/COEP + Permissions-Policy on /discover/(place|world)
  so SharedArrayBuffer works for bevy on Vercel previews
The bevy iframe was loading but failing to use SharedArrayBuffer because
its `self.crossOriginIsolated` was never granted. Root cause: React's
JSX spread of an unknown `credentialless` attribute on `<iframe>` was
being stripped in the built bundle, so the iframe loaded with the parent
COEP credentialless mode but without the per-element opt-in needed for
COI propagation. Attach the attribute imperatively via a ref callback —
that survives the bundler and any React attribute filtering. Also lock
the vercel.json source pattern to path-to-regexp's canonical
`/discover/:type(place|world)/:path*` form.
- Extract useSceneRoom to src/hooks/ with spec (6 tests)
- Add discover.client.spec.ts smoke test (4 tests)
- Move getSyntheticAvatarUrl into src/utils/avatarColor.ts; drop the
  duplicate in PlaceCard + CommunityCard
- Consolidate loaders to <CenteredBox>; remove dead Loader/InitialLoader
- Tighten isRoad() to require empty categories alongside title prefix
- Add /discover entries to bug_report.yml + feature_request.yml
- Sync CLAUDE.md routes and feature map to /discover; refresh README
- Add discover.community.about so community detail no longer borrows
  the scene-namespaced key
- Restore CLDR-correct =0/other plural shape for waiting.hint on ja/ko/zh
- Wrap PersonRow in memo() to match sibling row components
- Replace stale data-testid="social-page" with discover-page
… across /discover

- SceneWatcherCard's no-broadcast branch now renders a stripped-down
  SceneOnlyWatcher with the DCL Web tab, EXPLORE SCENE launch, fullscreen
  and the credentialless iframe ref. Previously it short-circuited to a
  placeholder so users could not enter scenes with nobody streaming
  (eg /discover/place/1,95). LiveKit hooks are not used in this path
  because useEnsureRoom throws outside a LiveKitRoom context.

- vercel.json: extend COOP/COEP/Permissions-Policy from
  /discover/:type(place|world)/:path* to the whole /discover tree.
  Without this, a user landing on /discover and then SPA-navigating
  into a scene keeps the un-isolated parent document and bevy's
  SharedArrayBuffer worker DataCloneErrors until a hard reload.
Roblox-style /creators dashboard: a Creations grid of worlds the connected
wallet owns or collaborates on, and a per-world routed left-rail layout with
Overview, Preview (click-to-mount bevy), Events, Auth Server (server logs +
embedded scene/player storage), Streaming, Scene admins, Access (world ACL),
and Bans, plus Analytics/Monetization placeholders.

Adds the gatekeeperClient RTK Query base and authServer/sceneGatekeeper/
worldPermissions/bans/creators feature folders, the signed /logs SSE stream,
and shared storage managers reused by /storage and /creators. Streaming
expiry uses the gatekeeper's epoch-ms ends_at.
@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sites Ready Ready Preview, Comment Jun 22, 2026 8:13pm

Request Review

@coveralls

coveralls commented Jun 10, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 27980919875

Coverage decreased (-1.0%) to 92.497%

Details

  • Coverage decreased (-1.0%) from the base build.
  • Patch coverage: 96 uncovered changes across 2 files (1144 of 1240 lines covered, 92.26%).
  • 22 coverage regressions across 5 files.

Uncovered Changes

File Changed Covered %
src/features/discover/discover.client.ts 115 23 20.0%
src/utils/avatarColor.ts 12 8 66.67%
Total (52 files) 1240 1144 92.26%

Coverage Regressions

22 previously-covered lines in 5 files lost coverage.

File Lines Losing Coverage Coverage
src/components/whats-on/CreateEvent/EventForm.tsx 8 86.84%
src/features/events/events.helpers.ts 6 88.92%
src/hooks/useCreateEventForm.ts 6 93.84%
src/components/whats-on/LiveNow/LiveNow.tsx 1 91.95%
src/hooks/useCreateEventForm.helpers.ts 1 92.73%

Coverage Stats

Coverage Status
Relevant Lines: 6791
Covered Lines: 6578
Line Coverage: 96.86%
Relevant Branches: 4871
Covered Branches: 4209
Branch Coverage: 86.41%
Branches in Coverage %: Yes
Coverage Strength: 16.47 hits per line

💛 - Coveralls

A creator may only manage worlds they own (DCL names) or collaborate on
(contributable domains). CreatorWorldLayout now checks the connected wallet
against that set — the same one the Creations grid lists — before rendering
any tab or fetching the world's data. Unauthenticated users get a sign-in
prompt; authenticated wallets without rights get a 'no access' state instead
of the dashboard, so the route can't be reached by URL.
KeyTable now slices its rows with a MUI TablePagination (10/25/50 per page),
matching the UsersAdminPage pattern, so worlds with many storage keys stay
manageable. The pager only appears past one page, resets on rows-per-page
change, and clamps back into range when keys are deleted. Shared by the
/storage Scene/Environment tabs and the creators Auth Server storage tab.
Adds a co-located spec (KeyTable was previously untested).
Adds a Moderation rail entry with Auth-Server-style sub-tabs (Scene admins /
Bans), de-cluttering the rail. The Admins/Bans pages become SceneAdminsPanel /
BansPanel sub-panels hosted by ModerationPage (one card, one title, sub-tab
nav); Access stays its own tab. Old /admins and /bans deep links redirect to
/moderation.
The scene/env key table already paged its rows; the remaining storage
lists (players, plus the worlds/lands tabs on the select page) rendered
every card at once, so worlds with many players or accounts owning many
names scrolled forever. Extract the table's inline pager into a shared
usePagination hook + StoragePagination component, refactor KeyTable onto
them, and apply them to the three card grids (12/24/48 per page) so all
storage lists stay manageable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants