PromptBox3D: drive letterbox from the new aspect-ratio picker

For models with `supportsNewAspectRatio()`, the picker only stored a
`CommonAspectRatio` in local state for the API request payload — it
never called `onAspectRatioSelect`, so the editor's render-camera
aspect and the Letterbox stayed on the previous setting.

Wrap the picker callback to also map the chosen `CommonAspectRatio`
to the closest `CameraAspectRatio` and forward it through
`onAspectRatioSelect`. `Auto*` ratios have no fixed shape, so they
leave the letterbox alone.

Export `commonToCameraAspect` so PageEditor can reuse the same
mapping for the cold-load sync.
This commit is contained in:
Tanish Manku committed 2026-05-01 16:22:05 -07:00
1 parent 2725281775
commit 1ee30284df
1 file changed
+46 -1
@@ -174,6 +174,15 @@ export const PromptBox3D = ({
CommonAspectRatio | undefined
>(undefined);
// Drives both the API request payload (commonAspectRatio) and the 3D
// editor letterbox in one shot. Auto* ratios have no fixed shape, so
// they leave the letterbox alone.
const handleCommonAspectRatioSelect = (ratio: CommonAspectRatio) => {
setCommonAspectRatio(ratio);
const mapped = commonToCameraAspect(ratio);
if (mapped) onAspectRatioSelect(mapped);
};
useEffect(() => {
if (textareaRef.current && !isExpanded) {
textareaRef.current.style.height = "auto";
@@ -643,7 +652,7 @@ export const PromptBox3D = ({
<AspectRatioPicker
model={selectedImageModel}
currentAspectRatio={commonAspectRatio}
handleCommonAspectRatioSelect={setCommonAspectRatio}
handleCommonAspectRatioSelect={handleCommonAspectRatioSelect}
/>
)}
{selectedImageModel?.canChangeAspectRatio &&
@@ -812,3 +821,39 @@ export const PromptBox3D = ({
</>
);
};
// Map a CommonAspectRatio (the 2D/API-side enum) to the closest
// CameraAspectRatio variant the 3D editor's letterbox supports.
// Returns undefined for Auto* values, which have no fixed shape.
// Exported so PageEditor can sync the editor letterbox to a model's
// default on first load (where the picker fallback applies).
export const commonToCameraAspect = (
ratio: CommonAspectRatio,
): CameraAspectRatio | undefined => {
switch (ratio) {
case CommonAspectRatio.Square:
case CommonAspectRatio.SquareHd:
return CameraAspectRatio.SQUARE_1_1;
case CommonAspectRatio.WideSixteenByNine:
case CommonAspectRatio.WideTwentyOneByNine:
return CameraAspectRatio.HORIZONTAL_16_9;
case CommonAspectRatio.WideThreeByTwo:
case CommonAspectRatio.WideFourByThree:
case CommonAspectRatio.WideFiveByFour:
case CommonAspectRatio.Wide:
return CameraAspectRatio.HORIZONTAL_3_2;
case CommonAspectRatio.TallNineBySixteen:
case CommonAspectRatio.TallNineByTwentyOne:
return CameraAspectRatio.VERTICAL_9_16;
case CommonAspectRatio.TallTwoByThree:
case CommonAspectRatio.TallThreeByFour:
case CommonAspectRatio.TallFourByFive:
case CommonAspectRatio.Tall:
return CameraAspectRatio.VERTICAL_2_3;
case CommonAspectRatio.Auto:
case CommonAspectRatio.Auto2k:
case CommonAspectRatio.Auto3k:
case CommonAspectRatio.Auto4k:
return undefined;
}
};