Refactor Settings and Task Views for API Base URL Management

- Deprecated `ApiSettingsViewModel` in favor of enhancing `SettingsViewModel`.
- Moved the API Base URL field from `TaskView` to `SettingsView` to centralize configuration.
- Integrated `RestApiUtility` dependency into `SettingsViewModel` to ensure consistent URL management across the app.
This commit is contained in:
hunteraraujo
2023-09-24 21:41:12 -07:00
parent ffa76c3a19
commit da8b9d58ac
6 changed files with 24 additions and 70 deletions

View File

@@ -10,7 +10,6 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:auto_gpt_flutter_client/viewmodels/task_viewmodel.dart'; import 'package:auto_gpt_flutter_client/viewmodels/task_viewmodel.dart';
import 'package:auto_gpt_flutter_client/viewmodels/chat_viewmodel.dart'; import 'package:auto_gpt_flutter_client/viewmodels/chat_viewmodel.dart';
import 'package:auto_gpt_flutter_client/viewmodels/skill_tree_viewmodel.dart'; import 'package:auto_gpt_flutter_client/viewmodels/skill_tree_viewmodel.dart';
import 'package:auto_gpt_flutter_client/viewmodels/api_settings_viewmodel.dart';
import 'package:auto_gpt_flutter_client/services/chat_service.dart'; import 'package:auto_gpt_flutter_client/services/chat_service.dart';
import 'package:auto_gpt_flutter_client/services/task_service.dart'; import 'package:auto_gpt_flutter_client/services/task_service.dart';
@@ -55,11 +54,11 @@ void main() async {
update: (context, restApiUtility, leaderboardService) => update: (context, restApiUtility, leaderboardService) =>
LeaderboardService(restApiUtility), LeaderboardService(restApiUtility),
), ),
ChangeNotifierProxyProvider<RestApiUtility, ApiSettingsViewModel>( ChangeNotifierProxyProvider<RestApiUtility, SettingsViewModel>(
create: (context) => ApiSettingsViewModel( create: (context) => SettingsViewModel(
Provider.of<RestApiUtility>(context, listen: false)), Provider.of<RestApiUtility>(context, listen: false)),
update: (context, restApiUtility, apiSettingsViewModel) => update: (context, restApiUtility, settingsViewModel) =>
ApiSettingsViewModel(restApiUtility), SettingsViewModel(restApiUtility),
), ),
], ],
child: MyApp(), child: MyApp(),
@@ -87,9 +86,6 @@ class MyApp extends StatelessWidget {
if (snapshot.hasData && snapshot.data != null) { if (snapshot.hasData && snapshot.data != null) {
return MultiProvider( return MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(
create: (context) => SettingsViewModel(),
),
ChangeNotifierProvider( ChangeNotifierProvider(
create: (context) => ChatViewModel( create: (context) => ChatViewModel(
Provider.of<ChatService>(context, listen: false))), Provider.of<ChatService>(context, listen: false))),

View File

@@ -1,30 +0,0 @@
import 'package:auto_gpt_flutter_client/utils/rest_api_utility.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ApiSettingsViewModel with ChangeNotifier {
String _baseURL = "http://127.0.0.1:8000/ap/v1";
SharedPreferences? _prefs;
final RestApiUtility _restApiUtility;
ApiSettingsViewModel(this._restApiUtility) {
_loadBaseURL();
}
String get baseURL => _baseURL;
void _loadBaseURL() async {
_prefs = await SharedPreferences.getInstance();
_baseURL = _prefs?.getString('baseURL') ?? _baseURL;
_restApiUtility.updateBaseURL(_baseURL);
notifyListeners();
}
void updateBaseURL(String newURL) async {
_baseURL = newURL;
_prefs ??= await SharedPreferences.getInstance();
_prefs?.setString('baseURL', newURL);
_restApiUtility.updateBaseURL(newURL);
notifyListeners();
}
}

View File

@@ -1,4 +1,5 @@
import 'package:auto_gpt_flutter_client/services/auth_service.dart'; import 'package:auto_gpt_flutter_client/services/auth_service.dart';
import 'package:auto_gpt_flutter_client/utils/rest_api_utility.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@@ -11,6 +12,8 @@ class SettingsViewModel extends ChangeNotifier {
String _baseURL = ''; // State for Base URL String _baseURL = ''; // State for Base URL
int _continuousModeSteps = 1; // State for Continuous Mode Steps int _continuousModeSteps = 1; // State for Continuous Mode Steps
final RestApiUtility _restApiUtility;
// Getters to access the private state variables // Getters to access the private state variables
bool get isDarkModeEnabled => _isDarkModeEnabled; bool get isDarkModeEnabled => _isDarkModeEnabled;
bool get isDeveloperModeEnabled => _isDeveloperModeEnabled; bool get isDeveloperModeEnabled => _isDeveloperModeEnabled;
@@ -19,8 +22,8 @@ class SettingsViewModel extends ChangeNotifier {
final AuthService _authService = AuthService(); final AuthService _authService = AuthService();
SettingsViewModel() { SettingsViewModel(this._restApiUtility) {
_loadPreferences(); // Load stored preferences when the view model is created _loadPreferences();
} }
// Method to load stored preferences // Method to load stored preferences
@@ -28,7 +31,8 @@ class SettingsViewModel extends ChangeNotifier {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
_isDarkModeEnabled = prefs.getBool('isDarkModeEnabled') ?? false; _isDarkModeEnabled = prefs.getBool('isDarkModeEnabled') ?? false;
_isDeveloperModeEnabled = prefs.getBool('isDeveloperModeEnabled') ?? false; _isDeveloperModeEnabled = prefs.getBool('isDeveloperModeEnabled') ?? false;
_baseURL = prefs.getString('baseURL') ?? ''; _baseURL = prefs.getString('baseURL') ?? 'http://127.0.0.1:8000/ap/v1';
_restApiUtility.updateBaseURL(_baseURL);
_continuousModeSteps = prefs.getInt('continuousModeSteps') ?? 10; _continuousModeSteps = prefs.getInt('continuousModeSteps') ?? 10;
notifyListeners(); notifyListeners();
} }
@@ -47,11 +51,12 @@ class SettingsViewModel extends ChangeNotifier {
_saveBoolPreference('isDeveloperModeEnabled', value); _saveBoolPreference('isDeveloperModeEnabled', value);
} }
/// Updates the state of Base URL and notifies listeners. /// Updates the state of Base URL, notifies listeners, and updates the RestApiUtility baseURL.
void updateBaseURL(String value) { void updateBaseURL(String value) {
_baseURL = value; _baseURL = value;
notifyListeners(); notifyListeners();
_saveStringPreference('baseURL', value); _saveStringPreference('baseURL', value);
_restApiUtility.updateBaseURL(value);
} }
/// Increments the number of Continuous Mode Steps and notifies listeners. /// Increments the number of Continuous Mode Steps and notifies listeners.

View File

@@ -1,16 +1,16 @@
import 'package:auto_gpt_flutter_client/viewmodels/settings_viewmodel.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:auto_gpt_flutter_client/viewmodels/api_settings_viewmodel.dart';
class ApiBaseUrlField extends StatelessWidget { class ApiBaseUrlField extends StatelessWidget {
final TextEditingController controller; final TextEditingController controller = TextEditingController();
const ApiBaseUrlField({required this.controller});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<ApiSettingsViewModel>( return Consumer<SettingsViewModel>(
builder: (context, apiSettingsViewModel, child) { builder: (context, settingsViewModel, child) {
// TODO: This view shouldn't know about the settings view model. It should use a delegate
controller.text = settingsViewModel.baseURL;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column( child: Column(
@@ -39,8 +39,8 @@ class ApiBaseUrlField extends StatelessWidget {
children: [ children: [
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
controller.text = 'http://127.0.0.1:8000/api/v1'; controller.text = 'http://127.0.0.1:8000/ap/v1';
apiSettingsViewModel.updateBaseURL(controller.text); settingsViewModel.updateBaseURL(controller.text);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: Colors.white, backgroundColor: Colors.white,
@@ -53,7 +53,7 @@ class ApiBaseUrlField extends StatelessWidget {
), ),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
apiSettingsViewModel.updateBaseURL(controller.text); settingsViewModel.updateBaseURL(controller.text);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: Colors.white, backgroundColor: Colors.white,

View File

@@ -1,4 +1,5 @@
import 'package:auto_gpt_flutter_client/viewmodels/settings_viewmodel.dart'; import 'package:auto_gpt_flutter_client/viewmodels/settings_viewmodel.dart';
import 'package:auto_gpt_flutter_client/views/settings/api_base_url_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// [SettingsView] displays a list of settings that the user can configure. /// [SettingsView] displays a list of settings that the user can configure.
@@ -32,16 +33,7 @@ class SettingsView extends StatelessWidget {
onChanged: viewModel.toggleDeveloperMode, onChanged: viewModel.toggleDeveloperMode,
), ),
// Base URL Configuration // Base URL Configuration
ListTile( ApiBaseUrlField(),
title: const Text('Base URL'),
subtitle: TextFormField(
initialValue: viewModel.baseURL,
onChanged: viewModel.updateBaseURL,
decoration: const InputDecoration(
hintText: 'Enter Base URL',
),
),
),
// Continuous Mode Steps Configuration // Continuous Mode Steps Configuration
ListTile( ListTile(
title: const Text('Continuous Mode Steps'), title: const Text('Continuous Mode Steps'),

View File

@@ -1,7 +1,5 @@
import 'package:auto_gpt_flutter_client/models/task.dart'; import 'package:auto_gpt_flutter_client/models/task.dart';
import 'package:auto_gpt_flutter_client/models/test_suite.dart'; import 'package:auto_gpt_flutter_client/models/test_suite.dart';
import 'package:auto_gpt_flutter_client/viewmodels/api_settings_viewmodel.dart';
import 'package:auto_gpt_flutter_client/views/task/api_base_url_field.dart';
import 'package:auto_gpt_flutter_client/views/task/test_suite_detail_view.dart'; import 'package:auto_gpt_flutter_client/views/task/test_suite_detail_view.dart';
import 'package:auto_gpt_flutter_client/views/task/test_suite_list_tile.dart'; import 'package:auto_gpt_flutter_client/views/task/test_suite_list_tile.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -21,8 +19,6 @@ class TaskView extends StatefulWidget {
} }
class _TaskViewState extends State<TaskView> { class _TaskViewState extends State<TaskView> {
final TextEditingController _baseUrlController = TextEditingController();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -30,8 +26,6 @@ class _TaskViewState extends State<TaskView> {
// Schedule the fetchTasks call for after the initial build // Schedule the fetchTasks call for after the initial build
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
widget.viewModel.fetchAndCombineData(); widget.viewModel.fetchAndCombineData();
_baseUrlController.text =
Provider.of<ApiSettingsViewModel>(context, listen: false).baseURL;
}); });
} }
@@ -116,9 +110,6 @@ class _TaskViewState extends State<TaskView> {
}, },
), ),
), ),
const SizedBox(height: 16),
ApiBaseUrlField(controller: _baseUrlController),
const SizedBox(height: 16),
], ],
), ),
if (widget.viewModel.selectedTestSuite != null) if (widget.viewModel.selectedTestSuite != null)