mirror of
https://github.com/aljazceru/Auto-GPT.git
synced 2026-01-08 00:34:20 +01:00
Implement TaskListTile with tests
This commit introduces the TaskListTile, a custom widget designed to display individual tasks in the TaskView. The tile offers a user-friendly interface with interactive features, such as selection and deletion. Key Features: - Responsive design that adapts its width based on the TaskView's constraints. - Interactive tile that changes its background color upon selection. - A delete icon that appears only when the tile is selected. - Comprehensive widget tests to ensure the TaskListTile behaves as expected. By splitting this into its own widget, the codebase remains modular, making it easier to maintain and update in the future.
This commit is contained in:
81
lib/views/task_list_tile.dart
Normal file
81
lib/views/task_list_tile.dart
Normal file
@@ -0,0 +1,81 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:auto_gpt_flutter_client/models/task.dart';
|
||||
|
||||
class TaskListTile extends StatefulWidget {
|
||||
final Task task;
|
||||
final VoidCallback onTap;
|
||||
final VoidCallback onDelete;
|
||||
|
||||
const TaskListTile({
|
||||
Key? key,
|
||||
required this.task,
|
||||
required this.onTap,
|
||||
required this.onDelete,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_TaskListTileState createState() => _TaskListTileState();
|
||||
}
|
||||
|
||||
class _TaskListTileState extends State<TaskListTile> {
|
||||
bool _isSelected = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Determine the width of the TaskView
|
||||
double taskViewWidth = MediaQuery.of(context).size.width;
|
||||
double tileWidth = taskViewWidth - 20;
|
||||
if (tileWidth > 260) {
|
||||
tileWidth = 260;
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isSelected = !_isSelected;
|
||||
});
|
||||
widget.onTap();
|
||||
},
|
||||
child: Material(
|
||||
// Use a transparent color to avoid any unnecessary color overlay
|
||||
color: Colors.transparent,
|
||||
child: Padding(
|
||||
// Provide a horizontal padding to ensure the tile does not touch the edges
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Container(
|
||||
// Width and height specifications for the tile
|
||||
width: tileWidth,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
// Use conditional operator to determine background color based on selection
|
||||
color: _isSelected ? Colors.grey[300] : Colors.white,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// Space from the left edge of the tile
|
||||
const SizedBox(width: 8),
|
||||
// Message bubble icon indicating a task
|
||||
const Icon(Icons.messenger_outline, color: Colors.black),
|
||||
const SizedBox(width: 8),
|
||||
// Task title
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.task.title,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
),
|
||||
),
|
||||
// If the task is selected, show a delete icon
|
||||
if (_isSelected)
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close, color: Colors.black),
|
||||
onPressed: widget.onDelete,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
71
test/task_list_tile_test.dart
Normal file
71
test/task_list_tile_test.dart
Normal file
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:auto_gpt_flutter_client/views/task_list_tile.dart';
|
||||
import 'package:auto_gpt_flutter_client/models/task.dart';
|
||||
|
||||
void main() {
|
||||
final Task testTask = Task(id: 1, title: "Sample Task");
|
||||
|
||||
testWidgets('TaskListTile displays the task title',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: TaskListTile(task: testTask, onTap: () {}, onDelete: () {})));
|
||||
expect(find.text('Sample Task'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('TaskListTile toggles isSelected state on tap',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: TaskListTile(task: testTask, onTap: () {}, onDelete: () {})));
|
||||
|
||||
// Initially, the delete icon should not be present
|
||||
expect(find.byIcon(Icons.close), findsNothing);
|
||||
|
||||
// Tap the tile
|
||||
await tester.tap(find.text('Sample Task'));
|
||||
await tester.pump();
|
||||
|
||||
// The delete icon should appear
|
||||
expect(find.byIcon(Icons.close), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('TaskListTile triggers onDelete when delete icon is tapped',
|
||||
(WidgetTester tester) async {
|
||||
bool wasDeleteCalled = false;
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: TaskListTile(
|
||||
task: testTask,
|
||||
onTap: () {},
|
||||
onDelete: () {
|
||||
wasDeleteCalled = true;
|
||||
})));
|
||||
|
||||
// Tap the tile to make the delete icon appear
|
||||
await tester.tap(find.text('Sample Task'));
|
||||
await tester.pump();
|
||||
|
||||
// Tap the delete icon
|
||||
await tester.tap(find.byIcon(Icons.close));
|
||||
await tester.pump();
|
||||
|
||||
expect(wasDeleteCalled, true);
|
||||
});
|
||||
|
||||
testWidgets('TaskListTile triggers onTap when tapped',
|
||||
(WidgetTester tester) async {
|
||||
bool wasTapped = false;
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: TaskListTile(
|
||||
task: testTask,
|
||||
onTap: () {
|
||||
wasTapped = true;
|
||||
},
|
||||
onDelete: () {})));
|
||||
|
||||
// Tap the tile
|
||||
await tester.tap(find.text('Sample Task'));
|
||||
await tester.pump();
|
||||
|
||||
expect(wasTapped, true);
|
||||
});
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// This is a basic Flutter widget test.
|
||||
//
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:auto_gpt_flutter_client/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(const MyApp());
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user