improve typing indicator

This commit is contained in:
otsmr 2026-05-19 14:46:01 +02:00
parent 2cb51d668a
commit d32e319c49
2 changed files with 15 additions and 2 deletions

View file

@ -146,7 +146,9 @@ class _ChatMessagesViewState extends State<ChatMessagesView>
_nextTypingIndicator = Timer.periodic(const Duration(seconds: 2), ( _nextTypingIndicator = Timer.periodic(const Duration(seconds: 2), (
_, _,
) async { ) async {
if (_isViewActive()) {
await sendTypingIndication(widget.groupId, false); await sendTypingIndication(widget.groupId, false);
}
}); });
} }
} }

View file

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:audio_waveforms/audio_waveforms.dart'; import 'package:audio_waveforms/audio_waveforms.dart';
import 'package:clock/clock.dart';
import 'package:drift/drift.dart' show Value; import 'package:drift/drift.dart' show Value;
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart'; import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -51,6 +52,7 @@ class _MessageInputState extends State<MessageInput> {
Offset _recordingOffset = Offset.zero; Offset _recordingOffset = Offset.zero;
RecordingState _recordingState = RecordingState.none; RecordingState _recordingState = RecordingState.none;
Timer? _nextTypingIndicator; Timer? _nextTypingIndicator;
DateTime? _lastTextChangeTime;
Future<void> _sendMessage() async { Future<void> _sendMessage() async {
if (_textFieldController.text == '') return; if (_textFieldController.text == '') return;
@ -70,6 +72,7 @@ class _MessageInputState extends State<MessageInput> {
void initState() { void initState() {
super.initState(); super.initState();
_textFieldController = TextEditingController(); _textFieldController = TextEditingController();
_textFieldController.addListener(_handleTextChange);
if (widget.group.draftMessage != null) { if (widget.group.draftMessage != null) {
_textFieldController.text = widget.group.draftMessage!; _textFieldController.text = widget.group.draftMessage!;
} }
@ -78,7 +81,10 @@ class _MessageInputState extends State<MessageInput> {
_nextTypingIndicator = Timer.periodic(const Duration(seconds: 1), ( _nextTypingIndicator = Timer.periodic(const Duration(seconds: 1), (
_, _,
) async { ) async {
if (widget.textFieldFocus.hasFocus) { if (widget.textFieldFocus.hasFocus &&
_lastTextChangeTime != null &&
DateTime.now().difference(_lastTextChangeTime!) <=
const Duration(seconds: 6)) {
await sendTypingIndication(widget.group.groupId, true); await sendTypingIndication(widget.group.groupId, true);
} }
}); });
@ -88,6 +94,7 @@ class _MessageInputState extends State<MessageInput> {
@override @override
void dispose() { void dispose() {
_textFieldController.removeListener(_handleTextChange);
widget.textFieldFocus.removeListener(_handleTextFocusChange); widget.textFieldFocus.removeListener(_handleTextFocusChange);
widget.textFieldFocus.dispose(); widget.textFieldFocus.dispose();
recorderController.dispose(); recorderController.dispose();
@ -105,6 +112,10 @@ class _MessageInputState extends State<MessageInput> {
}); });
} }
void _handleTextChange() {
_lastTextChangeTime = clock.now();
}
void _handleTextFocusChange() { void _handleTextFocusChange() {
if (widget.textFieldFocus.hasFocus) { if (widget.textFieldFocus.hasFocus) {
setState(() { setState(() {