feat(setup): first-run gate, hub-first preview, honest wording — setup before the app
Some checks are pending
Security / Security check (push) Waiting to run
Some checks are pending
Security / Security check (push) Waiting to run
Stefan's live findings, all four addressed at the root:
- 'In 3 Fragen loslegen' read like ad copy → the entry is now plainly
'Einrichtung starten' / 'Start setup'.
- The setup button sat permanently on the Welcome page of a running
app ('setup after the app runs is backwards' — reported twice). A
fresh install now starts INSIDE the setup: SetupGateScreen hosts
the wizard embedded as the page (new embedded/onFinished modes on
GuidedSetupDialog), with an explicit 'Später einrichten' skip.
Welcome loses the setup button entirely and stays a calm intro.
- Re-running the setup later lives in Settings → General ('Run setup
again…'), the single post-first-run home.
- 'You must grant access first and only then see what will be done':
the preview used to spawn the chain CLI, whose first run could pop
the macOS permission prompt BEFORE the plan was ever shown. The
preview now calls the new PlanSetup RPC over the live hub
connection (no subprocess, nothing granted); the CLI remains only
a fallback when no hub is reachable — and applying stays the
explicit, separate step.
Widget tests: gate hosts the wizard + skip/cancel leave it; CLI-path
tests drive the fallback through the new hub-preview test seam.
Suite 76 green, analyze clean.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
06f023aada
commit
065939be74
13 changed files with 377 additions and 62 deletions
|
|
@ -30,35 +30,10 @@ class WelcomePage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _WelcomePageState extends State<WelcomePage> {
|
||||
/// Bumped when the guided-setup dialog closes so the onboarding
|
||||
/// checklist remounts and re-probes — the assistant may have just
|
||||
/// installed the modules the checklist looks for.
|
||||
int _checklistEpoch = 0;
|
||||
|
||||
/// One auto-open per app run: a fresh install that dismisses the
|
||||
/// wizard should not have it spring back on every rebuild.
|
||||
static bool _autoOpenedThisRun = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _maybeAutoOpen());
|
||||
}
|
||||
|
||||
/// On a fresh hub (no config, no recorded setup plan) the wizard
|
||||
/// IS the onboarding — open it rather than hoping the operator
|
||||
/// finds the button. Once a setup exists it steps back for good.
|
||||
Future<void> _maybeAutoOpen() async {
|
||||
if (_autoOpenedThisRun || !mounted) return;
|
||||
if (!GuidedSetupDialog.isFreshInstall()) return;
|
||||
_autoOpenedThisRun = true;
|
||||
await _openSetup();
|
||||
}
|
||||
|
||||
Future<void> _openSetup() async {
|
||||
await GuidedSetupDialog.show(context);
|
||||
if (mounted) setState(() => _checklistEpoch++);
|
||||
}
|
||||
// Setup no longer lives on this page. A fresh install starts in
|
||||
// the SetupGateScreen (setup BEFORE the app, not a dialog over
|
||||
// it), and re-running the setup later is a Settings action —
|
||||
// Welcome stays a calm introduction, not a second setup surface.
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -95,19 +70,6 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const _Hero(),
|
||||
const SizedBox(height: ChainSpace.md),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
// High-emphasis: the guided setup is the fastest path
|
||||
// to a working first run, so lead with a filled button
|
||||
// rather than a low-key outlined one. Honest framing:
|
||||
// "get started in 3 questions", not tool-speak.
|
||||
child: FilledButton.icon(
|
||||
onPressed: _openSetup,
|
||||
icon: const Icon(Icons.auto_fix_high),
|
||||
label: Text(l.setupStartCta),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: ChainSpace.xxl),
|
||||
// When the hub is down the onboarding checklist
|
||||
// would render dead (all-unchecked, nothing to
|
||||
|
|
@ -117,7 +79,7 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
const _HubDownHero(),
|
||||
const SizedBox(height: ChainSpace.xxl),
|
||||
] else
|
||||
_OnboardingChecklist(key: ValueKey(_checklistEpoch)),
|
||||
const _OnboardingChecklist(),
|
||||
const _PillarRow(),
|
||||
const SizedBox(height: ChainSpace.xxl),
|
||||
const _SectionLabel(textKey: _SectionLabelKey.trust),
|
||||
|
|
@ -551,7 +513,7 @@ const String _kChecklistDismissedKey = 'welcome.checklist.dismissed';
|
|||
/// parallel; failures stay false and the checklist still
|
||||
/// renders (with the "Refresh" button for retry).
|
||||
class _OnboardingChecklist extends StatefulWidget {
|
||||
const _OnboardingChecklist({super.key});
|
||||
const _OnboardingChecklist();
|
||||
|
||||
@override
|
||||
State<_OnboardingChecklist> createState() => _OnboardingChecklistState();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue