Files
rely/lib/features/signals/signals_controller.dart
T
2026-02-15 15:12:23 +01:00

92 lines
3.0 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:relationship_saver/features/local/local_models.dart';
import 'package:relationship_saver/features/local/local_repository.dart';
import 'package:relationship_saver/integrations/backend/backend_gateway_provider.dart';
import 'package:relationship_saver/integrations/backend/models/backend_models.dart';
class SignalsController extends AsyncNotifier<SignalsFeed> {
@override
Future<SignalsFeed> build() async {
return _load();
}
Future<void> refresh() async {
state = const AsyncLoading<SignalsFeed>();
try {
final SignalsFeed feed = await _load();
state = AsyncData<SignalsFeed>(feed);
} catch (error, stackTrace) {
state = AsyncError<SignalsFeed>(error, stackTrace);
}
}
Future<void> acknowledge(String id, SignalAction action) async {
final SignalsFeed? current = state.asData?.value;
if (current == null) {
return;
}
await ref
.read(backendGatewayProvider)
.acknowledgeSignal(signalId: id, action: action);
final List<SignalItem> updated = current.items
.where((SignalItem item) => item.id != id)
.toList(growable: false);
state = AsyncData<SignalsFeed>(current.copyWith(items: updated));
}
Future<SignalsFeed> _load() async {
try {
return await ref.read(backendGatewayProvider).getSignalsFeed(limit: 20);
} catch (_) {
final LocalDataState localData = await ref.read(
localRepositoryProvider.future,
);
final List<PersonProfile> people = localData.people;
final PersonProfile defaultPerson = people.isNotEmpty
? people.first
: PersonProfile(
id: 'person-default',
name: 'Someone Important',
relationship: 'Relationship',
affinityScore: 70,
nextMoment: DateTime(2026, 2, 20),
tags: <String>[],
notes: '',
);
final PersonProfile secondaryPerson = people.length > 1
? people[1]
: defaultPerson;
final DateTime now = DateTime.now().toUtc();
return SignalsFeed(
cursor: 'fallback-signals',
items: <SignalItem>[
SignalItem(
id: 'fallback-1',
type: 'recommendation',
title: 'Check in with ${defaultPerson.name} tonight',
description: 'A short voice memo can keep momentum.',
personId: defaultPerson.id,
createdAt: now,
),
SignalItem(
id: 'fallback-2',
type: 'trend',
title: 'Gift idea: practical + personal is trending',
description: 'Combine utility with one sentimental detail.',
personId: secondaryPerson.id,
createdAt: now.subtract(const Duration(hours: 2)),
),
],
);
}
}
}
final AsyncNotifierProvider<SignalsController, SignalsFeed>
signalsControllerProvider =
AsyncNotifierProvider<SignalsController, SignalsFeed>(
SignalsController.new,
);