didvan-app/lib/main.dart

235 lines
8.4 KiB
Dart

// lib/main.dart
// ignore_for_file: deprecated_member_use
import 'dart:async';
import 'dart:io';
import 'package:bot_toast/bot_toast.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/firebase_options.dart';
import 'package:didvan/models/notification_message.dart';
import 'package:didvan/models/requests/news.dart';
import 'package:didvan/models/requests/radar.dart';
import 'package:didvan/providers/media.dart';
import 'package:didvan/providers/theme.dart';
import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/route_generator.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/app_home_widget/home_widget_repository.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/notification/firebase_api.dart';
import 'package:didvan/services/notification/notification_service.dart';
import 'package:didvan/utils/my_custom_scroll_behavior.dart';
import 'package:didvan/views/ai/ai_chat_state.dart';
import 'package:didvan/views/ai/ai_state.dart';
import 'package:didvan/views/ai/bot_assistants_state.dart';
import 'package:didvan/views/ai/history_ai_chat_state.dart';
import 'package:didvan/views/podcasts/podcasts_state.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart';
import 'package:home_widget/home_widget.dart';
import 'package:provider/provider.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:app_links/app_links.dart';
import 'services/network/request.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
Uri? initialURI;
@pragma('vm:entry-point')
Future<void> _backgroundCallbackHomeWidget(Uri? uri) async {
if (uri != null) {
await HomeWidget.saveWidgetData("uri", uri.host);
}
}
void main() async {
runZonedGuarded(
() async {
WidgetsFlutterBinding.ensureInitialized();
try {
if (!kIsWeb) {
HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget);
HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget);
await NotificationService.initializeNotification();
try {
if (Platform.isAndroid) {
await FlutterDownloader.initialize(debug: true, ignoreSsl: true);
}
} catch (e) {
e.printError();
}
}
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await FirebaseApi().initNotification();
} catch (e) {
debugPrint(e.toString());
}
await SentryFlutter.init(
(options) {
options.dsn = 'https://a4cfcaa7d67471240d295c25c968d91d@o4508585857384448.ingest.de.sentry.io/4508585886548048';
options.tracesSampleRate = 1.0;
options.profilesSampleRate = 1.0;
},
appRunner: () => runApp(const Didvan()),
);
},
(error, stack) {
Sentry.captureException(error, stackTrace: stack);
},
);
}
class Didvan extends StatefulWidget {
const Didvan({Key? key}) : super(key: key);
@override
State<Didvan> createState() => _DidvanState();
}
class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
late AppLinks _appLinks;
StreamSubscription<Uri>? _linkSubscription;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_initDeepLinks();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_linkSubscription?.cancel();
if (MediaService.currentPodcast != null) {
MediaService.audioPlayer.dispose();
}
super.dispose();
}
Future<void> _initDeepLinks() async {
_appLinks = AppLinks();
initialURI = await _appLinks.getInitialLink();
_linkSubscription = _appLinks.uriLinkStream.listen((uri) {
_navigateTo(uri);
});
}
void _navigateTo(Uri uri) {
if (mounted) {
String path = uri.path;
final Map<String, String> params = uri.queryParameters;
final String? token = params['token'];
if (token != null) {
//todo: this didnt work
print("DEBUG: received token in url, token: $token, path: $path");
RequestService.token = token;
}
if (path.startsWith('/news/')) {
final id = path.split('/news/').last;
if (id.isNotEmpty) {
navigatorKey.currentState?.pushNamed(
Routes.newsDetails,
arguments: {'id': int.parse(id), 'args': const NewsRequestArgs(page: 0)},
);
}
} else if (path.startsWith('/radar/')) {
final id = path.split('/radar/').last;
if (id.isNotEmpty) {
navigatorKey.currentState?.pushNamed(
Routes.radarDetails,
arguments: {'id': int.parse(id), 'args': const RadarRequestArgs(page: 0)},
);
}
}
}
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
if (!kIsWeb) {
if (state == AppLifecycleState.resumed) {
var r = await HomeWidget.getWidgetData("cRoute", defaultValue: '');
if (r.toString() != Routes.splash) {
await HomeWidgetRepository.decideWhereToGo();
NotificationMessage? data = HomeWidgetRepository.data;
if (data != null) {
await HomeWidgetRepository.decideWhereToGoNotif();
}
}
}
}
}
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<PodcastsState>(create: (context) => PodcastsState()),
ChangeNotifierProvider<MediaProvider>(create: (context) => MediaProvider()),
ChangeNotifierProvider<UserProvider>(create: (context) => UserProvider()),
ChangeNotifierProvider<ThemeProvider>(create: (context) => ThemeProvider()),
ChangeNotifierProvider<StudioDetailsState>(create: (context) => StudioDetailsState()),
ChangeNotifierProvider<HistoryAiChatState>(create: (context) => HistoryAiChatState()),
ChangeNotifierProvider<AiState>(create: (context) => AiState()),
ChangeNotifierProvider<AiChatState>(create: (context) => AiChatState()),
ChangeNotifierProvider<BotAssistantsState>(create: (context) => BotAssistantsState()),
],
child: Consumer<ThemeProvider>(
builder: (context, themeProvider, child) => Container(
color: Theme.of(context).colorScheme.surface,
child: SafeArea(
child: MaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
navigatorKey: navigatorKey,
debugShowCheckedModeBanner: false,
title: 'Didvan',
theme: LightThemeConfig.themeData.copyWith(
bottomSheetTheme: const BottomSheetThemeData(
surfaceTintColor: Colors.transparent,
backgroundColor: Colors.transparent),
textTheme: LightThemeConfig.themeData.textTheme.apply(
fontFamily: themeProvider.fontFamily,
)),
darkTheme: DarkThemeConfig.themeData.copyWith(
bottomSheetTheme: const BottomSheetThemeData(
surfaceTintColor: Colors.transparent,
backgroundColor: Colors.transparent),
textTheme: DarkThemeConfig.themeData.textTheme.apply(
fontFamily: themeProvider.fontFamily,
)),
color: LightThemeConfig.themeData.primaryColor,
themeMode: themeProvider.themeMode,
onGenerateRoute: (settings) =>
RouteGenerator.generateRoute(settings),
builder: BotToastInit(),
navigatorObservers: [BotToastNavigatorObserver()],
initialRoute: "/",
localizationsDelegates: const [
GlobalCupertinoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [
Locale("fa", "IR"),
],
locale: const Locale("fa", "IR"),
)),
),
),
);
}
}