Files
ignis_app/lib/main.dart
2026-05-01 09:13:23 +07:00

174 lines
5.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:workmanager/workmanager.dart';
import 'app/app_bootstrap.dart';
import 'features/homes/services/geofence_notifications_service.dart';
import 'screens/homes_screen.dart';
import 'screens/remote_screen.dart';
import 'services/geofence_worker.dart';
/// Top-level callback для workmanager (выполняется в отдельном изоляте).
@pragma('vm:entry-point')
void callbackDispatcher() {
DartPluginRegistrant.ensureInitialized();
Workmanager().executeTask((taskName, inputData) async {
if (taskName == geofenceTaskName) {
return await executeGeofenceCheck();
}
return true;
});
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await GeofenceNotificationsService().initialize();
// Инициализация workmanager
Workmanager().initialize(callbackDispatcher);
runApp(const ProviderScope(child: IgnisApp()));
}
class IgnisApp extends StatelessWidget {
const IgnisApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Ignis',
debugShowCheckedModeBanner: false,
theme: ThemeData.dark(useMaterial3: true).copyWith(
scaffoldBackgroundColor: const Color(0xFF0E0E0E),
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepOrange,
brightness: Brightness.dark,
),
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF1A1A1A),
elevation: 0,
centerTitle: true,
),
cardTheme: CardThemeData(
color: const Color(0xFF1E1E1E),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
sliderTheme: const SliderThemeData(
trackHeight: 4,
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 8),
),
),
home: const MainGate(),
);
}
}
/// Стартовый экран -- проверяет наличие домов и перенаправляет
class MainGate extends ConsumerStatefulWidget {
const MainGate({super.key});
@override
ConsumerState<MainGate> createState() => _MainGateState();
}
class _MainGateState extends ConsumerState<MainGate> {
@override
void initState() {
super.initState();
Future.microtask(_bootstrap);
}
Future<void> _bootstrap() async {
await ref.read(appBootstrapProvider.notifier).bootstrap();
if (!mounted) return;
final bootstrap = ref.read(appBootstrapProvider);
switch (bootstrap.status) {
case AppBootstrapStatus.ready:
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const RemoteScreen()),
);
break;
case AppBootstrapStatus.noHomes:
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const HomesScreen()),
);
break;
case AppBootstrapStatus.bootstrapping:
case AppBootstrapStatus.authFailed:
case AppBootstrapStatus.networkFailed:
case AppBootstrapStatus.invalidConfig:
case AppBootstrapStatus.failed:
break;
}
}
@override
Widget build(BuildContext context) {
final bootstrap = ref.watch(appBootstrapProvider);
final message = bootstrap.message;
if (!bootstrap.isBootstrapping && message != null) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.warning_amber_rounded,
color: Colors.deepOrange,
size: 56,
),
const SizedBox(height: 16),
const Text(
'Не удалось запустить приложение',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
message,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white54),
),
const SizedBox(height: 20),
FilledButton.icon(
onPressed: _bootstrap,
icon: const Icon(Icons.refresh),
label: const Text('Повторить'),
),
TextButton(
onPressed: () => Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const HomesScreen()),
),
child: const Text('Открыть список домов'),
),
],
),
),
),
);
}
return const Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(color: Colors.deepOrange),
SizedBox(height: 20),
Text("Загрузка...", style: TextStyle(color: Colors.white54)),
],
),
),
);
}
}