90 lines
2.3 KiB
Dart
90 lines
2.3 KiB
Dart
import 'dart:async';
|
|
import 'package:equatable/equatable.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import '../data/maps_repository.dart';
|
|
import '../data/models/place_model.dart';
|
|
|
|
/// حالة شاشة البحث عن الوجهة.
|
|
class DestinationState extends Equatable {
|
|
final String query;
|
|
final List<PlaceModel> results;
|
|
final bool searching;
|
|
final String? error;
|
|
|
|
const DestinationState({
|
|
this.query = '',
|
|
this.results = const [],
|
|
this.searching = false,
|
|
this.error,
|
|
});
|
|
|
|
DestinationState copyWith({
|
|
String? query,
|
|
List<PlaceModel>? results,
|
|
bool? searching,
|
|
String? error,
|
|
bool clearError = false,
|
|
}) {
|
|
return DestinationState(
|
|
query: query ?? this.query,
|
|
results: results ?? this.results,
|
|
searching: searching ?? this.searching,
|
|
error: clearError ? null : (error ?? this.error),
|
|
);
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [query, results, searching, error];
|
|
}
|
|
|
|
/// البحث عن وجهة مع debounce.
|
|
class DestinationCubit extends Cubit<DestinationState> {
|
|
final MapsRepository _mapsRepo;
|
|
Timer? _debounce;
|
|
|
|
DestinationCubit(this._mapsRepo) : super(const DestinationState());
|
|
|
|
void onQueryChanged(String query) {
|
|
_debounce?.cancel();
|
|
emit(state.copyWith(query: query, clearError: true));
|
|
|
|
if (query.trim().length < 2) {
|
|
emit(state.copyWith(results: [], searching: false));
|
|
return;
|
|
}
|
|
|
|
emit(state.copyWith(searching: true));
|
|
|
|
_debounce = Timer(const Duration(milliseconds: 500), () {
|
|
_search(query);
|
|
});
|
|
}
|
|
|
|
Future<void> _search(String query) async {
|
|
try {
|
|
final results = await _mapsRepo.autocomplete(query);
|
|
emit(state.copyWith(results: results, searching: false));
|
|
} catch (e) {
|
|
emit(state.copyWith(searching: false, error: e.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> searchDirectly(String query) async {
|
|
_debounce?.cancel();
|
|
if (query.trim().length < 2) return;
|
|
emit(state.copyWith(searching: true, clearError: true));
|
|
try {
|
|
final results = await _mapsRepo.autocomplete(query);
|
|
emit(state.copyWith(results: results, searching: false));
|
|
} catch (e) {
|
|
emit(state.copyWith(searching: false, error: e.toString()));
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> close() {
|
|
_debounce?.cancel();
|
|
return super.close();
|
|
}
|
|
}
|