| .. | .. |
|---|
| 213 | 213 | case 'image': |
|---|
| 214 | 214 | _handleIncomingImage(msg); |
|---|
| 215 | 215 | case 'typing': |
|---|
| 216 | | - final typing = msg['typing'] as bool? ?? msg['isTyping'] as bool? ?? true; |
|---|
| 217 | | - ref.read(isTypingProvider.notifier).state = typing; |
|---|
| 216 | + final typing = msg['typing'] as bool? ?? msg['isTyping'] as bool? ?? msg['active'] as bool? ?? true; |
|---|
| 217 | + final typingSession = msg['sessionId'] as String?; |
|---|
| 218 | + final activeId = ref.read(activeSessionIdProvider); |
|---|
| 219 | + // Only show typing indicator for the active session |
|---|
| 220 | + if (typingSession == null || typingSession == activeId) { |
|---|
| 221 | + ref.read(isTypingProvider.notifier).state = typing; |
|---|
| 222 | + } |
|---|
| 218 | 223 | case 'typing_end': |
|---|
| 219 | 224 | ref.read(isTypingProvider.notifier).state = false; |
|---|
| 220 | 225 | case 'screenshot': |
|---|
| .. | .. |
|---|
| 794 | 799 | // Show caption dialog |
|---|
| 795 | 800 | final fileNames = result.files.map((f) => f.name).join(', '); |
|---|
| 796 | 801 | final caption = await _showCaptionDialog(result.files.length); |
|---|
| 797 | | - if (caption == null) return; |
|---|
| 802 | + if (caption == null) { |
|---|
| 803 | + if (mounted) FocusManager.instance.primaryFocus?.unfocus(); |
|---|
| 804 | + return; |
|---|
| 805 | + } |
|---|
| 798 | 806 | |
|---|
| 799 | 807 | // Handle voice caption |
|---|
| 800 | 808 | String textCaption = caption; |
|---|
| .. | .. |
|---|
| 856 | 864 | } |
|---|
| 857 | 865 | } |
|---|
| 858 | 866 | |
|---|
| 867 | + // Dismiss keyboard after file flow completes |
|---|
| 868 | + if (mounted) FocusManager.instance.primaryFocus?.unfocus(); |
|---|
| 859 | 869 | _scrollToBottom(); |
|---|
| 860 | 870 | } |
|---|
| 861 | 871 | |
|---|
| .. | .. |
|---|
| 964 | 974 | } |
|---|
| 965 | 975 | |
|---|
| 966 | 976 | final caption = await _showCaptionDialog(images.length); |
|---|
| 967 | | - if (caption == null) return; // user cancelled |
|---|
| 977 | + if (caption == null) { |
|---|
| 978 | + if (mounted) FocusManager.instance.primaryFocus?.unfocus(); |
|---|
| 979 | + return; // user cancelled |
|---|
| 980 | + } |
|---|
| 968 | 981 | |
|---|
| 969 | 982 | // Handle voice caption |
|---|
| 970 | 983 | String textCaption = caption; |
|---|
| .. | .. |
|---|
| 1016 | 1029 | ref.read(messagesProvider.notifier).addMessage(message); |
|---|
| 1017 | 1030 | } |
|---|
| 1018 | 1031 | |
|---|
| 1032 | + // Dismiss keyboard after image flow completes |
|---|
| 1033 | + if (mounted) FocusManager.instance.primaryFocus?.unfocus(); |
|---|
| 1019 | 1034 | _scrollToBottom(); |
|---|
| 1020 | 1035 | } |
|---|
| 1021 | 1036 | |
|---|