186 lines
5.3 KiB
Dart
186 lines
5.3 KiB
Dart
import 'dart:async';
|
||
import 'dart:developer';
|
||
import 'dart:io';
|
||
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:fps_widget/fps_widget.dart';
|
||
import 'package:provider/provider.dart';
|
||
import 'package:remever/common/events/events.dart';
|
||
import 'package:remever/common/functions.dart';
|
||
import 'package:remever/common/getters.dart';
|
||
import 'package:remever/common/mixin/subscriptionable.dart';
|
||
import 'package:remever/common/storage.dart';
|
||
import 'package:remever/components/notifiers/app_settings.dart';
|
||
import 'package:remever/components/listeners/theme_listener.dart';
|
||
import 'package:remever/i18n/strings.g.dart';
|
||
import 'package:remever/theme/custom_theme.dart';
|
||
import 'package:talker_flutter/talker_flutter.dart';
|
||
|
||
final Completer<GlobalKey<NavigatorState>> navKeyCompleter =
|
||
Completer<GlobalKey<NavigatorState>>();
|
||
|
||
class MyApp extends StatefulWidget {
|
||
///
|
||
/// Основной класс приложения
|
||
///
|
||
const MyApp({super.key});
|
||
|
||
@override
|
||
State<MyApp> createState() => _MyAppState();
|
||
}
|
||
|
||
///
|
||
/// Состояние приложения
|
||
///
|
||
class _MyAppState extends State<MyApp>
|
||
with Subscriptionable<MyApp>, WidgetsBindingObserver {
|
||
///
|
||
/// Установка максимально фреймрейта
|
||
///
|
||
Future<void> setOptimalDisplayMode() async {
|
||
if (Platform.isAndroid) {
|
||
try {
|
||
await FlutterDisplayMode.setHighRefreshRate();
|
||
} on PlatformException catch (e) {
|
||
debugPrint('Не удалось установить частоту кадров экрана ${e.code}');
|
||
}
|
||
}
|
||
}
|
||
|
||
@override
|
||
void initState() {
|
||
unawaited(setOptimalDisplayMode());
|
||
|
||
WidgetsBinding.instance.addObserver(this);
|
||
|
||
super.initState();
|
||
}
|
||
|
||
@override
|
||
List<StreamSubscription<dynamic>> get subscribe {
|
||
return <StreamSubscription<dynamic>>[
|
||
/// Слушатель событий оповещений
|
||
eventBus.on<NotificationEvent>().listen((NotificationEvent event) {
|
||
log('app -> ${event.text}');
|
||
}),
|
||
];
|
||
}
|
||
|
||
@override
|
||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||
switch (state) {
|
||
case AppLifecycleState.resumed:
|
||
break;
|
||
|
||
case AppLifecycleState.inactive:
|
||
case AppLifecycleState.paused:
|
||
case AppLifecycleState.detached:
|
||
case AppLifecycleState.hidden:
|
||
|
||
///
|
||
/// При сворачивании/закрывании приложения
|
||
/// Компонуем все [Hive] хранилища
|
||
///
|
||
hiveLang.compact();
|
||
hiveTheme.compact();
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
WidgetsBinding.instance.removeObserver(this);
|
||
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
SystemChrome.setPreferredOrientations(<DeviceOrientation>[
|
||
DeviceOrientation.portraitUp,
|
||
DeviceOrientation.portraitDown,
|
||
]);
|
||
|
||
return Builder(
|
||
builder: (BuildContext context) {
|
||
return ScreenUtilInit(
|
||
designSize: const Size(380, 812),
|
||
minTextAdapt: true,
|
||
splitScreenMode: true,
|
||
useInheritedMediaQuery: true,
|
||
builder: (_, __) => _buildListeners(),
|
||
);
|
||
},
|
||
);
|
||
}
|
||
|
||
///
|
||
/// Построение слушателей
|
||
///
|
||
Widget _buildListeners() {
|
||
return ThemeModeListener(
|
||
builder: (BuildContext context, ThemeMode themeMode) {
|
||
return _buildMaterialApp(themeMode);
|
||
},
|
||
);
|
||
}
|
||
|
||
///
|
||
/// Основной построитель приложения
|
||
///
|
||
Widget _buildMaterialApp(ThemeMode themeMode) {
|
||
return MaterialApp.router(
|
||
title: 'Remever',
|
||
theme: CustomTheme.lightTheme,
|
||
darkTheme: CustomTheme.darkTheme,
|
||
themeMode: themeMode,
|
||
showPerformanceOverlay: false,
|
||
locale: TranslationProvider.of(context).flutterLocale,
|
||
supportedLocales: AppLocaleUtils.supportedLocales,
|
||
localizationsDelegates: GlobalMaterialLocalizations.delegates,
|
||
|
||
routerConfig: globalRouter.config(
|
||
navigatorObservers:
|
||
() => <NavigatorObserver>[TalkerRouteObserver(talker)],
|
||
),
|
||
builder: (BuildContext context, Widget? child) {
|
||
return ChangeNotifierProvider<AppSettingsNotifier>(
|
||
create: (_) => settingsNotifier,
|
||
builder: (BuildContext context, Widget? nchild) {
|
||
if (nchild != null) return nchild;
|
||
|
||
return Consumer<AppSettingsNotifier>(
|
||
// TIP: должно убрать мерцание
|
||
key: const Key('consumer AppSettingsNotifier'),
|
||
child: child,
|
||
builder: (
|
||
BuildContext context,
|
||
AppSettingsNotifier value,
|
||
Widget? nchild,
|
||
) {
|
||
final Widget result = nchild ?? const SizedBox();
|
||
|
||
if (value.showFps) {
|
||
return Material(
|
||
child: FPSWidget(
|
||
alignment: Alignment.centerLeft,
|
||
child: result,
|
||
),
|
||
);
|
||
}
|
||
|
||
return result;
|
||
},
|
||
);
|
||
},
|
||
);
|
||
},
|
||
);
|
||
}
|
||
}
|