Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/editor/app/client-bootstrap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// idempotent under HMR.
import '../lib/bootstrap'
import { type ReactNode, useEffect } from 'react'
import { I18nProvider } from '@/lib/i18n'

export function ClientBootstrap({
children,
Expand All @@ -22,5 +23,5 @@ export function ClientBootstrap({
if (!enableDevDiagnostics) return
import('react-scan').then(({ scan }) => scan({ enabled: true }))
}, [enableDevDiagnostics])
return children
return <I18nProvider>{children}</I18nProvider>
}
17 changes: 11 additions & 6 deletions apps/editor/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
WebXRFeatureConsumer,
WebXRFeatureRuntime,
} from '@/components/webxr-feature-gate'
import { useI18n } from '@/lib/i18n'

// The open-source editor only ships the built-in catalog (no uploaded items),
// so the Library/Community/Mine source chips and tag filters add nothing —
Expand Down Expand Up @@ -111,6 +112,11 @@ const PROJECT_ID = 'local-editor'

export default function Home() {
const webXRInstalled = useWebXRInstalled()
const { t, translateDisplayText } = useI18n()
const sidebarTabs = SIDEBAR_TABS.map((tab) => ({
...tab,
label: translateDisplayText(tab.label),
}))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sidebar tabs use the wrong catalog

Medium Severity

Home sidebar labels go through translateDisplayText instead of the typed sidebar.* keys. Scene and Settings have no display-map entries and stay English, while Build resolves to 建筑 rather than 建模.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 23b1703. Configure here.

return (
<div className="relative h-screen w-screen">
<WebXRFeatureRuntime enabled={webXRInstalled}>
Expand All @@ -120,14 +126,12 @@ export default function Home() {
{PROJECT_ID === 'local-editor' && (
<div className="pointer-events-none absolute top-14 left-1/2 z-40 -translate-x-1/2">
<div className="pointer-events-none flex max-w-[min(92vw,42rem)] flex-wrap items-center justify-center gap-x-3 gap-y-1 rounded-full border border-border/60 bg-background/90 px-4 py-1.5 text-xs shadow-sm backdrop-blur">
<span className="text-muted-foreground">
Blank canvas — saved scenes are under Scenes (not this page).
</span>
<span className="text-muted-foreground">{t('app.blankCanvas')}</span>
<Link
className="pointer-events-auto font-medium text-foreground hover:underline"
href="/scenes"
>
Open saved scenes
{t('app.openScenes')}
</Link>
</div>
</div>
Expand All @@ -136,7 +140,8 @@ export default function Home() {
immersive={vr?.session ? vr.immersive : undefined}
layoutVersion="v2"
projectId={PROJECT_ID}
sidebarTabs={SIDEBAR_TABS}
sidebarTabs={sidebarTabs}
translateDisplayText={translateDisplayText}
viewerToolbarLeft={<CommunityViewerToolbarLeft />}
viewerToolbarRight={
<CommunityViewerToolbarRight
Expand All @@ -148,7 +153,7 @@ export default function Home() {
/>
) : null
}
vrLabel="Enter VR"
vrLabel={translateDisplayText('Enter VR')}
/>
}
/>
Expand Down
38 changes: 26 additions & 12 deletions apps/editor/app/scenes/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { headers } from 'next/headers'
import { cookies, headers } from 'next/headers'
import Link from 'next/link'
import { CreateSceneButton } from '@/components/save-button'
import type { SceneMeta } from '@/components/scene-loader'
Expand Down Expand Up @@ -43,6 +43,8 @@ function formatDate(iso: string): string {

export default async function ScenesPage() {
const scenes = await fetchScenes()
const locale = (await cookies()).get('pascal.locale')?.value === 'zh-CN' ? 'zh-CN' : 'en'
const zh = locale === 'zh-CN'

return (
<div className="min-h-screen bg-background">
Expand All @@ -53,28 +55,34 @@ export default async function ScenesPage() {
className="text-muted-foreground transition-colors hover:text-foreground"
href="/"
>
Home
{zh ? '首页' : 'Home'}
</Link>
<span className="text-muted-foreground">/</span>
<span className="font-medium text-foreground">Scenes</span>
<span className="font-medium text-foreground">{zh ? '场景' : 'Scenes'}</span>
</nav>
<CreateSceneButton />
<CreateSceneButton label={zh ? '新建场景' : 'Create new scene'} locale={locale} />
</div>
</header>

<main className="container mx-auto max-w-5xl px-6 py-12">
<h1 className="mb-2 font-bold text-3xl">Your scenes</h1>
<h1 className="mb-2 font-bold text-3xl">{zh ? '我的场景' : 'Your scenes'}</h1>
<p className="mb-8 text-muted-foreground text-sm">
{scenes.length === 0
? 'No scenes yet. Create one to get started.'
: `${scenes.length} scene${scenes.length === 1 ? '' : 's'}.`}
? zh
? '还没有场景,可以先新建一个。'
: 'No scenes yet. Create one to get started.'
: zh
? `共 ${scenes.length} 个场景。`
: `${scenes.length} scene${scenes.length === 1 ? '' : 's'}.`}
</p>

{scenes.length === 0 ? (
<div className="rounded-xl border border-border/60 border-dashed bg-background p-12 text-center">
<p className="text-muted-foreground text-sm">You haven&apos;t saved any scenes yet.</p>
<p className="text-muted-foreground text-sm">
{zh ? '尚未保存任何场景。' : "You haven't saved any scenes yet."}
</p>
<div className="mt-4 flex justify-center">
<CreateSceneButton />
<CreateSceneButton label={zh ? '新建场景' : 'Create new scene'} locale={locale} />
</div>
</div>
) : (
Expand All @@ -94,16 +102,22 @@ export default async function ScenesPage() {
src={scene.thumbnailUrl}
/>
) : (
<span className="text-muted-foreground text-xs">No thumbnail</span>
<span className="text-muted-foreground text-xs">
{zh ? '暂无缩略图' : 'No thumbnail'}
</span>
)}
</div>
<div className="mt-3">
<h2 className="truncate font-semibold text-sm group-hover:text-foreground">
{scene.name}
</h2>
<div className="mt-1 flex items-center justify-between text-muted-foreground text-xs">
<span>{scene.nodeCount} nodes</span>
<time dateTime={scene.updatedAt}>{formatDate(scene.updatedAt)}</time>
<span>{zh ? `${scene.nodeCount} 个节点` : `${scene.nodeCount} nodes`}</span>
<time dateTime={scene.updatedAt}>
{zh
? new Date(scene.updatedAt).toLocaleString('zh-CN')
: formatDate(scene.updatedAt)}
</time>
</div>
</div>
</Link>
Expand Down
6 changes: 4 additions & 2 deletions apps/editor/components/build-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
MODULAR_CABINET_ICON,
} from '@/lib/build-palette'
import { getActiveRoofFeatureId, ROOF_TYPE_OPTIONS } from '@/lib/build-tab-state'
import { useI18n } from '@/lib/i18n'
import { cn } from '@/lib/utils'

const subscribeToClientMount = () => () => {}
Expand All @@ -60,6 +61,7 @@ const subscribeToClientMount = () => () => {}
* with the kind's own `def.defaults()`. Painting has its own rail panel.
*/
export function BuildTab() {
const { translateDisplayText } = useI18n()
const [mepOpen, setMepOpen] = useState(false)
const activeTool = useEditor((s) => s.tool)
const selectedId = useViewer((s) => s.selection.selectedIds[0])
Expand Down Expand Up @@ -178,13 +180,13 @@ export function BuildTab() {
data-build-tool={type.id}
iconSrc={type.iconSrc}
key={type.id}
label={type.label}
label={translateDisplayText(type.label)}
onClick={() => {
triggerSFX('sfx:menu-click')
handleTypeClick(type)
}}
onMouseEnter={() => triggerSFX('sfx:menu-hover')}
title={type.label}
title={translateDisplayText(type.label)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roof UI ignores prepared translation keys

Medium Severity

ROOF_TYPE_OPTIONS now carries labelKey values, and catalogs include build.roofType, build.roofFeatures, and roof.conicalHint, but the Build tab still renders the English label plus hardcoded section copy. Roof type controls stay English in Simplified Chinese.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 23b1703. Configure here.

/>
)
const typesIn = (section: NonNullable<BuildType['section']>) =>
Expand Down
10 changes: 8 additions & 2 deletions apps/editor/components/save-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ interface SaveButtonProps {
/**
* Creates a new empty scene and navigates the user to it.
*/
export function CreateSceneButton({ label = 'Create new scene' }: { label?: string } = {}) {
export function CreateSceneButton({
label = 'Create new scene',
locale = 'en',
}: {
label?: string
locale?: 'en' | 'zh-CN'
} = {}) {
const router = useRouter()
const [isCreating, setIsCreating] = useState(false)
const [error, setError] = useState<string | null>(null)
Expand Down Expand Up @@ -55,7 +61,7 @@ export function CreateSceneButton({ label = 'Create new scene' }: { label?: stri
onClick={handleCreate}
type="button"
>
{isCreating ? 'Creating…' : label}
{isCreating ? (locale === 'zh-CN' ? '正在创建…' : 'Creating…') : label}
</button>
</div>
)
Expand Down
Loading