Skip to content

Commit

Permalink
;)
Browse files Browse the repository at this point in the history
  • Loading branch information
Levi-Lesches committed Jul 20, 2023
1 parent 7685704 commit ceccc53
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 32 deletions.
File renamed without changes
Binary file added assets/rover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 11 additions & 3 deletions lib/src/data/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,22 @@ class AutonomySettings {
///
/// Implement these! Ask Levi for details.
class EasterEggsSettings {
/// Whether to do a SEGA-like intro during boot.
final bool segaIntro;

/// A const constructor.
const EasterEggsSettings();
const EasterEggsSettings({
required this.segaIntro,
});

/// Parses easter eggs settings from JSON.
EasterEggsSettings.fromJson(Json? json); // ignore: avoid_unused_constructor_parameters
EasterEggsSettings.fromJson(Json? json) :
segaIntro = json?["segaIntro"] ?? true;

/// Serializes these settings to JSON.
Json toJson() => { };
Json toJson() => {
"segaIntro": segaIntro,
};
}

/// Contains the settings for running the dashboard and the rover.
Expand Down
3 changes: 3 additions & 0 deletions lib/src/models/data/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class SettingsModel extends Model {
/// The user's autonomy settings.
AutonomySettings get autonomy => all.autonomy;

/// The user's easter egg settings.
EasterEggsSettings get easterEggs => all.easterEggs;

@override
Future<void> init() async {
all = await services.files.readSettings();
Expand Down
31 changes: 29 additions & 2 deletions lib/src/models/view/builders/settings_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,28 @@ class AutonomySettingsBuilder extends ValueBuilder<AutonomySettings> {
AutonomySettings get value => AutonomySettings(blockSize: blockSize.value);
}

/// A [ValueBuilder] that modifies an [EasterEggsSettings].
class EasterEggsSettingsBuilder extends ValueBuilder<EasterEggsSettings> {
/// Whether to show a SEGA intro. See [EasterEggsSettings.segaIntro].
bool segaIntro;

/// Fills in the fields with the given [initial] settings.
EasterEggsSettingsBuilder(EasterEggsSettings initial) :
segaIntro = initial.segaIntro;

@override
bool get isValid => true;

@override
EasterEggsSettings get value => EasterEggsSettings(segaIntro: segaIntro);

/// Updates the value of [EasterEggsSettings.segaIntro].
void updateSegaIntro(bool input) { // ignore: avoid_positional_boolean_parameters
segaIntro = input;
notifyListeners();
}
}

/// A [ValueBuilder] representing an [ArmSettings].
class SettingsBuilder extends ValueBuilder<Settings> {
/// The [NetworkSettings] view model.
Expand All @@ -228,6 +250,9 @@ class SettingsBuilder extends ValueBuilder<Settings> {
/// The [AutonomySettings] view model.
final AutonomySettingsBuilder autonomy;

/// The [EasterEggsSettings] view model.
final EasterEggsSettingsBuilder easterEggs;

/// Whether the page is loading.
bool isLoading = false;

Expand All @@ -237,13 +262,15 @@ class SettingsBuilder extends ValueBuilder<Settings> {
network = NetworkSettingsBuilder(models.settings.network),
arm = ArmSettingsBuilder(models.settings.arm),
video = VideoSettingsBuilder(models.settings.video),
science = ScienceSettingsBuilder(models.settings.science)
science = ScienceSettingsBuilder(models.settings.science),
easterEggs = EasterEggsSettingsBuilder(models.settings.easterEggs)
{
autonomy.addListener(notifyListeners);
network.addListener(notifyListeners);
arm.addListener(notifyListeners);
video.addListener(notifyListeners);
science.addListener(notifyListeners);
easterEggs.addListener(notifyListeners);
}

@override
Expand All @@ -258,7 +285,7 @@ class SettingsBuilder extends ValueBuilder<Settings> {
autonomy: autonomy.value,
network: network.value,
video: video.value,
easterEggs: const EasterEggsSettings(),
easterEggs: easterEggs.value,
science: science.value,
arm: arm.value,
);
Expand Down
8 changes: 6 additions & 2 deletions lib/src/pages/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,14 @@ class SettingsPage extends StatelessWidget {
],
),
const Divider(),
const ValueEditor<EasterEggsSettings>(
ValueEditor<EasterEggsSettings>(
name: "Easter eggs",
children: [
ListTile(title: Text("Coming soon!")),
SwitchListTile(
title: const Text("Enable SEGA Intro"),
value: model.easterEggs.segaIntro,
onChanged: model.easterEggs.updateSegaIntro,
),
],
),
const Divider(),
Expand Down
80 changes: 60 additions & 20 deletions lib/src/pages/splash.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ import "package:flutter/services.dart";
import "package:rover_dashboard/models.dart";
import "package:rover_dashboard/pages.dart";
import "package:rover_dashboard/services.dart";
import "package:rover_dashboard/widgets.dart";

/// Initializes the dashboard and handles errors.
class SplashPage extends StatefulWidget {
@override
SplashPageState createState() => SplashPageState();
}

/// The state of the SEGA animation.
enum SegaState {
/// The rover is off-screen to the left, facing the right, and the text is transparent.
partOne,
/// The rover is off-screen to the right, facing the right, and the text is 30% opaque.
partTwo,
/// The rover is off-screen to the left, facing the left, and the text is 100% opaque.
partThree,
}

/// Initializes the dashboard and handles errors.
class SplashPageState extends State<SplashPage>{
/// The error message produced during initialization, if any.
Expand All @@ -19,12 +30,24 @@ class SplashPageState extends State<SplashPage>{
/// The current task, if any.
String? current;

/// The state of the SEGA animation.
SegaState state = SegaState.partOne;

@override
void initState() {
super.initState();
init();
}

/// Starts the SEGA animation.
Future<void> initAnimation() async {
// await Future<void>.delayed(const Duration(milliseconds: 1000));
setState(() => state = SegaState.partTwo);
await Future<void>.delayed(const Duration(milliseconds: 1000));
setState(() => state = SegaState.partThree);
await Future<void>.delayed(const Duration(milliseconds: 1000));
}

/// Calls [Services.init] and [Models.init] while monitoring for errors.
Future<void> init() async {
try {
Expand All @@ -37,34 +60,51 @@ class SplashPageState extends State<SplashPage>{

current = "models";
await models.init();
if (models.settings.easterEggs.segaIntro) await initAnimation();
if (mounted) {
await Navigator.of(context).pushReplacementNamed(Routes.home);
}
} catch (error) {
setState(() => errorText = error.toString());
rethrow;
}

if (mounted) {
await Navigator.of(context).pushReplacementNamed(Routes.home);
}
}

@override
Widget build(BuildContext context) => Scaffold(
body: Center(child: errorText == null
? const CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(flex: 2),
Text("Something went wrong", style: Theme.of(context).textTheme.displayLarge),
const Spacer(),
Text("The error occurred when trying to initialize $current", style: Theme.of(context).textTheme.headlineLarge),
const SizedBox(height: 24),
Text("Here is the exact error:", style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 16),
Text(errorText!),
const Spacer(flex: 2),
],
),
body: Stack(
alignment: Alignment.center,
children: [
AnimatedOpacity(
duration: const Duration(milliseconds: 1000),
opacity: switch (state) {
SegaState.partOne => 0,
SegaState.partTwo => 0.3,
SegaState.partThree => 1,
},
child: Text("Binghamton University\nRover Team", textAlign: TextAlign.center, style: context.textTheme.displayMedium),
),
AnimatedAlign(
duration: const Duration(milliseconds: 750),
alignment: switch (state) {
SegaState.partOne => const Alignment(-1.5, 0),
SegaState.partTwo => const Alignment(1.5, 0),
SegaState.partThree => const Alignment(-1.5, 0),
},
child: Transform.flip(
flipX: switch (state) {
SegaState.partOne => true,
SegaState.partTwo => true,
SegaState.partThree => false,
},
child: SizedBox(
width: 150,
height: 150,
child: Image.asset("assets/rover.png"),
),
),
),
],
),
);
}
12 changes: 7 additions & 5 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@ dependency_overrides:
# Generates icons for the given platforms
# Run: flutter pub run icons_launcher:create
icons_launcher:
image_path: "logo.png"
image_path: "assets/logo.png"
platforms:
android:
# adaptive_foreground_image: "logo.png"
# adaptive_foreground_image: "assets/logo.png"
# adaptive_background_color: "#000000"
# adaptive_monochrome_image: "logo.png"
# adaptive_monochrome_image: "assets/logo.png"
enable: true
windows:
enable: true

flutter_launcher_icons:
image_path: "logo.png"
image_path: "assets/logo.png"
android: true
windows:
generate: true
Expand All @@ -67,7 +67,7 @@ msix_config:
display_name: Dashboard
publisher_display_name: Binghamton University Rover Team
identity_name: edu.binghamton.rover
logo_path: logo.png
logo_path: assets/logo.png
trim_logo: false
capabilities: internetClientServer, privateNetworkClientServer, usb, serialcommunication, lowLevel
output_name: Dashboard
Expand All @@ -78,3 +78,5 @@ msix_config:
# The following section is specific to Flutter packages.
flutter:
uses-material-design: true
assets:
- assets/rover.png

0 comments on commit ceccc53

Please sign in to comment.