added separate setting to change currency
This commit is contained in:
parent
f0a17af845
commit
1377a5dbdd
@ -10,9 +10,12 @@
|
|||||||
"addedToFavourite": "is added to favourites",
|
"addedToFavourite": "is added to favourites",
|
||||||
"removedFromFavourite": "is removed from favourites",
|
"removedFromFavourite": "is removed from favourites",
|
||||||
|
|
||||||
|
"cardsLoadingFailed": "Server is unreachable",
|
||||||
|
"cardsLoadingFailedSnackBar": "Failed to load crypto data",
|
||||||
"coinDataPriceChange": "for the last 24 hours",
|
"coinDataPriceChange": "for the last 24 hours",
|
||||||
|
|
||||||
"settingsLanguage": "Language",
|
"settingsLanguage": "Language",
|
||||||
|
"settingsCurrency": "Currency",
|
||||||
|
|
||||||
"navigationHome": "Home",
|
"navigationHome": "Home",
|
||||||
"navigationFavourites": "Favourites",
|
"navigationFavourites": "Favourites",
|
||||||
|
@ -10,9 +10,12 @@
|
|||||||
"addedToFavourite": "добавлен в избранное",
|
"addedToFavourite": "добавлен в избранное",
|
||||||
"removedFromFavourite": "удален из избранного",
|
"removedFromFavourite": "удален из избранного",
|
||||||
|
|
||||||
|
"cardsLoadingFailed": "Сервер недоступен",
|
||||||
|
"cardsLoadingFailedSnackBar": "Не удалось загрузить данные о криптовалюте",
|
||||||
"coinDataPriceChange": "за последние 24 часа",
|
"coinDataPriceChange": "за последние 24 часа",
|
||||||
|
|
||||||
"settingsLanguage": "Язык",
|
"settingsLanguage": "Язык",
|
||||||
|
"settingsCurrency": "Валюта",
|
||||||
|
|
||||||
"navigationHome": "Главная",
|
"navigationHome": "Главная",
|
||||||
"navigationFavourites": "Избранное",
|
"navigationFavourites": "Избранное",
|
||||||
|
@ -137,6 +137,18 @@ abstract class AppLocale {
|
|||||||
/// **'is removed from favourites'**
|
/// **'is removed from favourites'**
|
||||||
String get removedFromFavourite;
|
String get removedFromFavourite;
|
||||||
|
|
||||||
|
/// No description provided for @cardsLoadingFailed.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Server is unreachable'**
|
||||||
|
String get cardsLoadingFailed;
|
||||||
|
|
||||||
|
/// No description provided for @cardsLoadingFailedSnackBar.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Failed to load crypto data'**
|
||||||
|
String get cardsLoadingFailedSnackBar;
|
||||||
|
|
||||||
/// No description provided for @coinDataPriceChange.
|
/// No description provided for @coinDataPriceChange.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@ -149,6 +161,12 @@ abstract class AppLocale {
|
|||||||
/// **'Language'**
|
/// **'Language'**
|
||||||
String get settingsLanguage;
|
String get settingsLanguage;
|
||||||
|
|
||||||
|
/// No description provided for @settingsCurrency.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Currency'**
|
||||||
|
String get settingsCurrency;
|
||||||
|
|
||||||
/// No description provided for @navigationHome.
|
/// No description provided for @navigationHome.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
@ -27,12 +27,21 @@ class AppLocaleEn extends AppLocale {
|
|||||||
@override
|
@override
|
||||||
String get removedFromFavourite => 'is removed from favourites';
|
String get removedFromFavourite => 'is removed from favourites';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cardsLoadingFailed => 'Server is unreachable';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cardsLoadingFailedSnackBar => 'Failed to load crypto data';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get coinDataPriceChange => 'for the last 24 hours';
|
String get coinDataPriceChange => 'for the last 24 hours';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get settingsLanguage => 'Language';
|
String get settingsLanguage => 'Language';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settingsCurrency => 'Currency';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get navigationHome => 'Home';
|
String get navigationHome => 'Home';
|
||||||
|
|
||||||
|
@ -27,12 +27,21 @@ class AppLocaleRu extends AppLocale {
|
|||||||
@override
|
@override
|
||||||
String get removedFromFavourite => 'удален из избранного';
|
String get removedFromFavourite => 'удален из избранного';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cardsLoadingFailed => 'Сервер недоступен';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cardsLoadingFailedSnackBar => 'Не удалось загрузить данные о криптовалюте';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get coinDataPriceChange => 'за последние 24 часа';
|
String get coinDataPriceChange => 'за последние 24 часа';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get settingsLanguage => 'Язык';
|
String get settingsLanguage => 'Язык';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settingsCurrency => 'Валюта';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get navigationHome => 'Главная';
|
String get navigationHome => 'Главная';
|
||||||
|
|
||||||
|
@ -4,28 +4,26 @@ import 'package:flutter_android_app/domain/models/card.dart';
|
|||||||
import 'package:flutter_android_app/domain/models/home.dart';
|
import 'package:flutter_android_app/domain/models/home.dart';
|
||||||
|
|
||||||
extension CoinDataDtoToModel on CoinDataDto {
|
extension CoinDataDtoToModel on CoinDataDto {
|
||||||
CardData toDomain(AppLocale? locale) => CardData(
|
CardData toDomain(AppLocale? locale, String currencyId) => CardData(
|
||||||
id: id ?? 'UNKNOWN',
|
id: id ?? 'UNKNOWN',
|
||||||
title: name ?? 'UNKNOWN',
|
title: name ?? 'UNKNOWN',
|
||||||
imageUrl: image,
|
imageUrl: image,
|
||||||
currentPrice: _getLocalizedPrice(currentPrice, locale?.localeName),
|
currentPrice: '$currentPrice ${_getCurrencySymbol(currencyId)}',
|
||||||
priceChange: _getLocalizedPriceChange(priceChange24h, locale),
|
priceChange: _getLocalizedPriceChange(priceChange24h, locale, currencyId),
|
||||||
);
|
);
|
||||||
|
|
||||||
String _getLocalizedPrice(double? price, String? localeName) {
|
String _getCurrencySymbol(String currencyId) {
|
||||||
if (localeName == null) {
|
return switch (currencyId) {
|
||||||
return '$price \$';
|
'rub' => '₽',
|
||||||
}
|
'usd' => '\$',
|
||||||
|
|
||||||
return switch (localeName) {
|
_ => '?',
|
||||||
'ru' => '$price ₽',
|
|
||||||
_ => '$price \$',
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getLocalizedPriceChange(double? priceChange, AppLocale? locale) {
|
String _getLocalizedPriceChange(double? priceChange, AppLocale? locale, String currencyId) {
|
||||||
if (priceChange == null) {
|
if (priceChange == null) {
|
||||||
return '+${_getLocalizedPrice(0, locale?.localeName)}';
|
return '+0 ${_getCurrencySymbol(currencyId)}';
|
||||||
}
|
}
|
||||||
|
|
||||||
String retVal = '';
|
String retVal = '';
|
||||||
@ -33,15 +31,15 @@ extension CoinDataDtoToModel on CoinDataDto {
|
|||||||
retVal += '+';
|
retVal += '+';
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal += _getLocalizedPrice(priceChange, locale?.localeName);
|
retVal += '$priceChange ${_getCurrencySymbol(currencyId)}';
|
||||||
|
|
||||||
return '$retVal ${locale?.coinDataPriceChange}';
|
return '$retVal ${locale?.coinDataPriceChange}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension CoinsDtoToModel on CoinsDto {
|
extension CoinsDtoToModel on CoinsDto {
|
||||||
HomeData toDomain(AppLocale? locale, int currentPage) => HomeData(
|
HomeData toDomain(AppLocale? locale, String currencyId, int currentPage) => HomeData(
|
||||||
data: coins?.map((e) => e.toDomain(locale)).toList(),
|
data: coins?.map((e) => e.toDomain(locale, currencyId)).toList(),
|
||||||
nextPage: currentPage + 1,
|
nextPage: currentPage + 1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_bloc.dart';
|
||||||
import 'package:flutter_android_app/presentation/favourites_bloc/favourites_bloc.dart';
|
import 'package:flutter_android_app/presentation/favourites_bloc/favourites_bloc.dart';
|
||||||
import 'package:flutter_android_app/presentation/home_page/bloc/bloc.dart';
|
import 'package:flutter_android_app/presentation/home_page/bloc/bloc.dart';
|
||||||
import 'package:flutter_android_app/presentation/home_page/home_page.dart';
|
import 'package:flutter_android_app/presentation/home_page/home_page.dart';
|
||||||
@ -30,6 +31,9 @@ class _MyAppState extends State<MyApp> {
|
|||||||
return BlocProvider<FavouritesBloc>(
|
return BlocProvider<FavouritesBloc>(
|
||||||
lazy: false,
|
lazy: false,
|
||||||
create: (context) => FavouritesBloc(),
|
create: (context) => FavouritesBloc(),
|
||||||
|
child: BlocProvider<CurrencyBloc>(
|
||||||
|
lazy: false,
|
||||||
|
create: (context) => CurrencyBloc(),
|
||||||
child: BlocProvider<LocaleBloc>(
|
child: BlocProvider<LocaleBloc>(
|
||||||
lazy: false,
|
lazy: false,
|
||||||
create: (context) => LocaleBloc(Locale(_getLangCode(Platform.localeName))),
|
create: (context) => LocaleBloc(Locale(_getLangCode(Platform.localeName))),
|
||||||
@ -63,6 +67,7 @@ class _MyAppState extends State<MyApp> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
61
lib/presentation/currency_bloc/currency_bloc.dart
Normal file
61
lib/presentation/currency_bloc/currency_bloc.dart
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_events.dart';
|
||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_state.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class CurrencyBloc extends Bloc<CurrencyEvent, CurrencyState> {
|
||||||
|
static const String _currencyPrefsKey = 'local_currency';
|
||||||
|
static const List<String> _availableCurrencyIds = ['usd', 'rub'];
|
||||||
|
static final String _defaultCurrencyId = _availableCurrencyIds[0];
|
||||||
|
|
||||||
|
CurrencyBloc() : super(const CurrencyState()) {
|
||||||
|
on<LoadLocalCurrencyEvent>(_onLoadLocalCurrency);
|
||||||
|
on<ToggleLocalCurrencyEvent>(_onToggleLocalCurrency);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onLoadLocalCurrency(
|
||||||
|
LoadLocalCurrencyEvent event, Emitter<CurrencyState> emit
|
||||||
|
) async {
|
||||||
|
emit(state.copyWith(
|
||||||
|
hasCurrencyLoaded: false,
|
||||||
|
));
|
||||||
|
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final data = prefs.getString(_currencyPrefsKey);
|
||||||
|
|
||||||
|
String currencyId = '';
|
||||||
|
if (data != null) {
|
||||||
|
currencyId = data;
|
||||||
|
} else {
|
||||||
|
currencyId = _defaultCurrencyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(state.copyWith(
|
||||||
|
currencyId: currencyId,
|
||||||
|
hasCurrencyLoaded: true,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onToggleLocalCurrency(
|
||||||
|
ToggleLocalCurrencyEvent event, Emitter<CurrencyState> emit
|
||||||
|
) async {
|
||||||
|
if (state.currencyId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int oldCurrencyIdIdx = _availableCurrencyIds.indexOf(state.currencyId!);
|
||||||
|
int newCurrencyIdIdx = oldCurrencyIdIdx + 1;
|
||||||
|
if (newCurrencyIdIdx >= _availableCurrencyIds.length){
|
||||||
|
newCurrencyIdIdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
final newCurrencyId = _availableCurrencyIds[newCurrencyIdIdx];
|
||||||
|
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
prefs.setString(_currencyPrefsKey, newCurrencyId);
|
||||||
|
|
||||||
|
emit(state.copyWith(
|
||||||
|
currencyId: newCurrencyId,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
11
lib/presentation/currency_bloc/currency_events.dart
Normal file
11
lib/presentation/currency_bloc/currency_events.dart
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
abstract class CurrencyEvent {
|
||||||
|
const CurrencyEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoadLocalCurrencyEvent extends CurrencyEvent {
|
||||||
|
const LoadLocalCurrencyEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ToggleLocalCurrencyEvent extends CurrencyEvent {
|
||||||
|
const ToggleLocalCurrencyEvent();
|
||||||
|
}
|
21
lib/presentation/currency_bloc/currency_state.dart
Normal file
21
lib/presentation/currency_bloc/currency_state.dart
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import 'package:copy_with_extension/copy_with_extension.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
part 'currency_state.g.dart';
|
||||||
|
|
||||||
|
@CopyWith()
|
||||||
|
class CurrencyState extends Equatable {
|
||||||
|
final String? currencyId;
|
||||||
|
final bool hasCurrencyLoaded;
|
||||||
|
|
||||||
|
const CurrencyState({
|
||||||
|
this.currencyId,
|
||||||
|
this.hasCurrencyLoaded = false
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
currencyId,
|
||||||
|
hasCurrencyLoaded,
|
||||||
|
];
|
||||||
|
}
|
69
lib/presentation/currency_bloc/currency_state.g.dart
Normal file
69
lib/presentation/currency_bloc/currency_state.g.dart
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'currency_state.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// CopyWithGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
abstract class _$CurrencyStateCWProxy {
|
||||||
|
CurrencyState currencyId(String? currencyId);
|
||||||
|
|
||||||
|
CurrencyState hasCurrencyLoaded(bool hasCurrencyLoaded);
|
||||||
|
|
||||||
|
/// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `CurrencyState(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
|
||||||
|
///
|
||||||
|
/// Usage
|
||||||
|
/// ```dart
|
||||||
|
/// CurrencyState(...).copyWith(id: 12, name: "My name")
|
||||||
|
/// ````
|
||||||
|
CurrencyState call({
|
||||||
|
String? currencyId,
|
||||||
|
bool? hasCurrencyLoaded,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Proxy class for `copyWith` functionality. This is a callable class and can be used as follows: `instanceOfCurrencyState.copyWith(...)`. Additionally contains functions for specific fields e.g. `instanceOfCurrencyState.copyWith.fieldName(...)`
|
||||||
|
class _$CurrencyStateCWProxyImpl implements _$CurrencyStateCWProxy {
|
||||||
|
const _$CurrencyStateCWProxyImpl(this._value);
|
||||||
|
|
||||||
|
final CurrencyState _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
CurrencyState currencyId(String? currencyId) => this(currencyId: currencyId);
|
||||||
|
|
||||||
|
@override
|
||||||
|
CurrencyState hasCurrencyLoaded(bool hasCurrencyLoaded) =>
|
||||||
|
this(hasCurrencyLoaded: hasCurrencyLoaded);
|
||||||
|
|
||||||
|
@override
|
||||||
|
|
||||||
|
/// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `CurrencyState(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
|
||||||
|
///
|
||||||
|
/// Usage
|
||||||
|
/// ```dart
|
||||||
|
/// CurrencyState(...).copyWith(id: 12, name: "My name")
|
||||||
|
/// ````
|
||||||
|
CurrencyState call({
|
||||||
|
Object? currencyId = const $CopyWithPlaceholder(),
|
||||||
|
Object? hasCurrencyLoaded = const $CopyWithPlaceholder(),
|
||||||
|
}) {
|
||||||
|
return CurrencyState(
|
||||||
|
currencyId: currencyId == const $CopyWithPlaceholder()
|
||||||
|
? _value.currencyId
|
||||||
|
// ignore: cast_nullable_to_non_nullable
|
||||||
|
: currencyId as String?,
|
||||||
|
hasCurrencyLoaded: hasCurrencyLoaded == const $CopyWithPlaceholder() ||
|
||||||
|
hasCurrencyLoaded == null
|
||||||
|
? _value.hasCurrencyLoaded
|
||||||
|
// ignore: cast_nullable_to_non_nullable
|
||||||
|
: hasCurrencyLoaded as bool,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $CurrencyStateCopyWith on CurrencyState {
|
||||||
|
/// Returns a callable class that can be used as follows: `instanceOfCurrencyState.copyWith(...)` or like so:`instanceOfCurrencyState.copyWith.fieldName(...)`.
|
||||||
|
// ignore: library_private_types_in_public_api
|
||||||
|
_$CurrencyStateCWProxy get copyWith => _$CurrencyStateCWProxyImpl(this);
|
||||||
|
}
|
@ -22,7 +22,7 @@ class FavouritesBloc extends Bloc<FavouritesEvent, FavouritesState> {
|
|||||||
final data = prefs.getStringList(_likedPrefsKey);
|
final data = prefs.getStringList(_likedPrefsKey);
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
likedIds: data,
|
favouritesIds: data,
|
||||||
hasFavouritesLoaded: true,
|
hasFavouritesLoaded: true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ class FavouritesBloc extends Bloc<FavouritesEvent, FavouritesState> {
|
|||||||
prefs.setStringList(_likedPrefsKey, updatedList);
|
prefs.setStringList(_likedPrefsKey, updatedList);
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
likedIds: updatedList,
|
favouritesIds: updatedList,
|
||||||
hasFavouritesLoaded: true,
|
hasFavouritesLoaded: true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ part of 'favourites_state.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
abstract class _$FavouritesStateCWProxy {
|
abstract class _$FavouritesStateCWProxy {
|
||||||
FavouritesState likedIds(List<String>? likedIds);
|
FavouritesState favouritesIds(List<String>? favouritesIds);
|
||||||
|
|
||||||
FavouritesState hasFavouritesLoaded(bool hasFavouritesLoaded);
|
FavouritesState hasFavouritesLoaded(bool hasFavouritesLoaded);
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ abstract class _$FavouritesStateCWProxy {
|
|||||||
/// FavouritesState(...).copyWith(id: 12, name: "My name")
|
/// FavouritesState(...).copyWith(id: 12, name: "My name")
|
||||||
/// ````
|
/// ````
|
||||||
FavouritesState call({
|
FavouritesState call({
|
||||||
List<String>? likedIds,
|
List<String>? favouritesIds,
|
||||||
bool? hasFavouritesLoaded,
|
bool? hasFavouritesLoaded,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -30,7 +30,8 @@ class _$FavouritesStateCWProxyImpl implements _$FavouritesStateCWProxy {
|
|||||||
final FavouritesState _value;
|
final FavouritesState _value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FavouritesState likedIds(List<String>? likedIds) => this(likedIds: likedIds);
|
FavouritesState favouritesIds(List<String>? favouritesIds) =>
|
||||||
|
this(favouritesIds: favouritesIds);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FavouritesState hasFavouritesLoaded(bool hasFavouritesLoaded) =>
|
FavouritesState hasFavouritesLoaded(bool hasFavouritesLoaded) =>
|
||||||
@ -45,14 +46,14 @@ class _$FavouritesStateCWProxyImpl implements _$FavouritesStateCWProxy {
|
|||||||
/// FavouritesState(...).copyWith(id: 12, name: "My name")
|
/// FavouritesState(...).copyWith(id: 12, name: "My name")
|
||||||
/// ````
|
/// ````
|
||||||
FavouritesState call({
|
FavouritesState call({
|
||||||
Object? likedIds = const $CopyWithPlaceholder(),
|
Object? favouritesIds = const $CopyWithPlaceholder(),
|
||||||
Object? hasFavouritesLoaded = const $CopyWithPlaceholder(),
|
Object? hasFavouritesLoaded = const $CopyWithPlaceholder(),
|
||||||
}) {
|
}) {
|
||||||
return FavouritesState(
|
return FavouritesState(
|
||||||
favouritesIds: likedIds == const $CopyWithPlaceholder()
|
favouritesIds: favouritesIds == const $CopyWithPlaceholder()
|
||||||
? _value.favouritesIds
|
? _value.favouritesIds
|
||||||
// ignore: cast_nullable_to_non_nullable
|
// ignore: cast_nullable_to_non_nullable
|
||||||
: likedIds as List<String>?,
|
: favouritesIds as List<String>?,
|
||||||
hasFavouritesLoaded:
|
hasFavouritesLoaded:
|
||||||
hasFavouritesLoaded == const $CopyWithPlaceholder() ||
|
hasFavouritesLoaded == const $CopyWithPlaceholder() ||
|
||||||
hasFavouritesLoaded == null
|
hasFavouritesLoaded == null
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_android_app/components/extensions/context_x.dart';
|
import 'package:flutter_android_app/components/extensions/context_x.dart';
|
||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_bloc.dart';
|
||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_events.dart';
|
||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_state.dart';
|
||||||
import 'package:flutter_android_app/presentation/favourites_bloc/favourites_bloc.dart';
|
import 'package:flutter_android_app/presentation/favourites_bloc/favourites_bloc.dart';
|
||||||
import 'package:flutter_android_app/presentation/favourites_bloc/favourites_events.dart';
|
import 'package:flutter_android_app/presentation/favourites_bloc/favourites_events.dart';
|
||||||
import 'package:flutter_android_app/presentation/favourites_bloc/favourites_state.dart';
|
import 'package:flutter_android_app/presentation/favourites_bloc/favourites_state.dart';
|
||||||
@ -21,9 +24,12 @@ class FavouritesPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _FavouritesPageState extends State<FavouritesPage> {
|
class _FavouritesPageState extends State<FavouritesPage> {
|
||||||
final ScrollController scrollController = ScrollController();
|
final ScrollController scrollController = ScrollController();
|
||||||
|
|
||||||
List<String>? favouritesIds;
|
List<String>? favouritesIds;
|
||||||
bool wereIdsPreviouslyLoaded = false;
|
bool wereIdsPreviouslyLoaded = false;
|
||||||
|
|
||||||
|
String? currencyId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
@ -47,14 +53,22 @@ class _FavouritesPageState extends State<FavouritesPage> {
|
|||||||
if (state.hasFavouritesLoaded && !wereIdsPreviouslyLoaded) {
|
if (state.hasFavouritesLoaded && !wereIdsPreviouslyLoaded) {
|
||||||
wereIdsPreviouslyLoaded = true;
|
wereIdsPreviouslyLoaded = true;
|
||||||
favouritesIds = state.favouritesIds;
|
favouritesIds = state.favouritesIds;
|
||||||
|
context.read<CurrencyBloc>().add(const LoadLocalCurrencyEvent());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: BlocListener<CurrencyBloc, CurrencyState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state.hasCurrencyLoaded && state.currencyId != null) {
|
||||||
|
currencyId = state.currencyId;
|
||||||
context.read<HomeBloc>().add(HomeLoadFavouritesDataEvent(
|
context.read<HomeBloc>().add(HomeLoadFavouritesDataEvent(
|
||||||
ids: favouritesIds,
|
ids: favouritesIds,
|
||||||
locale: context.locale,
|
locale: context.locale,
|
||||||
|
currencyId: currencyId!,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(top: 12),
|
padding: const EdgeInsets.only(top: 12),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
CardsList(
|
CardsList(
|
||||||
@ -74,14 +88,11 @@ class _FavouritesPageState extends State<FavouritesPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onRefresh() {
|
Future<void> _onRefresh() {
|
||||||
//context.read<HomeBloc>().add(HomeLoadFavouritesDataEvent(
|
|
||||||
// ids: favouritesIds,
|
|
||||||
// locale: context.locale,
|
|
||||||
//));
|
|
||||||
wereIdsPreviouslyLoaded = false;
|
wereIdsPreviouslyLoaded = false;
|
||||||
context.read<FavouritesBloc>().add(const LoadFavouritesEvent());
|
context.read<FavouritesBloc>().add(const LoadFavouritesEvent());
|
||||||
return Future.value(null);
|
return Future.value(null);
|
||||||
@ -120,6 +131,7 @@ class _FavouritesPageState extends State<FavouritesPage> {
|
|||||||
ids: favouritesIds,
|
ids: favouritesIds,
|
||||||
nextPage: bloc.state.data?.nextPage,
|
nextPage: bloc.state.data?.nextPage,
|
||||||
locale: context.locale,
|
locale: context.locale,
|
||||||
|
currencyId: currencyId!,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
const int pageSize = 20;
|
const int pageSize = 20;
|
||||||
|
|
||||||
if (event.nextPage == null) {
|
if (event.nextPage == null) {
|
||||||
emit(state.copyWith(isLoading: true));
|
emit(state.copyWith(
|
||||||
|
isLoading: true,
|
||||||
|
error: 'NO_ERROR',
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
emit(state.copyWith(isPaginationLoading: true));
|
emit(state.copyWith(isPaginationLoading: true));
|
||||||
}
|
}
|
||||||
@ -28,6 +31,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
pageSize: pageSize,
|
pageSize: pageSize,
|
||||||
onError: (e) => error = e,
|
onError: (e) => error = e,
|
||||||
locale: event.locale,
|
locale: event.locale,
|
||||||
|
currencyId: event.currencyId,
|
||||||
);
|
);
|
||||||
|
|
||||||
bool isLastPage = false;
|
bool isLastPage = false;
|
||||||
@ -52,7 +56,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
const int pageSize = 10;
|
const int pageSize = 10;
|
||||||
|
|
||||||
if (event.nextPage == null) {
|
if (event.nextPage == null) {
|
||||||
emit(state.copyWith(isLoading: true));
|
emit(state.copyWith(
|
||||||
|
isLoading: true,
|
||||||
|
error: 'NO_ERROR',
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
emit(state.copyWith(isPaginationLoading: true));
|
emit(state.copyWith(isPaginationLoading: true));
|
||||||
}
|
}
|
||||||
@ -65,6 +72,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
pageSize: pageSize,
|
pageSize: pageSize,
|
||||||
onError: (e) => error = e,
|
onError: (e) => error = e,
|
||||||
locale: event.locale,
|
locale: event.locale,
|
||||||
|
currencyId: event.currencyId,
|
||||||
);
|
);
|
||||||
|
|
||||||
bool isLastPage = false;
|
bool isLastPage = false;
|
||||||
|
@ -8,14 +8,26 @@ class HomeLoadDataEvent extends HomeEvent {
|
|||||||
final String? search;
|
final String? search;
|
||||||
final int? nextPage;
|
final int? nextPage;
|
||||||
final AppLocale? locale;
|
final AppLocale? locale;
|
||||||
|
final String currencyId;
|
||||||
|
|
||||||
const HomeLoadDataEvent({this.search, this.nextPage, this.locale});
|
const HomeLoadDataEvent({
|
||||||
|
this.search,
|
||||||
|
this.nextPage,
|
||||||
|
this.locale,
|
||||||
|
required this.currencyId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class HomeLoadFavouritesDataEvent extends HomeEvent {
|
class HomeLoadFavouritesDataEvent extends HomeEvent {
|
||||||
final List<String>? ids;
|
final List<String>? ids;
|
||||||
final int? nextPage;
|
final int? nextPage;
|
||||||
final AppLocale? locale;
|
final AppLocale? locale;
|
||||||
|
final String currencyId;
|
||||||
|
|
||||||
const HomeLoadFavouritesDataEvent({this.ids, this.nextPage, this.locale});
|
const HomeLoadFavouritesDataEvent({
|
||||||
|
this.ids,
|
||||||
|
this.nextPage,
|
||||||
|
this.locale,
|
||||||
|
required this.currencyId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_android_app/components/extensions/context_x.dart';
|
||||||
import 'package:flutter_android_app/domain/models/card.dart';
|
import 'package:flutter_android_app/domain/models/card.dart';
|
||||||
import 'package:flutter_android_app/presentation/home_page/card_crypto.dart';
|
import 'package:flutter_android_app/presentation/home_page/card_crypto.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -45,17 +46,39 @@ class _CardsListState extends State<CardsList> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<HomeBloc, HomeState>(
|
return BlocListener<HomeBloc, HomeState>(
|
||||||
builder: (context, state) => state.error != null
|
listener: (context, state) {
|
||||||
? Text(
|
if (state.error != null && state.error != 'NO_ERROR') {
|
||||||
state.error ?? '',
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
style: Theme.of(context).textTheme.headlineSmall?.copyWith(color: Colors.red),
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
|
content: Text(
|
||||||
|
context.locale.cardsLoadingFailedSnackBar,
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
),
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.errorContainer,
|
||||||
|
duration: const Duration(seconds: 2),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: BlocBuilder<HomeBloc, HomeState>(
|
||||||
|
builder: (context, state) => state.error != null && state.error != 'NO_ERROR'
|
||||||
|
? Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: Text(
|
||||||
|
context.locale.cardsLoadingFailed,
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall?.copyWith(color: Theme.of(context).disabledColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: state.isLoading
|
: state.isLoading
|
||||||
? const Center(child: Padding(
|
? const Center(
|
||||||
|
child: Padding(
|
||||||
padding: EdgeInsets.only(top: 20),
|
padding: EdgeInsets.only(top: 20),
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
))
|
)
|
||||||
|
)
|
||||||
: BlocBuilder<FavouritesBloc, FavouritesState>(
|
: BlocBuilder<FavouritesBloc, FavouritesState>(
|
||||||
builder: (context, likeState) => Expanded(
|
builder: (context, likeState) => Expanded(
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
@ -79,6 +102,7 @@ class _CardsListState extends State<CardsList> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@ import 'package:flutter_android_app/presentation/home_page/cards_list.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
import '../common/svg_objects.dart';
|
import '../common/svg_objects.dart';
|
||||||
|
import '../currency_bloc/currency_bloc.dart';
|
||||||
|
import '../currency_bloc/currency_events.dart';
|
||||||
|
import '../currency_bloc/currency_state.dart';
|
||||||
import '../favourites_bloc/favourites_bloc.dart';
|
import '../favourites_bloc/favourites_bloc.dart';
|
||||||
import '../favourites_bloc/favourites_events.dart';
|
import '../favourites_bloc/favourites_events.dart';
|
||||||
import '../settings_page/settings_page.dart';
|
import '../settings_page/settings_page.dart';
|
||||||
@ -83,13 +86,14 @@ class HomePage extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
final TextEditingController searchController = TextEditingController();
|
final TextEditingController searchController = TextEditingController();
|
||||||
|
late String? currencyId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
SvgObjects.init();
|
SvgObjects.init();
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
context.read<HomeBloc>().add(HomeLoadDataEvent(locale: context.locale));
|
context.read<CurrencyBloc>().add(const LoadLocalCurrencyEvent());
|
||||||
context.read<FavouritesBloc>().add(const LoadFavouritesEvent());
|
context.read<FavouritesBloc>().add(const LoadFavouritesEvent());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -105,7 +109,17 @@ class _HomePageState extends State<HomePage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return BlocListener<CurrencyBloc, CurrencyState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state.hasCurrencyLoaded && state.currencyId != null) {
|
||||||
|
currencyId = state.currencyId;
|
||||||
|
context.read<HomeBloc>().add(HomeLoadDataEvent(
|
||||||
|
locale: context.locale,
|
||||||
|
currencyId: currencyId!,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@ -114,7 +128,11 @@ class _HomePageState extends State<HomePage> {
|
|||||||
child: SearchBar(
|
child: SearchBar(
|
||||||
controller: searchController,
|
controller: searchController,
|
||||||
onChanged: (search) {
|
onChanged: (search) {
|
||||||
Debounce.run(() => context.read<HomeBloc>().add(HomeLoadDataEvent(search: search, locale: context.locale)));
|
Debounce.run(() => context.read<HomeBloc>().add(HomeLoadDataEvent(
|
||||||
|
search: search,
|
||||||
|
locale: context.locale,
|
||||||
|
currencyId: currencyId!,
|
||||||
|
)));
|
||||||
},
|
},
|
||||||
leading: const Icon(Icons.search),
|
leading: const Icon(Icons.search),
|
||||||
trailing: [
|
trailing: [
|
||||||
@ -122,8 +140,12 @@ class _HomePageState extends State<HomePage> {
|
|||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (searchController.text.isNotEmpty) {
|
if (searchController.text.isNotEmpty) {
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
searchController.clear();
|
searchController.clear();
|
||||||
context.read<HomeBloc>().add(HomeLoadDataEvent(locale: context.locale));
|
context.read<HomeBloc>().add(HomeLoadDataEvent(
|
||||||
|
locale: context.locale,
|
||||||
|
currencyId: currencyId!,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -150,6 +172,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +190,11 @@ class _HomePageState extends State<HomePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onRefresh() {
|
Future<void> _onRefresh() {
|
||||||
context.read<HomeBloc>().add(HomeLoadDataEvent(search: searchController.text, locale: context.locale));
|
context.read<HomeBloc>().add(HomeLoadDataEvent(
|
||||||
|
search: searchController.text,
|
||||||
|
locale: context.locale,
|
||||||
|
currencyId: currencyId!,
|
||||||
|
));
|
||||||
return Future.value(null);
|
return Future.value(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +206,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _navToDetails(CardData data) {
|
void _navToDetails(CardData data) {
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
Navigator.push(context, MaterialPageRoute<void>(
|
Navigator.push(context, MaterialPageRoute<void>(
|
||||||
builder: (context) => DetailsPage(data)),
|
builder: (context) => DetailsPage(data)),
|
||||||
);
|
);
|
||||||
@ -191,6 +219,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
search: searchController.text,
|
search: searchController.text,
|
||||||
nextPage: bloc.state.data?.nextPage,
|
nextPage: bloc.state.data?.nextPage,
|
||||||
locale: context.locale,
|
locale: context.locale,
|
||||||
|
currencyId: currencyId!,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_android_app/components/extensions/context_x.dart';
|
import 'package:flutter_android_app/components/extensions/context_x.dart';
|
||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_bloc.dart';
|
||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_events.dart';
|
||||||
|
import 'package:flutter_android_app/presentation/currency_bloc/currency_state.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
import '../common/svg_objects.dart';
|
import '../common/svg_objects.dart';
|
||||||
@ -40,6 +43,34 @@ class SettingsPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${context.locale.settingsCurrency}:',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
BlocBuilder<CurrencyBloc, CurrencyState>(
|
||||||
|
builder: (context, currencyState) => GestureDetector(
|
||||||
|
onTap: () => context.read<CurrencyBloc>().add(const ToggleLocalCurrencyEvent()),
|
||||||
|
child: SizedBox.square(
|
||||||
|
dimension: 50,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 0),
|
||||||
|
child: BlocBuilder<LocaleBloc, LocaleState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return switch (currencyState.currencyId) {
|
||||||
|
'rub' => const SvgRu(),
|
||||||
|
'usd' => const SvgUs(),
|
||||||
|
_ => const SvgUs(),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -10,6 +10,7 @@ abstract class ApiInterface {
|
|||||||
int page = 1,
|
int page = 1,
|
||||||
int pageSize = 20,
|
int pageSize = 20,
|
||||||
AppLocale? locale,
|
AppLocale? locale,
|
||||||
|
String currencyId,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<HomeData?> loadDataWithIds({
|
Future<HomeData?> loadDataWithIds({
|
||||||
@ -18,5 +19,6 @@ abstract class ApiInterface {
|
|||||||
int page = 1,
|
int page = 1,
|
||||||
int pageSize = 8,
|
int pageSize = 8,
|
||||||
AppLocale? locale,
|
AppLocale? locale,
|
||||||
|
String currencyId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,12 @@ class CryptoRepository extends ApiInterface {
|
|||||||
int page = 1,
|
int page = 1,
|
||||||
int pageSize = 20,
|
int pageSize = 20,
|
||||||
AppLocale? locale,
|
AppLocale? locale,
|
||||||
|
String currencyId = '',
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, dynamic> queryParams = {
|
Map<String, dynamic> queryParams = {
|
||||||
'x_cg_demo_api_key': _apiKey,
|
'x_cg_demo_api_key': _apiKey,
|
||||||
'vs_currency': _getCurrencyName(locale?.localeName),
|
'vs_currency': currencyId,
|
||||||
'per_page': pageSize,
|
'per_page': pageSize,
|
||||||
'page': page,
|
'page': page,
|
||||||
};
|
};
|
||||||
@ -68,7 +69,7 @@ class CryptoRepository extends ApiInterface {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final CoinsDto dto = CoinsDto.fromJson(response.data as List<dynamic>);
|
final CoinsDto dto = CoinsDto.fromJson(response.data as List<dynamic>);
|
||||||
final HomeData data = dto.toDomain(locale, page);
|
final HomeData data = dto.toDomain(locale, currencyId, page);
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
@ -84,11 +85,12 @@ class CryptoRepository extends ApiInterface {
|
|||||||
int page = 1,
|
int page = 1,
|
||||||
int pageSize = 20,
|
int pageSize = 20,
|
||||||
AppLocale? locale,
|
AppLocale? locale,
|
||||||
|
String currencyId = '',
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, dynamic> queryParams = {
|
Map<String, dynamic> queryParams = {
|
||||||
'x_cg_demo_api_key': _apiKey,
|
'x_cg_demo_api_key': _apiKey,
|
||||||
'vs_currency': _getCurrencyName(locale?.localeName),
|
'vs_currency': currencyId,
|
||||||
'per_page': pageSize,
|
'per_page': pageSize,
|
||||||
'page': page,
|
'page': page,
|
||||||
};
|
};
|
||||||
@ -108,7 +110,7 @@ class CryptoRepository extends ApiInterface {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final CoinsDto dto = CoinsDto.fromJson(response.data as List<dynamic>);
|
final CoinsDto dto = CoinsDto.fromJson(response.data as List<dynamic>);
|
||||||
final HomeData data = dto.toDomain(locale, page);
|
final HomeData data = dto.toDomain(locale, currencyId, page);
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
@ -116,15 +118,4 @@ class CryptoRepository extends ApiInterface {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getCurrencyName(String? localeName) {
|
|
||||||
if (localeName == null) {
|
|
||||||
return 'usd';
|
|
||||||
}
|
|
||||||
|
|
||||||
return switch (localeName) {
|
|
||||||
'ru' => 'rub',
|
|
||||||
_ => 'usd',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ class MockRepository extends ApiInterface {
|
|||||||
int page = 1,
|
int page = 1,
|
||||||
int pageSize = 20,
|
int pageSize = 20,
|
||||||
AppLocale? locale,
|
AppLocale? locale,
|
||||||
|
String currencyId = '',
|
||||||
}) async {
|
}) async {
|
||||||
return HomeData(data: [
|
return HomeData(data: [
|
||||||
CardData(
|
CardData(
|
||||||
@ -46,6 +47,7 @@ class MockRepository extends ApiInterface {
|
|||||||
int page = 1,
|
int page = 1,
|
||||||
int pageSize = 20,
|
int pageSize = 20,
|
||||||
AppLocale? locale,
|
AppLocale? locale,
|
||||||
|
String currencyId = '',
|
||||||
}) async {
|
}) async {
|
||||||
return HomeData(data: [
|
return HomeData(data: [
|
||||||
CardData(
|
CardData(
|
||||||
|
Loading…
Reference in New Issue
Block a user