navigation_safety 0.9.1 copy "navigation_safety: ^0.9.1" to clipboard
navigation_safety: ^0.9.1 copied to clipboard

Flutter safety-alert overlay + navigation session state machine with configurable severity thresholds. Display-only, never controlling.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:latlong2/latlong.dart';
import 'package:navigation_safety/navigation_safety.dart';
import 'package:routing_engine/routing_engine.dart';

/// Local adapter mirroring lib/adapters/navigation_route_adapter.dart.
/// Examples sit at the routing→navigation boundary; the production
/// adapter is internal to the main app and not exported from any
/// package, so examples carry their own identical copy.
extension _RouteResultToNavigation on RouteResult {
  NavigationRoute toNavigationRoute() => NavigationRoute(
    shape: shape,
    maneuvers: maneuvers
        .map(
          (m) => NavigationManeuver(
            index: m.index,
            instruction: m.instruction,
            type: m.type,
            lengthKm: m.lengthKm,
            timeSeconds: m.timeSeconds,
            position: m.position,
          ),
        )
        .toList(),
    totalDistanceKm: totalDistanceKm,
    totalTimeSeconds: totalTimeSeconds,
    summary: summary,
  );
}

final _exampleRoute = RouteResult(
  shape: const [LatLng(35.1709, 136.9066), LatLng(34.9551, 137.1771)],
  maneuvers: const [
    RouteManeuver(
      index: 0,
      instruction: 'Depart Sakae Station',
      type: 'depart',
      lengthKm: 12,
      timeSeconds: 900,
      position: LatLng(35.1709, 136.9066),
    ),
    RouteManeuver(
      index: 1,
      instruction: 'Arrive Higashiokazaki Station',
      type: 'arrive',
      lengthKm: 0,
      timeSeconds: 0,
      position: LatLng(34.9551, 137.1771),
    ),
  ],
  totalDistanceKm: 40.0,
  totalTimeSeconds: 2400,
  summary: '40 km, 40 min',
  engineInfo: const EngineInfo(name: 'mock'),
);

void main() {
  runApp(const NavigationSafetyExampleApp());
}

class NavigationSafetyExampleApp extends StatelessWidget {
  const NavigationSafetyExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider(
        create: (_) => NavigationBloc()
          ..add(NavigationStarted(route: _exampleRoute.toNavigationRoute())),
        child: const _ExampleScreen(),
      ),
    );
  }
}

class _ExampleScreen extends StatelessWidget {
  const _ExampleScreen();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('navigation_safety example')),
      body: Stack(
        children: [
          Positioned.fill(
            child: ColoredBox(
              color: Colors.blueGrey.shade50,
              child: const Center(child: Text('Map layer placeholder')),
            ),
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Wrap(
                spacing: 12,
                runSpacing: 12,
                alignment: WrapAlignment.center,
                children: [
                  FilledButton(
                    onPressed: () => context.read<NavigationBloc>().add(
                      const SafetyAlertReceived(
                        message: 'Snow expected in 30 minutes',
                        severity: AlertSeverity.info,
                      ),
                    ),
                    child: const Text('Info'),
                  ),
                  FilledButton(
                    onPressed: () => context.read<NavigationBloc>().add(
                      const SafetyAlertReceived(
                        message: 'Icy road conditions ahead',
                        severity: AlertSeverity.warning,
                      ),
                    ),
                    child: const Text('Warning'),
                  ),
                  FilledButton(
                    onPressed: () => context.read<NavigationBloc>().add(
                      const SafetyAlertReceived(
                        message: 'Visibility zero - pull over immediately',
                        severity: AlertSeverity.critical,
                        dismissible: false,
                      ),
                    ),
                    child: const Text('Critical'),
                  ),
                  OutlinedButton(
                    onPressed: () => context.read<NavigationBloc>().add(
                      const SafetyAlertDismissed(),
                    ),
                    child: const Text('Dismiss'),
                  ),
                ],
              ),
            ),
          ),
          const SafetyOverlay(),
        ],
      ),
    );
  }
}
0
likes
150
points
348
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter safety-alert overlay + navigation session state machine with configurable severity thresholds. Display-only, never controlling.

Repository (GitHub)
View/report issues
Contributing

Topics

#safety #navigation #winter-driving #automotive #snow

License

BSD-3-Clause (license)

Dependencies

equatable, flutter, flutter_bloc, latlong2, navigation_safety_core

More

Packages that depend on navigation_safety