Components: Implementation of Search Debounces

This commit is contained in:
nikbel2004@outlook.com 2024-12-18 17:22:07 +04:00
parent f57f4aa7e8
commit 6eda69fcc5
5 changed files with 88 additions and 1 deletions

View File

@ -0,0 +1,22 @@
import 'dart:async';
import 'dart:ui';
class Debounce {
// Фабричный конструктор, возвращающий экземпляр класса Debounce. Паттерн Singleton
factory Debounce() => _instance;
// Приватный конструктор (Не даёт создание класса извне)
Debounce._();
// Статический экземпляр класса
static final Debounce _instance = Debounce._();
static Timer? _timer;
// Статический метод, где action функция, совершающая действие, а delay совершает задержку
static void run(
{required VoidCallback action, Duration delay = const Duration(milliseconds: 500)}) {
_timer?.cancel();
_timer = Timer(delay, action);
}
}

View File

@ -0,0 +1,31 @@
import 'package:candystore/data/repositories/candy_repository.dart';
import 'package:candystore/presentation/bloc/candy_bloc/candy_event.dart';
import 'package:candystore/presentation/bloc/candy_bloc/candy_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class CandyBloc extends Bloc<CandyEvent, CandyState> {
final CandyRepository repository;
CandyBloc(this.repository) : super(const CandyState()) {
on<CandyLoadDataEvent>(_onLoadData);
}
Future<void> _onLoadData(CandyLoadDataEvent event, Emitter<CandyState> emit) async {
if (event.nextPage == null) {
emit(state.copyWith(isLoading: true));
} else {
emit(state.copyWith(isPaginationLoading: true));
}
String? error;
final data = await repository.loadData(
q: event.search, page: event.nextPage ?? 1, onError: (e) => error = e);
if (event.nextPage != null) {
data?.data?.insertAll(0, state.data?.data ?? []);
}
emit(state.copyWith(isLoading: false, isPaginationLoading: false, data: data, error: error));
}
}

View File

@ -0,0 +1,10 @@
abstract class CandyEvent {
const CandyEvent();
}
class CandyLoadDataEvent extends CandyEvent {
final String? search;
final int? nextPage;
const CandyLoadDataEvent({this.search, this.nextPage});
}

View File

@ -0,0 +1,25 @@
import 'package:candystore/models/candy_data.dart';
import 'package:equatable/equatable.dart';
class CandyState extends Equatable {
final CandyData? data;
final bool isLoading;
final bool isPaginationLoading;
final String? error;
const CandyState(
{this.data, this.isLoading = false, this.isPaginationLoading = false, this.error});
// Получение нового экземпляра состояния
CandyState copyWith(
{CandyData? data, bool? isLoading, bool? isPaginationLoading, String? error}) =>
CandyState(
data: data ?? this.data,
isLoading: isLoading ?? this.isLoading,
isPaginationLoading: isPaginationLoading ?? this.isPaginationLoading,
error: error ?? this.error);
// Поля, по которым Equtable сравнивает состояния
@override
List<Object?> get props => [data, isLoading, isPaginationLoading, error];
}

View File

@ -1,5 +1,4 @@
import 'dart:math';
import 'package:candystore/components/l10n/app_locale.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';