main.dart 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'dart:ui';
  4. import 'package:auto_route/auto_route.dart';
  5. import 'package:easy_localization/easy_localization.dart';
  6. import 'package:firebase_core/firebase_core.dart';
  7. import 'package:firebase_messaging/firebase_messaging.dart';
  8. import 'package:flutter/foundation.dart';
  9. import 'package:flutter/material.dart';
  10. import 'package:flutter/services.dart';
  11. import 'package:flutter_bloc/flutter_bloc.dart';
  12. import 'package:flutter_local_notifications/flutter_local_notifications.dart';
  13. // import 'package:flutter_native_splash/flutter_native_splash.dart';
  14. import 'package:fluttertoast/fluttertoast.dart';
  15. import 'package:page_transition/page_transition.dart';
  16. import 'package:provider/provider.dart';
  17. import 'package:quick_notify_2/quick_notify.dart';
  18. import 'package:shared_preferences/shared_preferences.dart';
  19. import 'package:telnow_mobile_new/src/api/api_auth_provider.dart';
  20. import 'package:telnow_mobile_new/src/cubit/user_data_cubit.dart';
  21. import 'package:telnow_mobile_new/src/injector/injector.dart';
  22. import 'package:telnow_mobile_new/src/layouts/mobile/history_forum.dart';
  23. import 'package:telnow_mobile_new/src/layouts/mobile/message_list.dart';
  24. import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
  25. import 'package:telnow_mobile_new/src/utils/U.dart';
  26. import 'package:telnow_mobile_new/src/utils/dio_logging_interceptors.dart';
  27. import 'package:telnow_mobile_new/src/utils/provider.dart';
  28. import 'package:upgrader/upgrader.dart';
  29. import 'package:http/http.dart' as http;
  30. import 'package:telnow_mobile_new/src/api/jwt_token.dart';
  31. import 'app_router.dart';
  32. import 'package:telnow_mobile_new/src/utils/ui_service.dart';
  33. // final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();
  34. var isDebug = true;
  35. class MyHttpOverrides extends HttpOverrides {
  36. @override
  37. HttpClient createHttpClient(SecurityContext? context) {
  38. return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
  39. }
  40. }
  41. void main() async{
  42. WidgetsFlutterBinding.ensureInitialized();
  43. await EasyLocalization.ensureInitialized();
  44. try{
  45. if (kIsWeb){
  46. await Firebase.initializeApp(
  47. options: FirebaseOptions(
  48. apiKey: "AIzaSyDlJQaEV9aPnPFeFA7QeiVijoGZXqemCRw",
  49. authDomain: "telmessenger-d3935.firebaseapp.com",
  50. databaseURL: "https://telmessenger-d3935.firebaseio.com",
  51. projectId: "telmessenger-d3935",
  52. storageBucket: "telmessenger-d3935.appspot.com",
  53. messagingSenderId: "647562261340",
  54. appId: "1:647562261340:web:01b97a27460e4bfd5b0799",
  55. measurementId: "G-BFCBWCK70H"
  56. )
  57. );
  58. }
  59. else{
  60. await Firebase.initializeApp();
  61. await U.flutterLocalNotificationsPlugin.cancelAll();
  62. await U.flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(U.channel);
  63. }
  64. await setupLocator();
  65. SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  66. HttpOverrides.global = MyHttpOverrides();
  67. runApp(
  68. EasyLocalization(
  69. path: 'assets/lang',
  70. supportedLocales: [
  71. Locale('en'),
  72. Locale('id'),
  73. Locale('ja'),
  74. Locale('zh'),
  75. Locale('ko'),
  76. Locale('ar'),
  77. Locale('fr'),
  78. Locale('de'),
  79. Locale('hi'),
  80. Locale('nl')
  81. ],
  82. startLocale: Locale('id'),
  83. saveLocale: true,
  84. child: MyApp()
  85. )
  86. );
  87. } catch (error, stacktrace) {
  88. debugPrint('$error & $stacktrace');
  89. }
  90. }
  91. class MyCustomScrollBehavior extends MaterialScrollBehavior {
  92. @override
  93. Set<PointerDeviceKind> get dragDevices {
  94. return {
  95. PointerDeviceKind.touch,
  96. PointerDeviceKind.mouse,
  97. };
  98. }
  99. }
  100. final _appRouter = AppRouter(navigatorKey: UIService.navigatorKey);
  101. class MyApp extends StatelessWidget {
  102. const MyApp({super.key});
  103. @override
  104. Widget build(BuildContext context) {
  105. return MultiProvider(
  106. providers: [
  107. ChangeNotifierProvider(create: (_) => UserModule()),
  108. ChangeNotifierProvider(create: (_) => ServiceModule()),
  109. ChangeNotifierProvider(create: (_) => HistoryModule()),
  110. ChangeNotifierProvider(create: (_) => RequestModule()),
  111. ChangeNotifierProvider(create: (_) => CreateSerModule()),
  112. ChangeNotifierProvider(create: (_) => MessageModule()),
  113. ],
  114. child: MultiBlocProvider(
  115. providers: [
  116. BlocProvider(create: (_) => UserCubit()),
  117. ],
  118. child: MaterialApp.router(
  119. // routerDelegate: _appRouter.delegate(),
  120. // routeInformationParser: _appRouter.defaultRouteParser(),
  121. scrollBehavior: MyCustomScrollBehavior(),
  122. debugShowCheckedModeBanner: false,
  123. localizationsDelegates: context.localizationDelegates,
  124. supportedLocales: context.supportedLocales,
  125. locale: context.locale,
  126. key: NavigationService.navigatorKey,
  127. theme: ThemeData(useMaterial3: false, fontFamily: 'SF Compact Display', appBarTheme: AppBarTheme(
  128. systemOverlayStyle: SystemUiOverlayStyle(
  129. statusBarColor: Colors.transparent,
  130. statusBarIconBrightness: Brightness.dark,
  131. statusBarBrightness: Brightness.dark
  132. ),
  133. ), colorScheme: ColorScheme.fromSeed(seedColor: Color(0xff078C84))),
  134. routerConfig: _appRouter.config(),
  135. ),
  136. ),
  137. );
  138. }
  139. }
  140. class NavigationService {
  141. static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
  142. }
  143. @RoutePage()
  144. class HomeGuardPage extends StatefulWidget {
  145. const HomeGuardPage({super.key});
  146. @override
  147. State<HomeGuardPage> createState() => _HomeGuardPageState();
  148. }
  149. class _HomeGuardPageState extends State<HomeGuardPage> {
  150. late DateTime currentBackPressTime;
  151. JwtToken token = JwtToken();
  152. @override
  153. Widget build(BuildContext context) {
  154. eventBus.on().listen((event) {
  155. if(event.toString() == 'logout') {
  156. UIService.navigateNamed('/end-session');
  157. // context.navigateToPath('/end-session');
  158. }
  159. });
  160. // TODO: implement build
  161. return Scaffold(
  162. body: !kIsWeb ? UpgradeAlert(child: AutoRouter()):AutoRouter(),
  163. );
  164. }
  165. Future<bool> onWillPop() {
  166. DateTime now = DateTime.now();
  167. if (now.difference(currentBackPressTime) > Duration(seconds: 2)) {
  168. currentBackPressTime = now;
  169. Fluttertoast.showToast(msg: 'pressAgain'.tr());
  170. return Future.value(false);
  171. }
  172. return Future.value(true);
  173. }
  174. }
  175. class NotificationClass {
  176. final ApiAuthProvider _apiAuthProvider = ApiAuthProvider();
  177. initFirebaseMessaging(BuildContext context) {
  178. final locale = context.locale.toString();
  179. FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
  180. var mid = message.data['mid'];
  181. var token = await U.getFcmToken();
  182. if (token != null) {
  183. _apiAuthProvider.postDataNoAuth('/api/notifications/received/$token/$mid').then((value) =>
  184. debugPrint('Send confirm succes!')
  185. );
  186. }
  187. if(kIsWeb){
  188. QuickNotify.notify(
  189. title: message.data['subject'],
  190. content: locale == 'id' ? message.data['description'] : message.data['descriptionEn'],
  191. );
  192. }
  193. else{
  194. const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('notification_icon');
  195. final InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid);
  196. // U.flutterLocalNotificationsPlugin.initialize(initializationSettings,);
  197. U.flutterLocalNotificationsPlugin.initialize(initializationSettings, onDidReceiveNotificationResponse: (NotificationResponse notificationResponse) async {
  198. if (notificationResponse.payload != null) {
  199. var list = jsonDecode(notificationResponse.payload!);
  200. goNotification(list, context);
  201. }
  202. });
  203. var androidPlatformChannelSpecifics = AndroidNotificationDetails(
  204. 'notification_channel2', // id
  205. 'Normal Notification', // title
  206. channelDescription: 'This channel is used for normal notifications.', // description
  207. importance: Importance.max,
  208. priority: Priority.high,
  209. color: Color(0xff0D497F),
  210. styleInformation: BigTextStyleInformation(''),
  211. playSound: true,
  212. enableVibration: true,
  213. // sound: RawResourceAndroidNotificationSound('notification_alarm'),
  214. largeIcon: DrawableResourceAndroidBitmap('banner_icon_blue'),
  215. setAsGroupSummary: true,
  216. groupKey: message.data['subject']
  217. );
  218. var platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics);
  219. U.flutterLocalNotificationsPlugin.show(0, message.data['subject'],
  220. locale == 'id' ? message.data['description'] : message.data['descriptionEn'], platformChannelSpecifics,
  221. payload: jsonEncode(message.data));
  222. }
  223. });
  224. FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  225. FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) {
  226. if (message != null && !U.hidePayload) {
  227. // goNotification(message.data, context);
  228. UIService.goNotification(message.data);
  229. }
  230. });
  231. FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
  232. U.setHidePayload(false);
  233. UIService.goNotification(message.data);
  234. // goNotification(message.data, context);
  235. });
  236. }
  237. getActiveNotification() async {
  238. List<ActiveNotification>? activeNotification = await U.flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.getActiveNotifications();
  239. return activeNotification;
  240. }
  241. startNotification({code}) async {
  242. final locale = NavigationService.navigatorKey.currentContext?.locale.toString();
  243. var token = await U.getFcmToken();
  244. if (token != null) {
  245. Map data = {'token': token, 'language': code ?? locale?.toUpperCase()};
  246. var res = _apiAuthProvider.postData('/api/fcmTokens/register', null, data);
  247. return res;
  248. }
  249. }
  250. stopNotification(BuildContext context) async {
  251. var token = await U.getFcmToken();
  252. if (token != null) {
  253. var res = _apiAuthProvider.postData('/api/fcmTokens/remove/$token', null, null);
  254. return res;
  255. }
  256. }
  257. goNotification(list, BuildContext context) {
  258. if (list['type'] == 'MESSAGE') {
  259. Navigator.push(context, PageTransition(type: PageTransitionType.rightToLeft, child: MobMessageListPage(null)));
  260. }
  261. else if (list['type'] == 'FORUM') {
  262. // print(list['requestHistory']);
  263. Navigator.push(context, PageTransition(type: PageTransitionType.rightToLeft, child: MobHistoryForumPage(data: jsonDecode(list['requestHistory']))));
  264. }
  265. else{
  266. var pid = U.getPidFromUrl(context.router.currentUrl);
  267. context.router.removeLast();
  268. context.navigateToPath("/app/$pid/menu/history");
  269. }
  270. }
  271. }
  272. Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  273. await Firebase.initializeApp();
  274. SharedPreferences prefs = await SharedPreferences.getInstance();
  275. await prefs.reload();
  276. // print('background : ${message.data}');
  277. String accCode = prefs.getString(SharedPreferencesManager.keyAccessCode)!;
  278. var decAccCode = U.decodeBase64Url(accCode);
  279. var mid = message.data['mid'];
  280. FirebaseMessaging.instance.getToken().then((token) async {
  281. if (token != null) {
  282. http.post(Uri.https(U.decodeBase64Url(prefs.getString(SharedPreferencesManager.keyBaseUrl)!).split('//')[1], '$decAccCode/api/notifications/received/$token/$mid')).then((value) {
  283. debugPrint("kirim confirm");
  284. prefs.setString(SharedPreferencesManager.lastMid, mid);
  285. });
  286. }
  287. });
  288. }