Add rejection payload inspection in sync view
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:relationship_saver/core/config/app_theme.dart';
|
||||
@@ -17,6 +19,7 @@ class SyncView extends ConsumerStatefulWidget {
|
||||
class _SyncViewState extends ConsumerState<SyncView> {
|
||||
bool _busy = false;
|
||||
String _status = 'Ready. Local-first mode keeps app usable without sync.';
|
||||
final Set<String> _expandedRejections = <String>{};
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -185,18 +188,28 @@ class _SyncViewState extends ConsumerState<SyncView> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
...state.lastRejected.map(
|
||||
(MutationRejection rejection) => Padding(
|
||||
...state.lastRejected.map((MutationRejection rejection) {
|
||||
final ChangeEnvelope? matched = _findRejectedChange(
|
||||
state.lastRejectedChanges,
|
||||
rejection.clientMutationId,
|
||||
);
|
||||
final bool expanded = _expandedRejections.contains(
|
||||
rejection.clientMutationId,
|
||||
);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: _rejectionTile(
|
||||
rejection,
|
||||
matched: _findRejectedChange(
|
||||
state.lastRejectedChanges,
|
||||
rejection.clientMutationId,
|
||||
),
|
||||
matched: matched,
|
||||
expanded: expanded,
|
||||
onToggleExpanded: matched?.payload == null
|
||||
? null
|
||||
: () => _toggleRejectionExpanded(
|
||||
rejection.clientMutationId,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -258,6 +271,8 @@ class _SyncViewState extends ConsumerState<SyncView> {
|
||||
Widget _rejectionTile(
|
||||
MutationRejection rejection, {
|
||||
required ChangeEnvelope? matched,
|
||||
required bool expanded,
|
||||
required VoidCallback? onToggleExpanded,
|
||||
}) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
@@ -300,6 +315,17 @@ class _SyncViewState extends ConsumerState<SyncView> {
|
||||
color: AppTheme.textSecondary,
|
||||
),
|
||||
),
|
||||
if (onToggleExpanded != null)
|
||||
IconButton(
|
||||
onPressed: onToggleExpanded,
|
||||
tooltip: expanded ? 'Hide payload' : 'Show payload',
|
||||
icon: Icon(
|
||||
expanded
|
||||
? Icons.keyboard_arrow_up_rounded
|
||||
: Icons.keyboard_arrow_down_rounded,
|
||||
color: AppTheme.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
@@ -307,6 +333,21 @@ class _SyncViewState extends ConsumerState<SyncView> {
|
||||
rejection.message,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
if (expanded && matched?.payload != null) ...<Widget>[
|
||||
const SizedBox(height: 10),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF3F8FB),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: SelectableText(
|
||||
const JsonEncoder.withIndent(' ').convert(matched!.payload),
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -435,4 +476,14 @@ class _SyncViewState extends ConsumerState<SyncView> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _toggleRejectionExpanded(String clientMutationId) {
|
||||
setState(() {
|
||||
if (_expandedRejections.contains(clientMutationId)) {
|
||||
_expandedRejections.remove(clientMutationId);
|
||||
} else {
|
||||
_expandedRejections.add(clientMutationId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user