bottleneckcrm/mobile/lib/main.dart

99 lines
3.2 KiB
Dart

import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'core/theme/theme.dart';
import 'firebase_options.dart';
import 'providers/org_modules_provider.dart';
import 'routes/app_router.dart';
import 'services/auth_service.dart';
import 'services/crash_reporting.dart';
import 'services/org_date.dart';
void main() async {
runZonedGuarded<Future<void>>(
() async {
WidgetsFlutterBinding.ensureInitialized();
// Firebase + Crashlytics. Android only. iOS has no GoogleService-Info.plist
// yet, so skip init there to avoid a startup crash.
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// Off in debug to avoid spamming the Crashlytics console with dev noise.
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(
!kDebugMode,
);
FlutterError.onError =
FirebaseCrashlytics.instance.recordFlutterFatalError;
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
}
// The IANA database behind every "today" default (`orgToday`).
loadTimeZones();
await AuthService().initialize();
// Tag any already-signed-in session so the first uncaught error has a user.
await CrashReporting.applyFromAuth(AuthService());
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
systemNavigationBarColor: AppColors.surface,
systemNavigationBarIconBrightness: Brightness.dark,
),
);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
runApp(const ProviderScope(child: BottleCRMApp()));
},
(error, stack) {
// Catch-all for anything that escaped the zone, e.g. errors from
// microtasks scheduled before PlatformDispatcher.onError was wired.
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
}
},
);
}
/// BottleCRM - Main Application Widget
class BottleCRMApp extends ConsumerWidget {
const BottleCRMApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final router = ref.watch(appRouterProvider);
ref.watch(moduleOffListenerProvider);
return MaterialApp.router(
title: 'BottleCRM',
debugShowCheckedModeBanner: false,
// Theme
theme: AppTheme.light,
darkTheme: AppTheme.dark,
themeMode: ThemeMode.light,
// Router
routerConfig: router,
// Scroll behavior for smooth scrolling
scrollBehavior: const MaterialScrollBehavior().copyWith(
physics: const BouncingScrollPhysics(),
),
);
}
}