77 lines
2.5 KiB
Dart
77 lines
2.5 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 List<PersonProfile> people = ref
|
|
.read(localRepositoryProvider)
|
|
.people();
|
|
final DateTime now = DateTime.now().toUtc();
|
|
return SignalsFeed(
|
|
cursor: 'fallback-signals',
|
|
items: <SignalItem>[
|
|
SignalItem(
|
|
id: 'fallback-1',
|
|
type: 'recommendation',
|
|
title: 'Check in with ${people.first.name} tonight',
|
|
description: 'A short voice memo can keep momentum.',
|
|
personId: people.first.id,
|
|
createdAt: now,
|
|
),
|
|
SignalItem(
|
|
id: 'fallback-2',
|
|
type: 'trend',
|
|
title: 'Gift idea: practical + personal is trending',
|
|
description: 'Combine utility with one sentimental detail.',
|
|
personId: people.last.id,
|
|
createdAt: now.subtract(const Duration(hours: 2)),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
final AsyncNotifierProvider<SignalsController, SignalsFeed>
|
|
signalsControllerProvider =
|
|
AsyncNotifierProvider<SignalsController, SignalsFeed>(
|
|
SignalsController.new,
|
|
);
|