From 29f7a2c444d60fa155451d7e7f65cf637a1b7f41 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Wed, 25 Mar 2026 17:22:28 +0100
Subject: [PATCH] fix: M1 M2 M6 M7 L3 L5 - subnet batching, scroll debounce, error logging, typing timeout, remove unused deps

---
 lib/screens/chat_screen.dart |   20 +++++++++++++++++---
 1 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index 3c03072..5017f31 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -1,3 +1,4 @@
+import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 
@@ -63,6 +64,7 @@
   final List<Map<String, dynamic>> _pendingMessages = [];
   final Map<String, List<Message>> _catchUpPending = {};
   List<String>? _cachedSessionOrder;
+  Timer? _typingTimer;
 
   @override
   void initState() {
@@ -132,10 +134,13 @@
     }
   }
 
+  bool _isLoadingMore = false;
   void _onScroll() {
-    if (_scrollController.position.pixels >=
-        _scrollController.position.maxScrollExtent - 100) {
-      ref.read(messagesProvider.notifier).loadMore();
+    if (!_isLoadingMore &&
+        _scrollController.position.pixels >=
+            _scrollController.position.maxScrollExtent - 100) {
+      _isLoadingMore = true;
+      ref.read(messagesProvider.notifier).loadMore().then((_) => _isLoadingMore = false);
     }
   }
 
@@ -247,6 +252,15 @@
         // Strict: only show typing for the ACTIVE session, ignore all others
         if (activeId != null && typingSession == activeId) {
           ref.read(isTypingProvider.notifier).state = typing;
+          // Auto-clear after 10s in case typing_end is missed
+          if (typing) {
+            _typingTimer?.cancel();
+            _typingTimer = Timer(const Duration(seconds: 10), () {
+              if (mounted) ref.read(isTypingProvider.notifier).state = false;
+            });
+          } else {
+            _typingTimer?.cancel();
+          }
         }
       case 'typing_end':
         final endSession = msg['sessionId'] as String?;

--
Gitblit v1.3.1