fix(studio): live-search exception, daemon-card width, featured tile size; add Start-hub button (v0.20.1)
Three reported bugs and one onramp gap: - Store live-search threw `setState() callback returned a Future`. The `=>` body of `_runSearch` evaluated to the Future returned by `_load()`. Switched to a block body so the closure resolves to void; the future itself is still awaited by the FutureBuilder. - Doctor's Daemon-control card was visibly narrower than its siblings — its only stretching child was a Wrap of small buttons. Wrapped the content in `SizedBox(width: infinity)` so the card fills the section's width like every other panel. Card now leads with the live `running on local: 127.0.0.1:50051` status row + status pill so operators see state at a glance, then offers Restart / Start (when stopped) / Stop / Status. - Featured tiles were 320×152 against the regular grid's ~360×168, so the editorial picks looked subordinate to the dense grid. Bumped to 480×220 with bigger icon, larger title, larger tagline so the strip reads as a hero band. - ConnectionPill in the sidebar now offers an inline "Start hub" button when the daemon is unreachable. Spawns `fai daemon start` via SystemActions; the shell-level health poll picks the daemon up on its next tick. Closes the chicken-and-egg for Windows users who can't open a shell to bootstrap. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
26691b7471
commit
fb7352d182
4 changed files with 256 additions and 96 deletions
|
|
@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'data/hub.dart';
|
||||
import 'data/system_actions.dart';
|
||||
import 'pages/approvals.dart';
|
||||
import 'pages/audit.dart';
|
||||
import 'pages/doctor.dart';
|
||||
|
|
@ -23,7 +24,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.20.0';
|
||||
const String kStudioVersion = '0.20.1';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
|
@ -338,6 +339,19 @@ class _Sidebar extends StatelessWidget {
|
|||
child: _ConnectionPill(
|
||||
connected: connected,
|
||||
label: endpointLabel,
|
||||
onStartRequested: () async {
|
||||
final r = await SystemActions.faiDaemon(['start']);
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
r.ok
|
||||
? 'Daemon start requested. Reconnecting…'
|
||||
: 'Could not start daemon: ${r.stderr.trim().isEmpty ? r.stdout.trim() : r.stderr.trim()}',
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (activeChannel != null && activeChannel!.isNotEmpty) ...[
|
||||
|
|
@ -482,8 +496,17 @@ class _ChannelPill extends StatelessWidget {
|
|||
class _ConnectionPill extends StatelessWidget {
|
||||
final bool? connected;
|
||||
final String label;
|
||||
/// Triggered by the inline "Start hub" button when the
|
||||
/// daemon is unreachable. Runs `fai daemon start` server-side
|
||||
/// (well, locally — Studio shells out). The shell-level
|
||||
/// health poll picks the daemon up on its next tick.
|
||||
final Future<void> Function() onStartRequested;
|
||||
|
||||
const _ConnectionPill({required this.connected, required this.label});
|
||||
const _ConnectionPill({
|
||||
required this.connected,
|
||||
required this.label,
|
||||
required this.onStartRequested,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -536,6 +559,31 @@ class _ConnectionPill extends StatelessWidget {
|
|||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
// Inline "Start hub" affordance when the daemon
|
||||
// isn't there. Resolves the chicken-and-egg for
|
||||
// Windows operators who can't run `fai daemon start`
|
||||
// from a shell.
|
||||
if (connected == false) ...[
|
||||
const SizedBox(height: FaiSpace.sm),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: FilledButton.tonalIcon(
|
||||
onPressed: onStartRequested,
|
||||
icon: const Icon(Icons.play_arrow, size: 14),
|
||||
label: const Text(
|
||||
'Start hub',
|
||||
style: TextStyle(fontSize: 11),
|
||||
),
|
||||
style: FilledButton.styleFrom(
|
||||
visualDensity: VisualDensity.compact,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: FaiSpace.sm,
|
||||
vertical: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue