diff --git a/android/.gitignore b/android/.gitignore index 6f56801..5c6f20f 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -11,3 +11,4 @@ GeneratedPluginRegistrant.java key.properties **/*.keystore **/*.jks +/app/.cxx \ No newline at end of file diff --git a/android/settings.gradle b/android/settings.gradle index 599ca9d..615b56a 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -19,7 +19,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "7.4.2" apply false - id "org.jetbrains.kotlin.android" version "1.7.10" apply false + id "org.jetbrains.kotlin.android" version "1.8.22" apply false } include ":app" \ No newline at end of file diff --git a/lib/builders/PlatformRoute.dart b/lib/builders/PlatformRoute.dart index 4fcb507..58a3a82 100644 --- a/lib/builders/PlatformRoute.dart +++ b/lib/builders/PlatformRoute.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:scouting_platform/components/navigation/NavigationSidebar.dart'; import 'package:scouting_platform/styles/AppStyle.dart'; +import 'package:scouting_platform/utils/data/values/SettingValues.dart'; import 'package:scouting_platform/utils/helpers/UIHelper.dart'; import 'package:scouting_platform/utils/data/constants/AppConstants.dart'; @@ -20,6 +21,27 @@ class PlatformRoute extends StatefulWidget { class _PlatformRouteState extends State { final scaffoldKey = GlobalKey(); + Color appBarColor = AppStyle.textInputColor; + + @override + void initState() { + super.initState(); + _loadColor(); + if(!SettingValues.isTeamListenerRegistered) { + SettingValues.isTeamListenerRegistered = true; + Stream.periodic(Duration(seconds: 1)).listen((_) { + _loadColor(); + }); + } + } + + void _loadColor() async { + appBarColor = await UIHelper.getAppBarColour(); + setState(() { + appBarColor = appBarColor; + }); + } + @override Widget build(BuildContext context) { return PopScope( @@ -31,7 +53,7 @@ class _PlatformRouteState extends State { appBar: PreferredSize( preferredSize: const Size.fromHeight(40.0), child: AppBar( - backgroundColor: AppStyle.textInputColor, + backgroundColor: appBarColor, title: Text( widget.title, textAlign: TextAlign.center, diff --git a/lib/components/navigation/components/SidebarItem.dart b/lib/components/navigation/components/SidebarItem.dart index e8fad1c..6f94476 100644 --- a/lib/components/navigation/components/SidebarItem.dart +++ b/lib/components/navigation/components/SidebarItem.dart @@ -26,10 +26,10 @@ class _SidebarItemState extends State { style: const TextStyle(fontFamily: 'Futura', fontWeight: FontWeight.bold), ), - onTap: () => - Navigator.push(context, MaterialPageRoute(builder: (context) { + onTap: () => Navigator.pushAndRemoveUntil(context, + MaterialPageRoute(builder: (context) { return widget.route; - })), + }), (r) => false), ); } } diff --git a/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow4.dart b/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow4.dart index 4a40109..baec2c2 100644 --- a/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow4.dart +++ b/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow4.dart @@ -85,7 +85,7 @@ class _AutonomousRow4State extends State { checkColor: Colors.white, labelColor: Colors.white, margin: const EdgeInsets.only(right: 0.0)), - Align( + Align( alignment: Alignment.centerLeft, child: SizedBox( width: 170.0, diff --git a/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow5.dart b/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow5.dart index a712657..75a6a23 100644 --- a/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow5.dart +++ b/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow5.dart @@ -85,7 +85,7 @@ class _AutonomousRow5State extends State { checkColor: Colors.white, labelColor: Colors.white, margin: const EdgeInsets.only(right: 0.0)), - Align( + Align( alignment: Alignment.centerLeft, child: SizedBox( width: 170.0, diff --git a/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow6.dart b/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow6.dart index 96eddc2..30edffa 100644 --- a/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow6.dart +++ b/lib/routes/auto/fields/AutonomousCheckboxRows/AutonomousRow6.dart @@ -85,7 +85,7 @@ class _AutonomousRow6State extends State { checkColor: Colors.white, labelColor: Colors.white, margin: const EdgeInsets.only(right: 0.0)), - Align( + Align( alignment: Alignment.centerLeft, child: SizedBox( width: 170.0, diff --git a/lib/routes/prematch/PrematchRoute.dart b/lib/routes/prematch/PrematchRoute.dart index 84c4994..a7da1c0 100644 --- a/lib/routes/prematch/PrematchRoute.dart +++ b/lib/routes/prematch/PrematchRoute.dart @@ -20,6 +20,7 @@ class _PrematchRouteState extends State { @override void initState() { super.initState(); + UIHelper.setBrightness(0.3); AppDataHelper.getCurrentEventIDAndCurrentDriverStation().then((value) { if (value != "") { @@ -30,8 +31,6 @@ class _PrematchRouteState extends State { }); } }); - - UIHelper.setBrightness(0.3); } @override diff --git a/lib/routes/qrcode/QRCodeRoute.dart b/lib/routes/qrcode/QRCodeRoute.dart index a368839..3463d45 100644 --- a/lib/routes/qrcode/QRCodeRoute.dart +++ b/lib/routes/qrcode/QRCodeRoute.dart @@ -119,9 +119,10 @@ class _QRCodeRouteState extends State { AppDataHelper.resetStates(); }); Navigator.of(context, rootNavigator: true).pop('dialog'); - Navigator.push(context, MaterialPageRoute(builder: (context) { + Navigator.pushAndRemoveUntil(context, + MaterialPageRoute(builder: (context) { return const PrematchRoute(title: "Prematch Data"); - })); + }), (r) => false); }, ); diff --git a/lib/utils/data/constants/OptionConstants.dart b/lib/utils/data/constants/OptionConstants.dart index 22205f0..b375347 100644 --- a/lib/utils/data/constants/OptionConstants.dart +++ b/lib/utils/data/constants/OptionConstants.dart @@ -1,11 +1,11 @@ // ignore_for_file: file_names class OptionConstants { - static final yesNoOptions = ["Yes", "No"]; + static final yesNoOptions = ["", "Yes", "No"]; - static final startPositions = ["Top", "Center", "Bottom"]; + static final startPositions = ["", "Top", "Center", "Bottom"]; - static final endgameOptions = ["No", "Shallow", "Deep", "Park"]; + static final endgameOptions = ["", "No", "Shallow", "Deep", "Park"]; static List availableDriverstations = [ "Red 1", diff --git a/lib/utils/data/values/AutonomousValues.dart b/lib/utils/data/values/AutonomousValues.dart index 54c6d99..116c179 100644 --- a/lib/utils/data/values/AutonomousValues.dart +++ b/lib/utils/data/values/AutonomousValues.dart @@ -4,8 +4,8 @@ import 'package:flutter/material.dart'; class AutonomousValues { // other static TextEditingController autoStartPosition = - TextEditingController(text: "Center"); - static TextEditingController autoMobility = TextEditingController(text: "No"); + TextEditingController(text: ""); + static TextEditingController autoMobility = TextEditingController(text: ""); static TextEditingController coralMissed = TextEditingController(text: "0"); static TextEditingController algaeRemoved = TextEditingController(text: "0"); static TextEditingController algaeProcessor = @@ -66,8 +66,8 @@ class AutonomousValues { static TextEditingController l2G = TextEditingController(text: "0"); static void resetAutoEtcValues() { - AutonomousValues.autoStartPosition.text = "Center"; - AutonomousValues.autoMobility.text = "No"; + AutonomousValues.autoStartPosition.text = ""; + AutonomousValues.autoMobility.text = ""; AutonomousValues.coralMissed.text = "0"; AutonomousValues.algaeRemoved.text = "0"; AutonomousValues.algaeBarge.text = "0"; diff --git a/lib/utils/data/values/EndgameValues.dart b/lib/utils/data/values/EndgameValues.dart index 0dc7f74..084bed7 100644 --- a/lib/utils/data/values/EndgameValues.dart +++ b/lib/utils/data/values/EndgameValues.dart @@ -6,11 +6,11 @@ class EndgameValues { /// These don't hold the value of the stopwatch, only properties such as state and the instance static final stopwatch = Stopwatch(); - static TextEditingController endgame = TextEditingController(text: "No"); + static TextEditingController endgame = TextEditingController(text: ""); static TextEditingController climbTime = TextEditingController(text: "0"); static void resetEndgameValues() { - EndgameValues.endgame.text = "No"; // was climb, now endgame + EndgameValues.endgame.text = ""; // was climb, now endgame EndgameValues.climbTime.text = "0"; // parked was below EndgameValues.stopwatch.stop(); EndgameValues.stopwatch.reset(); diff --git a/lib/utils/data/values/SettingValues.dart b/lib/utils/data/values/SettingValues.dart index 51f21b5..7f86aef 100644 --- a/lib/utils/data/values/SettingValues.dart +++ b/lib/utils/data/values/SettingValues.dart @@ -10,6 +10,7 @@ class SettingValues { TextEditingController(text: AppConstants.defaultEventID); static TextEditingController fileName = TextEditingController(text: AppConstants.defaultFileName); + static bool isTeamListenerRegistered = false; static String isTeamNumberEditable = "No"; static bool isTeamNumberReadOnly = true; diff --git a/lib/utils/data/values/TeleoperatedValues.dart b/lib/utils/data/values/TeleoperatedValues.dart index 6628bfb..ab8aeeb 100644 --- a/lib/utils/data/values/TeleoperatedValues.dart +++ b/lib/utils/data/values/TeleoperatedValues.dart @@ -25,5 +25,7 @@ class TeleoperatedValues { TeleoperatedValues.algaeProcessor.text = "0"; TeleoperatedValues.algaeBarge.text = "0"; TeleoperatedValues.defenseTime.text = "0"; + TeleoperatedValues.stopwatch.stop(); + TeleoperatedValues.stopwatch.reset(); } } diff --git a/lib/utils/helpers/AppDataHelper.dart b/lib/utils/helpers/AppDataHelper.dart index 26cc46c..58e5660 100644 --- a/lib/utils/helpers/AppDataHelper.dart +++ b/lib/utils/helpers/AppDataHelper.dart @@ -30,7 +30,7 @@ class AppDataHelper { if (!await file.exists()) { await file.create(); } - await file.writeAsString("$data\n", mode: FileMode.append); + await file.writeAsString(data); } else { throw Exception('Permission denied'); } diff --git a/lib/utils/helpers/QRCodeHelper.dart b/lib/utils/helpers/QRCodeHelper.dart index 300225a..7910d4a 100644 --- a/lib/utils/helpers/QRCodeHelper.dart +++ b/lib/utils/helpers/QRCodeHelper.dart @@ -9,7 +9,6 @@ import 'package:scouting_platform/utils/data/values/EndgameValues.dart'; import 'package:scouting_platform/utils/data/values/PrematchValues.dart'; import 'package:scouting_platform/utils/data/values/SettingValues.dart'; import 'package:scouting_platform/utils/data/values/TeleoperatedValues.dart'; -import 'package:scouting_platform/utils/helpers/AppDataHelper.dart'; class QrcodeHelper { /// Returns a string that represents the contents of the QR code that will be generated and separates them with a "^" character @@ -29,7 +28,7 @@ class QrcodeHelper { // Encode to UTF-8 and then base64 to compress size and reduce issues with characters List utf8Encoded = utf8.encode(computedValues); - AppDataHelper.saveQRCodeCopy(computedValues); + // AppDataHelper.saveQRCodeCopy(computedValues); return base64.encode(utf8Encoded); } diff --git a/lib/utils/helpers/ScheduleHelper.dart b/lib/utils/helpers/ScheduleHelper.dart index b1b031d..a3e449d 100644 --- a/lib/utils/helpers/ScheduleHelper.dart +++ b/lib/utils/helpers/ScheduleHelper.dart @@ -4,11 +4,13 @@ import 'dart:io'; import 'package:permission_handler/permission_handler.dart'; import 'package:scouting_platform/utils/data/constants/AppConstants.dart'; +import 'package:scouting_platform/utils/data/values/PrematchValues.dart'; import 'package:scouting_platform/utils/data/values/SettingValues.dart'; class Schedulehelper { static late int argumentReadingIndex; static late int driverStationIdentifier; + static List simbotMatches = []; static Future get _scheduleDirecotyPath async { final directory = Directory('/storage/emulated/0/Documents'); @@ -53,6 +55,60 @@ class Schedulehelper { return null; } + static Future getNumberOfLinesInSchedule() async { + final file = File( + "/storage/emulated/0/Documents/match_schedule_${SettingValues.eventID.text}.csv"); + + if (await file.exists()) { + final lines = await file.readAsLines(); + return lines.length - 1; + } + return 0; + } + + static Future> getSimbotMatches() async { + if (simbotMatches.isNotEmpty) { + // memoization + return simbotMatches; + } + + for (var i = 0; i < await getNumberOfLinesInSchedule(); i++) { + String? matchData = await readLineFromSchedule(i); + if (matchData == null) { + break; + } + if (matchData.contains("1114")) { + simbotMatches.add(matchData); + } + } + return simbotMatches; + } + + static Future isTeamInUpcomingMatches(int teamNumber) async { + if (PrematchValues.matchNumber.text.isEmpty) { + return false; + } + + List simbotMatches = await getSimbotMatches(); + for (String simbotMatch in simbotMatches) { + List simbotMatchData = simbotMatch.split(","); + String matchNumber = simbotMatchData[0]; + simbotMatchData.removeAt(0); + int teamIndex = simbotMatchData.indexOf(teamNumber.toString()); + int simbotIndex = simbotMatchData.indexOf("1114"); + + bool teamAlliance = teamIndex < 2 && teamIndex != -1; + bool simbotAlliance = simbotIndex < 2 && simbotIndex != -1; + + if (int.parse(matchNumber) > + int.parse(PrematchValues.matchNumber.text) + 1 && + teamAlliance == simbotAlliance) { + return true; + } + } + return false; + } + static Future getTeamNumberFromSchedule(int matchNumber) async { switch (SettingValues.selectedDriverStation.text) { case "Red 1": diff --git a/lib/utils/helpers/UIHelper.dart b/lib/utils/helpers/UIHelper.dart index 69425d2..d2598a0 100644 --- a/lib/utils/helpers/UIHelper.dart +++ b/lib/utils/helpers/UIHelper.dart @@ -2,7 +2,9 @@ import 'dart:ui'; import 'package:scouting_platform/styles/AppStyle.dart'; +import 'package:scouting_platform/utils/data/values/PrematchValues.dart'; import 'package:scouting_platform/utils/data/values/SettingValues.dart'; +import 'package:scouting_platform/utils/helpers/ScheduleHelper.dart'; import 'package:screen_brightness/screen_brightness.dart'; class UIHelper { @@ -15,6 +17,19 @@ class UIHelper { } } + static Future getAppBarColour() async { + try { + if (await Schedulehelper.isTeamInUpcomingMatches( + int.parse(PrematchValues.teamNumber.text))) { + return Color.from(alpha: 1, red: 0, green: 0.5, blue: 0); + } else { + return AppStyle.textInputColor; + } + } catch (e) { + return AppStyle.textInputColor; + } + } + // Sets the brightness of the screen static Future setBrightness(double brightness) async { try {