76 lines
2.5 KiB
Dart
76 lines
2.5 KiB
Dart
import 'package:drift/drift.dart';
|
|||
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
|
|
import '../database/app_database.dart';
|
||
|
|
import 'database_provider.dart';
|
||
|
|
|
||
|
|
// ── All activities stream ─────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
final activitiesProvider = StreamProvider.autoDispose<List<Activity>>((ref) {
|
||
|
|
return ref.watch(activityDaoProvider).watchAllActivities();
|
||
|
|
});
|
||
|
|
|
||
|
|
// ── Activity frequency for charts ────────────────────────────────────────────
|
||
|
|
|
||
|
|
final activityFrequencyProvider = FutureProvider.autoDispose
|
||
|
|
.family<Map<int, int>, ({DateTime start, DateTime end})>(
|
||
|
|
(ref, range) =>
|
||
|
|
ref.watch(activityDaoProvider).getActivityFrequency(range.start, range.end),
|
||
|
|
);
|
||
|
|
|
||
|
|
// ── Selected activities (used by log mood screen) ─────────────────────────────
|
||
|
|
|
||
|
|
class SelectedActivities extends Notifier<Set<int>> {
|
||
|
|
@override
|
||
|
|
Set<int> build() => {};
|
||
|
|
|
||
|
|
void toggle(int activityId) {
|
||
|
|
if (state.contains(activityId)) {
|
||
|
|
state = <int>{...state}..remove(activityId);
|
||
|
|
} else {
|
||
|
|
state = {...state, activityId};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void clear() => state = {};
|
||
|
|
}
|
||
|
|
|
||
|
|
final selectedActivitiesProvider =
|
||
|
|
NotifierProvider.autoDispose<SelectedActivities, Set<int>>(
|
||
|
|
SelectedActivities.new);
|
||
|
|
|
||
|
|
// ── Activity notifier (create / delete custom activities) ─────────────────────
|
||
|
|
|
||
|
|
class ActivityNotifier extends Notifier<AsyncValue<void>> {
|
||
|
|
@override
|
||
|
|
AsyncValue<void> build() => const AsyncData(null);
|
||
|
|
|
||
|
|
Future<void> addActivity({
|
||
|
|
required String name,
|
||
|
|
required int iconCodepoint,
|
||
|
|
required String colourHex,
|
||
|
|
}) async {
|
||
|
|
state = const AsyncLoading();
|
||
|
|
state = await AsyncValue.guard(
|
||
|
|
() => ref.read(activityDaoProvider).insertActivity(
|
||
|
|
ActivitiesCompanion.insert(
|
||
|
|
name: name,
|
||
|
|
iconCodepoint: iconCodepoint,
|
||
|
|
colourHex: colourHex,
|
||
|
|
isCustom: const Value(true),
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> deleteActivity(int id) async {
|
||
|
|
state = const AsyncLoading();
|
||
|
|
state = await AsyncValue.guard(
|
||
|
|
() => ref.read(activityDaoProvider).deleteActivity(id),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
final activityNotifierProvider =
|
||
|
|
NotifierProvider.autoDispose<ActivityNotifier, AsyncValue<void>>(
|
||
|
|
ActivityNotifier.new);
|