autogpt / frontend /lib /viewmodels /task_viewmodel.dart
kakumusic's picture
Upload folder using huggingface_hub
b225a21 verified
raw
history blame
7.31 kB
import 'dart:convert';
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/services/shared_preferences_service.dart';
import 'package:flutter/foundation.dart';
import 'package:collection/collection.dart';
import 'package:auto_gpt_flutter_client/services/task_service.dart';
import 'package:auto_gpt_flutter_client/models/task_request_body.dart';
// TODO: How will all these functions work with test suites?
class TaskViewModel with ChangeNotifier {
final TaskService _taskService;
final SharedPreferencesService _prefsService;
List<Task> _tasks = [];
List<TestSuite> _testSuites = [];
List<dynamic> combinedDataSource = [];
List<Task> tasksDataSource = [];
Task? _selectedTask;
TestSuite? _selectedTestSuite;
bool _isWaitingForAgentResponse = false;
bool get isWaitingForAgentResponse => _isWaitingForAgentResponse;
TaskViewModel(this._taskService, this._prefsService);
/// Returns the currently selected task.
Task? get selectedTask => _selectedTask;
TestSuite? get selectedTestSuite => _selectedTestSuite;
/// Adds a task and returns its ID.
Future<String> createTask(String title) async {
_isWaitingForAgentResponse = true;
notifyListeners();
try {
final newTask = TaskRequestBody(input: title);
// Add to data source
final createdTask = await _taskService.createTask(newTask);
// Create a Task object from the created task response
final newTaskObject =
Task(id: createdTask['task_id'], title: createdTask['input']);
fetchAndCombineData();
final taskId = newTaskObject.id;
print("Task $taskId created successfully!");
return newTaskObject.id;
} catch (e) {
// TODO: We are bubbling up the full response. Revisit this.
rethrow;
} finally {
_isWaitingForAgentResponse = false;
notifyListeners();
}
}
/// Deletes a task.
void deleteTask(String taskId) {
_taskService.saveDeletedTask(taskId);
_tasks.removeWhere((task) => task.id == taskId);
notifyListeners();
print("Task $taskId deleted successfully!");
}
/// Fetches tasks from the data source.
Future<void> fetchTasks() async {
try {
final tasksFromApi = await _taskService.fetchAllTasks();
_tasks = tasksFromApi
.where((task) => !_taskService.isTaskDeleted(task.id))
.toList();
_tasks = _tasks.reversed.toList();
notifyListeners();
print("Tasks fetched successfully!");
} catch (error) {
print("Error fetching tasks: $error");
}
}
/// Handles the selection of a task by its ID.
void selectTask(String id) {
final task = _tasks.firstWhereOrNull((t) => t.id == id);
if (task != null) {
_selectedTask = task;
print("Selected task with ID: ${task.id} and Title: ${task.title}");
notifyListeners(); // Notify listeners to rebuild UI
} else {
final errorMessage =
"Error: Attempted to select a task with ID: $id that does not exist in the data source.";
print(errorMessage);
throw ArgumentError(errorMessage);
}
}
/// Deselects the currently selected task.
void deselectTask() {
_selectedTask = null;
print("Deselected the current task.");
notifyListeners(); // Notify listeners to rebuild UI
}
void selectTestSuite(TestSuite testSuite) {
_selectedTestSuite = testSuite;
notifyListeners();
}
void deselectTestSuite() {
_selectedTestSuite = null;
notifyListeners();
}
// Helper method to save test suites to SharedPreferences
Future<void> _saveTestSuitesToPrefs() async {
final testSuitesToStore =
_testSuites.map((testSuite) => jsonEncode(testSuite.toJson())).toList();
await _prefsService.setStringList('testSuites', testSuitesToStore);
}
// Adds a new test suite and saves it to SharedPreferences
void addTestSuite(TestSuite testSuite) async {
_testSuites.add(testSuite);
await _saveTestSuitesToPrefs();
notifyListeners();
print("Test suite successfully added!");
}
// Fetch test suites from SharedPreferences
Future<void> fetchTestSuites() async {
final storedTestSuites =
await _prefsService.getStringList('testSuites') ?? [];
_testSuites = storedTestSuites
.map((testSuiteMap) => TestSuite.fromJson(jsonDecode(testSuiteMap)))
.toList();
notifyListeners();
}
// The fetchAndCombineData method performs several tasks:
// 1. It fetches the tasks and filters out deleted ones.
// 2. It fetches the test suites from SharedPreferences.
// 3. It combines both the tasks and test suites into a single data source according to specified logic.
Future<void> fetchAndCombineData() async {
// Step 1: Fetch tasks from the data source
// This will populate the _tasks list with tasks fetched from the backend.
await fetchTasks();
// Step 2: Fetch test suites from SharedPreferences
// This will populate the _testSuites list with test suites fetched from SharedPreferences.
await fetchTestSuites();
// Step 3: Combine into a shared data source
// Create a map to hold test suites by their timestamp.
Map<String, TestSuite> testSuiteMap = {};
// Clear the existing combined data source to start fresh.
combinedDataSource.clear();
tasksDataSource.clear();
// Iterate through each task to check if it's contained in any of the test suites.
for (var task in _tasks) {
bool found = false;
// Iterate through each test suite.
for (var testSuite in _testSuites) {
// Check if the current task is contained in the current test suite.
if (testSuite.tests.contains(task)) {
found = true;
// If this test suite is already in the map, add this task to its list of tasks.
if (testSuiteMap.containsKey(testSuite.timestamp)) {
testSuiteMap[testSuite.timestamp]!.tests.add(task);
// Find and replace the test suite in the combined data source.
final index = combinedDataSource.indexWhere((item) =>
item is TestSuite && item.timestamp == testSuite.timestamp);
if (index != -1) {
combinedDataSource[index] = testSuiteMap[testSuite.timestamp]!;
}
}
// If this test suite is not in the map, add it to the map and to the combined data source.
else {
final newTestSuite = TestSuite(
timestamp: testSuite.timestamp,
tests: [task],
);
testSuiteMap[testSuite.timestamp] = newTestSuite;
combinedDataSource.add(
newTestSuite); // Add the new test suite to the combined data source.
}
break; // Exit the loop as the task is found in a test suite.
}
}
// If the task was not found in any test suite, add it to the combined data source.
if (!found) {
combinedDataSource.add(task);
tasksDataSource.add(task);
}
}
// After processing all tasks, call notifyListeners to rebuild the widgets that depend on this data.
notifyListeners();
print("Combined tasks and test suites successfully!");
}
}