Vaani/lib/main.dart

172 lines
5.7 KiB
Dart
Raw Normal View History

import 'package:dynamic_color/dynamic_color.dart';
2024-05-08 05:03:49 -04:00
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
2024-06-28 06:01:56 -04:00
import 'package:logging/logging.dart';
2024-08-23 04:21:46 -04:00
import 'package:vaani/api/server_provider.dart';
import 'package:vaani/db/storage.dart';
import 'package:vaani/features/downloads/providers/download_manager.dart';
import 'package:vaani/features/logging/core/logger.dart';
2024-08-23 04:21:46 -04:00
import 'package:vaani/features/playback_reporting/providers/playback_reporter_provider.dart';
import 'package:vaani/features/player/core/init.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart'
show audiobookPlayerProvider, simpleAudiobookPlayerProvider;
import 'package:vaani/features/shake_detection/providers/shake_detector.dart';
2024-08-23 04:21:46 -04:00
import 'package:vaani/features/sleep_timer/providers/sleep_timer_provider.dart';
import 'package:vaani/router/router.dart';
import 'package:vaani/settings/api_settings_provider.dart';
import 'package:vaani/settings/app_settings_provider.dart';
import 'package:vaani/theme/providers/system_theme_provider.dart';
import 'package:vaani/theme/providers/theme_from_cover_provider.dart';
2024-08-23 04:21:46 -04:00
import 'package:vaani/theme/theme.dart';
2024-05-08 05:03:49 -04:00
2024-08-23 04:21:46 -04:00
final appLogger = Logger('vaani');
2024-06-28 06:01:56 -04:00
2024-05-08 05:03:49 -04:00
void main() async {
WidgetsFlutterBinding.ensureInitialized();
2024-06-28 06:01:56 -04:00
// Configure the root Logger
await initLogging();
2024-05-08 05:03:49 -04:00
// initialize the storage
await initStorage();
2024-05-09 23:23:50 -04:00
// initialize audio player
await configurePlayer();
2024-05-17 11:04:20 -04:00
// run the app
2024-05-09 23:23:50 -04:00
runApp(
const ProviderScope(
child: _EagerInitialization(child: MyApp()),
2024-05-08 05:03:49 -04:00
),
);
}
var routerConfig = const MyAppRouter().config;
2024-05-09 23:23:50 -04:00
2024-05-08 05:03:49 -04:00
class MyApp extends ConsumerWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final servers = ref.watch(audiobookShelfServerProvider);
final apiSettings = ref.watch(apiSettingsProvider);
final needOnboarding = apiSettings.activeUser == null || servers.isEmpty;
2024-05-10 04:11:39 -04:00
if (needOnboarding) {
routerConfig.goNamed(Routes.onboarding.name);
}
final appSettings = ref.watch(appSettingsProvider);
final themeSettings = appSettings.themeSettings;
2024-05-10 04:11:39 -04:00
ColorScheme lightColorScheme = brandLightColorScheme;
ColorScheme darkColorScheme = brandDarkColorScheme;
final shouldUseHighContrast =
themeSettings.highContrast || MediaQuery.of(context).highContrast;
if (shouldUseHighContrast) {
lightColorScheme = lightColorScheme.copyWith(
surface: Colors.white,
);
darkColorScheme = darkColorScheme.copyWith(
surface: Colors.black,
);
}
if (themeSettings.useMaterialThemeFromSystem) {
var themes =
ref.watch(systemThemeProvider(highContrast: shouldUseHighContrast));
if (themes.valueOrNull != null) {
lightColorScheme = themes.valueOrNull!.$1;
darkColorScheme = themes.valueOrNull!.$2;
}
}
if (themeSettings.useCurrentPlayerThemeThroughoutApp) {
try {
final player = ref.watch(audiobookPlayerProvider);
if (player.book != null) {
final themeLight = ref.watch(
themeOfLibraryItemProvider(
player.book!.libraryItemId,
highContrast: shouldUseHighContrast,
brightness: Brightness.light,
),
);
final themeDark = ref.watch(
themeOfLibraryItemProvider(
player.book!.libraryItemId,
highContrast: shouldUseHighContrast,
brightness: Brightness.dark,
),
);
if (themeLight.valueOrNull != null && themeDark.valueOrNull != null) {
lightColorScheme = themeLight.valueOrNull!;
darkColorScheme = themeDark.valueOrNull!;
}
}
} catch (e) {
debugPrintStack(stackTrace: StackTrace.current, label: e.toString());
appLogger.severe('not building with player theme');
appLogger.severe(e.toString());
}
}
final appThemeLight = ThemeData(
useMaterial3: true,
colorScheme: lightColorScheme.harmonized(),
);
final appThemeDark = ThemeData(
useMaterial3: true,
colorScheme: darkColorScheme.harmonized(),
brightness: Brightness.dark,
// TODO bottom sheet theme is not working
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: darkColorScheme.surface,
),
);
try {
return MaterialApp.router(
// debugShowCheckedModeBanner: false,
theme: appThemeLight,
darkTheme: appThemeDark,
themeMode: themeSettings.themeMode,
routerConfig: routerConfig,
themeAnimationCurve: Curves.easeInOut,
);
} catch (e) {
debugPrintStack(stackTrace: StackTrace.current, label: e.toString());
appLogger.severe(e.toString());
if (needOnboarding) {
routerConfig.goNamed(Routes.onboarding.name);
}
return const SizedBox.shrink();
}
2024-05-08 05:03:49 -04:00
}
}
2024-06-06 15:35:30 -04:00
// https://riverpod.dev/docs/essentials/eager_initialization
// Eagerly initialize providers by watching them.
class _EagerInitialization extends ConsumerWidget {
const _EagerInitialization({required this.child});
final Widget child;
@override
Widget build(BuildContext context, WidgetRef ref) {
// Eagerly initialize providers by watching them.
// By using "watch", the provider will stay alive and not be disposed.
try {
ref.watch(simpleAudiobookPlayerProvider);
ref.watch(sleepTimerProvider);
2024-06-15 23:43:08 -04:00
ref.watch(playbackReporterProvider);
2024-08-20 08:36:39 -04:00
ref.watch(simpleDownloadManagerProvider);
ref.watch(shakeDetectorProvider);
2024-06-06 15:35:30 -04:00
} catch (e) {
debugPrintStack(stackTrace: StackTrace.current, label: e.toString());
appLogger.severe(e.toString());
2024-06-06 15:35:30 -04:00
}
2024-06-15 23:43:08 -04:00
2024-06-06 15:35:30 -04:00
return child;
}
}