Add related-screen navigation for sync rejections

This commit is contained in:
Rijad Zuzo
2026-02-15 23:56:08 +01:00
parent 560716100d
commit c20c29550a
2 changed files with 111 additions and 2 deletions
+91
View File
@@ -3,6 +3,10 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:relationship_saver/core/config/app_theme.dart';
import 'package:relationship_saver/features/ideas/ideas_view.dart';
import 'package:relationship_saver/features/moments/moments_view.dart';
import 'package:relationship_saver/features/people/people_view.dart';
import 'package:relationship_saver/features/reminders/reminders_view.dart';
import 'package:relationship_saver/features/shared/frosted_card.dart';
import 'package:relationship_saver/features/sync/sync_coordinator.dart';
import 'package:relationship_saver/features/sync/sync_queue_repository.dart';
@@ -207,6 +211,11 @@ class _SyncViewState extends ConsumerState<SyncView> {
: () => _toggleRejectionExpanded(
rejection.clientMutationId,
),
onOpenEntity:
matched != null &&
_entityViewForType(matched.entityType) != null
? () => _openEntityViewFor(matched)
: null,
),
);
}),
@@ -273,6 +282,7 @@ class _SyncViewState extends ConsumerState<SyncView> {
required ChangeEnvelope? matched,
required bool expanded,
required VoidCallback? onToggleExpanded,
required VoidCallback? onOpenEntity,
}) {
return Container(
width: double.infinity,
@@ -348,6 +358,19 @@ class _SyncViewState extends ConsumerState<SyncView> {
),
),
],
if (onOpenEntity != null) ...<Widget>[
const SizedBox(height: 8),
Wrap(
spacing: 8,
children: <Widget>[
TextButton.icon(
onPressed: onOpenEntity,
icon: const Icon(Icons.open_in_new_rounded),
label: const Text('Open Related Screen'),
),
],
),
],
],
),
);
@@ -486,4 +509,72 @@ class _SyncViewState extends ConsumerState<SyncView> {
}
});
}
Future<void> _openEntityViewFor(ChangeEnvelope matched) async {
final Widget? view = _entityViewForType(matched.entityType);
if (view == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('No editor available for ${matched.entityType}.'),
),
);
return;
}
await Navigator.of(context).push<void>(
MaterialPageRoute<void>(
builder: (BuildContext context) => _EntityResolveScreen(
title: _titleForEntityType(matched.entityType),
child: view,
),
),
);
}
Widget? _entityViewForType(String entityType) {
switch (entityType) {
case 'person':
return const PeopleView();
case 'capture':
return const MomentsView();
case 'giftIdea':
case 'eventIdea':
return const IdeasView();
case 'reminderRule':
return const RemindersView();
default:
return null;
}
}
String _titleForEntityType(String entityType) {
switch (entityType) {
case 'person':
return 'Resolve Person';
case 'capture':
return 'Resolve Moment';
case 'giftIdea':
case 'eventIdea':
return 'Resolve Idea';
case 'reminderRule':
return 'Resolve Reminder';
default:
return 'Resolve Item';
}
}
}
class _EntityResolveScreen extends StatelessWidget {
const _EntityResolveScreen({required this.title, required this.child});
final String title;
final Widget child;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: child,
);
}
}