feat: better custom preview aspect ratios - #4450
Conversation
…ton preview Every surface already reports a layout manifest when it connects - style presets with bitmap sizes, and the map of controls that use them - but Companion threw it away after resolving the draw styles. That left the layered button preview's aspect ratio picker with a hardcoded list, which cannot grow to cover every surface model. Persist the manifest alongside the other details kept for offline surfaces (type, integrationType, gridSize) and publish it on two subscriptions: the full manifest for future use (drawing real surface shapes in the ui), and a compact per-surface list of distinct button sizes for consumers which only need the shapes. Both are only rebuilt while something is subscribed. The custom aspect ratio popover now offers the ratios of the surfaces you actually have, reduced to their simplest form and labelled with the model names shown in the surfaces table. Connecting a Stream Deck Neo is enough for 124:29 to appear; no surface details are baked into the ui. Also fixes an emulator resize not being pushed to the ui: the handler persisted the new size but never triggered a surfaces list update. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZbz3FYcyfrqRFSUUBuuV4
The dropdown was the wrong control: it binds a selected value, so whenever the applied ratio was not one of the surface derived choices - which is the normal case, since the preset bar covers the common ones - it rendered its invalid state, showing a red "Custom: 9:7". These are actions, not a selection. They are now rows in the popover, in the same style as the grid zoom control's reset row: click one to apply it and close. What is currently applied is already shown by the preset bar and the W/H fields, and the row matching it is marked active. Ratios the preset buttons already cover are left out, so the list only ever offers a shape that cannot be reached otherwise, and it disappears entirely when there is nothing to add - leaving the popover exactly as it was. The picker moves into its own file so it can be rendered in a story, which is how the above was checked. That turned up the ratio glyph being invisible in the popover: its rule was nested under the canvas footer, so it never applied anywhere else. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZbz3FYcyfrqRFSUUBuuV4
The input group prefixes size to their text, so the single letter W and H labels came out different widths (41px vs 37px) and the two fields did not line up. Pin them to a shared width, with the letter centred. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZbz3FYcyfrqRFSUUBuuV4
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (22)
💤 Files with no reviewable changes (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe PR adds shared surface layout models, persists layouts from panels, publishes layout and bitmap-size subscriptions, and replaces the layered editor’s aspect ratio controls with a surface-aware picker. ChangesSurface Layout and Aspect Ratio Picker
Poem
Merge Risk: ⚪ Minimal · up to No actionable merge-blocking risk remains in the current change. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
shared-lib had a hand written copy of the surface layout schema, which is owned by @companion-surface/base and is what both the plugin and satellite surfaces already describe their layouts with. There was no reason for it: that package's only dependency is zod, which shared-lib already depends on. Depend on it directly and re-export its types, so there is one description of a surface layout. PluginPanel had ended up importing both, which is how obvious this should have been. The models keep only what is genuinely theirs: the client side items, and a bitmap size alias derived from the schema's own type with Pick. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZbz3FYcyfrqRFSUUBuuV4
The picker's styles were spread across EditButton.css: the footer strip nested inside the preview panel block, and the popover's rules stranded at the bottom of the file because it portals to the body. Neither had anything to do with the rest of that stylesheet. They now live in AspectRatioPicker.css, imported by the component, in the same layer as before (features, by path). The story no longer has to import the whole feature stylesheet to render one popover. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZbz3FYcyfrqRFSUUBuuV4
|
Just saw this and wanted to say it looks great! Nice elegant solution. |
Replaces #4381
Shortcuts for more aspect ratios for different surfaces in the style editor.
There isn't enough space on the bar to show everything the user could end up with, and if that list becomes dynamic they will need some better way to identify them.
So instead, we add some options to the bottom of the popover:
This uses data sourced from the 'known' surfaces (the ones both connected and disconnected in the surfaces table).
To do this we are now storing the full surface layout definition they provide, which we can use for more in the future. So this will start working after Companion next sees those surfaces.
So this will work for any connected surfaces that use different aspect ratios, not just official ones. Anything connected over satellite will appear here too.
Summary by CodeRabbit
New Features
Improvements