mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
i18n(it): address code review findings
Localize a bootstrap shot title without a source pack only when the Nepal pack marker binds that title to the shot's id, so an operator shot renamed to a bootstrap title in the built-in scene stays as typed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
d383f25bb3
commit
f8e96e1484
4 files changed
+57
-10
No files matched your search
@@ -0,0 +1,20 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { SCENE_RECIPES, displayShotTitle } from './recipes.js';
|
||||
import { setLocale } from '../i18n/index.js';
|
||||
|
||||
test('an operator-typed title in the built-in Nepal scene stays as typed', () => {
|
||||
const scene = SCENE_RECIPES.find((r) => r.id === 'bhote-koshi-nepal-scene');
|
||||
assert.ok(scene, 'built-in bootstrap scene exists');
|
||||
for (const locale of ['ru', 'es', 'it', 'zh-CN', 'zh-Hant']) {
|
||||
setLocale(locale);
|
||||
const title = 'Global Incident Context';
|
||||
// A shot captured by the operator: no sourcePackId, renamed to this title.
|
||||
const shown = displayShotTitle(
|
||||
title,
|
||||
{ id: 'shot-user', title },
|
||||
{ id: scene.id },
|
||||
);
|
||||
assert.equal(shown, title, `${locale}: got ${shown}`);
|
||||
}
|
||||
});
|
||||
@@ -712,6 +712,10 @@ test('a legacy three-shot Nepal browser project bootstraps to the current 25-sho
|
||||
assert.deepEqual(scene.shots.slice(0, 3).map(({ camera }) => camera), originalCameras);
|
||||
assert.equal(scene.appliedShotPacks[0].id, 'bhote-koshi-nepal-evidence-pack');
|
||||
assert.equal(scene.appliedShotPacks[0].version, 18);
|
||||
// displayShotTitle trusts these bindings to localize the bootstrap shots.
|
||||
for (const shot of scene.shots.slice(0, 8)) {
|
||||
assert.equal(scene.appliedShotPacks[0].shotBindings[shot.title], shot.id);
|
||||
}
|
||||
assert.equal(director._selectedSceneId, scene.id);
|
||||
assert.equal(director._selectedShotId, scene.shots[0].id);
|
||||
} finally {
|
||||
|
||||
+19
-8
@@ -1061,33 +1061,44 @@ export function displaySceneTitle(scene) {
|
||||
* (`sourcePackId`), so a typed title that matches a built-in one stays as
|
||||
* typed. Without `shot`, the title alone decides.
|
||||
* @param {string} title
|
||||
* @param {{sourcePackId?: string}} [shot]
|
||||
* @param {{id?: string}} [scene] The shot's scene, for projects saved before
|
||||
* shots recorded their source pack.
|
||||
* @param {{id?: string, sourcePackId?: string}} [shot]
|
||||
* @param {{id?: string, appliedShotPacks?: Array<{id?: string, shotBindings?: Object<string, string>}>}} [scene]
|
||||
* The shot's scene, for projects saved before shots recorded their source
|
||||
* pack.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function displayShotTitle(title, shot = undefined, scene = undefined) {
|
||||
const text = typeof title === 'string' ? title : '';
|
||||
const fromRecipe = shot
|
||||
? Boolean(shot.sourcePackId) || recipeDeclaresShotTitle(scene?.id, text)
|
||||
? Boolean(shot.sourcePackId) || recipeDeclaresShotTitle(scene, shot, text)
|
||||
: true;
|
||||
if (fromRecipe && BUILTIN_SHOT_TITLES.has(text)) return t(text);
|
||||
const numbered = /^Shot ([1-9]\d*)$/.exec(text);
|
||||
return numbered ? t('Shot {n}', { n: numbered[1] }) : text;
|
||||
}
|
||||
|
||||
/** Whether the built-in recipe behind a scene declares a shot with this title. */
|
||||
function recipeDeclaresShotTitle(sceneId, title) {
|
||||
const recipe = sceneId ? getSceneRecipeById(sceneId) : null;
|
||||
/** Whether the built-in recipe behind a scene declares this shot's title. */
|
||||
function recipeDeclaresShotTitle(scene, shot, title) {
|
||||
const recipe = scene?.id ? getSceneRecipeById(scene.id) : null;
|
||||
if (!recipe) return false;
|
||||
const declares = (path) =>
|
||||
Array.isArray(path) && path.some((keyframe) => keyframe?.title === title);
|
||||
if (declares(recipe.cameraPath)) return true;
|
||||
// A bootstrap recipe seeds legacy "Shot N" keyframes; the upgrade replaces
|
||||
// them with the append recipe's bootstrap shots, which carry no source pack.
|
||||
// The pack marker binds each of those titles to its shot id, so a shot the
|
||||
// operator later gave the same title stays as typed.
|
||||
return SCENE_APPEND_RECIPES.some(
|
||||
(append) =>
|
||||
append.legacySceneBootstrap?.targetSceneTitle === recipe.title &&
|
||||
declares(append.legacySceneBootstrap.cameraPath),
|
||||
declares(append.legacySceneBootstrap.cameraPath) &&
|
||||
Boolean(shot?.id) &&
|
||||
(Array.isArray(scene.appliedShotPacks)
|
||||
? scene.appliedShotPacks
|
||||
: []
|
||||
).some(
|
||||
(marker) =>
|
||||
marker?.id === append.id && marker.shotBindings?.[title] === shot.id,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -155,11 +155,23 @@ test('bootstrap shots of a built-in scene localize without a source pack', () =>
|
||||
);
|
||||
if (!scene) return;
|
||||
for (const { title } of bootstrap.cameraPath) {
|
||||
// The upgrade copies these keyframes into the scene without sourcePackId.
|
||||
// The upgrade copies these keyframes into the scene without sourcePackId
|
||||
// and binds each title to its shot in the pack marker.
|
||||
const upgraded = {
|
||||
id: scene.id,
|
||||
appliedShotPacks: [
|
||||
{ id: append.id, version: 1, shotBindings: { [title]: 'shot-old' } },
|
||||
],
|
||||
};
|
||||
assert.equal(
|
||||
displayShotTitle(title, { id: 'shot-old', title }, { id: scene.id }),
|
||||
displayShotTitle(title, { id: 'shot-old', title }, upgraded),
|
||||
displayShotTitle(title),
|
||||
);
|
||||
// Another shot the operator gave the same title stays as typed.
|
||||
assert.equal(
|
||||
displayShotTitle(title, { id: 'shot-user', title }, upgraded),
|
||||
title,
|
||||
);
|
||||
// The same title in an operator's own scene stays as typed.
|
||||
assert.equal(
|
||||
displayShotTitle(title, { id: 'shot-user', title }, { id: 'scene-user' }),
|
||||
|
||||
Reference in new issue
Block a user