Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 392ec22dcd | |||
| 064c014f8b | |||
| 410a7eb843 | |||
| 20b017b066 | |||
| a3258b84fe | |||
| f088b84c54 | |||
| 5a39148577 | |||
| 2b718b5bd8 | |||
| 023610804d | |||
| cee5af0f84 | |||
| 999023e48a | |||
| 82a74a66b5 | |||
| e645081204 |
+9
-1
@@ -4,7 +4,9 @@ import 'model/repositories/local_repository.dart';
|
|||||||
import 'pages/task_edit_page.dart';
|
import 'pages/task_edit_page.dart';
|
||||||
import 'pages/task_overview_page.dart';
|
import 'pages/task_overview_page.dart';
|
||||||
import 'service/controller_scope.dart';
|
import 'service/controller_scope.dart';
|
||||||
import 'service/task_controller.dart';
|
import 'service/controllers/alarm_controller.dart';
|
||||||
|
import 'service/controllers/location_controller.dart';
|
||||||
|
import 'service/controllers/task_controller.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
final repository = LocalRepository();
|
final repository = LocalRepository();
|
||||||
@@ -13,9 +15,15 @@ void main() async {
|
|||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
ControllerScope(
|
ControllerScope(
|
||||||
|
controller: LocationController(repository),
|
||||||
|
child: ControllerScope(
|
||||||
|
controller: AlarmController(repository),
|
||||||
|
child: ControllerScope(
|
||||||
controller: TaskController(repository),
|
controller: TaskController(repository),
|
||||||
child: const MainApp(),
|
child: const MainApp(),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'time_alarm.dart';
|
|||||||
|
|
||||||
abstract class Alarm {
|
abstract class Alarm {
|
||||||
String get id;
|
String get id;
|
||||||
|
String get taskId;
|
||||||
Map<String, dynamic> toJson();
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
factory Alarm.fromJson(Map<String, dynamic> json) {
|
factory Alarm.fromJson(Map<String, dynamic> json) {
|
||||||
@@ -25,5 +26,5 @@ abstract class Alarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => id.hashCode;
|
int get hashCode => taskId.hashCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import '../location.dart';
|
|
||||||
import '../task.dart';
|
import '../task.dart';
|
||||||
|
|
||||||
class CreateTaskRequest {
|
class CreateTaskRequest {
|
||||||
@@ -9,8 +8,6 @@ class CreateTaskRequest {
|
|||||||
final bool isCompleted;
|
final bool isCompleted;
|
||||||
final String category;
|
final String category;
|
||||||
final List<Task> subtasks;
|
final List<Task> subtasks;
|
||||||
final List<DateTime> alarms;
|
|
||||||
final Location? location;
|
|
||||||
final String url;
|
final String url;
|
||||||
|
|
||||||
CreateTaskRequest({
|
CreateTaskRequest({
|
||||||
@@ -21,8 +18,6 @@ class CreateTaskRequest {
|
|||||||
required this.isCompleted,
|
required this.isCompleted,
|
||||||
required this.category,
|
required this.category,
|
||||||
required this.subtasks,
|
required this.subtasks,
|
||||||
required this.alarms,
|
|
||||||
required this.location,
|
|
||||||
required this.url,
|
required this.url,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -34,8 +29,6 @@ class CreateTaskRequest {
|
|||||||
isCompleted = task.isCompleted,
|
isCompleted = task.isCompleted,
|
||||||
category = task.category,
|
category = task.category,
|
||||||
subtasks = task.subtasks,
|
subtasks = task.subtasks,
|
||||||
alarms = task.alarms,
|
|
||||||
location = task.location,
|
|
||||||
url = task.url;
|
url = task.url;
|
||||||
|
|
||||||
Task toTask({required String id}) {
|
Task toTask({required String id}) {
|
||||||
@@ -48,8 +41,6 @@ class CreateTaskRequest {
|
|||||||
isCompleted: isCompleted,
|
isCompleted: isCompleted,
|
||||||
category: category,
|
category: category,
|
||||||
subtasks: subtasks,
|
subtasks: subtasks,
|
||||||
alarms: alarms,
|
|
||||||
location: location,
|
|
||||||
url: url,
|
url: url,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,16 @@ class LocationAlarm implements Alarm {
|
|||||||
@override
|
@override
|
||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String taskId;
|
||||||
|
|
||||||
final Location location;
|
final Location location;
|
||||||
|
|
||||||
final int radiusMeters;
|
final int radiusMeters;
|
||||||
|
|
||||||
const LocationAlarm({
|
const LocationAlarm({
|
||||||
required this.id,
|
required this.id,
|
||||||
|
required this.taskId,
|
||||||
required this.location,
|
required this.location,
|
||||||
required this.radiusMeters,
|
required this.radiusMeters,
|
||||||
});
|
});
|
||||||
@@ -18,6 +22,7 @@ class LocationAlarm implements Alarm {
|
|||||||
factory LocationAlarm.fromJson(Map<String, dynamic> json) {
|
factory LocationAlarm.fromJson(Map<String, dynamic> json) {
|
||||||
return LocationAlarm(
|
return LocationAlarm(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
|
taskId: json['taskId'] as String,
|
||||||
location: Location.fromJson(json['location'] as Map<String, dynamic>),
|
location: Location.fromJson(json['location'] as Map<String, dynamic>),
|
||||||
radiusMeters: json['radiusMeters'] as int,
|
radiusMeters: json['radiusMeters'] as int,
|
||||||
);
|
);
|
||||||
@@ -27,6 +32,7 @@ class LocationAlarm implements Alarm {
|
|||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'id': id,
|
'id': id,
|
||||||
|
'taskId': taskId,
|
||||||
'location': location.toJson(),
|
'location': location.toJson(),
|
||||||
'radiusMeters': radiusMeters,
|
'radiusMeters': radiusMeters,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import '../../location.dart';
|
||||||
|
|
||||||
|
abstract class LocationRepository {
|
||||||
|
// Create
|
||||||
|
|
||||||
|
Future<void> createLocation(Location location);
|
||||||
|
|
||||||
|
// Read
|
||||||
|
|
||||||
|
Future<List<Location>> loadLocations();
|
||||||
|
|
||||||
|
// Update
|
||||||
|
|
||||||
|
Future<void> updateLocation(Location location);
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
|
||||||
|
Future<void> deleteLocation(Location location);
|
||||||
|
}
|
||||||
@@ -3,14 +3,18 @@ import 'dart:convert';
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import '../alarm.dart';
|
import '../alarm.dart';
|
||||||
|
import '../location.dart';
|
||||||
import '../task.dart';
|
import '../task.dart';
|
||||||
import 'interfaces/alarm_repository.dart';
|
import 'interfaces/alarm_repository.dart';
|
||||||
|
import 'interfaces/location_repository.dart';
|
||||||
import 'interfaces/task_repository.dart';
|
import 'interfaces/task_repository.dart';
|
||||||
|
|
||||||
class LocalRepository implements TaskRepository, AlarmRepository {
|
class LocalRepository
|
||||||
|
implements TaskRepository, AlarmRepository, LocationRepository {
|
||||||
static const String _tasksKey = 'tasks';
|
static const String _tasksKey = 'tasks';
|
||||||
static const String _taskOrderKey = 'taskOrder';
|
static const String _taskOrderKey = 'taskOrder';
|
||||||
static const String _alarmsKey = 'alarms';
|
static const String _alarmsKey = 'alarms';
|
||||||
|
static const String _locationsKey = 'locations';
|
||||||
|
|
||||||
SharedPreferencesWithCache? _prefs;
|
SharedPreferencesWithCache? _prefs;
|
||||||
|
|
||||||
@@ -18,7 +22,12 @@ class LocalRepository implements TaskRepository, AlarmRepository {
|
|||||||
if (_prefs == null) {
|
if (_prefs == null) {
|
||||||
await SharedPreferencesWithCache.create(
|
await SharedPreferencesWithCache.create(
|
||||||
cacheOptions: const SharedPreferencesWithCacheOptions(
|
cacheOptions: const SharedPreferencesWithCacheOptions(
|
||||||
allowList: <String>{_tasksKey, _taskOrderKey},
|
allowList: <String>{
|
||||||
|
_tasksKey,
|
||||||
|
_taskOrderKey,
|
||||||
|
_alarmsKey,
|
||||||
|
_locationsKey,
|
||||||
|
},
|
||||||
),
|
),
|
||||||
).then((value) => _prefs = value);
|
).then((value) => _prefs = value);
|
||||||
}
|
}
|
||||||
@@ -29,6 +38,13 @@ class LocalRepository implements TaskRepository, AlarmRepository {
|
|||||||
_prefs!.setStringList(_tasksKey, jsonList);
|
_prefs!.setStringList(_tasksKey, jsonList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _saveLocations(List<Location> locations) async {
|
||||||
|
final jsonList = locations
|
||||||
|
.map<String>((e) => jsonEncode(e.toJson()))
|
||||||
|
.toList();
|
||||||
|
_prefs!.setStringList(_locationsKey, jsonList);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _saveTaskOrder(List<String> taskOrder) async {
|
Future<void> _saveTaskOrder(List<String> taskOrder) async {
|
||||||
final jsonList = taskOrder.map((e) => jsonEncode(e)).toList();
|
final jsonList = taskOrder.map((e) => jsonEncode(e)).toList();
|
||||||
return _prefs!.setStringList(_taskOrderKey, jsonList);
|
return _prefs!.setStringList(_taskOrderKey, jsonList);
|
||||||
@@ -62,6 +78,13 @@ class LocalRepository implements TaskRepository, AlarmRepository {
|
|||||||
_saveAlarms(alarms);
|
_saveAlarms(alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> createLocation(Location location) async {
|
||||||
|
final locations = await loadLocations();
|
||||||
|
locations.add(location);
|
||||||
|
_saveLocations(locations);
|
||||||
|
}
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -83,6 +106,15 @@ class LocalRepository implements TaskRepository, AlarmRepository {
|
|||||||
return jsonList.map<Alarm>((e) => Alarm.fromJson(jsonDecode(e))).toList();
|
return jsonList.map<Alarm>((e) => Alarm.fromJson(jsonDecode(e))).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<Location>> loadLocations() async {
|
||||||
|
final Iterable<String> jsonList =
|
||||||
|
_prefs!.getStringList(_locationsKey) ?? [];
|
||||||
|
return jsonList
|
||||||
|
.map<Location>((e) => Location.fromJson(jsonDecode(e)))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -106,6 +138,14 @@ class LocalRepository implements TaskRepository, AlarmRepository {
|
|||||||
_saveAlarms(alarms);
|
_saveAlarms(alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updateLocation(Location location) async {
|
||||||
|
final locations = await loadLocations();
|
||||||
|
locations.remove(location);
|
||||||
|
locations.add(location);
|
||||||
|
_saveLocations(locations);
|
||||||
|
}
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -128,4 +168,11 @@ class LocalRepository implements TaskRepository, AlarmRepository {
|
|||||||
alarms.remove(alarm);
|
alarms.remove(alarm);
|
||||||
_saveAlarms(alarms);
|
_saveAlarms(alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> deleteLocation(Location location) async {
|
||||||
|
final locations = await loadLocations();
|
||||||
|
locations.remove(location);
|
||||||
|
_saveLocations(locations);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ class Task {
|
|||||||
final bool isCompleted;
|
final bool isCompleted;
|
||||||
final String category;
|
final String category;
|
||||||
final List<Task> subtasks;
|
final List<Task> subtasks;
|
||||||
final List<DateTime> alarms;
|
|
||||||
final Location? location;
|
|
||||||
final String url;
|
final String url;
|
||||||
|
|
||||||
Task({
|
Task({
|
||||||
@@ -22,8 +20,6 @@ class Task {
|
|||||||
this.isCompleted = false,
|
this.isCompleted = false,
|
||||||
this.category = '',
|
this.category = '',
|
||||||
this.subtasks = const [],
|
this.subtasks = const [],
|
||||||
this.alarms = const [],
|
|
||||||
this.location,
|
|
||||||
this.url = '',
|
this.url = '',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -49,8 +45,6 @@ class Task {
|
|||||||
isCompleted: isCompleted ?? this.isCompleted,
|
isCompleted: isCompleted ?? this.isCompleted,
|
||||||
category: category ?? this.category,
|
category: category ?? this.category,
|
||||||
subtasks: subtasks ?? this.subtasks,
|
subtasks: subtasks ?? this.subtasks,
|
||||||
alarms: alarms ?? this.alarms,
|
|
||||||
location: location ?? this.location,
|
|
||||||
url: url ?? this.url,
|
url: url ?? this.url,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -71,14 +65,6 @@ class Task {
|
|||||||
?.map((e) => Task.fromJson(e as Map<String, dynamic>))
|
?.map((e) => Task.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
[],
|
[],
|
||||||
alarms:
|
|
||||||
(json['alarms'] as List<dynamic>?)
|
|
||||||
?.map((e) => DateTime.parse(e as String))
|
|
||||||
.toList() ??
|
|
||||||
[],
|
|
||||||
location: json['location'] != null
|
|
||||||
? Location.fromJson(json['location'] as Map<String, dynamic>)
|
|
||||||
: null,
|
|
||||||
url: json['url'] as String? ?? '',
|
url: json['url'] as String? ?? '',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -93,8 +79,6 @@ class Task {
|
|||||||
'isCompleted': isCompleted,
|
'isCompleted': isCompleted,
|
||||||
'category': category,
|
'category': category,
|
||||||
'subtasks': subtasks.map((e) => e.toJson()).toList(),
|
'subtasks': subtasks.map((e) => e.toJson()).toList(),
|
||||||
'alarms': alarms.map((e) => e.toIso8601String()).toList(),
|
|
||||||
'location': location?.toJson(),
|
|
||||||
'url': url,
|
'url': url,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,31 @@ class TimeAlarm implements Alarm {
|
|||||||
@override
|
@override
|
||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String taskId;
|
||||||
|
|
||||||
final DateTime triggerAt;
|
final DateTime triggerAt;
|
||||||
|
|
||||||
const TimeAlarm({required this.id, required this.triggerAt});
|
const TimeAlarm({
|
||||||
|
required this.id,
|
||||||
|
required this.taskId,
|
||||||
|
required this.triggerAt,
|
||||||
|
});
|
||||||
|
|
||||||
factory TimeAlarm.fromJson(Map<String, dynamic> json) {
|
factory TimeAlarm.fromJson(Map<String, dynamic> json) {
|
||||||
return TimeAlarm(
|
return TimeAlarm(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
|
taskId: json['taskId'] as String,
|
||||||
triggerAt: DateTime.parse(json['triggerAt'] as String),
|
triggerAt: DateTime.parse(json['triggerAt'] as String),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {'id': id, 'triggerAt': triggerAt.toIso8601String()};
|
return {
|
||||||
|
'id': id,
|
||||||
|
'taskId': taskId,
|
||||||
|
'triggerAt': triggerAt.toIso8601String(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import '../model/callback_models/create_task_request.dart';
|
import '../model/callback_models/create_task_request.dart';
|
||||||
import '../model/extensions/controller_context.dart';
|
import '../model/extensions/controller_context.dart';
|
||||||
import '../model/task.dart';
|
import '../model/task.dart';
|
||||||
import '../service/task_controller.dart';
|
import '../service/controllers/task_controller.dart';
|
||||||
import '../service/tools.dart';
|
import '../service/tools.dart';
|
||||||
import '../widgets/time_selector.dart';
|
import '../widgets/time_selector.dart';
|
||||||
|
|
||||||
@@ -139,8 +139,6 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||||||
isCompleted: false,
|
isCompleted: false,
|
||||||
category: categoryController.text,
|
category: categoryController.text,
|
||||||
subtasks: [],
|
subtasks: [],
|
||||||
alarms: [],
|
|
||||||
location: null,
|
|
||||||
url: urlController.text,
|
url: urlController.text,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import 'package:flutter/material.dart';
|
|||||||
import '../model/callback_models/create_task_request.dart';
|
import '../model/callback_models/create_task_request.dart';
|
||||||
import '../model/extensions/controller_context.dart';
|
import '../model/extensions/controller_context.dart';
|
||||||
import '../model/task.dart';
|
import '../model/task.dart';
|
||||||
import '../service/task_controller.dart';
|
import '../service/controllers/task_controller.dart';
|
||||||
import '../service/tools.dart';
|
import '../service/tools.dart';
|
||||||
|
import '../widgets/task_dismissible.dart';
|
||||||
import 'task_edit_page.dart';
|
import 'task_edit_page.dart';
|
||||||
|
|
||||||
class TaskOverviewPage extends StatefulWidget {
|
class TaskOverviewPage extends StatefulWidget {
|
||||||
@@ -37,8 +38,11 @@ class _TaskOverviewPageState extends State<TaskOverviewPage> {
|
|||||||
Widget itemBuilder(BuildContext context, int index) {
|
Widget itemBuilder(BuildContext context, int index) {
|
||||||
final task = tasks.elementAt(index);
|
final task = tasks.elementAt(index);
|
||||||
|
|
||||||
return ListTile(
|
return TaskDismissible(
|
||||||
key: Key(task.id),
|
key: Key(task.id),
|
||||||
|
onDismissedRight: () =>
|
||||||
|
context.controller<TaskController>().deleteTask(task),
|
||||||
|
child: ListTile(
|
||||||
title: Text(task.title),
|
title: Text(task.title),
|
||||||
subtitle: task.description.isNotEmpty ? Text(task.description) : null,
|
subtitle: task.description.isNotEmpty ? Text(task.description) : null,
|
||||||
trailing: Checkbox(
|
trailing: Checkbox(
|
||||||
@@ -55,6 +59,7 @@ class _TaskOverviewPageState extends State<TaskOverviewPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../model/alarm.dart';
|
||||||
|
import '../../model/repositories/interfaces/alarm_repository.dart';
|
||||||
|
|
||||||
|
class AlarmController extends ChangeNotifier {
|
||||||
|
AlarmController(AlarmRepository repository) : _repository = repository {
|
||||||
|
_loadAlarms();
|
||||||
|
}
|
||||||
|
|
||||||
|
final AlarmRepository _repository;
|
||||||
|
|
||||||
|
final List<Alarm> _alarms = [];
|
||||||
|
|
||||||
|
Future<void> addAlarm(Alarm alarm) {
|
||||||
|
_alarms.add(alarm);
|
||||||
|
notifyListeners();
|
||||||
|
return _repository.createAlarm(alarm);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteAlarm(Alarm alarm) {
|
||||||
|
_alarms.remove(alarm);
|
||||||
|
notifyListeners();
|
||||||
|
return _repository.deleteAlarm(alarm);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadAlarms() {
|
||||||
|
_alarms.clear();
|
||||||
|
return _repository.loadAlarms().then((value) => _alarms.addAll(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../model/location.dart';
|
||||||
|
import '../../model/repositories/interfaces/location_repository.dart';
|
||||||
|
|
||||||
|
class LocationController extends ChangeNotifier {
|
||||||
|
LocationController(LocationRepository repository) : _repository = repository {
|
||||||
|
_loadLocations();
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocationRepository _repository;
|
||||||
|
|
||||||
|
final List<Location> _locations = [];
|
||||||
|
|
||||||
|
Future<void> addLocation(Location location) {
|
||||||
|
_locations.add(location);
|
||||||
|
notifyListeners();
|
||||||
|
return _repository.createLocation(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteLocation(Location location) {
|
||||||
|
_locations.remove(location);
|
||||||
|
notifyListeners();
|
||||||
|
return _repository.deleteLocation(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadLocations() {
|
||||||
|
_locations.clear();
|
||||||
|
return _repository.loadLocations().then(
|
||||||
|
(value) => _locations.addAll(value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart' show ChangeNotifier;
|
import 'package:flutter/material.dart' show ChangeNotifier;
|
||||||
|
|
||||||
import '../model/repositories/interfaces/task_repository.dart';
|
import '../../model/repositories/interfaces/task_repository.dart';
|
||||||
import '../model/task.dart';
|
import '../../model/task.dart';
|
||||||
|
|
||||||
class TaskController extends ChangeNotifier {
|
class TaskController extends ChangeNotifier {
|
||||||
TaskController(TaskRepository repository) : _repository = repository {
|
TaskController(TaskRepository repository) : _repository = repository {
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class TaskDismissible extends StatelessWidget {
|
||||||
|
const TaskDismissible({
|
||||||
|
required super.key,
|
||||||
|
this.onDismissedRight,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
final VoidCallback? onDismissedRight;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Dismissible(
|
||||||
|
key: key!,
|
||||||
|
direction: DismissDirection.startToEnd,
|
||||||
|
background: Container(
|
||||||
|
color: Theme.of(context).colorScheme.error,
|
||||||
|
child: Align(
|
||||||
|
alignment: AlignmentGeometry.centerLeft,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
child: Icon(
|
||||||
|
Icons.delete,
|
||||||
|
color: Theme.of(context).colorScheme.onError,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onDismissed: onDismissed,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDismissed(DismissDirection direction) {
|
||||||
|
if (direction == DismissDirection.startToEnd && onDismissedRight != null) {
|
||||||
|
onDismissedRight!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user