From 866d3a72ca0344e99950c5841f8428ec77be0025 Mon Sep 17 00:00:00 2001 From: Mairon Lucas Date: Tue, 30 Jul 2024 19:59:01 -0300 Subject: [PATCH] HomeBloc, intl and some mappers fixes --- lib/data/mapper/game_summary_mapper.dart | 2 +- lib/data/mapper/team_mapper.dart | 2 +- lib/data/remote/data_sources/game_rds.dart | 2 +- lib/data/remote/model/arena_rm.dart | 2 +- lib/data/remote/model/date_rm.dart | 4 +- lib/data/remote/model/game_summary_rm.dart | 2 +- lib/data/remote/model/team_rm.dart | 2 +- lib/generated/intl/messages_all.dart | 63 ++++++ lib/generated/intl/messages_en_US.dart | 33 ++++ lib/generated/l10n.dart | 128 +++++++++++++ lib/l10n/intl_en_US.arb | 8 + lib/main.dart | 9 + lib/presentation/home/home_bloc.dart | 110 +++++++++++ lib/presentation/home/home_models.dart | 19 ++ lib/presentation/home/home_page.dart | 213 ++++++++------------- pubspec.lock | 45 +++++ pubspec.yaml | 9 + test/widget_test.dart | 16 -- 18 files changed, 515 insertions(+), 154 deletions(-) create mode 100644 lib/generated/intl/messages_all.dart create mode 100644 lib/generated/intl/messages_en_US.dart create mode 100644 lib/generated/l10n.dart create mode 100644 lib/l10n/intl_en_US.arb create mode 100644 lib/presentation/home/home_bloc.dart create mode 100644 lib/presentation/home/home_models.dart diff --git a/lib/data/mapper/game_summary_mapper.dart b/lib/data/mapper/game_summary_mapper.dart index e825434..85d50d4 100644 --- a/lib/data/mapper/game_summary_mapper.dart +++ b/lib/data/mapper/game_summary_mapper.dart @@ -12,7 +12,7 @@ extension GameSummaryRMtoDM on GameSummaryRM { date: DateTime.parse(date.start), period: periods.current, gameStatus: status.toDM(), - id: id, + id: id.toString(), arenaName: arena.name, homeTeam: teams.home.toDM(), visitorTeam: teams.visitors.toDM(), diff --git a/lib/data/mapper/team_mapper.dart b/lib/data/mapper/team_mapper.dart index 14d8478..3cb846b 100644 --- a/lib/data/mapper/team_mapper.dart +++ b/lib/data/mapper/team_mapper.dart @@ -3,7 +3,7 @@ import 'package:nbapp/data/remote/model/team_rm.dart'; extension TeamMapper on TeamRM { Team toDM() => Team( - id: id, + id: id.toString(), name: name, code: code, logoUrl: logo, diff --git a/lib/data/remote/data_sources/game_rds.dart b/lib/data/remote/data_sources/game_rds.dart index ceb878f..c99a39f 100644 --- a/lib/data/remote/data_sources/game_rds.dart +++ b/lib/data/remote/data_sources/game_rds.dart @@ -11,7 +11,7 @@ class GameRDS { final Dio _dio; Future> getLiveGames() async { - final response = await _dio.get('${baseUrl}/games?live=all'); + final response = await _dio.get('${baseUrl}/games?date=2024-04-21'); if (response.statusCode == 200 || response.data == null) { final games = []; final data = response.data as Map; diff --git a/lib/data/remote/model/arena_rm.dart b/lib/data/remote/model/arena_rm.dart index 95077d6..1fa3a7e 100644 --- a/lib/data/remote/model/arena_rm.dart +++ b/lib/data/remote/model/arena_rm.dart @@ -14,7 +14,7 @@ class ArenaRM { final String city; final String name; final String state; - final String country; + final String? country; factory ArenaRM.fromJson(Map json) => _$ArenaRMFromJson(json); diff --git a/lib/data/remote/model/date_rm.dart b/lib/data/remote/model/date_rm.dart index cb90068..095ac55 100644 --- a/lib/data/remote/model/date_rm.dart +++ b/lib/data/remote/model/date_rm.dart @@ -11,8 +11,8 @@ class DateRM { ); final String start; - final String end; - final String duration; + final String? end; + final String? duration; factory DateRM.fromJson(Map json) => _$DateRMFromJson(json); } diff --git a/lib/data/remote/model/game_summary_rm.dart b/lib/data/remote/model/game_summary_rm.dart index 3a0d255..5e10864 100644 --- a/lib/data/remote/model/game_summary_rm.dart +++ b/lib/data/remote/model/game_summary_rm.dart @@ -20,7 +20,7 @@ class GameSummaryRM { this.scores, ); - final String id; + final int id; final DateRM date; final GameStatusRM status; final PeriodsRM periods; diff --git a/lib/data/remote/model/team_rm.dart b/lib/data/remote/model/team_rm.dart index 150e277..0fe1fef 100644 --- a/lib/data/remote/model/team_rm.dart +++ b/lib/data/remote/model/team_rm.dart @@ -12,7 +12,7 @@ class TeamRM { this.logo, ); - final String id; + final int id; final String name; final String nickname; final String code; diff --git a/lib/generated/intl/messages_all.dart b/lib/generated/intl/messages_all.dart new file mode 100644 index 0000000..cc8ee49 --- /dev/null +++ b/lib/generated/intl/messages_all.dart @@ -0,0 +1,63 @@ +// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart +// This is a library that looks up messages for specific locales by +// delegating to the appropriate library. + +// Ignore issues from commonly used lints in this file. +// ignore_for_file:implementation_imports, file_names, unnecessary_new +// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering +// ignore_for_file:argument_type_not_assignable, invalid_assignment +// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases +// ignore_for_file:comment_references + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:intl/intl.dart'; +import 'package:intl/message_lookup_by_library.dart'; +import 'package:intl/src/intl_helpers.dart'; + +import 'messages_en_US.dart' as messages_en_us; + +typedef Future LibraryLoader(); +Map _deferredLibraries = { + 'en_US': () => new SynchronousFuture(null), +}; + +MessageLookupByLibrary? _findExact(String localeName) { + switch (localeName) { + case 'en_US': + return messages_en_us.messages; + default: + return null; + } +} + +/// User programs should call this before using [localeName] for messages. +Future initializeMessages(String localeName) { + var availableLocale = Intl.verifiedLocale( + localeName, (locale) => _deferredLibraries[locale] != null, + onFailure: (_) => null); + if (availableLocale == null) { + return new SynchronousFuture(false); + } + var lib = _deferredLibraries[availableLocale]; + lib == null ? new SynchronousFuture(false) : lib(); + initializeInternalMessageLookup(() => new CompositeMessageLookup()); + messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor); + return new SynchronousFuture(true); +} + +bool _messagesExistFor(String locale) { + try { + return _findExact(locale) != null; + } catch (e) { + return false; + } +} + +MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) { + var actualLocale = + Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null); + if (actualLocale == null) return null; + return _findExact(actualLocale); +} diff --git a/lib/generated/intl/messages_en_US.dart b/lib/generated/intl/messages_en_US.dart new file mode 100644 index 0000000..5d50bc0 --- /dev/null +++ b/lib/generated/intl/messages_en_US.dart @@ -0,0 +1,33 @@ +// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart +// This is a library that provides messages for a en_US locale. All the +// messages from the main program should be duplicated here with the same +// function name. + +// Ignore issues from commonly used lints in this file. +// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new +// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering +// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases +// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes +// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes + +import 'package:intl/intl.dart'; +import 'package:intl/message_lookup_by_library.dart'; + +final messages = new MessageLookup(); + +typedef String MessageIfAbsent(String messageStr, List args); + +class MessageLookup extends MessageLookupByLibrary { + String get localeName => 'en_US'; + + final messages = _notInlinedMessages(_notInlinedMessages); + static Map _notInlinedMessages(_) => { + "appName": MessageLookupByLibrary.simpleMessage("NBApp"), + "emptyLiveGames": MessageLookupByLibrary.simpleMessage( + "There is no game being played right now.\nCome back when the season starts!"), + "homeOnboardingMessage": MessageLookupByLibrary.simpleMessage( + "Welcome to NBApp!\nThis is the right place to follow\nthe NBA season by live games"), + "liveGames": MessageLookupByLibrary.simpleMessage("Live Games"), + "tryAgain": MessageLookupByLibrary.simpleMessage("Try Again") + }; +} diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart new file mode 100644 index 0000000..4e87507 --- /dev/null +++ b/lib/generated/l10n.dart @@ -0,0 +1,128 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'intl/messages_all.dart'; + +// ************************************************************************** +// Generator: Flutter Intl IDE plugin +// Made by Localizely +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, lines_longer_than_80_chars +// ignore_for_file: join_return_with_assignment, prefer_final_in_for_each +// ignore_for_file: avoid_redundant_argument_values, avoid_escaping_inner_quotes + +class S { + S(); + + static S? _current; + + static S get current { + assert(_current != null, + 'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.'); + return _current!; + } + + static const AppLocalizationDelegate delegate = AppLocalizationDelegate(); + + static Future load(Locale locale) { + final name = (locale.countryCode?.isEmpty ?? false) + ? locale.languageCode + : locale.toString(); + final localeName = Intl.canonicalizedLocale(name); + return initializeMessages(localeName).then((_) { + Intl.defaultLocale = localeName; + final instance = S(); + S._current = instance; + + return instance; + }); + } + + static S of(BuildContext context) { + final instance = S.maybeOf(context); + assert(instance != null, + 'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?'); + return instance!; + } + + static S? maybeOf(BuildContext context) { + return Localizations.of(context, S); + } + + /// `NBApp` + String get appName { + return Intl.message( + 'NBApp', + name: 'appName', + desc: '', + args: [], + ); + } + + /// `Welcome to NBApp!\nThis is the right place to follow\nthe NBA season by live games` + String get homeOnboardingMessage { + return Intl.message( + 'Welcome to NBApp!\nThis is the right place to follow\nthe NBA season by live games', + name: 'homeOnboardingMessage', + desc: '', + args: [], + ); + } + + /// `Live Games` + String get liveGames { + return Intl.message( + 'Live Games', + name: 'liveGames', + desc: '', + args: [], + ); + } + + /// `Try Again` + String get tryAgain { + return Intl.message( + 'Try Again', + name: 'tryAgain', + desc: '', + args: [], + ); + } + + /// `There is no game being played right now.\nCome back when the season starts!` + String get emptyLiveGames { + return Intl.message( + 'There is no game being played right now.\nCome back when the season starts!', + name: 'emptyLiveGames', + desc: '', + args: [], + ); + } +} + +class AppLocalizationDelegate extends LocalizationsDelegate { + const AppLocalizationDelegate(); + + List get supportedLocales { + return const [ + Locale.fromSubtags(languageCode: 'en', countryCode: 'US'), + ]; + } + + @override + bool isSupported(Locale locale) => _isSupported(locale); + @override + Future load(Locale locale) => S.load(locale); + @override + bool shouldReload(AppLocalizationDelegate old) => false; + + bool _isSupported(Locale locale) { + for (var supportedLocale in supportedLocales) { + if (supportedLocale.languageCode == locale.languageCode) { + return true; + } + } + return false; + } +} diff --git a/lib/l10n/intl_en_US.arb b/lib/l10n/intl_en_US.arb new file mode 100644 index 0000000..080ec1e --- /dev/null +++ b/lib/l10n/intl_en_US.arb @@ -0,0 +1,8 @@ +{ + "@@locale": "en_US", + "appName": "NBApp", + "homeOnboardingMessage": "Welcome to NBApp!\nThis is the right place to follow\nthe NBA season by live games", + "liveGames": "Live Games", + "tryAgain": "Try Again", + "emptyLiveGames": "There is no game being played right now.\nCome back when the season starts!" +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 8868d03..7992047 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,13 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:logger/logger.dart'; import 'package:nbapp/common/di.dart'; import 'package:nbapp/common/routing/routing.dart'; import 'package:nbapp/common/theme/theme.dart'; import 'package:nbapp/common/theme/util.dart'; +import 'package:nbapp/generated/l10n.dart'; class Log { Logger logger = Logger(printer: PrettyPrinter()); @@ -46,6 +48,13 @@ class _MyApp extends StatelessWidget { return MaterialApp.router( title: 'NBApp', debugShowCheckedModeBanner: false, + localizationsDelegates: const [ + S.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: S.delegate.supportedLocales, theme: theme.dark(), routerConfig: appRoutes, ); diff --git a/lib/presentation/home/home_bloc.dart b/lib/presentation/home/home_bloc.dart new file mode 100644 index 0000000..e2a55a6 --- /dev/null +++ b/lib/presentation/home/home_bloc.dart @@ -0,0 +1,110 @@ +import 'package:bloc/bloc.dart'; +import 'package:domain/model/game_status.dart'; +import 'package:domain/model/game_summary.dart'; +import 'package:domain/model/team.dart'; +import 'package:domain/model/team_score.dart'; +import 'package:domain/use_case/get_live_games_uc.dart'; +import 'package:nbapp/presentation/home/home_models.dart'; + +class HomeBloc extends Bloc { + HomeBloc({ + required GetLiveGamesUC getLiveGamesUC, + }) : _getLiveGamesUC = getLiveGamesUC, + super(HomeLoading()) { + on(_onGetLiveGames); + + add(GetLiveGames()); + } + + final GetLiveGamesUC _getLiveGamesUC; + + Future _onGetLiveGames( + GetLiveGames event, + Emitter emitter, + ) async { + final useMock = false; + emitter(HomeLoading()); + try { + await Future.delayed(Duration(seconds: 2)); + final liveGames = await _getLiveGamesUC.getFuture(null); + emitter( + HomeSuccess( + liveGames: !useMock + ? liveGames + : [ + GameSummary( + date: DateTime.now(), + period: 1, + gameStatus: GameStatus( + isFinished: false, + isHalfTime: false, + ), + id: '123', + arenaName: 'Crypto Arena', + homeTeam: Team( + id: 'hasd', + name: 'Los Angeles Lakers', + nickName: 'Lakers', + code: 'LKR', + logoUrl: + 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Los_Angeles_Lakers_logo.svg/220px-Los_Angeles_Lakers_logo.svg.png'), + visitorTeam: Team( + id: 'hasd', + name: 'Boston Celtics', + nickName: 'Celtics', + code: 'BCS', + logoUrl: + 'https://upload.wikimedia.org/wikipedia/fr/thumb/6/65/Celtics_de_Boston_logo.svg/1024px-Celtics_de_Boston_logo.svg.png'), + homeTeamScore: TeamScore( + wins: 10, + loses: 5, + points: 27, + ), + visitorTeamScore: TeamScore( + wins: 13, + loses: 2, + points: 33, + ), + ), + GameSummary( + date: DateTime.now(), + period: 4, + gameStatus: GameStatus( + isFinished: false, + isHalfTime: false, + ), + id: '123', + arenaName: 'Crypto Arena', + homeTeam: Team( + id: 'hasd', + name: 'Atlanta Hawks', + nickName: 'Lakers', + code: 'LKR', + logoUrl: + 'https://upload.wikimedia.org/wikipedia/fr/e/ee/Hawks_2016.png'), + visitorTeam: Team( + id: 'hasd', + name: 'Boston Celtics', + nickName: 'Celtics', + code: 'BCS', + logoUrl: + 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Brooklyn_Nets_newlogo.svg/130px-Brooklyn_Nets_newlogo.svg.png'), + homeTeamScore: TeamScore( + wins: 10, + loses: 5, + points: 120, + ), + visitorTeamScore: TeamScore( + wins: 13, + loses: 2, + points: 100, + ), + ), + ], + ), + ); + } catch (e) { + emitter(HomeError()); + } + } +} diff --git a/lib/presentation/home/home_models.dart b/lib/presentation/home/home_models.dart new file mode 100644 index 0000000..61c2551 --- /dev/null +++ b/lib/presentation/home/home_models.dart @@ -0,0 +1,19 @@ +import 'package:domain/model/game_summary.dart'; + +sealed class HomeState {} + +class HomeLoading extends HomeState {} + +class HomeSuccess extends HomeState { + HomeSuccess({ + required this.liveGames, + }); + + final List liveGames; +} + +class HomeError extends HomeState {} + +sealed class HomeEvent {} + +class GetLiveGames extends HomeEvent {} diff --git a/lib/presentation/home/home_page.dart b/lib/presentation/home/home_page.dart index 26fdcee..bc5ed2f 100644 --- a/lib/presentation/home/home_page.dart +++ b/lib/presentation/home/home_page.dart @@ -1,98 +1,27 @@ -import 'package:domain/model/game_status.dart'; -import 'package:domain/model/game_summary.dart'; -import 'package:domain/model/team.dart'; -import 'package:domain/model/team_score.dart'; +import 'package:domain/use_case/get_live_games_uc.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:get_it/get_it.dart'; +import 'package:nbapp/generated/l10n.dart'; +import 'package:nbapp/presentation/home/home_bloc.dart'; +import 'package:nbapp/presentation/home/home_models.dart'; class HomePage extends StatelessWidget { HomePage({ super.key, }); - final isEmpty = false; - - final mockGames = [ - // GameSummary( - // date: DateTime.now(), - // period: 1, - // gameStatus: GameStatus( - // isFinished: false, - // isHalfTime: false, - // ), - // id: '123', - // arenaName: 'Crypto Arena', - // homeTeam: Team( - // id: 'hasd', - // name: 'Los Angeles Lakers', - // nickName: 'Lakers', - // code: 'LKR', - // logoUrl: - // 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Los_Angeles_Lakers_logo.svg/220px-Los_Angeles_Lakers_logo.svg.png'), - // visitorTeam: Team( - // id: 'hasd', - // name: 'Boston Celtics', - // nickName: 'Celtics', - // code: 'BCS', - // logoUrl: - // 'https://upload.wikimedia.org/wikipedia/fr/thumb/6/65/Celtics_de_Boston_logo.svg/1024px-Celtics_de_Boston_logo.svg.png'), - // homeTeamScore: TeamScore( - // wins: 10, - // loses: 5, - // points: 27, - // ), - // visitorTeamScore: TeamScore( - // wins: 13, - // loses: 2, - // points: 33, - // ), - // ), - // GameSummary( - // date: DateTime.now(), - // period: 4, - // gameStatus: GameStatus( - // isFinished: false, - // isHalfTime: false, - // ), - // id: '123', - // arenaName: 'Crypto Arena', - // homeTeam: Team( - // id: 'hasd', - // name: 'Atlanta Hawks', - // nickName: 'Lakers', - // code: 'LKR', - // logoUrl: - // 'https://upload.wikimedia.org/wikipedia/fr/e/ee/Hawks_2016.png'), - // visitorTeam: Team( - // id: 'hasd', - // name: 'Boston Celtics', - // nickName: 'Celtics', - // code: 'BCS', - // logoUrl: - // 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Brooklyn_Nets_newlogo.svg/130px-Brooklyn_Nets_newlogo.svg.png'), - // homeTeamScore: TeamScore( - // wins: 10, - // loses: 5, - // points: 120, - // ), - // visitorTeamScore: TeamScore( - // wins: 13, - // loses: 2, - // points: 100, - // ), - // ), - ]; - @override Widget build(BuildContext context) => Scaffold( appBar: AppBar( - title: Text('NBApp'), + title: Text(S.of(context).appName), ), body: Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: Column( children: [ Text( - 'Welcome to NBApp!\nThis is the right place to follow\nthe NBA season by live games', + S.of(context).homeOnboardingMessage, style: Theme.of(context).textTheme.bodyLarge, textAlign: TextAlign.center, ), @@ -100,7 +29,7 @@ class HomePage extends StatelessWidget { Container( width: double.infinity, child: Text( - 'Live Games', + S.of(context).liveGames, style: Theme.of(context).textTheme.bodyMedium, textAlign: TextAlign.start, ), @@ -116,61 +45,85 @@ class HomePage extends StatelessWidget { width: 1, ), ), - child: mockGames.isEmpty - ? Center( - child: Text( - 'There is no game being played right now.\nCome back when the season starts!', - textAlign: TextAlign.center, + child: BlocProvider( + create: (context) => HomeBloc( + getLiveGamesUC: GetIt.instance.get(), + ), + child: BlocBuilder( + builder: (context, state) => switch (state) { + HomeLoading() => Center( + child: CircularProgressIndicator(), ), - ) - : Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ...mockGames.map( - (game) => Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8.0), - child: Container( - decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .surfaceContainer, - borderRadius: BorderRadius.circular(8), - border: Border.all( - color: - Theme.of(context).colorScheme.outline, - width: 1, - ), - ), - padding: EdgeInsets.all(4), - child: Column( - children: [ - Image.network( - game.homeTeam.logoUrl, - height: 50, - width: 50, - ), - Text( - game.homeTeamScore.points.toString(), - ), - Text( - game.visitorTeamScore.points.toString(), - ), - Image.network( - game.visitorTeam.logoUrl, - height: 50, - width: 50, + HomeError() => Center( + child: Text( + S.of(context).tryAgain, + style: TextStyle( + color: Theme.of(context).colorScheme.error, + ), + ), + ), + HomeSuccess() => state.liveGames.isEmpty + ? Center( + child: Text( + S.of(context).emptyLiveGames, + textAlign: TextAlign.center, + ), + ) + : Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ...state.liveGames.map( + (game) => Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: Container( + decoration: BoxDecoration( + color: Theme.of(context) + .colorScheme + .surfaceContainer, + borderRadius: + BorderRadius.circular(8), + border: Border.all( + color: Theme.of(context) + .colorScheme + .outline, + width: 1, + ), + ), + padding: EdgeInsets.all(4), + child: Column( + children: [ + Image.network( + game.homeTeam.logoUrl, + height: 50, + width: 50, + ), + Text( + game.homeTeamScore.points + .toString(), + ), + Text( + game.visitorTeamScore.points + .toString(), + ), + Image.network( + game.visitorTeam.logoUrl, + height: 50, + width: 50, + ), + ], + ), ), - ], + ), ), - ), + ], ), ), - ], - ), - ), + }, + ), + ), ), ], ), diff --git a/pubspec.lock b/pubspec.lock index c719777..8c5333b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -33,6 +33,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + bloc: + dependency: "direct main" + description: + name: bloc + sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e" + url: "https://pub.dev" + source: hosted + version: "8.1.4" boolean_selector: dependency: transitive description: @@ -229,6 +237,19 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a + url: "https://pub.dev" + source: hosted + version: "8.1.6" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -311,6 +332,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" io: dependency: transitive description: @@ -415,6 +444,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" package_config: dependency: transitive description: @@ -503,6 +540,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + provider: + dependency: transitive + description: + name: provider + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + url: "https://pub.dev" + source: hosted + version: "6.1.2" pub_semver: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c32f964..0ec2201 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,6 +9,8 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter cupertino_icons: ^1.0.6 dio: ^5.4.3+1 domain: @@ -18,6 +20,9 @@ dependencies: get_it: ^7.7.0 go_router: ^14.2.0 google_fonts: ^6.2.1 + bloc: ^8.1.4 + flutter_bloc: ^8.1.6 + intl: ^0.19.0 dev_dependencies: build_runner: ^2.4.11 @@ -27,3 +32,7 @@ dev_dependencies: flutter: uses-material-design: true + +flutter_intl: + main_locale: en_US + enabled: true \ No newline at end of file diff --git a/test/widget_test.dart b/test/widget_test.dart index 01ac5d8..548d416 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -10,20 +10,4 @@ import 'package:flutter_test/flutter_test.dart'; void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); }