Skip to content

Instantly share code, notes, and snippets.

@RobertApikyan
Created June 28, 2023 11:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RobertApikyan/8c8c3bed8b636caf38c22a39bbf3247c to your computer and use it in GitHub Desktop.
Save RobertApikyan/8c8c3bed8b636caf38c22a39bbf3247c to your computer and use it in GitHub Desktop.
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