Skip to content

Commit a45ac03

Browse files
feat: ✨ Add Search Debounce Option in ChatViewList
1 parent 4be707d commit a45ac03

File tree

5 files changed

+26
-9
lines changed

5 files changed

+26
-9
lines changed

example/lib/chat_view_list_screen.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class _ChatViewListScreenState extends State<ChatViewListScreen> {
102102
),
103103
searchConfig: ChatViewListSearchConfig(
104104
textEditingController: TextEditingController(),
105+
debounceDuration: const Duration(milliseconds: 300),
105106
onSearch: (value) async {
106107
if (value.isEmpty) {
107108
return null;

lib/src/models/config_models/chat_view_list/search_config.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class ChatViewListSearchConfig {
5252
this.border,
5353
this.suffixIcon,
5454
this.onSearch,
55+
this.debounceDuration,
5556
this.decoration,
5657
this.maxLength,
5758
});
@@ -122,6 +123,9 @@ class ChatViewListSearchConfig {
122123
/// Callback function that is called when the search text changes.
123124
final SearchUserCallback? onSearch;
124125

126+
/// Duration to debounce the search callback.
127+
final Duration? debounceDuration;
128+
125129
/// Decoration for the search text field.
126130
final InputDecoration? decoration;
127131

lib/src/utils/debounce.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,17 @@ import 'dart:async';
2525
import 'package:flutter/material.dart';
2626

2727
class Debouncer {
28-
Timer? _debounce;
29-
Duration duration;
30-
3128
Debouncer(this.duration);
3229

33-
void run(VoidCallback callbackAfterTimeLapsed,
34-
VoidCallback callbackBeforeTimeLapsed) {
30+
final Duration duration;
31+
Timer? _debounce;
32+
33+
void run({required VoidCallback onComplete, VoidCallback? onInterrupt}) {
3534
if (_debounce?.isActive ?? false) {
36-
callbackBeforeTimeLapsed();
35+
onInterrupt?.call();
3736
_debounce?.cancel();
3837
}
39-
_debounce = Timer(duration, callbackAfterTimeLapsed);
38+
_debounce = Timer(duration, onComplete);
4039
}
4140

4241
void dispose() {

lib/src/widgets/chat_view_list/search_text_field.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import 'package:flutter/material.dart';
2525

2626
import '../../controller/chat_list_view_controller.dart';
2727
import '../../models/config_models/chat_view_list/search_config.dart';
28+
import '../../utils/debounce.dart';
2829
import '../../utils/package_strings.dart';
2930

3031
class SearchTextField extends StatefulWidget {
@@ -47,6 +48,10 @@ class SearchTextField extends StatefulWidget {
4748
class _SearchTextFieldState extends State<SearchTextField> {
4849
final ValueNotifier<String> _inputText = ValueNotifier('');
4950

51+
late final _debouncer = _config.debounceDuration == null
52+
? null
53+
: Debouncer(_config.debounceDuration!);
54+
5055
ChatViewListSearchConfig get _config => widget.config;
5156

5257
InputBorder get _outlineBorder =>
@@ -112,6 +117,14 @@ class _SearchTextFieldState extends State<SearchTextField> {
112117

113118
FutureOr<void> _onSearchChanged(String value) async {
114119
_inputText.value = value;
120+
if (_debouncer != null) {
121+
_debouncer.run(onComplete: () => _performSearch(value));
122+
} else {
123+
await _performSearch(value);
124+
}
125+
}
126+
127+
FutureOr<void> _performSearch(String value) async {
115128
final chatList = await _config.onSearch?.call(value);
116129
if (chatList != null) {
117130
widget.chatViewListController?.setSearchChats(chatList);

lib/src/widgets/chatui_textfield.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,9 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
444444
}
445445

446446
void _onChanged(String inputText) {
447-
debouncer.run(() {
447+
debouncer.run(onComplete: () {
448448
composingStatus.value = TypeWriterStatus.typed;
449-
}, () {
449+
}, onInterrupt: () {
450450
composingStatus.value = TypeWriterStatus.typing;
451451
});
452452
_inputText.value = inputText;

0 commit comments

Comments
 (0)