This commit is contained in:
2026-05-26 12:28:12 +02:00
parent 2afe97c6db
commit 45455a16c4
12 changed files with 851 additions and 8 deletions

View File

@@ -0,0 +1,92 @@
import 'dart:async';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/features/tasks/data/task_repository.dart';
import 'package:flux/features/tasks/models/task_model.dart';
import 'package:flux/features/tasks/models/task_status.dart';
import 'package:get_it/get_it.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
part 'task_list_state.dart';
class TaskListCubit extends Cubit<TaskListState> {
final SupabaseClient _supabase = GetIt.I.get<SupabaseClient>();
RealtimeChannel? _taskChannel;
final TaskRepository _repository = GetIt.I.get<TaskRepository>();
TaskListCubit() : super(TaskListState(status: TaskListStatus.initial));
// --- AVVIA L'ASCOLTO IN TEMPO REALE ---
void startListening({required String companyId, String? storeId}) {
emit(state.copyWith(status: TaskListStatus.loading));
// Facciamo subito il caricamento manuale, chiedendo SOLO quelli attivi
_loadTasks(companyId: companyId, storeId: storeId);
_taskChannel?.unsubscribe();
_taskChannel = _supabase
.channel('public:tasks_company_$companyId')
.onPostgresChanges(
event: PostgresChangeEvent.all,
schema: 'public',
table: 'tasks',
filter: PostgresChangeFilter(
type: PostgresChangeFilterType.eq,
column: 'company_id',
value: companyId,
),
callback: (payload) {
// Ricarica la lista applicando sempre i filtri di stato
_loadTasks(companyId: companyId, storeId: storeId);
},
);
_taskChannel?.subscribe();
}
// --- HELPER DI CARICAMENTO ---
Future<void> _loadTasks({required String companyId, String? storeId}) async {
try {
final tasks = await _repository.getTasks(
companyId: companyId,
storeId: storeId,
// CHICCA: Passiamo solo gli stati attivi!
statuses: [TaskStatus.open, TaskStatus.inProgress],
);
emit(
state.copyWith(
status: TaskListStatus.success,
tasks: tasks,
errorMessage: null,
),
);
} catch (e) {
emit(
state.copyWith(
status: TaskListStatus.failure,
errorMessage: e.toString(),
),
);
}
}
// --- OPERAZIONI MANUALI ---
// (Le lasciamo gestire al repository o le metti qui se preferisci,
// tanto il risultato lo vedrai magicamente aggiornato dallo stream sopra!)
/*
Future<void> markAsCompleted(String taskId) async { ... }
Future<void> deleteTask(String taskId) async { ... }
*/
// --- PULIZIA FONDAMENTALE ---
@override
Future<void> close() {
// Chiudiamo il rubinetto quando usciamo dalla pagina per non intasarci la memoria!
_taskChannel?.unsubscribe();
return super.close();
}
}

View File

@@ -0,0 +1,31 @@
part of 'task_list_cubit.dart';
enum TaskListStatus { initial, loading, success, failure }
class TaskListState extends Equatable {
final TaskListStatus status;
final List<TaskModel> tasks;
final String? errorMessage;
const TaskListState({
this.status = TaskListStatus.initial,
this.tasks = const [],
this.errorMessage,
});
TaskListState copyWith({
TaskListStatus? status,
List<TaskModel>? tasks,
String? errorMessage,
}) {
return TaskListState(
status: status ?? this.status,
tasks: tasks ?? this.tasks,
// Se lo status è success o loading, puliamo eventuali errori precedenti
errorMessage: errorMessage ?? this.errorMessage,
);
}
@override
List<Object?> get props => [status, tasks, errorMessage];
}