mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 03:14:00 +00:00
i18n(de): address code review findings
Localize a legacy Nepal base shot only when the applied pack marker binds that title to this exact shot id, so a user shot renamed to a built-in title stays as typed in every locale. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
a0c8b6f893
commit
0e45bcdf14
3 files changed
+80
-15
No files matched your search
+14
-13
@@ -1071,7 +1071,7 @@ export function displayShotTitle(title, shot = undefined, scene = undefined) {
|
|||||||
const fromRecipe = shot
|
const fromRecipe = shot
|
||||||
? Boolean(shot.sourcePackId) ||
|
? Boolean(shot.sourcePackId) ||
|
||||||
recipeDeclaresShotTitle(scene?.id, text) ||
|
recipeDeclaresShotTitle(scene?.id, text) ||
|
||||||
shotPackDeclaresBaseTitle(scene, text)
|
shotPackBindsShot(scene, text, shot)
|
||||||
: true;
|
: true;
|
||||||
if (fromRecipe && BUILTIN_SHOT_TITLES.has(text)) return t(text);
|
if (fromRecipe && BUILTIN_SHOT_TITLES.has(text)) return t(text);
|
||||||
const numbered = /^Shot ([1-9]\d*)$/.exec(text);
|
const numbered = /^Shot ([1-9]\d*)$/.exec(text);
|
||||||
@@ -1079,21 +1079,22 @@ export function displayShotTitle(title, shot = undefined, scene = undefined) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether a shot pack that upgraded this scene declares the title for one of
|
* Whether a shot pack applied to this scene binds this title to this exact
|
||||||
* its legacy base shots. The upgrade rebuilds those shots without a
|
* shot. The legacy upgrade rebuilds the base shots without a sourcePackId
|
||||||
* sourcePackId (see SceneDirector._bootstrapLegacyShotPacks), so the pack's
|
* (see SceneDirector._bootstrapLegacyShotPacks), but the pack marker records
|
||||||
* own shots in the scene vouch for them.
|
* their ids, so a user shot that only shares the title is not vouched for.
|
||||||
* @param {{shots?: Array<{sourcePackId?: string}>}} [scene]
|
* @param {{appliedShotPacks?: Array<{shotBindings?: Object<string, string>}>}} [scene]
|
||||||
* @param {string} title
|
* @param {string} title
|
||||||
|
* @param {{id?: string}} shot
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
function shotPackDeclaresBaseTitle(scene, title) {
|
function shotPackBindsShot(scene, title, shot) {
|
||||||
const shots = Array.isArray(scene?.shots) ? scene.shots : [];
|
const packs = Array.isArray(scene?.appliedShotPacks)
|
||||||
return SCENE_APPEND_RECIPES.some(
|
? scene.appliedShotPacks
|
||||||
(pack) =>
|
: [];
|
||||||
pack.legacySceneBootstrap?.cameraPath?.some(
|
return (
|
||||||
(keyframe) => keyframe?.title === title,
|
Boolean(shot?.id) &&
|
||||||
) && shots.some((item) => item?.sourcePackId === pack.id),
|
packs.some((pack) => pack?.shotBindings?.[title] === shot.id)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,12 +151,25 @@ test('the base shots of a scene the Nepal pack upgraded localize', () => {
|
|||||||
setLocale('de');
|
setLocale('de');
|
||||||
const title = pack.legacySceneBootstrap.cameraPath[0].title;
|
const title = pack.legacySceneBootstrap.cameraPath[0].title;
|
||||||
const base = { id: 'shot-base', title };
|
const base = { id: 'shot-base', title };
|
||||||
|
// A user shot renamed to the same built-in title is not the bound one.
|
||||||
|
const renamed = { id: 'shot-user', title };
|
||||||
const upgraded = {
|
const upgraded = {
|
||||||
id: 'scene-upgraded',
|
id: 'scene-upgraded',
|
||||||
shots: [base, { id: 'shot-pack', title: 'x', sourcePackId: pack.id }],
|
shots: [
|
||||||
|
base,
|
||||||
|
{ id: 'shot-pack', title: 'x', sourcePackId: pack.id },
|
||||||
|
renamed,
|
||||||
|
],
|
||||||
|
appliedShotPacks: [
|
||||||
|
{ id: pack.id, version: 1, shotBindings: { [title]: base.id } },
|
||||||
|
],
|
||||||
};
|
};
|
||||||
assert.equal(displayShotTitle(title, base, upgraded), displayShotTitle(title));
|
assert.equal(
|
||||||
|
displayShotTitle(title, base, upgraded),
|
||||||
|
displayShotTitle(title),
|
||||||
|
);
|
||||||
assert.notEqual(displayShotTitle(title), title);
|
assert.notEqual(displayShotTitle(title), title);
|
||||||
|
assert.equal(displayShotTitle(title, renamed, upgraded), title);
|
||||||
// The same title in a scene no pack touched stays as typed.
|
// The same title in a scene no pack touched stays as typed.
|
||||||
assert.equal(
|
assert.equal(
|
||||||
displayShotTitle(title, base, { id: 'scene-user', shots: [base] }),
|
displayShotTitle(title, base, { id: 'scene-user', shots: [base] }),
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// Reproduction: a user-authored shot whose typed title equals a legacy base
|
||||||
|
// title of the Nepal pack must stay as typed in an upgraded scene.
|
||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { SCENE_APPEND_RECIPES, displayShotTitle } from './recipes.js';
|
||||||
|
import { setLocale } from '../i18n/index.js';
|
||||||
|
|
||||||
|
test.afterEach(() => setLocale('en'));
|
||||||
|
|
||||||
|
test('a user shot named like a legacy base shot stays as typed in an upgraded scene', () => {
|
||||||
|
const pack = SCENE_APPEND_RECIPES.find(
|
||||||
|
(recipe) => recipe.legacySceneBootstrap?.cameraPath?.length,
|
||||||
|
);
|
||||||
|
assert.ok(pack, 'Nepal append pack with legacy bootstrap');
|
||||||
|
const baseTitles = pack.legacySceneBootstrap.cameraPath.map((k) => k.title);
|
||||||
|
// Shape written by SceneDirector._bootstrapLegacyShotPacks + appendShotPack:
|
||||||
|
// base shots without sourcePackId, pack shots with it, marker bindings.
|
||||||
|
const base = baseTitles.map((title, i) => ({ id: `base-${i}`, title }));
|
||||||
|
const packShot = {
|
||||||
|
id: 'pack-0',
|
||||||
|
title: 'Upper Valley Collapse',
|
||||||
|
sourcePackId: pack.id,
|
||||||
|
};
|
||||||
|
// Captured by captureShot ("Shot 10"), then renamed by the user.
|
||||||
|
const userShot = { id: 'user-1', title: 'Bhote Koshi Flood Path' };
|
||||||
|
const scene = {
|
||||||
|
id: 'scene-user-upgraded',
|
||||||
|
shots: [...base, packShot, userShot],
|
||||||
|
appliedShotPacks: [
|
||||||
|
{
|
||||||
|
id: pack.id,
|
||||||
|
version: Number(pack.version) || 1,
|
||||||
|
shotBindings: Object.fromEntries(base.map((s) => [s.title, s.id])),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
for (const locale of ['de', 'ru', 'es']) {
|
||||||
|
setLocale(locale);
|
||||||
|
// The real base shot localizes (intended by the branch).
|
||||||
|
assert.notEqual(
|
||||||
|
displayShotTitle(base[5].title, base[5], scene),
|
||||||
|
base[5].title,
|
||||||
|
);
|
||||||
|
// The user's shot must stay as typed.
|
||||||
|
assert.equal(
|
||||||
|
displayShotTitle(userShot.title, userShot, scene),
|
||||||
|
userShot.title,
|
||||||
|
`${locale}: user-typed title was translated`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in new issue
Block a user