Files
doormile_customer_app/lib/state/app_scope.dart
Thiru-tenext 0d66627c3c Replace the customer app with Doormile CX
Book a pickup, track it to delivery — the rebuilt customer app.

- Design language from doormile-screens.html: brand #8F0F06, Manrope +
  Geist Mono (variable fonts), bordered cards instead of shadows, crimson
  brand headers, sliding tab indicator, mono for anything read digit by digit.
- lib/data (one live API implementation, plus a debug-only offline fake),
  lib/state, lib/ui (tokens, widgets, screens).
- 84 tests, plus a design snapshot harness that renders every screen with the
  real fonts: flutter test test/design_snapshot_test.dart --run-skipped
  --update-goldens

This replaces the previous app (pubspec 'doormile', app id
com.doormile.customer). That tree remains in history at 6c7d656; note its
android/app/google-services.json is not carried over, and the application id
here is in.doormile.customer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 16:07:33 +05:30

25 lines
950 B
Dart

import 'package:flutter/widgets.dart';
import 'app_state.dart';
/// Makes [AppState] available to the widget tree and rebuilds dependents when
/// it changes. Deliberately dependency-free — no external state package.
class AppScope extends InheritedNotifier<AppState> {
const AppScope({super.key, required AppState state, required super.child})
: super(notifier: state);
/// Subscribes the calling widget to changes.
static AppState of(BuildContext context) {
final scope = context.dependOnInheritedWidgetOfExactType<AppScope>();
assert(scope != null, 'AppScope.of() called outside an AppScope');
return scope!.notifier!;
}
/// Reads without subscribing — for callbacks and one-shot lookups.
static AppState read(BuildContext context) {
final scope = context.getInheritedWidgetOfExactType<AppScope>();
assert(scope != null, 'AppScope.read() called outside an AppScope');
return scope!.notifier!;
}
}