mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Add five new selectable themes alongside the existing Catppuccin Mocha and Gruvbox Dark, each built through the shared buildAppTheme so they stay visually consistent. Palettes are taken from each project's official source; a few intermediate surface shades are interpolated where the canonical palette omits them (noted in the theme files). Register the new themes in main.dart and add their dropdown entries in settings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
110 lines
3.3 KiB
Dart
110 lines
3.3 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:frontend/theme/alucard_theme.dart';
|
|
import 'package:frontend/theme/catppuccin_latte_theme.dart';
|
|
import 'package:frontend/theme/catppuccin_mocha_theme.dart';
|
|
import 'package:frontend/theme/dracula_theme.dart';
|
|
import 'package:frontend/theme/nord_theme.dart';
|
|
import 'package:frontend/theme/tokyo_night_theme.dart';
|
|
import 'package:frontend/utils/local_network_permission.dart';
|
|
import 'package:frontend/utils/pref_utils.dart';
|
|
import 'package:frontend/utils/push_service.dart';
|
|
import 'package:frontend/utils/ui_snackbars.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'navigation.dart';
|
|
import 'theme/gruvbox_theme.dart';
|
|
|
|
void main() {
|
|
runZonedGuarded(
|
|
() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
FlutterError.onError = (details) {
|
|
FlutterError.presentError(details);
|
|
debugPrint('FlutterError: ${details.exceptionAsString()}');
|
|
};
|
|
PlatformDispatcher.instance.onError = (error, stack) {
|
|
debugPrint('Uncaught platform error: $error\n$stack');
|
|
return true;
|
|
};
|
|
|
|
try {
|
|
await PrefUtil.init();
|
|
} catch (e, stack) {
|
|
debugPrint(
|
|
'PrefUtil.init failed, continuing with defaults: $e\n$stack',
|
|
);
|
|
}
|
|
|
|
// Resume push at launch (Firebase init + foreground handler + token
|
|
// re-registration when already enabled); see initPushOnLaunch.
|
|
try {
|
|
await initPushOnLaunch();
|
|
} catch (e, stack) {
|
|
debugPrint('Push launch init failed, continuing: $e\n$stack');
|
|
}
|
|
|
|
// Settle iOS's local-network permission now, at launch, so it isn't
|
|
// still being decided when the user first taps "Test" in settings.
|
|
unawaited(requestLocalNetworkPermission());
|
|
|
|
runApp(const MainApp());
|
|
},
|
|
(error, stack) {
|
|
debugPrint('Uncaught zone error: $error\n$stack');
|
|
},
|
|
);
|
|
}
|
|
|
|
final class MainApp extends StatelessWidget {
|
|
const MainApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ChangeNotifierProvider(
|
|
create: (context) => AppState(),
|
|
child: Consumer<AppState>(
|
|
builder: (context, appState, _) => MaterialApp.router(
|
|
title: 'OOTT',
|
|
theme: appState.theme,
|
|
routerConfig: router,
|
|
// Host snackbars above the router's Navigator so they render on top
|
|
// of dialogs (their barrier no longer dims them). See buildSnackbarHost.
|
|
builder: buildSnackbarHost,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
final _themes = {
|
|
'alucard': alucardLightTheme,
|
|
'catppuccin_latte': catppuccinLatteLightTheme,
|
|
'catppuccin_mocha': catppuccinMochaDarkTheme,
|
|
'dracula': draculaDarkTheme,
|
|
'gruvbox_dark': gruvboxDarkTheme,
|
|
'nord': nordDarkTheme,
|
|
'tokyo_night': tokyoNightDarkTheme,
|
|
};
|
|
|
|
class AppState extends ChangeNotifier {
|
|
AppState() {
|
|
final saved = PrefUtil.getValue('theme', 'gruvbox_dark') as String;
|
|
_themeKey = _themes.containsKey(saved) ? saved : 'gruvbox_dark';
|
|
}
|
|
|
|
late String _themeKey;
|
|
String get themeKey => _themeKey;
|
|
ThemeData get theme => _themes[_themeKey]!;
|
|
|
|
Future<bool> setTheme(String key) async {
|
|
if (!_themes.containsKey(key)) return false;
|
|
if (key == _themeKey) return true;
|
|
_themeKey = key;
|
|
notifyListeners();
|
|
return PrefUtil.setValue('theme', key);
|
|
}
|
|
}
|