feat: filters added to home page
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
abstract class TimeDelayConst {
|
||||
static const Duration durationMill150 = Duration(milliseconds: 150);
|
||||
static const Duration durationMill300 = Duration(milliseconds: 300);
|
||||
static const Duration durationMill800 = Duration(milliseconds: 800);
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
_i526.EnvironmentFilter? environmentFilter,
|
||||
}) {
|
||||
final gh = _i526.GetItHelper(this, environment, environmentFilter);
|
||||
gh.factory<_i1007.HomeBloc>(() => _i1007.HomeBloc());
|
||||
gh.factory<_i580.MainBloc>(() => _i580.MainBloc());
|
||||
gh.factory<_i311.SplashBloc>(() => _i311.SplashBloc());
|
||||
gh.factory<_i1007.HomeBloc>(() => _i1007.HomeBloc());
|
||||
gh.singleton<_i306.StorageService>(() => _i306.StorageService());
|
||||
gh.singleton<_i152.AppRoutes>(() => _i152.AppRoutes());
|
||||
gh.factory<_i942.LanguageBloc>(
|
||||
|
||||
@@ -327,6 +327,162 @@ abstract class AppLocalizations {
|
||||
/// In en, this message translates to:
|
||||
/// **'More'**
|
||||
String get more;
|
||||
|
||||
/// No description provided for @orderDetails.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Order details'**
|
||||
String get orderDetails;
|
||||
|
||||
/// No description provided for @deliverNow.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Deliver now'**
|
||||
String get deliverNow;
|
||||
|
||||
/// No description provided for @schedule.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Schedule'**
|
||||
String get schedule;
|
||||
|
||||
/// No description provided for @enterNewAddress.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter a new address'**
|
||||
String get enterNewAddress;
|
||||
|
||||
/// No description provided for @nearby.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Nearby'**
|
||||
String get nearby;
|
||||
|
||||
/// No description provided for @currentLocation.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Current location'**
|
||||
String get currentLocation;
|
||||
|
||||
/// No description provided for @enable.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enable'**
|
||||
String get enable;
|
||||
|
||||
/// No description provided for @recentLocations.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Recent locations'**
|
||||
String get recentLocations;
|
||||
|
||||
/// No description provided for @allFilters.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'All filters'**
|
||||
String get allFilters;
|
||||
|
||||
/// No description provided for @sort.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Sort'**
|
||||
String get sort;
|
||||
|
||||
/// No description provided for @pickedForYou.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Picked for you (default)'**
|
||||
String get pickedForYou;
|
||||
|
||||
/// No description provided for @mostPopular.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Most popular'**
|
||||
String get mostPopular;
|
||||
|
||||
/// No description provided for @rating.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Rating'**
|
||||
String get rating;
|
||||
|
||||
/// No description provided for @deliveryTime.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delivery time'**
|
||||
String get deliveryTime;
|
||||
|
||||
/// No description provided for @fromUberEats.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'From Uber Eats'**
|
||||
String get fromUberEats;
|
||||
|
||||
/// No description provided for @deals.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Deals'**
|
||||
String get deals;
|
||||
|
||||
/// No description provided for @bestOverall.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Best overall'**
|
||||
String get bestOverall;
|
||||
|
||||
/// No description provided for @priceRange.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Price range'**
|
||||
String get priceRange;
|
||||
|
||||
/// No description provided for @maxDeliveryFee.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Max. Delivery Fee'**
|
||||
String get maxDeliveryFee;
|
||||
|
||||
/// No description provided for @dietary.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Dietary'**
|
||||
String get dietary;
|
||||
|
||||
/// No description provided for @vegetarian.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Vegetarian'**
|
||||
String get vegetarian;
|
||||
|
||||
/// No description provided for @vegan.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Vegan'**
|
||||
String get vegan;
|
||||
|
||||
/// No description provided for @glutenFree.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Gluten-free'**
|
||||
String get glutenFree;
|
||||
|
||||
/// No description provided for @allergyFriendly.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Allergy friendly'**
|
||||
String get allergyFriendly;
|
||||
|
||||
/// No description provided for @atLeast.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'At least'**
|
||||
String get atLeast;
|
||||
|
||||
/// No description provided for @apply.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Apply'**
|
||||
String get apply;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
||||
@@ -126,4 +126,82 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get more => 'More';
|
||||
|
||||
@override
|
||||
String get orderDetails => 'Order details';
|
||||
|
||||
@override
|
||||
String get deliverNow => 'Deliver now';
|
||||
|
||||
@override
|
||||
String get schedule => 'Schedule';
|
||||
|
||||
@override
|
||||
String get enterNewAddress => 'Enter a new address';
|
||||
|
||||
@override
|
||||
String get nearby => 'Nearby';
|
||||
|
||||
@override
|
||||
String get currentLocation => 'Current location';
|
||||
|
||||
@override
|
||||
String get enable => 'Enable';
|
||||
|
||||
@override
|
||||
String get recentLocations => 'Recent locations';
|
||||
|
||||
@override
|
||||
String get allFilters => 'All filters';
|
||||
|
||||
@override
|
||||
String get sort => 'Sort';
|
||||
|
||||
@override
|
||||
String get pickedForYou => 'Picked for you (default)';
|
||||
|
||||
@override
|
||||
String get mostPopular => 'Most popular';
|
||||
|
||||
@override
|
||||
String get rating => 'Rating';
|
||||
|
||||
@override
|
||||
String get deliveryTime => 'Delivery time';
|
||||
|
||||
@override
|
||||
String get fromUberEats => 'From Uber Eats';
|
||||
|
||||
@override
|
||||
String get deals => 'Deals';
|
||||
|
||||
@override
|
||||
String get bestOverall => 'Best overall';
|
||||
|
||||
@override
|
||||
String get priceRange => 'Price range';
|
||||
|
||||
@override
|
||||
String get maxDeliveryFee => 'Max. Delivery Fee';
|
||||
|
||||
@override
|
||||
String get dietary => 'Dietary';
|
||||
|
||||
@override
|
||||
String get vegetarian => 'Vegetarian';
|
||||
|
||||
@override
|
||||
String get vegan => 'Vegan';
|
||||
|
||||
@override
|
||||
String get glutenFree => 'Gluten-free';
|
||||
|
||||
@override
|
||||
String get allergyFriendly => 'Allergy friendly';
|
||||
|
||||
@override
|
||||
String get atLeast => 'At least';
|
||||
|
||||
@override
|
||||
String get apply => 'Apply';
|
||||
}
|
||||
|
||||
@@ -127,4 +127,82 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get more => 'Ещё';
|
||||
|
||||
@override
|
||||
String get orderDetails => 'Детали заказа';
|
||||
|
||||
@override
|
||||
String get deliverNow => 'Доставить сейчас';
|
||||
|
||||
@override
|
||||
String get schedule => 'Запланировать';
|
||||
|
||||
@override
|
||||
String get enterNewAddress => 'Введите новый адрес';
|
||||
|
||||
@override
|
||||
String get nearby => 'Рядом';
|
||||
|
||||
@override
|
||||
String get currentLocation => 'Текущее местоположение';
|
||||
|
||||
@override
|
||||
String get enable => 'Включить';
|
||||
|
||||
@override
|
||||
String get recentLocations => 'Недавние адреса';
|
||||
|
||||
@override
|
||||
String get allFilters => 'Все фильтры';
|
||||
|
||||
@override
|
||||
String get sort => 'Сортировка';
|
||||
|
||||
@override
|
||||
String get pickedForYou => 'Подобрано для вас (по умолчанию)';
|
||||
|
||||
@override
|
||||
String get mostPopular => 'Самые популярные';
|
||||
|
||||
@override
|
||||
String get rating => 'Рейтинг';
|
||||
|
||||
@override
|
||||
String get deliveryTime => 'Время доставки';
|
||||
|
||||
@override
|
||||
String get fromUberEats => 'От Uber Eats';
|
||||
|
||||
@override
|
||||
String get deals => 'Скидки';
|
||||
|
||||
@override
|
||||
String get bestOverall => 'Лучший выбор';
|
||||
|
||||
@override
|
||||
String get priceRange => 'Диапазон цен';
|
||||
|
||||
@override
|
||||
String get maxDeliveryFee => 'Макс. стоимость доставки';
|
||||
|
||||
@override
|
||||
String get dietary => 'Диета';
|
||||
|
||||
@override
|
||||
String get vegetarian => 'Вегетарианское';
|
||||
|
||||
@override
|
||||
String get vegan => 'Веганское';
|
||||
|
||||
@override
|
||||
String get glutenFree => 'Без глютена';
|
||||
|
||||
@override
|
||||
String get allergyFriendly => 'Без аллергенов';
|
||||
|
||||
@override
|
||||
String get atLeast => 'Kак минимум';
|
||||
|
||||
@override
|
||||
String get apply => 'Применить';
|
||||
}
|
||||
|
||||
@@ -127,4 +127,82 @@ class AppLocalizationsUz extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get more => 'Ko\'proq';
|
||||
|
||||
@override
|
||||
String get orderDetails => 'Buyurtma tafsilotlari';
|
||||
|
||||
@override
|
||||
String get deliverNow => 'Hozir yetkazish';
|
||||
|
||||
@override
|
||||
String get schedule => 'Rejalashtirish';
|
||||
|
||||
@override
|
||||
String get enterNewAddress => 'Yangi manzil kiriting';
|
||||
|
||||
@override
|
||||
String get nearby => 'Yaqin joylar';
|
||||
|
||||
@override
|
||||
String get currentLocation => 'Joriy joylashuv';
|
||||
|
||||
@override
|
||||
String get enable => 'Yoqqish';
|
||||
|
||||
@override
|
||||
String get recentLocations => 'Yaqinda ishlatilgan manzillar';
|
||||
|
||||
@override
|
||||
String get allFilters => 'Barcha filtrlar';
|
||||
|
||||
@override
|
||||
String get sort => 'Saralash';
|
||||
|
||||
@override
|
||||
String get pickedForYou => 'Siz uchun';
|
||||
|
||||
@override
|
||||
String get mostPopular => 'Eng ommabop';
|
||||
|
||||
@override
|
||||
String get rating => 'Reyting';
|
||||
|
||||
@override
|
||||
String get deliveryTime => 'Yetkazib berish vaqti';
|
||||
|
||||
@override
|
||||
String get fromUberEats => 'Uber Eats dan';
|
||||
|
||||
@override
|
||||
String get deals => 'Aksiyalar';
|
||||
|
||||
@override
|
||||
String get bestOverall => 'Eng yaxshisi';
|
||||
|
||||
@override
|
||||
String get priceRange => 'Narx oralig‘i';
|
||||
|
||||
@override
|
||||
String get maxDeliveryFee => 'Maks. yetkazish narxi';
|
||||
|
||||
@override
|
||||
String get dietary => 'Parhez';
|
||||
|
||||
@override
|
||||
String get vegetarian => 'Vegetarian';
|
||||
|
||||
@override
|
||||
String get vegan => 'Vegan';
|
||||
|
||||
@override
|
||||
String get glutenFree => 'Glutensiz';
|
||||
|
||||
@override
|
||||
String get allergyFriendly => 'Allergiyaga mos';
|
||||
|
||||
@override
|
||||
String get atLeast => 'Kаmida';
|
||||
|
||||
@override
|
||||
String get apply => 'Qo‘llash';
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import '../../food_delivery_client.dart';
|
||||
abstract class AppColors {
|
||||
static const Color cTransparent = Colors.transparent;
|
||||
static const Color cRed = Colors.red;
|
||||
static const Color cYellow = Colors.yellow;
|
||||
|
||||
|
||||
static const Color cFFFFFF = Color(0xFFFFFFFF);
|
||||
static const Color c000000 = Color(0xFF000000);
|
||||
|
||||
@@ -23,5 +23,24 @@ abstract class AppIcons {
|
||||
static const String icLocation = "$baseUrl/ic_location.svg";
|
||||
static const String icArrowBottom = "$baseUrl/ic_arrow_btm.svg";
|
||||
|
||||
static const String icPicked = "$baseUrl/ic_picked.svg";
|
||||
static const String icMostPopular = "$baseUrl/ic_popular.svg";
|
||||
static const String icStar = "$baseUrl/ic_rating.svg";
|
||||
static const String icDeliveryTime = "$baseUrl/ic_delivery_time.svg";
|
||||
static const String icDeals = "$baseUrl/ic_deals.svg";
|
||||
static const String icClose = "$baseUrl/ic_close.svg";
|
||||
static const String icCurrentLocation = "$baseUrl/ic_current_loc.svg";
|
||||
static const String icEdit = "$baseUrl/ic_edit.svg";
|
||||
static const String icSearch = "$baseUrl/ic_search.svg";
|
||||
static const String icCheck= "$baseUrl/ic_check.svg";
|
||||
static const String icCheck1= "$baseUrl/ic_check1.svg";
|
||||
|
||||
|
||||
///.png icons
|
||||
static const String icBestOverall = "$baseUrl/ic_best.png";
|
||||
static const String icVegetarian = "$baseUrl/ic_vegetarian.png";
|
||||
static const String icVegen = "$baseUrl/ic_vegen.png";
|
||||
static const String icGlutenFree = "$baseUrl/ic_gluten_free.png";
|
||||
static const String icAllergyFriendly = "$baseUrl/ic_allergy_friendly.png";
|
||||
static const String icClock = "$baseUrl/ic_clock.png";
|
||||
}
|
||||
|
||||
@@ -63,6 +63,20 @@ abstract class AppTextStyles {
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
static const TextStyle size20Medium = TextStyle(
|
||||
color: _defaultColor,
|
||||
fontSize: SizesCons.size_20,
|
||||
fontFamily: _fontMedium,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
static const TextStyle size16Bold= TextStyle(
|
||||
color: _defaultColor,
|
||||
fontSize: SizesCons.size_16,
|
||||
fontFamily: _fontBold,
|
||||
fontWeight: FontWeight.w700,
|
||||
);
|
||||
|
||||
static const TextStyle size17Bold = TextStyle(
|
||||
color: _defaultColor,
|
||||
fontSize: SizesCons.size_17,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import '../../food_delivery_client.dart';
|
||||
|
||||
abstract class AppUtils {
|
||||
static const SizedBox kSizedBox = SizedBox.shrink();
|
||||
|
||||
static const Radius kRadius = Radius.zero;
|
||||
static const Radius kRadius8 = Radius.circular(8);
|
||||
static const Radius kRadius12 = Radius.circular(12);
|
||||
@@ -79,6 +81,10 @@ abstract class AppUtils {
|
||||
static const BorderRadius kBorderRadius40 = BorderRadius.all(
|
||||
Radius.circular(40),
|
||||
);
|
||||
static const BorderRadius kBorderRadiusTop20 = BorderRadius.only(
|
||||
topLeft: kRadius20,
|
||||
topRight: kRadius20,
|
||||
);
|
||||
static const BorderRadius kBorderRadiusTop20Bottom20 = BorderRadius.only(
|
||||
bottomRight: kRadius20,
|
||||
topRight: kRadius20,
|
||||
|
||||
61
lib/feature/common/presentation/widgets/app_button.dart
Normal file
61
lib/feature/common/presentation/widgets/app_button.dart
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
import '../../../../food_delivery_client.dart';
|
||||
|
||||
|
||||
class AppButton extends StatelessWidget {
|
||||
const AppButton({
|
||||
super.key,
|
||||
required this.name,
|
||||
required this.onPressed,
|
||||
this.margin,
|
||||
this.backgroundColor,
|
||||
this.borderRadius,
|
||||
this.height,
|
||||
this.textColor,
|
||||
this.width,
|
||||
this.action,
|
||||
this.trailing,
|
||||
this.mainAxisAlignment,
|
||||
});
|
||||
|
||||
final String name;
|
||||
final VoidCallback onPressed;
|
||||
final EdgeInsets? margin;
|
||||
final Color? backgroundColor;
|
||||
final Color? textColor;
|
||||
final double? borderRadius;
|
||||
final double? width;
|
||||
final double? height;
|
||||
final Widget? action;
|
||||
final Widget? trailing;
|
||||
final MainAxisAlignment? mainAxisAlignment;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Bounceable(
|
||||
onTap: onPressed,
|
||||
duration: TimeDelayConst.durationMill150,
|
||||
child: Container(
|
||||
width: width ?? double.infinity,
|
||||
height: height ?? 55,
|
||||
margin: margin,
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor ?? AppColors.c000000,
|
||||
borderRadius: BorderRadius.circular(borderRadius ?? 0),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: mainAxisAlignment ?? MainAxisAlignment.center,
|
||||
children: [
|
||||
action ?? AppUtils.kSizedBox,
|
||||
Text(name, style: AppTextStyles.size16Bold.copyWith(
|
||||
color: AppColors.cFFFFFF
|
||||
)),
|
||||
trailing ?? AppUtils.kSizedBox,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WCustomModalBottomSheet extends StatelessWidget {
|
||||
const WCustomModalBottomSheet({super.key, required this.child});
|
||||
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
color: AppColors.cFFFFFF,
|
||||
borderRadius: AppUtils.kBorderRadiusTop20,
|
||||
child: SafeArea(
|
||||
child: SizedBox(
|
||||
width: context.w,
|
||||
child: Column(
|
||||
children: [
|
||||
10.verticalSpace,
|
||||
SizedBox(
|
||||
height: 6,
|
||||
width: 100,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius6,
|
||||
color: AppColors.cE6E6E6.newWithOpacity(.6),
|
||||
),
|
||||
),
|
||||
),
|
||||
10.verticalSpace,
|
||||
child,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,3 +3,5 @@ export 'w_food_item.dart';
|
||||
export 'w_divider.dart';
|
||||
export 'w_see_all_raw.dart';
|
||||
export 'w_stories_list_item.dart';
|
||||
export 'w_custom_modal_bottom_sheet.dart';
|
||||
export 'app_button.dart';
|
||||
|
||||
@@ -9,3 +9,6 @@ export 'presentation/pages/home_page/widgets/w_offers_carouseL_slider.dart';
|
||||
export 'presentation/pages/home_page/widgets/w_popular_near_you.dart';
|
||||
export 'presentation/pages/home_page/widgets/w_todays_offers.dart';
|
||||
export 'package:food_delivery_client/feature/home/presentation/pages/home_page/widgets/pick_it_for_free.dart';
|
||||
export 'package:flutter_svg/flutter_svg.dart';
|
||||
export 'package:food_delivery_client/feature/home/presentation/pages/categories_page/categories_page.dart';
|
||||
export 'package:food_delivery_client/feature/home/presentation/pages/home_page/widgets/w_rating_btm_sheet.dart';
|
||||
|
||||
@@ -5,13 +5,33 @@ part 'home_event.dart';
|
||||
part 'home_state.dart';
|
||||
|
||||
part 'home_bloc.freezed.dart';
|
||||
|
||||
@injectable
|
||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
HomeBloc() : super(const HomeState()) {
|
||||
on<_Changed>(_onChanged);
|
||||
on<_Filtered>(_onFiltered);
|
||||
on<_Rated>(_onRated);
|
||||
}
|
||||
|
||||
void _onChanged(_Changed event, Emitter<HomeState> emit) {
|
||||
emit(state.copyWith(currentIndex: event.index));
|
||||
}
|
||||
|
||||
void _onFiltered(_Filtered event, Emitter<HomeState> emit) {
|
||||
final oldFilters = List.from(state.filters);
|
||||
if (oldFilters.contains(event.filter)) {
|
||||
final newFilters = oldFilters..remove(event.filter);
|
||||
emit(state.copyWith(filters: newFilters));
|
||||
} else {
|
||||
final newFilters = oldFilters..add(event.filter);
|
||||
emit(state.copyWith(filters: newFilters));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _onRated(_Rated event, Emitter<HomeState> emit){
|
||||
emit(state.copyWith(rating: event.filter));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,12 +55,14 @@ extension HomeEventPatterns on HomeEvent {
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Started value)? started,TResult Function( _Changed value)? changed,required TResult orElse(),}){
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Started value)? started,TResult Function( _Changed value)? changed,TResult Function( _Filtered value)? filtered,TResult Function( _Rated value)? rated,required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Started() when started != null:
|
||||
return started(_that);case _Changed() when changed != null:
|
||||
return changed(_that);case _:
|
||||
return changed(_that);case _Filtered() when filtered != null:
|
||||
return filtered(_that);case _Rated() when rated != null:
|
||||
return rated(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -78,12 +80,14 @@ return changed(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Started value) started,required TResult Function( _Changed value) changed,}){
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Started value) started,required TResult Function( _Changed value) changed,required TResult Function( _Filtered value) filtered,required TResult Function( _Rated value) rated,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Started():
|
||||
return started(_that);case _Changed():
|
||||
return changed(_that);case _:
|
||||
return changed(_that);case _Filtered():
|
||||
return filtered(_that);case _Rated():
|
||||
return rated(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -100,12 +104,14 @@ return changed(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Started value)? started,TResult? Function( _Changed value)? changed,}){
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Started value)? started,TResult? Function( _Changed value)? changed,TResult? Function( _Filtered value)? filtered,TResult? Function( _Rated value)? rated,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Started() when started != null:
|
||||
return started(_that);case _Changed() when changed != null:
|
||||
return changed(_that);case _:
|
||||
return changed(_that);case _Filtered() when filtered != null:
|
||||
return filtered(_that);case _Rated() when rated != null:
|
||||
return rated(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -122,11 +128,13 @@ return changed(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? started,TResult Function( int index)? changed,required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? started,TResult Function( int index)? changed,TResult Function( String filter)? filtered,TResult Function( List<String> filter)? rated,required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Started() when started != null:
|
||||
return started();case _Changed() when changed != null:
|
||||
return changed(_that.index);case _:
|
||||
return changed(_that.index);case _Filtered() when filtered != null:
|
||||
return filtered(_that.filter);case _Rated() when rated != null:
|
||||
return rated(_that.filter);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -144,11 +152,13 @@ return changed(_that.index);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() started,required TResult Function( int index) changed,}) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() started,required TResult Function( int index) changed,required TResult Function( String filter) filtered,required TResult Function( List<String> filter) rated,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Started():
|
||||
return started();case _Changed():
|
||||
return changed(_that.index);case _:
|
||||
return changed(_that.index);case _Filtered():
|
||||
return filtered(_that.filter);case _Rated():
|
||||
return rated(_that.filter);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -165,11 +175,13 @@ return changed(_that.index);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? started,TResult? Function( int index)? changed,}) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? started,TResult? Function( int index)? changed,TResult? Function( String filter)? filtered,TResult? Function( List<String> filter)? rated,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Started() when started != null:
|
||||
return started();case _Changed() when changed != null:
|
||||
return changed(_that.index);case _:
|
||||
return changed(_that.index);case _Filtered() when filtered != null:
|
||||
return filtered(_that.filter);case _Rated() when rated != null:
|
||||
return rated(_that.filter);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -273,12 +285,150 @@ as int,
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Filtered implements HomeEvent {
|
||||
const _Filtered(this.filter);
|
||||
|
||||
|
||||
final String filter;
|
||||
|
||||
/// Create a copy of HomeEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$FilteredCopyWith<_Filtered> get copyWith => __$FilteredCopyWithImpl<_Filtered>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Filtered&&(identical(other.filter, filter) || other.filter == filter));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,filter);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeEvent.filtered(filter: $filter)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$FilteredCopyWith<$Res> implements $HomeEventCopyWith<$Res> {
|
||||
factory _$FilteredCopyWith(_Filtered value, $Res Function(_Filtered) _then) = __$FilteredCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String filter
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$FilteredCopyWithImpl<$Res>
|
||||
implements _$FilteredCopyWith<$Res> {
|
||||
__$FilteredCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Filtered _self;
|
||||
final $Res Function(_Filtered) _then;
|
||||
|
||||
/// Create a copy of HomeEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') $Res call({Object? filter = null,}) {
|
||||
return _then(_Filtered(
|
||||
null == filter ? _self.filter : filter // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Rated implements HomeEvent {
|
||||
const _Rated(final List<String> filter): _filter = filter;
|
||||
|
||||
|
||||
final List<String> _filter;
|
||||
List<String> get filter {
|
||||
if (_filter is EqualUnmodifiableListView) return _filter;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_filter);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of HomeEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$RatedCopyWith<_Rated> get copyWith => __$RatedCopyWithImpl<_Rated>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Rated&&const DeepCollectionEquality().equals(other._filter, _filter));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_filter));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeEvent.rated(filter: $filter)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$RatedCopyWith<$Res> implements $HomeEventCopyWith<$Res> {
|
||||
factory _$RatedCopyWith(_Rated value, $Res Function(_Rated) _then) = __$RatedCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
List<String> filter
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$RatedCopyWithImpl<$Res>
|
||||
implements _$RatedCopyWith<$Res> {
|
||||
__$RatedCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Rated _self;
|
||||
final $Res Function(_Rated) _then;
|
||||
|
||||
/// Create a copy of HomeEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') $Res call({Object? filter = null,}) {
|
||||
return _then(_Rated(
|
||||
null == filter ? _self._filter : filter // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$HomeState {
|
||||
|
||||
int get currentIndex;
|
||||
int get currentIndex; List get filters; List<String> get rating;
|
||||
/// Create a copy of HomeState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -289,16 +439,16 @@ $HomeStateCopyWith<HomeState> get copyWith => _$HomeStateCopyWithImpl<HomeState>
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&const DeepCollectionEquality().equals(other.filters, filters)&&const DeepCollectionEquality().equals(other.rating, rating));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,currentIndex);
|
||||
int get hashCode => Object.hash(runtimeType,currentIndex,const DeepCollectionEquality().hash(filters),const DeepCollectionEquality().hash(rating));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeState(currentIndex: $currentIndex)';
|
||||
return 'HomeState(currentIndex: $currentIndex, filters: $filters, rating: $rating)';
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +459,7 @@ abstract mixin class $HomeStateCopyWith<$Res> {
|
||||
factory $HomeStateCopyWith(HomeState value, $Res Function(HomeState) _then) = _$HomeStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int currentIndex
|
||||
int currentIndex, List filters, List<String> rating
|
||||
});
|
||||
|
||||
|
||||
@@ -326,10 +476,12 @@ class _$HomeStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of HomeState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? currentIndex = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? currentIndex = null,Object? filters = null,Object? rating = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
currentIndex: null == currentIndex ? _self.currentIndex : currentIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
as int,filters: null == filters ? _self.filters : filters // ignore: cast_nullable_to_non_nullable
|
||||
as List,rating: null == rating ? _self.rating : rating // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -414,10 +566,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int currentIndex)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int currentIndex, List filters, List<String> rating)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState() when $default != null:
|
||||
return $default(_that.currentIndex);case _:
|
||||
return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -435,10 +587,10 @@ return $default(_that.currentIndex);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int currentIndex) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int currentIndex, List filters, List<String> rating) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState():
|
||||
return $default(_that.currentIndex);case _:
|
||||
return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -455,10 +607,10 @@ return $default(_that.currentIndex);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int currentIndex)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int currentIndex, List filters, List<String> rating)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState() when $default != null:
|
||||
return $default(_that.currentIndex);case _:
|
||||
return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -470,10 +622,24 @@ return $default(_that.currentIndex);case _:
|
||||
|
||||
|
||||
class _HomeState implements HomeState {
|
||||
const _HomeState({this.currentIndex = 0});
|
||||
const _HomeState({this.currentIndex = 0, final List filters = const [], final List<String> rating = const []}): _filters = filters,_rating = rating;
|
||||
|
||||
|
||||
@override@JsonKey() final int currentIndex;
|
||||
final List _filters;
|
||||
@override@JsonKey() List get filters {
|
||||
if (_filters is EqualUnmodifiableListView) return _filters;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_filters);
|
||||
}
|
||||
|
||||
final List<String> _rating;
|
||||
@override@JsonKey() List<String> get rating {
|
||||
if (_rating is EqualUnmodifiableListView) return _rating;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_rating);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of HomeState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -485,16 +651,16 @@ _$HomeStateCopyWith<_HomeState> get copyWith => __$HomeStateCopyWithImpl<_HomeSt
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&const DeepCollectionEquality().equals(other._filters, _filters)&&const DeepCollectionEquality().equals(other._rating, _rating));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,currentIndex);
|
||||
int get hashCode => Object.hash(runtimeType,currentIndex,const DeepCollectionEquality().hash(_filters),const DeepCollectionEquality().hash(_rating));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeState(currentIndex: $currentIndex)';
|
||||
return 'HomeState(currentIndex: $currentIndex, filters: $filters, rating: $rating)';
|
||||
}
|
||||
|
||||
|
||||
@@ -505,7 +671,7 @@ abstract mixin class _$HomeStateCopyWith<$Res> implements $HomeStateCopyWith<$Re
|
||||
factory _$HomeStateCopyWith(_HomeState value, $Res Function(_HomeState) _then) = __$HomeStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int currentIndex
|
||||
int currentIndex, List filters, List<String> rating
|
||||
});
|
||||
|
||||
|
||||
@@ -522,10 +688,12 @@ class __$HomeStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of HomeState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? currentIndex = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? currentIndex = null,Object? filters = null,Object? rating = null,}) {
|
||||
return _then(_HomeState(
|
||||
currentIndex: null == currentIndex ? _self.currentIndex : currentIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
as int,filters: null == filters ? _self._filters : filters // ignore: cast_nullable_to_non_nullable
|
||||
as List,rating: null == rating ? _self._rating : rating // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,5 +4,7 @@ part of 'home_bloc.dart';
|
||||
class HomeEvent with _$HomeEvent {
|
||||
const factory HomeEvent.started() = _Started;
|
||||
const factory HomeEvent.changed(int index) = _Changed;
|
||||
const factory HomeEvent.filtered(String filter) = _Filtered;
|
||||
const factory HomeEvent.rated(List<String> filter) = _Rated;
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ part of 'home_bloc.dart';
|
||||
@freezed
|
||||
abstract class HomeState with _$HomeState {
|
||||
const factory HomeState({
|
||||
@Default(0) int currentIndex
|
||||
}) = _HomeState;
|
||||
@Default(0) int currentIndex,
|
||||
@Default([]) List filters,
|
||||
@Default([]) List<String> rating
|
||||
|
||||
}) = _HomeState;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'package:food_delivery_client/feature/home/presentation/pages/categories_page/categories_page.dart';
|
||||
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WDeliveryHeader extends StatelessWidget {
|
||||
@@ -13,55 +11,167 @@ class WDeliveryHeader extends StatelessWidget {
|
||||
context.loc.petSupplies,
|
||||
context.loc.more,
|
||||
];
|
||||
return Column(
|
||||
children: [
|
||||
15.verticalSpace,
|
||||
Row(
|
||||
spacing: 12,
|
||||
/*
|
||||
Siz uchun
|
||||
Eng ommabop,
|
||||
Reyting
|
||||
Yetkazib berish vaqti,
|
||||
Aksiyalar
|
||||
|
||||
|
||||
*/
|
||||
List titles = [
|
||||
'',
|
||||
context.loc.pickedForYou,
|
||||
context.loc.mostPopular,
|
||||
context.loc.rating,
|
||||
context.loc.deliveryTime,
|
||||
context.loc.deals,
|
||||
];
|
||||
return BlocBuilder<HomeBloc, HomeState>(
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
WCategoriesHeaderItem(
|
||||
onTap: () {},
|
||||
text: context.loc.american,
|
||||
imageUrl: AppImages.imgAmerican,
|
||||
),
|
||||
WCategoriesHeaderItem(
|
||||
onTap: () {},
|
||||
text: context.loc.grocery,
|
||||
imageUrl: AppImages.imgGrocery,
|
||||
Column(
|
||||
children: [
|
||||
15.verticalSpace,
|
||||
Row(
|
||||
spacing: 12,
|
||||
children: [
|
||||
WCategoriesHeaderItem(
|
||||
onTap: () {},
|
||||
text: context.loc.american,
|
||||
imageUrl: AppImages.imgAmerican,
|
||||
),
|
||||
WCategoriesHeaderItem(
|
||||
onTap: () {},
|
||||
text: context.loc.grocery,
|
||||
imageUrl: AppImages.imgGrocery,
|
||||
),
|
||||
],
|
||||
),
|
||||
8.verticalSpace,
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: _titles.length,
|
||||
padding: EdgeInsets.zero,
|
||||
scrollDirection: Axis.vertical,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
keyboardDismissBehavior:
|
||||
ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
crossAxisSpacing: 5,
|
||||
mainAxisSpacing: 10,
|
||||
mainAxisExtent: 118,
|
||||
// childAspectRatio: 78 / 100,
|
||||
),
|
||||
itemBuilder: (context, index) => WCategoryItem(
|
||||
onTap: () {
|
||||
if (index == 3) {
|
||||
CategoriesPage().show(context);
|
||||
}
|
||||
},
|
||||
imgUrl: index != 3 ? _images[index] : null,
|
||||
text: _titles[index],
|
||||
child: index == 3
|
||||
? SizedBox(
|
||||
height: 55,
|
||||
width: 55,
|
||||
child: Icon(Icons.more_horiz),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15),
|
||||
15.verticalSpace,
|
||||
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: titles.length,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
separatorBuilder: (context, index) => 10.horizontalSpace,
|
||||
itemBuilder: (context, index) => InkWell(
|
||||
onTap: () async {
|
||||
if (index != 3 && index != 0) {
|
||||
context.read<HomeBloc>().add(
|
||||
HomeEvent.filtered(titles[index]),
|
||||
);
|
||||
}
|
||||
|
||||
if (index == 3) {
|
||||
final response = await WRatingBottomSheet(
|
||||
savedRatings: state.rating ?? [],
|
||||
).show(context);
|
||||
|
||||
if (response != null) {
|
||||
context.read<HomeBloc>().add(
|
||||
HomeEvent.rated(response ?? []),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
borderRadius: AppUtils.kBorderRadius25,
|
||||
child: Ink(
|
||||
padding: EdgeInsets.zero,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.cEEEEEE,
|
||||
borderRadius: AppUtils.kBorderRadius25,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
if (index != 0 && state.filters.contains(titles[index]))
|
||||
SvgPicture.asset(
|
||||
AppIcons.icCheck1,
|
||||
).paddingOnly(right: 5),
|
||||
if (index == 0)
|
||||
Badge(
|
||||
isLabelVisible:
|
||||
state.filters.isNotEmpty ||
|
||||
state.rating.isNotEmpty,
|
||||
backgroundColor: AppColors.c34A853,
|
||||
child: SvgPicture.asset(AppIcons.icFilter),
|
||||
).paddingSymmetric(vertical: 6),
|
||||
|
||||
if (index == 3 && state.rating.isNotEmpty)
|
||||
SizedBox(
|
||||
height: 25,
|
||||
width: 25,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.c34A853,
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"${state.rating.length}",
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
).paddingOnly(right: 8),
|
||||
Text(titles[index], style: AppTextStyles.size14Medium),
|
||||
if (index == 3) Icon(Icons.keyboard_arrow_down),
|
||||
],
|
||||
).paddingSymmetric(vertical: 0, horizontal: 15),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
10.verticalSpace,
|
||||
WDivider(),
|
||||
],
|
||||
),
|
||||
8.verticalSpace,
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: _titles.length,
|
||||
padding: EdgeInsets.zero,
|
||||
scrollDirection: Axis.vertical,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
crossAxisSpacing: 5,
|
||||
mainAxisSpacing: 10,
|
||||
childAspectRatio: 78 / 100,
|
||||
),
|
||||
itemBuilder: (context, index) => WCategoryItem(
|
||||
onTap: () {
|
||||
if (index == 3) {
|
||||
CategoriesPage().show(context);
|
||||
}
|
||||
},
|
||||
imgUrl: index != 3 ? _images[index] : null,
|
||||
text: _titles[index],
|
||||
child: index == 3
|
||||
? SizedBox(height: 55, width: 55, child: Icon(Icons.more_horiz))
|
||||
: null,
|
||||
),
|
||||
),
|
||||
8.verticalSpace,
|
||||
WDivider()
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15);
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ class WHomeHeader extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<HomeBloc, HomeState>(
|
||||
builder: (context, state) {
|
||||
|
||||
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(color: AppColors.cFFFFFF),
|
||||
child: Column(
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WRatingBottomSheet extends StatefulWidget {
|
||||
const WRatingBottomSheet({super.key, required this.savedRatings});
|
||||
|
||||
final List<String> savedRatings;
|
||||
|
||||
Future<List<String>?> show(BuildContext context) {
|
||||
return showModalBottomSheet<List<String>>(
|
||||
context: context,
|
||||
builder: (context) => Wrap(children: [this]),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
State<WRatingBottomSheet> createState() => _WRatingBottomSheetState();
|
||||
}
|
||||
|
||||
class _WRatingBottomSheetState extends State<WRatingBottomSheet> {
|
||||
List<String> rating = [];
|
||||
|
||||
void updateRating(String value) {
|
||||
final list = List<String>.from(rating);
|
||||
if (list.contains(value)) {
|
||||
list.remove(value);
|
||||
setState(() {
|
||||
rating = list;
|
||||
});
|
||||
} else {
|
||||
list.add(value);
|
||||
setState(() {
|
||||
rating = list;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
rating = widget.savedRatings;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final List<String> value = [
|
||||
"${context.loc.atLeast} 4,9",
|
||||
"${context.loc.atLeast} 4,7",
|
||||
"${context.loc.atLeast} 4,5",
|
||||
];
|
||||
|
||||
return WCustomModalBottomSheet(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(context.loc.rating, style: AppTextStyles.size20Medium),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.pop(null);
|
||||
},
|
||||
icon: SvgPicture.asset(AppIcons.icClose, height: 15),
|
||||
),
|
||||
],
|
||||
),
|
||||
15.verticalSpace,
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
children: List.generate(value.length, (index) {
|
||||
return WRatingButton(
|
||||
onTap: () {
|
||||
updateRating(value[index]);
|
||||
},
|
||||
isActive: rating.contains(value[index]),
|
||||
rating: value[index],
|
||||
);
|
||||
}),
|
||||
),
|
||||
25.verticalSpace,
|
||||
AppButton(
|
||||
name: context.loc.apply,
|
||||
onPressed: () {
|
||||
context.pop(rating);
|
||||
},
|
||||
),
|
||||
20.verticalSpace,
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class WRatingButton extends StatelessWidget {
|
||||
const WRatingButton({
|
||||
super.key,
|
||||
required this.onTap,
|
||||
required this.isActive,
|
||||
required this.rating,
|
||||
});
|
||||
|
||||
final VoidCallback onTap;
|
||||
final bool isActive;
|
||||
final String rating;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
borderRadius: AppUtils.kBorderRadius25,
|
||||
onTap: onTap,
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
color: isActive
|
||||
? AppColors.c34A853
|
||||
: AppColors.cE6E6E6.newWithOpacity(.6),
|
||||
borderRadius: AppUtils.kBorderRadius25,
|
||||
),
|
||||
child: Row(
|
||||
spacing: 4,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.star, color: AppColors.cYellow),
|
||||
Text(
|
||||
rating,
|
||||
style: AppTextStyles.size14Medium.copyWith(
|
||||
color: isActive ? AppColors.cFFFFFF : AppColors.c000000,
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(vertical: 6, horizontal: 10),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -19,3 +19,4 @@ export 'package:freezed_annotation/freezed_annotation.dart';
|
||||
export 'package:shared_preferences/shared_preferences.dart';
|
||||
export 'package:cached_network_image/cached_network_image.dart';
|
||||
export 'package:carousel_slider/carousel_slider.dart';
|
||||
export 'package:flutter_bounceable/flutter_bounceable.dart';
|
||||
|
||||
Reference in New Issue
Block a user