mirror of
https://github.com/DefinedNet/mobile_nebula.git
synced 2025-01-18 19:27:05 +00:00
991837676a
This pulls out a component that we can use for "dangerous" operations like deleting, and styles it in one place. It also starts to move us slowly towards Material 3, with the rounded corners on these buttons in Android. Android: |Before Light|Before Dark|After Light|After Dark| |---|---|---|---| |<img width="425" alt="Android Studio 2025-01-15 14 16 36" src="https://github.com/user-attachments/assets/4823e551-6a40-48dd-9bc1-3004699b90ea" />|<img width="417" alt="Android Studio 2025-01-15 14 16 47" src="https://github.com/user-attachments/assets/df5461fd-586e-47bb-99b9-0212e63f0454" />|<img width="413" alt="Android Studio 2025-01-15 14 15 59" src="https://github.com/user-attachments/assets/d88a6225-b71a-4886-8387-e35811a3a6ec" />|<img width="418" alt="Android Studio 2025-01-15 14 16 15" src="https://github.com/user-attachments/assets/d4f23b1c-7003-4a00-b865-4a123d8fe3e9" />| iOS: |Before Light|Before Dark|After Light|After Dark| |---|---|---|---| |<img width="437" alt="Simulator 2025-01-15 15 56 26" src="https://github.com/user-attachments/assets/87c4eed3-6d07-4858-8ad8-d8c011538154" />|<img width="445" alt="Simulator 2025-01-15 15 56 36" src="https://github.com/user-attachments/assets/9dc5b174-7bc7-48ec-a3c0-61633168c31a" />|<img width="439" alt="Simulator 2025-01-15 16 05 23" src="https://github.com/user-attachments/assets/31dc9ab6-8a3c-49c7-892d-627f16e2a8cd" />|<img width="444" alt="Simulator 2025-01-15 16 05 37" src="https://github.com/user-attachments/assets/979280d6-e1f4-4d57-a86a-10bb4def729a" />|
158 lines
5.2 KiB
Dart
158 lines
5.2 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/cupertino.dart' show CupertinoThemeData, DefaultCupertinoLocalizations, CupertinoColors;
|
|
import 'package:flutter/material.dart'
|
|
show BottomSheetThemeData, ColorScheme, Colors, DefaultMaterialLocalizations, ThemeData, ThemeMode;
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
|
import 'package:mobile_nebula/screens/MainScreen.dart';
|
|
import 'package:mobile_nebula/screens/EnrollmentScreen.dart';
|
|
import 'package:mobile_nebula/services/settings.dart';
|
|
import 'package:flutter_web_plugins/url_strategy.dart';
|
|
import 'package:sentry_flutter/sentry_flutter.dart';
|
|
|
|
Future<void> main() async {
|
|
usePathUrlStrategy();
|
|
|
|
var settings = Settings();
|
|
if (settings.trackErrors) {
|
|
await SentryFlutter.init(
|
|
(options) {
|
|
options.dsn = 'https://96106df405ade3f013187dfc8e4200e7@o920269.ingest.us.sentry.io/4508132321001472';
|
|
// Capture all traces. May need to adjust if overwhelming
|
|
options.tracesSampleRate = 1.0;
|
|
// For each trace, capture all profiles
|
|
options.profilesSampleRate = 1.0;
|
|
},
|
|
appRunner: () => runApp(Main()),
|
|
);
|
|
} else {
|
|
runApp(Main());
|
|
}
|
|
}
|
|
|
|
//TODO: EventChannel might be better than the stream controller we are using now
|
|
|
|
class Main extends StatelessWidget {
|
|
// This widget is the root of your application.
|
|
@override
|
|
Widget build(BuildContext context) => App();
|
|
}
|
|
|
|
class App extends StatefulWidget {
|
|
@override
|
|
_AppState createState() => _AppState();
|
|
}
|
|
|
|
class _AppState extends State<App> {
|
|
final settings = Settings();
|
|
Brightness brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness;
|
|
StreamController dnEnrolled = StreamController.broadcast();
|
|
|
|
@override
|
|
void initState() {
|
|
//TODO: wait until settings is ready?
|
|
settings.onChange().listen((_) {
|
|
setState(() {
|
|
if (settings.useSystemColors) {
|
|
brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness;
|
|
} else {
|
|
brightness = settings.darkMode ? Brightness.dark : Brightness.light;
|
|
}
|
|
});
|
|
});
|
|
|
|
// Listen to changes to the system brightness mode, update accordingly
|
|
final dispatcher = SchedulerBinding.instance.platformDispatcher;
|
|
dispatcher.onPlatformBrightnessChanged = () {
|
|
if (settings.useSystemColors) {
|
|
setState(() {
|
|
brightness = dispatcher.platformBrightness;
|
|
});
|
|
}
|
|
};
|
|
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
dnEnrolled.close();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final ThemeData lightTheme = ThemeData(
|
|
useMaterial3: false,
|
|
colorScheme: ColorScheme.fromSwatch(
|
|
brightness: Brightness.light,
|
|
primarySwatch: Colors.blueGrey,
|
|
errorColor: CupertinoColors.systemRed.resolveFrom(context),
|
|
),
|
|
primaryColor: Colors.blueGrey[900],
|
|
fontFamily: 'PublicSans',
|
|
//scaffoldBackgroundColor: Colors.grey[100],
|
|
scaffoldBackgroundColor: Colors.white,
|
|
bottomSheetTheme: BottomSheetThemeData(
|
|
backgroundColor: Colors.blueGrey[50],
|
|
),
|
|
);
|
|
|
|
final ThemeData darkTheme = ThemeData(
|
|
useMaterial3: false,
|
|
colorScheme: ColorScheme.fromSwatch(
|
|
brightness: Brightness.dark,
|
|
primarySwatch: Colors.grey,
|
|
errorColor: CupertinoColors.systemRed.resolveFrom(context),
|
|
),
|
|
primaryColor: Colors.grey[900],
|
|
fontFamily: 'PublicSans',
|
|
scaffoldBackgroundColor: Colors.grey[800],
|
|
bottomSheetTheme: BottomSheetThemeData(
|
|
backgroundColor: Colors.grey[850],
|
|
),
|
|
);
|
|
|
|
return PlatformProvider(
|
|
settings: PlatformSettingsData(iosUsesMaterialWidgets: true),
|
|
builder: (context) => PlatformApp(
|
|
debugShowCheckedModeBanner: false,
|
|
localizationsDelegates: <LocalizationsDelegate<dynamic>>[
|
|
DefaultMaterialLocalizations.delegate,
|
|
DefaultWidgetsLocalizations.delegate,
|
|
DefaultCupertinoLocalizations.delegate,
|
|
],
|
|
title: 'Nebula',
|
|
material: (_, __) {
|
|
return new MaterialAppData(
|
|
themeMode: brightness == Brightness.light ? ThemeMode.light : ThemeMode.dark,
|
|
theme: brightness == Brightness.light ? lightTheme : darkTheme,
|
|
);
|
|
},
|
|
cupertino: (_, __) => CupertinoAppData(
|
|
theme: CupertinoThemeData(brightness: brightness),
|
|
),
|
|
onGenerateRoute: (settings) {
|
|
if (settings.name == '/') {
|
|
return platformPageRoute(context: context, builder: (context) => MainScreen(this.dnEnrolled));
|
|
}
|
|
|
|
final uri = Uri.parse(settings.name!);
|
|
if (uri.path == EnrollmentScreen.routeName) {
|
|
// TODO: maybe implement this as a dialog instead of a page, you can stack multiple enrollment screens which is annoying in dev
|
|
return platformPageRoute(
|
|
context: context,
|
|
builder: (context) =>
|
|
EnrollmentScreen(code: EnrollmentScreen.parseCode(settings.name!), stream: this.dnEnrolled),
|
|
);
|
|
}
|
|
|
|
return null;
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|