Files
Stocky/lib/Pages/controllers/MainController.dart

234 lines
7.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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});
}
}