Per channel skeleton

This commit is contained in:
2026-03-01 20:10:38 +08:00
parent b9153a070f
commit 029e671367
13 changed files with 380 additions and 153 deletions
+20 -4
View File
@@ -5,7 +5,7 @@ import '../providers/realtime_controller.dart';
/// Subtle, non-blocking connection status indicator.
/// Shows in the bottom-right corner when streams are recovering/stale.
/// Unlike the old blocking overlay, this does NOT prevent user interaction.
/// Displays which channels are reconnecting so the user knows what to expect.
class ReconnectIndicator extends ConsumerWidget {
const ReconnectIndicator({super.key});
@@ -18,6 +18,12 @@ class ReconnectIndicator extends ConsumerWidget {
return const SizedBox.shrink();
}
// Build a human-readable label for recovering channels.
final channels = ctrl.recoveringChannels;
final label = channels.length <= 2
? channels.map(_humanize).join(', ')
: '${channels.length} channels';
return Positioned(
bottom: 16,
right: 16,
@@ -52,13 +58,23 @@ class ReconnectIndicator extends ConsumerWidget {
),
),
const SizedBox(width: 8),
Text(
'Reconnecting...',
style: Theme.of(context).textTheme.labelSmall,
Flexible(
child: Text(
'Reconnecting $label',
style: Theme.of(context).textTheme.labelSmall,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
);
}
/// Converts a channel name like 'task_assignments' to 'task assignments'.
static String _humanize(String channel) {
// Strip instance suffixes like 'ticket_messages:abc123'
final base = channel.contains(':') ? channel.split(':').first : channel;
return base.replaceAll('_', ' ');
}
}