feat: implement debounced live search with clear button, refactor UI components, and adjust layout spacing and image cropping across screens.

This commit is contained in:
pradeepkumar
2026-05-08 18:41:06 +05:30
parent 4be171c0a7
commit 50c20ce0ce
5 changed files with 72 additions and 41 deletions

View File

@@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -31,6 +33,7 @@ class AgentSearchScreen extends ConsumerStatefulWidget {
class _AgentSearchScreenState extends ConsumerState<AgentSearchScreen> {
late TextEditingController _searchController;
final ScrollController _scrollController = ScrollController();
Timer? _searchDebounce;
@override
void initState() {
@@ -67,11 +70,22 @@ class _AgentSearchScreenState extends ConsumerState<AgentSearchScreen> {
@override
void dispose() {
_searchDebounce?.cancel();
_searchController.dispose();
_scrollController.dispose();
super.dispose();
}
/// Debounced live search — fires search() while the user types so results
/// update incrementally. Empty value resets to the default listing.
void _onSearchChanged(String value) {
_searchDebounce?.cancel();
_searchDebounce = Timer(const Duration(milliseconds: 300), () {
if (!mounted) return;
ref.read(searchAgentsProvider.notifier).search(value.trim());
});
}
void _onScroll() {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent - 200) {
@@ -185,10 +199,35 @@ class _AgentSearchScreenState extends ConsumerState<AgentSearchScreen> {
horizontal: 14,
vertical: 10,
),
// Clear (×) button — resets the listing instantly.
suffixIcon: _searchController.text.isNotEmpty
? IconButton(
icon: const Icon(
Icons.close,
size: 18,
color: AppColors.hintText,
),
onPressed: () {
_searchDebounce?.cancel();
_searchController.clear();
setState(() {});
ref
.read(searchAgentsProvider.notifier)
.search('');
},
)
: null,
),
onChanged: (value) {
// Toggle suffix-icon visibility on each keystroke.
setState(() {});
_onSearchChanged(value);
},
onSubmitted: (value) {
if (value.trim().isEmpty) return;
ref.read(searchAgentsProvider.notifier).search(value);
_searchDebounce?.cancel();
ref
.read(searchAgentsProvider.notifier)
.search(value.trim());
},
),
),