234 lines
7.0 KiB
Dart
234 lines
7.0 KiB
Dart
import 'package:Stocky/models/task_adapter.dart';
|
||
import 'package:Stocky/models/Documents.dart';
|
||
import 'package:Stocky/services/api/api_service.dart';
|
||
import 'package:Stocky/services/api/push_notification_service.dart';
|
||
import 'package:Stocky/services/local/StorageService.dart';
|
||
|
||
import 'package:get/get.dart';
|
||
|
||
class MainController extends GetxController {
|
||
final username = ''.obs;
|
||
|
||
final tasks = <Task>[].obs;
|
||
final documents = <Document>[].obs;
|
||
final RxBool isLoading = false.obs;
|
||
|
||
final RxBool isTask = true.obs;
|
||
final RxBool isProj = true.obs;
|
||
|
||
bool _isSyncingTasks = false;
|
||
|
||
Future<void> getSettings() async {
|
||
username.value = await Get.find<LocalStorageService>().getUsername();
|
||
}
|
||
|
||
Future<void> fetchTasks() async {
|
||
if (_isSyncingTasks) return;
|
||
_isSyncingTasks = true;
|
||
|
||
try {
|
||
isLoading.value = true;
|
||
final localTasks = Get.find<LocalStorageService>().getTasks();
|
||
|
||
if (localTasks.isEmpty) {
|
||
await _fetchTasksFromServer();
|
||
} else {
|
||
await _syncTasksWithServer(localTasks);
|
||
}
|
||
|
||
final activeTasks = await Get.find<LocalStorageService>()
|
||
.getCompletedTasks();
|
||
|
||
tasks.assignAll(activeTasks);
|
||
} catch (e) {
|
||
print('Ошибка при синхронизации задач: $e');
|
||
} finally {
|
||
_isSyncingTasks = false;
|
||
isLoading.value = false;
|
||
}
|
||
}
|
||
|
||
Future<void> _syncTasksWithServer(List<Task> localTasks) async {
|
||
try {
|
||
// Шаг 1: Обрабатываем все несинхронизированные задачи
|
||
final unsyncedTasks = localTasks.where((t) => !t.isSynced).toList();
|
||
for (final task in unsyncedTasks) {
|
||
if (task.isDeletedLocally == true) {
|
||
// Удаление: пытаемся удалить на сервере
|
||
final deleted = await Get.find<ApiService>().deleteTask(
|
||
task.id.toString(),
|
||
);
|
||
if (deleted) {
|
||
Get.find<LocalStorageService>().removeTask(task.id);
|
||
} else {
|
||
// Не удалось — оставляем помеченной, попробуем позже
|
||
continue;
|
||
}
|
||
} else {
|
||
// Создание или обновление
|
||
final syncedTask = await Get.find<ApiService>().upsertTask(task);
|
||
if (syncedTask != null) {
|
||
syncedTask.isSynced = true;
|
||
syncedTask.isDeletedLocally = false;
|
||
Get.find<LocalStorageService>().updateTask(syncedTask);
|
||
}
|
||
// Если не удалось — остаётся с isSynced = false
|
||
}
|
||
}
|
||
|
||
// Шаг 2: Получаем актуальный список с сервера
|
||
final serverTasks = await Get.find<ApiService>().fetchTasks();
|
||
await Get.find<LocalStorageService>().saveTasks(serverTasks);
|
||
} catch (e) {
|
||
print('Ошибка синхронизации: $e');
|
||
// В случае ошибки — восстанавливаем локальный список
|
||
tasks.assignAll(localTasks);
|
||
}
|
||
}
|
||
|
||
Future<void> _fetchTasksFromServer() async {
|
||
try {
|
||
final serverTasks = await Get.find<ApiService>().fetchTasks();
|
||
await Get.find<LocalStorageService>().saveTasks(serverTasks);
|
||
tasks.assignAll(serverTasks);
|
||
} catch (e) {
|
||
print('Ошибка загрузки задач с сервера: $e');
|
||
// Остаёмся с пустым списком
|
||
}
|
||
}
|
||
|
||
Future<void> assignTaskToCurrentUser(Task task) async {
|
||
task.executor = username.value;
|
||
task.isSynced = false;
|
||
updateTask(task);
|
||
}
|
||
|
||
Future<void> completeTask(Task task) async {
|
||
task.isCompleted = true;
|
||
task.endTime = DateTime.now();
|
||
task.isSynced = false;
|
||
updateTask(task);
|
||
final activeTasks = await Get.find<LocalStorageService>()
|
||
.getCompletedTasks();
|
||
|
||
tasks.assignAll(activeTasks);
|
||
}
|
||
|
||
Future<void> addTask(Task task) async {
|
||
task.isSynced = false;
|
||
task.isDeletedLocally = false;
|
||
|
||
Get.find<LocalStorageService>().addTask(task);
|
||
tasks.add(task);
|
||
|
||
_syncTaskToServer(task);
|
||
}
|
||
|
||
Future<void> updateTask(Task updatedTask) async {
|
||
final index = tasks.indexWhere((t) => t.id == updatedTask.id);
|
||
if (index == -1) return;
|
||
|
||
updatedTask.isSynced = false;
|
||
updatedTask.isDeletedLocally = false;
|
||
|
||
Get.find<LocalStorageService>().updateTask(updatedTask);
|
||
tasks[index] = updatedTask;
|
||
|
||
_syncTaskToServer(updatedTask);
|
||
}
|
||
|
||
Future<void> deleteTask(Task task) async {
|
||
final index = tasks.indexWhere((t) => t.id == task.id);
|
||
if (index == -1) return;
|
||
|
||
try {
|
||
final success = await Get.find<ApiService>().deleteTask(
|
||
task.id.toString(),
|
||
);
|
||
if (success) {
|
||
Get.find<LocalStorageService>().removeTask(task.id);
|
||
tasks.removeAt(index);
|
||
} else {
|
||
// Нет связи — помечаем для отложенного удаления
|
||
_markTaskForDeletion(task);
|
||
}
|
||
} catch (e) {
|
||
print('Ошибка при удалении задачи: $e');
|
||
_markTaskForDeletion(task);
|
||
}
|
||
}
|
||
|
||
void _markTaskForDeletion(Task task) {
|
||
task.isDeletedLocally = true;
|
||
task.isSynced = false;
|
||
Get.find<LocalStorageService>().updateTask(task);
|
||
}
|
||
|
||
Future<void> _syncTaskToServer(Task task) async {
|
||
final storage = Get.find<LocalStorageService>();
|
||
|
||
if (task.isDeletedLocally == true) {
|
||
final success = await Get.find<ApiService>().deleteTask(
|
||
task.id.toString(),
|
||
);
|
||
if (success) {
|
||
storage.removeTask(task.id);
|
||
tasks.removeWhere((t) => t.id == task.id);
|
||
} else {
|
||
// Оставить помеченной — будет обработано при полной синхронизации
|
||
}
|
||
return;
|
||
}
|
||
|
||
try {
|
||
final syncedTask = await Get.find<ApiService>().upsertTask(task);
|
||
if (syncedTask == null) return;
|
||
|
||
if (syncedTask.id != task.id) {
|
||
syncedTask.isSynced = true;
|
||
syncedTask.isDeletedLocally = false;
|
||
await storage.replaceTask(task.id, syncedTask);
|
||
} else {
|
||
task.isSynced = true;
|
||
task.isDeletedLocally = false;
|
||
await storage.updateTask(syncedTask);
|
||
}
|
||
|
||
final index = tasks.indexWhere((t) => t.id == task.id);
|
||
if (index != -1) {
|
||
if (syncedTask.id != task.id) {
|
||
tasks.removeAt(index);
|
||
tasks.add(syncedTask);
|
||
} else {
|
||
tasks[index] = syncedTask;
|
||
}
|
||
}
|
||
} catch (e) {
|
||
print('Ошибка синхронизации: $e');
|
||
}
|
||
}
|
||
|
||
Task? openTask(String taskId) {
|
||
return tasks.firstWhereOrNull((task) => task.id == taskId);
|
||
}
|
||
|
||
@override
|
||
void onInit() async {
|
||
super.onInit();
|
||
|
||
Get.find<PushNotificationService>().foregroundMessageStream.listen((
|
||
message,
|
||
) {
|
||
// _handleMessageAction(message); // тот же метод, что и выше
|
||
});
|
||
|
||
getSettings();
|
||
|
||
fetchTasks();
|
||
}
|
||
|
||
void openTaskFromNotification(String taskId) {
|
||
Get.toNamed('/task', arguments: {'id': taskId});
|
||
}
|
||
}
|