From 1295675bd9e0d05501406087abc80522d93eec14 Mon Sep 17 00:00:00 2001 From: flemming-it Date: Sat, 30 May 2026 16:08:22 +0200 Subject: [PATCH] fix(studio): sidebar left-anchor + pull flow-editor 0.1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two Stefan-reported fixes after the v0.51.x live test: 1. Sidebar icons appeared to shift between collapsed and expanded. Mathematically the icons stayed at x=24 ( ListView padding + AC padding), but the Column's default crossAxisAlignment.center re-centered the brand mark AND the top indicators (version, connection, channel) on every expand → in a 72 px rail the brand sits at x≈36, in a 220 px rail it sits at x≈110. Stefan perceived this horizontal repositioning of the brand+pills as a shift of the icons below. Fix: Column.crossAxisAlignment = start + left-pad every top item (brand mark, "F∆I Studio" label, version, connection pill, channel pill, mini-version, connection dot, channel chip) by exactly the same offset the destinations use (ListView.padding + AC.padding = FaiSpace.md + FaiSpace.md). The whole rail now reads as one stable left edge through the expand animation. 2. Pull fai_studio_flow_editor 0.1.2 — fixes the "opening hello.yaml shows extract-with-approval content" bug by switching `_code.text = ...` to the canonical `_code.fullText = ...` setter in the package. Version: 0.51.2 → 0.51.3 Signed-off-by: flemming-it --- lib/main.dart | 116 ++++++++++++++++++++++++++++++++++++-------------- pubspec.lock | 4 +- pubspec.yaml | 2 +- 3 files changed, 88 insertions(+), 34 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 2dcb566..e1d0450 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -27,7 +27,7 @@ import 'widgets/widgets.dart'; /// Studio's own build version. Bump on every UI commit so the /// running app self-identifies — visible in the sidebar header /// and quick-glance proof that you're seeing the current build. -const String kStudioVersion = '0.51.2'; +const String kStudioVersion = '0.51.3'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -479,29 +479,59 @@ class _SidebarState extends State<_Sidebar> { padding: const EdgeInsets.symmetric(vertical: FaiSpace.xl), child: ClipRect( child: Column( + // Left-align every column child so brand mark + top + // indicators sit at the same X-pixel as the icons + // below. With the default `center`, the brand mark + // re-positioned itself horizontally on every expand + // animation (centered in 72 vs centered in 220), + // which the user perceived as the whole nav rail + // shifting even though the destination icons stayed + // put. Anchoring everything to the start eliminates + // the perceived shift. + crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Brand mark — always visible. - FaiDeltaMark(color: theme.colorScheme.primary, mode: mode), + // Brand mark — always visible. Pad it to match the + // icon's left offset (ListView padding + AC padding + // = FaiSpace.md + FaiSpace.md), so the triangle's + // left edge aligns with the destination icons' + // left edges. + Padding( + padding: const EdgeInsets.only( + left: FaiSpace.md + FaiSpace.md, + ), + child: + FaiDeltaMark(color: theme.colorScheme.primary, mode: mode), + ), if (expanded) ...[ const SizedBox(height: FaiSpace.md), - Text( - 'F∆I Studio', - style: theme.textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, + const Padding( + padding: EdgeInsets.only(left: FaiSpace.md + FaiSpace.md), + child: Text( + 'F∆I Studio', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600), ), ), const SizedBox(height: 2), - Text( - 'v$kStudioVersion', - style: FaiTheme.mono( - size: 10, - color: theme.colorScheme.primary, + Padding( + padding: const EdgeInsets.only( + left: FaiSpace.md + FaiSpace.md, + ), + child: Text( + 'v$kStudioVersion', + style: FaiTheme.mono( + size: 10, + color: theme.colorScheme.primary, + ), ), ), const SizedBox(height: FaiSpace.md), - // Connection pill — full version when expanded. + // Connection pill — left-aligned to the same + // x-anchor as the icons. Padding( - padding: const EdgeInsets.symmetric(horizontal: FaiSpace.lg), + padding: const EdgeInsets.only( + left: FaiSpace.md + FaiSpace.md, + right: FaiSpace.md, + ), child: _ConnectionPill( connected: widget.connected, label: widget.endpointLabel, @@ -523,7 +553,10 @@ class _SidebarState extends State<_Sidebar> { if (widget.activeChannel != null && widget.activeChannel!.isNotEmpty) ...[ const SizedBox(height: FaiSpace.sm), Padding( - padding: const EdgeInsets.symmetric(horizontal: FaiSpace.lg), + padding: const EdgeInsets.only( + left: FaiSpace.md + FaiSpace.md, + right: FaiSpace.md, + ), child: _ChannelPill(channel: widget.activeChannel!), ), ], @@ -532,29 +565,50 @@ class _SidebarState extends State<_Sidebar> { // most glance-able status indicators (version, // connection dot, channel letter) so the rail // still reads as F∆I Studio at-a-glance without - // hovering to expand. + // hovering to expand. All left-padded by the + // same offset as the destination icons ( + // ListView.padding + AC.padding = 12 + 12) + // so the column reads as one stable left edge. const SizedBox(height: FaiSpace.sm), - Text( - 'v$kStudioVersion'.replaceFirst(RegExp(r'-.*'), ''), - style: FaiTheme.mono( - size: 9, - color: theme.colorScheme.primary, + Padding( + padding: const EdgeInsets.only( + left: FaiSpace.md + FaiSpace.md, + ), + child: Text( + 'v$kStudioVersion'.replaceFirst(RegExp(r'-.*'), ''), + style: FaiTheme.mono( + size: 9, + color: theme.colorScheme.primary, + ), ), ), const SizedBox(height: FaiSpace.md), - Tooltip( - message: widget.connected == true - ? 'Connected · ${widget.endpointLabel}' - : widget.connected == false - ? 'Disconnected · ${widget.endpointLabel}' - : 'Connecting · ${widget.endpointLabel}', - child: _CollapsedConnectionDot(connected: widget.connected), + Padding( + padding: const EdgeInsets.only( + left: FaiSpace.md + FaiSpace.md, + ), + child: Tooltip( + message: widget.connected == true + ? 'Connected · ${widget.endpointLabel}' + : widget.connected == false + ? 'Disconnected · ${widget.endpointLabel}' + : 'Connecting · ${widget.endpointLabel}', + child: + _CollapsedConnectionDot(connected: widget.connected), + ), ), if (widget.activeChannel != null && widget.activeChannel!.isNotEmpty) ...[ const SizedBox(height: FaiSpace.sm), - Tooltip( - message: widget.activeChannel!, - child: _CollapsedChannelChip(channel: widget.activeChannel!), + Padding( + padding: const EdgeInsets.only( + left: FaiSpace.md + FaiSpace.md, + ), + child: Tooltip( + message: widget.activeChannel!, + child: _CollapsedChannelChip( + channel: widget.activeChannel!, + ), + ), ), ], ], diff --git a/pubspec.lock b/pubspec.lock index 4e5aec4..c58cabd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -125,10 +125,10 @@ packages: description: path: "." ref: main - resolved-ref: "8b918f8f2afe5babe663897aa20483708a980c4b" + resolved-ref: "7655e0dc32fa3093b36c094a1fbad87625199227" url: "https://git.flemming.ai/fai/studio-flow-editor" source: git - version: "0.1.1" + version: "0.1.2" fake_async: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 34d1ada..85de955 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: fai_studio description: "F∆I Studio — desktop GUI for the F∆I hub" publish_to: 'none' -version: 0.51.2 +version: 0.51.3 environment: sdk: ^3.11.0-200.1.beta