Files
focusflow/lib/features/tasks/presentation/bloc/next_task_cubit.dart
Oracle Public Cloud User 50931d839d Initial scaffold: FocusFlow ADHD Task Manager Flutter app
BLoC/Cubit state management, ADHD-friendly theme (calming teal, no red),
GetIt DI, GoRouter navigation. Screens: task dashboard, focus mode,
task create/detail, streaks, time perception, settings, onboarding, auth.
Custom widgets: TaskCard, RewardPopup, StreakRing, GentleNudgeCard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:53:58 +00:00

85 lines
2.5 KiB
Dart

import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:focusflow_shared/focusflow_shared.dart';
import '../../../../core/network/api_client.dart';
import '../../../../main.dart';
// ── States ─────────────────────────────────────────────────────────
sealed class NextTaskState extends Equatable {
const NextTaskState();
@override
List<Object?> get props => [];
}
class NextTaskLoading extends NextTaskState {}
class NextTaskLoaded extends NextTaskState {
final Task task;
const NextTaskLoaded(this.task);
@override
List<Object?> get props => [task];
}
class NextTaskEmpty extends NextTaskState {}
class NextTaskError extends NextTaskState {
final String message;
const NextTaskError(this.message);
@override
List<Object?> get props => [message];
}
// ── Cubit ──────────────────────────────────────────────────────────
/// Simple cubit for focus mode: "just do the next thing."
///
/// Loads the single highest-priority task from the API.
class NextTaskCubit extends Cubit<NextTaskState> {
final ApiClient _api = getIt<ApiClient>();
NextTaskCubit() : super(NextTaskLoading());
/// Fetch the next recommended task.
Future<void> loadNext() async {
emit(NextTaskLoading());
try {
final response = await _api.fetchNextTask();
final data = response.data;
if (data != null && data['status'] == 'success' && data['data'] != null) {
final task = Task.fromJson(data['data'] as Map<String, dynamic>);
emit(NextTaskLoaded(task));
} else {
emit(NextTaskEmpty());
}
} catch (_) {
emit(const NextTaskError('Could not load your next task.'));
}
}
/// Mark the current task as done, then load the next one.
Future<void> complete() async {
final current = state;
if (current is! NextTaskLoaded) return;
try {
await _api.completeTask(current.task.id);
} catch (_) {
// Best-effort — still load next.
}
await loadNext();
}
/// Skip the current task, then load the next one.
Future<void> skip() async {
final current = state;
if (current is! NextTaskLoaded) return;
try {
await _api.skipTask(current.task.id);
} catch (_) {
// Best-effort.
}
await loadNext();
}
}