203 lines
6.9 KiB
Dart
203 lines
6.9 KiB
Dart
import "dart:io";
|
|
|
|
import "package:dynamic_color/dynamic_color.dart";
|
|
import "package:flutter/foundation.dart";
|
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
|
import "package:material_emoji_picker/material_emoji_picker.dart";
|
|
import "package:media_kit/media_kit.dart";
|
|
import "package:nexus/controllers/client_state.dart";
|
|
import "package:nexus/controllers/gomuks_listener.dart";
|
|
import "package:nexus/controllers/key.dart";
|
|
import "package:nexus/controllers/member_list_opened.dart";
|
|
import "package:nexus/controllers/multi_provider.dart";
|
|
import "package:nexus/controllers/notification.dart";
|
|
import "package:nexus/controllers/settings.dart";
|
|
import "package:nexus/controllers/unified_push.dart";
|
|
import "package:nexus/helpers/extensions/scheme_to_theme.dart";
|
|
import "package:nexus/helpers/font_licenses.dart";
|
|
import "package:nexus/widgets/pages/chat.dart";
|
|
import "package:nexus/widgets/pages/select_server.dart";
|
|
import "package:nexus/widgets/pages/settings.dart";
|
|
import "package:nexus/widgets/pages/verify.dart";
|
|
import "package:nexus/widgets/appbar.dart";
|
|
import "package:nexus/widgets/error_dialog.dart";
|
|
import "package:nexus/widgets/loading.dart";
|
|
import "package:window_manager/window_manager.dart";
|
|
import "package:material_ui/material_ui.dart";
|
|
|
|
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
|
late final bool isInBackground;
|
|
|
|
final class Logger extends ProviderObserver {
|
|
@override
|
|
void didUpdateProvider(
|
|
ProviderObserverContext context,
|
|
Object? previousValue,
|
|
Object? newValue,
|
|
) => debugPrint("""
|
|
Time: ${DateTime.now().toIso8601String()}
|
|
Provider: ${context.provider}
|
|
Previous Value: ${previousValue is AsyncData ? previousValue.value : previousValue}
|
|
New Value: ${newValue is AsyncData ? newValue.value : newValue}
|
|
""");
|
|
}
|
|
|
|
void showError(Object error, [StackTrace? stackTrace]) {
|
|
if (error.toString().contains("'_nextFrame != null': is not true.")) {
|
|
return;
|
|
}
|
|
|
|
debugPrintStack(stackTrace: stackTrace, label: error.toString());
|
|
if (navigatorKey.currentContext != null) {
|
|
Future.delayed(
|
|
Duration.zero,
|
|
() => showDialog(
|
|
context: navigatorKey.currentContext!,
|
|
builder: (_) => ErrorDialog(error, stackTrace),
|
|
barrierDismissible: false,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
void main(List<String> args) async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
MediaKit.ensureInitialized();
|
|
|
|
LicenseRegistry.addLicense(() => .fromIterable(fontLicenses));
|
|
|
|
FlutterError.onError = (FlutterErrorDetails details) =>
|
|
showError(details.exception.toString(), details.stack);
|
|
|
|
isInBackground =
|
|
Platform.environment["FLUTTER_HEADLESS"] != null ||
|
|
args.contains("--unifiedpush-bg");
|
|
|
|
if (isInBackground) {
|
|
await ProviderContainer()
|
|
.read(UnifiedPushController.provider.future)
|
|
.timeout(Duration(seconds: 5));
|
|
|
|
await Future.delayed(Duration(seconds: 10));
|
|
exit(0);
|
|
} else {
|
|
if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
|
|
await windowManager.ensureInitialized();
|
|
await windowManager.waitUntilReadyToShow(
|
|
WindowOptions(
|
|
titleBarStyle: TitleBarStyle.hidden,
|
|
windowButtonVisibility: false,
|
|
),
|
|
);
|
|
await windowManager.setMinimumSize(Size.square(500));
|
|
}
|
|
|
|
runApp(
|
|
ProviderScope(
|
|
retry: (_, _) => null,
|
|
observers: [
|
|
// Change false to true if you want debug information on provider reloads
|
|
// ignore: dead_code
|
|
if (false && kDebugMode) Logger(),
|
|
],
|
|
child: App(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class const App({super.key}) extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) => DynamicColorBuilder(
|
|
builder: (lightDynamic, darkDynamic) => Consumer(
|
|
builder: (context, ref, child) => MaterialApp(
|
|
navigatorKey: navigatorKey,
|
|
debugShowCheckedModeBanner: false,
|
|
theme:
|
|
(ref
|
|
.watch(SettingsController.provider)
|
|
.maybeWhen(
|
|
orElse: () => lightDynamic,
|
|
data: (settings) =>
|
|
settings.useDynamicTheming ? lightDynamic : null,
|
|
) ??
|
|
ThemeData.light().colorScheme)
|
|
.theme,
|
|
darkTheme:
|
|
(ref
|
|
.watch(SettingsController.provider)
|
|
.maybeWhen(
|
|
orElse: () => darkDynamic,
|
|
data: (settings) =>
|
|
settings.useDynamicTheming ? darkDynamic : null,
|
|
) ??
|
|
ThemeData.dark().colorScheme)
|
|
.theme,
|
|
themeMode: ref
|
|
.watch(SettingsController.provider)
|
|
.maybeWhen(
|
|
data: (settings) => settings.theme,
|
|
orElse: () => ThemeMode.system,
|
|
),
|
|
home: child,
|
|
),
|
|
child: DefaultTextHeightBehavior(
|
|
textHeightBehavior: .new(leadingDistribution: .even),
|
|
child: Scaffold(
|
|
body: Consumer(
|
|
builder: (context, ref, _) => switch (ref.watch(
|
|
MultiProviderController.provider(
|
|
.new([
|
|
GomuksListenerController.provider,
|
|
NotificationController.provider,
|
|
UnifiedPushController.provider,
|
|
MemberListOpenedController.provider,
|
|
KeyController.provider(KeyController.roomKey),
|
|
KeyController.provider(KeyController.spaceKey),
|
|
EmojiController.provider,
|
|
]),
|
|
),
|
|
)) {
|
|
AsyncData(value: _) || AsyncLoading(value: _?) => Consumer(
|
|
builder: (_, ref, _) {
|
|
final clientState = ref.watch(ClientStateController.provider);
|
|
|
|
if (clientState == null || !clientState.isInitialized) {
|
|
return Loading();
|
|
}
|
|
|
|
if (!clientState.isLoggedIn) {
|
|
return SelectServerPage();
|
|
} else if (!clientState.isVerified) {
|
|
return VerifyPage();
|
|
} else {
|
|
return ChatPage();
|
|
}
|
|
},
|
|
),
|
|
|
|
AsyncLoading _ => Scaffold(
|
|
appBar: Appbar(
|
|
actions: .new([
|
|
IconButton(
|
|
onPressed: () => showDialog(
|
|
context: context,
|
|
builder: (_) => SettingsPage(),
|
|
),
|
|
icon: Icon(Icons.settings),
|
|
),
|
|
]),
|
|
),
|
|
body: Loading(),
|
|
),
|
|
AsyncError(:final error, :final stackTrace) => ErrorDialog(
|
|
error,
|
|
stackTrace,
|
|
),
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|