Created
June 28, 2023 11:07
-
-
Save RobertApikyan/8c8c3bed8b636caf38c22a39bbf3247c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'package:firebase_core/firebase_core.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
import 'package:flutter_fgbg/flutter_fgbg.dart'; | |
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; | |
import 'package:flutter_jailbreak_detection/flutter_jailbreak_detection.dart'; | |
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; | |
import 'package:flutter_localizations/flutter_localizations.dart'; | |
import 'package:get/get.dart'; | |
import 'package:qundo/api/mock_api.dart'; | |
import 'package:qundo/api/server_api.dart'; | |
import 'package:qundo/api/test_api.dart'; | |
import 'package:qundo/app/app_font_sizes.dart'; | |
import 'package:qundo/components/app_future_builder.dart'; | |
import 'package:qundo/environment.dart'; | |
import 'package:qundo/legitimation/legitimation_session.dart'; | |
import 'package:qundo/legitimation/session_listeners/legitimation_context_session_listener.dart'; | |
import 'package:qundo/legitimation/session_listeners/orientation_session_listener.dart'; | |
import 'package:qundo/legitimation/session_listeners/status_bar_session_listener.dart'; | |
import 'package:qundo/legitimation/session_listeners/video_record_session_listener.dart'; | |
import 'package:qundo/plugins/app_attestation_plugin.dart'; | |
import 'package:qundo/plugins/face_tech_plugin.dart'; | |
import 'package:qundo/plugins/referrer_plugin.dart'; | |
import 'package:qundo/repositories/app_repo.dart'; | |
import 'package:qundo/repositories/authentication_repo.dart'; | |
import 'package:qundo/repositories/legitimation_repo.dart'; | |
import 'package:qundo/screens/home_screen.dart'; | |
import 'package:qundo/screens/jailbroken_screen.dart'; | |
import 'package:qundo/utilities/app_localization_helper.dart'; | |
import 'package:qundo/view_models/partner_theme_bundle.dart'; | |
import 'app_colors.dart'; | |
export 'package:flutter_gen/gen_l10n/app_localizations.dart'; | |
export 'package:flutter_gen/gen_l10n/app_localizations_en.dart'; | |
/// Bindings are part of GetX package, | |
/// Here we create plugin and repository instances, | |
/// which are later used by app's different screens | |
class AppBinding extends Bindings { | |
@override | |
void dependencies() { | |
// Note. Order does matter | |
Get.put(AppAttestationPlugin(), permanent: true); | |
Get.put(ReferrerPlugin(), permanent: true); | |
Get.put(FaceTecPlugin(), permanent: true); | |
Get.put(MockAPI(), permanent: true); | |
Get.put(ServerAPI(), permanent: true); | |
Get.put(TestAPI(), permanent: true); | |
Get.put(LegitimationRepo()); | |
Get.put(AuthenticationRepo()); | |
Get.put(AppRepo()); | |
Get.put(LegitimationFlowSession(), permanent: true); | |
Get.put(VideoRecordSessionListener(), permanent: true); | |
Get.put(LegitimationStatusBarSessionListener(), permanent: true); | |
Get.put(ScreenOrientationSessionListener(), permanent: true); | |
Get.put(LegitimationContextSessionListener(), permanent: true); | |
} | |
} | |
AppLocalizations get localizations => AppLocalizations.of(Get.context!)!; | |
BuildContext get context => Get.context!; | |
/// App is the first widget in application and receives an instance of | |
/// current environment (see [DEV],[STAGE],[QA],[PROD]...). | |
/// App provides access to current [environment] and allows to change status | |
/// bar style by calling [App.setDarkStatusBar()] and [App.setLightStatusBar()]. | |
class App extends StatefulWidget { | |
App(Environment environment) { | |
App.environment = environment; | |
} | |
/// Current environment (see [DEV],[STAGE],[QA],[PROD]...) | |
static late Environment environment; | |
static Stream<FGBGType> lifecycle = FGBGEvents.stream.asBroadcastStream(); | |
/// Makes status bar light with dark icons. | |
static void setDarkStatusBarIcons() async { | |
await Future.delayed(Duration(milliseconds: 500)); | |
final _lastSystemOverlayStyle = SystemUiOverlayStyle.dark.copyWith( | |
statusBarColor: Colors.transparent, | |
systemNavigationBarIconBrightness: Brightness.dark, | |
systemNavigationBarColor: AppColors.white); | |
SystemChrome.setSystemUIOverlayStyle(_lastSystemOverlayStyle); | |
} | |
/// Makes status bar dark with light icons. | |
static void setLightStatusBarIcons() async { | |
await Future.delayed(Duration(milliseconds: 500)); | |
final _lastSystemOverlayStyle = SystemUiOverlayStyle.light.copyWith( | |
statusBarColor: Colors.black.withOpacity(0.1), | |
systemNavigationBarIconBrightness: Brightness.dark, | |
systemNavigationBarColor: AppColors.white); | |
SystemChrome.setSystemUIOverlayStyle(_lastSystemOverlayStyle); | |
} | |
static ThemeData createThemeData() => ThemeData( | |
fontFamily: ThemeBundle.getFontBundle().familyName, | |
scrollbarTheme: ScrollbarThemeData( | |
thumbVisibility: MaterialStateProperty.all(false), | |
radius: const Radius.circular(10.0), | |
thumbColor: | |
MaterialStateProperty.all(AppColors.XXF_D0D0D0.withAlpha(196)), | |
thickness: MaterialStateProperty.all(5.0), | |
minThumbLength: 100, | |
), | |
canvasColor: Colors.white, | |
primaryColor: AppColors.primaryColor, | |
highlightColor: Colors.transparent, | |
splashColor: Colors.transparent, | |
textButtonTheme: TextButtonThemeData( | |
style: ButtonStyle( | |
foregroundColor: | |
MaterialStateProperty.resolveWith((state) => Colors.black), | |
overlayColor: MaterialStateColor.resolveWith( | |
(states) => AppColors.buttonColor.withOpacity(0.2)), | |
)), | |
textTheme: TextTheme( | |
headline4: TextStyle( | |
color: Colors.white, | |
fontWeight: FontWeight.w600, | |
// letterSpacing: -1 | |
), | |
headline5: TextStyle( | |
color: Colors.black, | |
fontWeight: FontWeight.w600, | |
// letterSpacing: -1 | |
), | |
headline6: TextStyle( | |
color: Colors.black, | |
fontWeight: FontWeight.w500, | |
// letterSpacing: -1 | |
), | |
bodyText2: TextStyle( | |
fontSize: AppFontSizes.extraBig, | |
color: Colors.black, | |
fontWeight: FontWeight.w500, | |
// letterSpacing: -1 | |
), | |
caption: TextStyle( | |
fontSize: AppFontSizes.def, | |
color: Colors.black54, | |
fontWeight: FontWeight.w400, | |
// letterSpacing: -0.5 | |
), | |
), | |
); | |
@override | |
_AppState createState() => _AppState(); | |
} | |
class _AppState extends State<App> { | |
String? languageCode = ''; | |
bool? hasJailBreak; | |
FirebaseApp? firebaseApp; | |
@override | |
void initState() { | |
super.initState(); | |
handleRemoveFocusOnHideKeyboard(); | |
SystemChrome.setPreferredOrientations( | |
[DeviceOrientation.portraitUp], | |
); | |
} | |
@override | |
void dispose() { | |
super.dispose(); | |
} | |
/// Removes focus from selected form when keyboard closes. | |
void handleRemoveFocusOnHideKeyboard() { | |
var keyboardVisibilityController = KeyboardVisibilityController(); | |
keyboardVisibilityController.onChange.listen((bool visible) { | |
if (!visible) { | |
FocusManager.instance.primaryFocus?.unfocus(); | |
} | |
}); | |
} | |
/// Initializes app language [languageCode], | |
/// wherever app is running on rooted or jail broken device [hasJailBreak], | |
/// and initialize the Firebase instance [firebaseApp] | |
Future<bool> initialize(BuildContext context) async { | |
languageCode = await AppLocaleHelper.fetchLanguageCode(); | |
if (hasJailBreak == null) { | |
hasJailBreak = await FlutterJailbreakDetection.jailbroken; | |
hasJailBreak ??= false; | |
} | |
if (firebaseApp == null) { | |
firebaseApp = await Firebase.initializeApp(); | |
} | |
if (!ThemeBundle.isInitialized) { | |
await ThemeBundle.initializeDefaults(); | |
} | |
return true; | |
} | |
@override | |
Widget build(BuildContext context) => DataFutureBuilder.simple( | |
future: initialize(context), | |
progressBuilder: (_) => SizedBox.shrink(), | |
errorBuilder: (_, __) => SizedBox.shrink(), | |
dataBuilder: (BuildContext context, dynamic _) => GetMaterialApp( | |
theme: App.createThemeData(), | |
localizationsDelegates: [ | |
GlobalMaterialLocalizations.delegate, | |
GlobalCupertinoLocalizations.delegate, | |
GlobalWidgetsLocalizations.delegate, | |
AppLocalizations.delegate | |
], | |
locale: Locale(languageCode!), | |
supportedLocales: AppLocalizations.supportedLocales, | |
home: defineInitialScreen(), | |
debugShowCheckedModeBanner: false, | |
initialBinding: AppBinding(), | |
builder: (context, navigator) => ValueListenableBuilder( | |
valueListenable: ThemeBundle.fontFamilyListenable, | |
builder: (BuildContext context, dynamic value, Widget? child) => | |
Theme( | |
data: App.createThemeData(), | |
child: wrapEnvironmentBanner(navigator!))), | |
)); | |
Widget wrapEnvironmentBanner(Widget navigator) { | |
if (App.environment.isProd) { | |
return navigator; | |
} | |
return Banner( | |
textStyle: TextStyle(fontSize: 9, fontWeight: FontWeight.w700), | |
color: AppColors.green, | |
message: App.environment.info, | |
location: BannerLocation.bottomEnd, | |
child: navigator); | |
} | |
/// Navigates to Blocking screen [JailBrokenScreen] if app is running on rooted | |
/// device or has Jailbreak, otherwise navigates to home screen [HomeScreen] | |
Widget defineInitialScreen() { | |
if (hasJailBreak!) { | |
return JailBrokenScreen(); | |
} | |
return HomeScreen(); // HomeScreen() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment