Matthias Nott
2026-03-25 9aea0e7837ae0ea3d417f3d2afd8554cd71f123d
feat: show connection status detail in app bar during connect
3 files modified
changed files
lib/providers/providers.dart patch | view | blame | history
lib/screens/chat_screen.dart patch | view | blame | history
lib/services/mqtt_service.dart patch | view | blame | history
lib/providers/providers.dart
....@@ -58,6 +58,8 @@
5858 final wsStatusProvider =
5959 StateProvider<ConnectionStatus>((ref) => ConnectionStatus.disconnected);
6060
61
+final connectionDetailProvider = StateProvider<String>((ref) => '');
62
+
6163 // --- Sessions ---
6264
6365 final sessionsProvider = StateProvider<List<Session>>((ref) => []);
lib/screens/chat_screen.dart
....@@ -160,6 +160,14 @@
160160 _ws!.onStatusChanged = (status) {
161161 if (mounted) {
162162 ref.read(wsStatusProvider.notifier).state = status;
163
+ if (status == ConnectionStatus.connected) {
164
+ ref.read(connectionDetailProvider.notifier).state = '';
165
+ }
166
+ }
167
+ };
168
+ _ws!.onStatusDetail = (detail) {
169
+ if (mounted) {
170
+ ref.read(connectionDetailProvider.notifier).state = detail;
163171 }
164172 };
165173 _ws!.onMessage = _handleMessage;
....@@ -1301,6 +1309,7 @@
13011309 final messages = ref.watch(messagesProvider);
13021310 final wsStatus = ref.watch(wsStatusProvider);
13031311 final isTyping = ref.watch(isTypingProvider);
1312
+ final connectionDetail = ref.watch(connectionDetailProvider);
13041313 final sessions = ref.watch(sessionsProvider);
13051314 final activeSession = ref.watch(activeSessionProvider);
13061315 final unreadCounts = ref.watch(unreadCountsProvider);
....@@ -1319,9 +1328,20 @@
13191328 _scaffoldKey.currentState?.openDrawer();
13201329 },
13211330 ),
1322
- title: Text(
1323
- activeSession?.name ?? 'PAILot',
1324
- style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
1331
+ title: Column(
1332
+ crossAxisAlignment: CrossAxisAlignment.center,
1333
+ mainAxisSize: MainAxisSize.min,
1334
+ children: [
1335
+ Text(
1336
+ activeSession?.name ?? 'PAILot',
1337
+ style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
1338
+ ),
1339
+ if (connectionDetail.isNotEmpty && wsStatus != ConnectionStatus.connected)
1340
+ Text(
1341
+ connectionDetail,
1342
+ style: TextStyle(fontSize: 11, color: Colors.grey.shade400),
1343
+ ),
1344
+ ],
13251345 ),
13261346 actions: [
13271347 StatusDot(status: wsStatus),
lib/services/mqtt_service.dart
....@@ -56,6 +56,7 @@
5656
5757 // Callbacks
5858 void Function(ConnectionStatus status)? onStatusChanged;
59
+ void Function(String detail)? onStatusDetail; // "Probing local...", "Scanning network..."
5960 void Function(Map<String, dynamic> message)? onMessage;
6061 void Function()? onOpen;
6162 void Function()? onClose;
....@@ -117,6 +118,7 @@
117118 if (config.vpnHost != null && config.vpnHost!.isNotEmpty) hosts.add(config.vpnHost!);
118119 if (config.host.isNotEmpty) hosts.add(config.host);
119120 _mqttLog('MQTT: probing ${hosts.length} hosts in parallel: ${hosts.join(", ")}');
121
+ onStatusDetail?.call('Probing ${hosts.length} hosts...');
120122
121123 // Probe all configured hosts in parallel — first to respond wins
122124 String? winner;
....@@ -143,6 +145,7 @@
143145
144146 if (winner != null && !_intentionalClose) {
145147 _mqttLog('MQTT: probe winner: $winner, connecting...');
148
+ onStatusDetail?.call('Connecting to $winner...');
146149 try {
147150 if (await _tryConnect(winner, clientId, timeout: 5000)) return;
148151 } catch (e) {
....@@ -152,6 +155,7 @@
152155
153156 // All hosts failed — retry after delay
154157 _mqttLog('MQTT: all attempts failed, retrying in 5s');
158
+ onStatusDetail?.call('No server found, retrying...');
155159 _setStatus(ConnectionStatus.reconnecting);
156160 Future.delayed(const Duration(seconds: 5), () {
157161 if (!_intentionalClose && _status != ConnectionStatus.connected) {
....@@ -201,6 +205,7 @@
201205
202206 // Fallback: scan local subnet for MQTT port (handles Personal Hotspot)
203207 _mqttLog('MQTT: Bonjour failed, trying subnet scan...');
208
+ onStatusDetail?.call('Scanning local network...');
204209 return _scanSubnetForMqtt();
205210 }
206211