Laser Proxy support

This commit is contained in:
Raktbastr 2026-01-06 21:32:11 -06:00
parent f97222dcc9
commit 5858a4a231
5 changed files with 49 additions and 69 deletions

View file

@ -1,21 +1,21 @@
![Laser Scouter](https://laserrobotics.org/wp-content/uploads/2025/02/laserscouterlogo.png) ![Laser Scouter](https://laserrobotics.org/wp-content/uploads/2025/02/laserscouterlogo.png)
<sub>WIP Logo</sub>
Simple FRC scouting app. Developed by Laser Robotics. # Simple FRC scouting app. Developed by me for Laser Robotics and the FRC community!
Input a team number and a TBA API key then select your event. Click on a team and start writing notes then export as a .CSV! Input your team number and event, and start scouting! When you're done export your notes as a .csv for Google Sheets or Excel.
# What is planned # What is planned
* Breakdowns of match statistics * Better and updated scouting questions, these are examples from Reefscape
* Scouting questions, these are examples to test out input * Match scouting
* Stat comparisons * Online accessible version
* Full release by 2025 Laser Lights Off Season!
# Some extra notes # Some extra notes
* This is a side project by a few of our members and is our first Flutter project. Please leave suggestions and tips about what we could do better! * This is a side project by a me and is my first Flutter project. Please leave suggestions and tips about what I could do better!
* I am providing binaries but recommend you compile it yourself. * I am providing APK's, but it may not be the most up to date version.
* To run on iOS you will still need to compile it, I do not have an Apple Dev Account. * To run on iOS you will still need to compile it and install with Xcode
# How to contribute # How to contribute
@ -26,6 +26,6 @@ Input a team number and a TBA API key then select your event. Click on a team an
# How to test # How to test
1. Run the command `flutter run` in your terminal while inside project folder. 1. Run the command `flutter run` in your terminal while inside project folder.
2. Open the app in your desired platform. 2. Open the app in a browser, on your phone, or as a computer app.
* If you plan to test on an iPhone, you must have a Apple Developer account and a MacOS device with Xcode. I reccomend [this guide](https://www.geeksforgeeks.org/how-to-install-flutter-app-on-ios/) * If you plan to test on an iPhone, you must have a Apple Developer account and a MacOS device with Xcode.

View file

@ -5,9 +5,8 @@ import 'teampicker.dart';
class EventPicker extends StatelessWidget { class EventPicker extends StatelessWidget {
final List<String> eventNames; final List<String> eventNames;
final List<String> eventCodes; final List<String> eventCodes;
final String apiKey;
EventPicker({required this.eventNames, required this.eventCodes, required this.apiKey}); EventPicker({required this.eventNames, required this.eventCodes});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -27,7 +26,6 @@ class EventPicker extends StatelessWidget {
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => TeamPicker( builder: (context) => TeamPicker(
apiKey: apiKey,
eventCode: eventCodes[index], eventCode: eventCodes[index],
), ),
), ),

View file

@ -4,12 +4,9 @@ import 'package:http/http.dart' as http;
import 'dart:convert'; import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
void getData(String apiKey, String teamNumber, Function(List<String>, List<String>) callback) async { void getData(String teamNumber, Function(List<String>, List<String>) callback) async {
final response = await http.get( final response = await http.get(
Uri.parse('https://www.thebluealliance.com/api/v3/team/frc$teamNumber/events/2025'), Uri.parse('https://laserscouter.halfheart.net/teamsearch/$teamNumber'),
headers: {
'X-TBA-Auth-Key': apiKey,
},
); );
if (response.statusCode == 200) { if (response.statusCode == 200) {
String data = response.body; String data = response.body;
@ -42,7 +39,7 @@ class MyApp extends StatelessWidget {
useMaterial3: true, useMaterial3: true,
primaryColor: const Color.fromARGB(255, 19, 81, 179), primaryColor: const Color.fromARGB(255, 19, 81, 179),
appBarTheme: const AppBarTheme( appBarTheme: const AppBarTheme(
color: Color.fromARGB(255, 19, 81, 179), backgroundColor: Color.fromARGB(255, 19, 81, 179),
iconTheme: IconThemeData(color: Colors.white), iconTheme: IconThemeData(color: Colors.white),
), ),
), ),
@ -109,27 +106,17 @@ class _LoginPageState extends State<LoginPage> {
), ),
), ),
const SizedBox(height: 16.0), const SizedBox(height: 16.0),
TextField(
controller: _apiKeyController,
decoration: const InputDecoration(
labelText: 'TBA API Key',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16.0),
ElevatedButton( ElevatedButton(
onPressed: () async { onPressed: () async {
await _saveData(); await _saveData();
String teamNumber = _teamNumberController.text; String teamNumber = _teamNumberController.text;
String apiKey = _apiKeyController.text; getData(teamNumber, (eventNames, eventCodes) {
getData(apiKey, teamNumber, (eventNames, eventCodes) {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => EventPicker( builder: (context) => EventPicker(
eventNames: eventNames, eventNames: eventNames,
eventCodes: eventCodes, eventCodes: eventCodes,
apiKey: apiKey,
), ),
), ),
); );

View file

@ -4,12 +4,9 @@ import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:to_csv/to_csv.dart' as exportCSV; import 'package:to_csv/to_csv.dart' as exportCSV;
void getData(String apiKey, String eventCode, Function(List<String>, List<String>) callback) async { void getData(String eventCode, Function(List<String>, List<String>) callback) async {
final response = await http.get( final response = await http.get(
Uri.parse('https://www.thebluealliance.com/api/v3/event/$eventCode/teams'), Uri.parse('https://laserscouter.halfheart.net/eventsearch/$eventCode'),
headers: {
'X-TBA-Auth-Key': apiKey,
},
); );
if (response.statusCode == 200) { if (response.statusCode == 200) {
String data = response.body; String data = response.body;
@ -28,10 +25,9 @@ void getData(String apiKey, String eventCode, Function(List<String>, List<String
} }
class TeamPicker extends StatefulWidget { class TeamPicker extends StatefulWidget {
final String apiKey;
final String eventCode; final String eventCode;
TeamPicker({required this.apiKey, required this.eventCode}); TeamPicker({required this.eventCode});
@override @override
_TeamPickerState createState() => _TeamPickerState(); _TeamPickerState createState() => _TeamPickerState();
@ -43,7 +39,6 @@ class NotesPage extends StatefulWidget {
final String teamName; final String teamName;
NotesPage({required this.teamCode, required this.teamName, required this.eventCode}); NotesPage({required this.teamCode, required this.teamName, required this.eventCode});
@override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@ -204,7 +199,7 @@ class _TeamPickerState extends State<TeamPicker> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
getData(widget.apiKey, widget.eventCode, (names, codes) { getData(widget.eventCode, (names, codes) {
setState(() { setState(() {
teamNames = names; teamNames = names;
teamCodes = codes; teamCodes = codes;

View file

@ -37,10 +37,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.4.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -69,18 +69,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.2"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.19.0" version: "1.19.1"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
@ -141,10 +141,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.3.3"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
@ -260,26 +260,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.7" version: "11.0.2"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.8" version: "3.0.10"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_testing name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -292,10 +292,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.16+1" version: "0.12.17"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
@ -308,10 +308,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.15.0" version: "1.17.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -324,10 +324,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.0" version: "1.9.1"
path_provider: path_provider:
dependency: transitive dependency: transitive
description: description:
@ -505,18 +505,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.12.0" version: "1.12.1"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.4"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
@ -537,10 +537,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.3" version: "0.7.7"
to_csv: to_csv:
dependency: "direct main" dependency: "direct main"
description: description:
@ -617,10 +617,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.2.0"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
@ -670,5 +670,5 @@ packages:
source: hosted source: hosted
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.6.1 <4.0.0" dart: ">=3.8.0-0 <4.0.0"
flutter: ">=3.27.0" flutter: ">=3.27.0"