From 3ef67ac722fee96ed71ce3246b6b97ade4ee2c0d Mon Sep 17 00:00:00 2001 From: Tyler Wilcox Date: Sat, 21 Mar 2026 22:28:55 -0400 Subject: [PATCH] Settings Page --- .../reports/problems/problems-report.html | 663 ++++++++++++++++++ lib/dbconstants.dart | 3 + lib/main.dart | 15 +- lib/pages/dashboard.dart | 18 + lib/pages/settings.dart | 88 +++ macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 173 ++++- pubspec.yaml | 3 +- 8 files changed, 939 insertions(+), 26 deletions(-) create mode 100644 android/build/reports/problems/problems-report.html create mode 100644 lib/dbconstants.dart create mode 100644 lib/pages/settings.dart diff --git a/android/build/reports/problems/problems-report.html b/android/build/reports/problems/problems-report.html new file mode 100644 index 0000000..f85479d --- /dev/null +++ b/android/build/reports/problems/problems-report.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Gradle Configuration Cache + + + +
+ +
+ Loading... +
+ + + + + + diff --git a/lib/dbconstants.dart b/lib/dbconstants.dart new file mode 100644 index 0000000..959dbb0 --- /dev/null +++ b/lib/dbconstants.dart @@ -0,0 +1,3 @@ +class DBConstants { + static final String ntServerAddrKey = "ntServerAddr"; +} diff --git a/lib/main.dart b/lib/main.dart index bad9274..19f2a97 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,6 @@ import 'package:helm/ntutils.dart'; +import 'dbconstants.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'pages/dashboard.dart'; import 'package:flutter/material.dart'; @@ -9,7 +11,18 @@ void main() { class MyApp extends StatelessWidget { MyApp({super.key}) { - NTUtils().connect("localhost"); + _connectNT(); + } + + void _connectNT() { + SharedPreferences.getInstance().then((value) async { + String addr = value.getString(DBConstants.ntServerAddrKey) ?? ""; + if (addr.isEmpty) { + addr = "localhost"; // Default to localhost and save + await value.setString(DBConstants.ntServerAddrKey, addr); + } + NTUtils().connect(addr); + }); } // This widget is the root of your application. diff --git a/lib/pages/dashboard.dart b/lib/pages/dashboard.dart index 22d3caa..4ec8171 100644 --- a/lib/pages/dashboard.dart +++ b/lib/pages/dashboard.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:helm/ntutils.dart'; +import 'package:helm/pages/settings.dart'; import 'package:helm/widgets/base_card.dart'; import 'package:helm/widgets/posty/posty_results_card.dart'; import 'package:helm/widgets/posty/posty_summary_card.dart'; @@ -55,6 +56,23 @@ class _DashboardState extends State { ], ), ), + drawer: Drawer( + child: ListView( + padding: EdgeInsets.zero, + children: [ + const DrawerHeader(child: Text("Helm")), + ListTile( + title: const Text("Settings"), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const Settings()), + ); + }, + ), + ], + ), + ), body: TabBarView( children: [ ResponsiveGridRow( diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart new file mode 100644 index 0000000..170c0ac --- /dev/null +++ b/lib/pages/settings.dart @@ -0,0 +1,88 @@ +import 'package:flutter/material.dart'; +import 'package:helm/dbconstants.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class Settings extends StatefulWidget { + const Settings({super.key}); + + @override + State createState() => _SettingsState(); +} + +class _SettingsState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Settings')), + body: ListView( + children: [ + _StringSettingTile( + title: "Server Address", + subtitle: "IP address of the Network Tables server.", + leading: Icon(Icons.network_wifi_sharp), + preferenceKey: DBConstants.ntServerAddrKey, + ), + ], + ), + ); + } +} + +class _StringSettingTile extends StatelessWidget { + final String title; + final String subtitle; + final Icon leading; + final String preferenceKey; + + const _StringSettingTile({ + required this.title, + required this.subtitle, + required this.leading, + required this.preferenceKey, + }); + + @override + Widget build(BuildContext context) { + return ListTile( + title: Text(title), + subtitle: Text(subtitle), + leading: leading, + trailing: const Icon(Icons.edit), + onTap: () async { + final prefs = await SharedPreferences.getInstance(); + final newValue = await showDialog( + context: context, + builder: (BuildContext context) { + String tempValue = prefs.getString(preferenceKey) ?? ""; + return AlertDialog( + title: Text('Edit $title'), + content: TextField( + controller: TextEditingController(text: tempValue), + onChanged: (value) { + tempValue = value; + }, + decoration: InputDecoration( + label: Text('Enter new $title'), + hintText: tempValue, + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(tempValue), + child: const Text('Save'), + ), + ], + ); + }, + ); + if (newValue != null) { + await prefs.setString(preferenceKey, newValue); + } + }, + ); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817..724bb2a 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,8 @@ import FlutterMacOS import Foundation +import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index cd3b966..546b8ea 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" clock: dependency: transitive description: @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" cupertino_icons: dependency: "direct main" description: @@ -65,6 +65,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -74,15 +90,20 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "6.0.0" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" leak_tracker: dependency: transitive description: @@ -111,26 +132,26 @@ packages: dependency: transitive description: name: lints - sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "6.1.0" matcher: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.18" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" messagepack: dependency: transitive description: @@ -171,6 +192,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" responsive_grid: dependency: "direct main" description: @@ -179,6 +240,62 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.4" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "8374d6200ab33ac99031a852eba4c8eb2170c4bf20778b3e2c9eccb45384fb41" + url: "https://pub.dev" + source: hosted + version: "2.4.21" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" sky_engine: dependency: transitive description: flutter @@ -188,10 +305,10 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.2" stack_trace: dependency: transitive description: @@ -228,10 +345,10 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.9" typed_data: dependency: transitive description: @@ -252,26 +369,34 @@ packages: dependency: transitive description: name: vm_service - sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" url: "https://pub.dev" source: hosted - version: "15.0.0" + version: "15.0.2" web: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.1.1" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "2.4.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" sdks: - dart: ">=3.8.0-0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=3.9.0 <4.0.0" + flutter: ">=3.35.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5862621..66c2cf6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,7 @@ dependencies: cupertino_icons: ^1.0.8 nt4: ^1.3.3 responsive_grid: ^2.4.4 + shared_preferences: ^2.5.4 dev_dependencies: flutter_test: @@ -46,7 +47,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^5.0.0 + flutter_lints: ^6.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec