diff --git a/android/gradle.properties b/android/gradle.properties index 9dfcc4273391875fdd4899077969cf717c1ace23..4617f96d772a363abed31166843abc0fc2c01732 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true -app.versionName=0.0.33 -app.versionCode=33 +app.versionName=0.0.34 +app.versionCode=34 diff --git a/fastlane/metadata/android/en-US/changelogs/34.txt b/fastlane/metadata/android/en-US/changelogs/34.txt new file mode 100644 index 0000000000000000000000000000000000000000..821b039c451de8acdbe5f0be76eaada73c6dbce7 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/34.txt @@ -0,0 +1 @@ +Improve update data and charts. diff --git a/fastlane/metadata/android/fr-FR/changelogs/34.txt b/fastlane/metadata/android/fr-FR/changelogs/34.txt new file mode 100644 index 0000000000000000000000000000000000000000..1c7bc32181311e8c12bf472959580486cd3f70f4 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/34.txt @@ -0,0 +1 @@ +Amélioration de la mise à jour des données et des graphiques. diff --git a/lib/cubit/data_counts_by_day_cubit.dart b/lib/cubit/data_counts_by_day_cubit.dart index 032aec8f184a3d43f7d0363b57048d08dee4e78b..cb5b7805613f51bf29de8c750b4b3af3f5341e4a 100644 --- a/lib/cubit/data_counts_by_day_cubit.dart +++ b/lib/cubit/data_counts_by_day_cubit.dart @@ -17,6 +17,12 @@ class DataCountsByDayCubit extends HydratedCubit<DataCountsByDayState> { return state.countsByDay; } + void update(CountsByDayData? countsByDay) { + if (state.countsByDay.toString() != countsByDay.toString()) { + setValue(countsByDay); + } + } + void setValue(CountsByDayData? countsByDay) { emit(DataCountsByDayState( countsByDay: countsByDay, diff --git a/lib/cubit/data_counts_by_hour_cubit.dart b/lib/cubit/data_counts_by_hour_cubit.dart index 2184993239ab427e7417a420811fbc397b65451c..fae65175af6c7fa7e70380c159b0f640fdf496e4 100644 --- a/lib/cubit/data_counts_by_hour_cubit.dart +++ b/lib/cubit/data_counts_by_hour_cubit.dart @@ -17,6 +17,12 @@ class DataCountsByHourCubit extends HydratedCubit<DataCountsByHourState> { return state.countsByHour; } + void update(CountsByHourData? countsByHour) { + if (state.countsByHour.toString() != countsByHour.toString()) { + setValue(countsByHour); + } + } + void setValue(CountsByHourData? countsByHour) { emit(DataCountsByHourState( countsByHour: countsByHour, diff --git a/lib/cubit/data_discoveries_cubit.dart b/lib/cubit/data_discoveries_cubit.dart index 1b9ff976d988edd3bd1b9f85237e8465ca5ed182..f2037ab450af2f0b697721bfe30125b49b69ef6c 100644 --- a/lib/cubit/data_discoveries_cubit.dart +++ b/lib/cubit/data_discoveries_cubit.dart @@ -17,6 +17,12 @@ class DataDiscoveriesCubit extends HydratedCubit<DataDiscoveriesState> { return state.discoveries; } + void update(DiscoveriesData? discoveries) { + if (state.discoveries.toString() != discoveries.toString()) { + setValue(discoveries); + } + } + void setValue(DiscoveriesData? discoveries) { emit(DataDiscoveriesState( discoveries: discoveries, diff --git a/lib/cubit/data_statistics_global_cubit.dart b/lib/cubit/data_statistics_global_cubit.dart index 28e7e6b92790c8506cbe7064c5cd223776a96490..5962e2c024a17bdc096074bff217d79b7d486303 100644 --- a/lib/cubit/data_statistics_global_cubit.dart +++ b/lib/cubit/data_statistics_global_cubit.dart @@ -17,6 +17,12 @@ class DataStatisticsGlobalCubit extends HydratedCubit<DataStatisticsGlobalState> return state.statisticsGlobal; } + void update(StatisticsGlobalData? statisticsGlobal) { + if (state.statisticsGlobal.toString() != statisticsGlobal.toString()) { + setValue(statisticsGlobal); + } + } + void setValue(StatisticsGlobalData? statisticsGlobal) { emit(DataStatisticsGlobalState( statisticsGlobal: statisticsGlobal, diff --git a/lib/cubit/data_statistics_recent_cubit.dart b/lib/cubit/data_statistics_recent_cubit.dart index d2bc4457c434fdfac1bd6a98e3b07ee0aa8d7db1..945e038f057bfe0b4b962b855c9180e41ea6ebfa 100644 --- a/lib/cubit/data_statistics_recent_cubit.dart +++ b/lib/cubit/data_statistics_recent_cubit.dart @@ -17,6 +17,12 @@ class DataStatisticsRecentCubit extends HydratedCubit<DataStatisticsRecentState> return state.statisticsRecent; } + void update(StatisticsRecentData? statisticsRecent) { + if (state.statisticsRecent.toString() != statisticsRecent.toString()) { + setValue(statisticsRecent); + } + } + void setValue(StatisticsRecentData? statisticsRecent) { emit(DataStatisticsRecentState( statisticsRecent: statisticsRecent, diff --git a/lib/cubit/data_timeline_cubit.dart b/lib/cubit/data_timeline_cubit.dart index 597e59407f6ee53ee20d6afd7e3e98efe2fb93a2..1dadcfef9edaabb75a06e56441cd815aab615380 100644 --- a/lib/cubit/data_timeline_cubit.dart +++ b/lib/cubit/data_timeline_cubit.dart @@ -17,6 +17,12 @@ class DataTimelineCubit extends HydratedCubit<DataTimelineState> { return state.timeline; } + void update(TimelineData? timeline) { + if (state.timeline.toString() != timeline.toString()) { + setValue(timeline); + } + } + void setValue(TimelineData? timeline) { emit(DataTimelineState( timeline: timeline, diff --git a/lib/cubit/data_top_artists_cubit.dart b/lib/cubit/data_top_artists_cubit.dart index 0011c5ebaeefa1963fd7bc89d7ac6968f6794709..713f659d0a61336c4b08d07ea61e287362828162 100644 --- a/lib/cubit/data_top_artists_cubit.dart +++ b/lib/cubit/data_top_artists_cubit.dart @@ -17,6 +17,12 @@ class DataTopArtistsCubit extends HydratedCubit<DataTopArtistsState> { return state.topArtists; } + void update(TopArtistsData? topArtists) { + if (state.topArtists.toString() != topArtists.toString()) { + setValue(topArtists); + } + } + void setValue(TopArtistsData? topArtists) { emit(DataTopArtistsState( topArtists: topArtists, diff --git a/lib/main.dart b/lib/main.dart index da465fa5d11fcbbec47fef771ca38e6d50b72ff6..52ae6ef743ac43935bfb2a373427b4a32b82950e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,11 +2,20 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hive/hive.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:path_provider/path_provider.dart'; import 'package:scrobbles/config/theme.dart'; +import 'package:scrobbles/cubit/bottom_nav_cubit.dart'; +import 'package:scrobbles/cubit/data_counts_by_day_cubit.dart'; +import 'package:scrobbles/cubit/data_counts_by_hour_cubit.dart'; +import 'package:scrobbles/cubit/data_discoveries_cubit.dart'; +import 'package:scrobbles/cubit/data_statistics_global_cubit.dart'; +import 'package:scrobbles/cubit/data_statistics_recent_cubit.dart'; +import 'package:scrobbles/cubit/data_timeline_cubit.dart'; +import 'package:scrobbles/cubit/data_top_artists_cubit.dart'; import 'package:scrobbles/ui/skeleton.dart'; void main() async { @@ -38,16 +47,30 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Scrobbles', - theme: appTheme, - home: const SkeletonScreen(), + return MultiBlocProvider( + providers: [ + BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()), + BlocProvider<DataCountsByDayCubit>(create: (context) => DataCountsByDayCubit()), + BlocProvider<DataCountsByHourCubit>(create: (context) => DataCountsByHourCubit()), + BlocProvider<DataDiscoveriesCubit>(create: (context) => DataDiscoveriesCubit()), + BlocProvider<DataStatisticsGlobalCubit>( + create: (context) => DataStatisticsGlobalCubit()), + BlocProvider<DataStatisticsRecentCubit>( + create: (context) => DataStatisticsRecentCubit()), + BlocProvider<DataTimelineCubit>(create: (context) => DataTimelineCubit()), + BlocProvider<DataTopArtistsCubit>(create: (context) => DataTopArtistsCubit()), + ], + child: MaterialApp( + title: 'Scrobbles', + theme: appTheme, + home: const SkeletonScreen(), - // Localization stuff - localizationsDelegates: context.localizationDelegates, - supportedLocales: context.supportedLocales, - locale: context.locale, - debugShowCheckedModeBanner: false, + // Localization stuff + localizationsDelegates: context.localizationDelegates, + supportedLocales: context.supportedLocales, + locale: context.locale, + debugShowCheckedModeBanner: false, + ), ); } } diff --git a/lib/network/scrobbles.dart b/lib/network/scrobbles.dart index ebfca8a82d63272abfa6df82ae1a6f2c8771d840..e107c29567caad1ec35f336919d087698dadbd3c 100644 --- a/lib/network/scrobbles.dart +++ b/lib/network/scrobbles.dart @@ -18,6 +18,7 @@ class ScrobblesApi { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { + print('ok - fetched ' + url); return StatisticsGlobalData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); } else { throw Exception('Failed to get data from API.'); @@ -30,6 +31,7 @@ class ScrobblesApi { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { + print('ok - fetched ' + url); return StatisticsRecentData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); } else { throw Exception('Failed to get data from API.'); @@ -42,6 +44,7 @@ class ScrobblesApi { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { + print('ok - fetched ' + url); return TimelineData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); } else { throw Exception('Failed to get data from API.'); @@ -54,6 +57,7 @@ class ScrobblesApi { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { + print('ok - fetched ' + url); return CountsByDayData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); } else { throw Exception('Failed to get data from API.'); @@ -66,6 +70,7 @@ class ScrobblesApi { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { + print('ok - fetched ' + url); return CountsByHourData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); } else { throw Exception('Failed to get data from API.'); @@ -78,6 +83,7 @@ class ScrobblesApi { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { + print('ok - fetched ' + url); return DiscoveriesData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); } else { throw Exception('Failed to get data from API.'); @@ -90,6 +96,7 @@ class ScrobblesApi { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { + print('ok - fetched ' + url); return TopArtistsData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); } else { throw Exception('Failed to get data from API.'); diff --git a/lib/ui/screens/discoveries.dart b/lib/ui/screens/discoveries.dart index fd5f836b9b929f9867fc570ebf15228ca4eef630..d93e921af0c410a90152bfc919f762f7a2e3b6be 100644 --- a/lib/ui/screens/discoveries.dart +++ b/lib/ui/screens/discoveries.dart @@ -2,14 +2,9 @@ import 'package:flutter/material.dart'; import 'package:scrobbles/ui/widgets/cards/discoveries.dart'; -class ScreenDiscoveries extends StatefulWidget { +class ScreenDiscoveries extends StatelessWidget { const ScreenDiscoveries({super.key}); - @override - State<ScreenDiscoveries> createState() => _ScreenDiscoveriesState(); -} - -class _ScreenDiscoveriesState extends State<ScreenDiscoveries> { @override Widget build(BuildContext context) { return Material( diff --git a/lib/ui/screens/home.dart b/lib/ui/screens/home.dart index c2acc00607c83b8dec1f39f13ee7168557689c3e..7bf2d94b7ecc9c9dbe5f234645b24cf32aba474a 100644 --- a/lib/ui/screens/home.dart +++ b/lib/ui/screens/home.dart @@ -5,14 +5,9 @@ import 'package:scrobbles/ui/widgets/cards/statistics_recent.dart'; import 'package:scrobbles/ui/widgets/cards/timeline.dart'; import 'package:scrobbles/ui/widgets/cards/top_artists.dart'; -class ScreenHome extends StatefulWidget { +class ScreenHome extends StatelessWidget { const ScreenHome({super.key}); - @override - State<ScreenHome> createState() => _ScreenHomeState(); -} - -class _ScreenHomeState extends State<ScreenHome> { @override Widget build(BuildContext context) { return Material( diff --git a/lib/ui/screens/statistics.dart b/lib/ui/screens/statistics.dart index b71936138f78c8d054d70ccb5f3754da48a9c90d..6f15f7e11a59469139bf64bb95f55e9a4125ceef 100644 --- a/lib/ui/screens/statistics.dart +++ b/lib/ui/screens/statistics.dart @@ -3,14 +3,9 @@ import 'package:flutter/material.dart'; import 'package:scrobbles/ui/widgets/cards/counts_by_day.dart'; import 'package:scrobbles/ui/widgets/cards/counts_by_hour.dart'; -class ScreenStatistics extends StatefulWidget { +class ScreenStatistics extends StatelessWidget { const ScreenStatistics({super.key}); - @override - State<ScreenStatistics> createState() => _ScreenStatisticsState(); -} - -class _ScreenStatisticsState extends State<ScreenStatistics> { @override Widget build(BuildContext context) { return Material( diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart index 00d12050b2e2fed3011b139d69079500a3268281..fe99383846d2e450b605a8e70b100dd0602e1f6e 100644 --- a/lib/ui/skeleton.dart +++ b/lib/ui/skeleton.dart @@ -25,47 +25,32 @@ class _SkeletonScreenState extends State<SkeletonScreen> { const ScreenStatistics(), ]; - return BlocProvider<BottomNavCubit>( - create: (BuildContext context) => BottomNavCubit(), - child: BlocBuilder<BottomNavCubit, int>( - builder: (BuildContext context, int state) { - return Scaffold( - appBar: StandardAppBar(notifyParent: refresh), - extendBodyBehindAppBar: false, - body: Swiper( - itemCount: BlocProvider.of<BottomNavCubit>(context).pagesCount, - itemBuilder: (BuildContext context, int index) { - return AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: pageNavigation.elementAt(index), - ); - }, - pagination: SwiperPagination( - builder: SwiperCustomPagination( - builder: (BuildContext context, SwiperPluginConfig config) { - return BottomNavBar(swipeController: config.controller); - }, - ), - ), - onIndexChanged: (newPageIndex) { - BlocProvider.of<BottomNavCubit>(context).updateIndex(newPageIndex); - }, - outer: true, - loop: false, - ), - backgroundColor: Theme.of(context).colorScheme.background, - ); + return Scaffold( + appBar: StandardAppBar(notifyParent: refresh), + extendBodyBehindAppBar: false, + body: Swiper( + itemCount: BlocProvider.of<BottomNavCubit>(context).pagesCount, + itemBuilder: (BuildContext context, int index) { + return pageNavigation.elementAt(index); }, + pagination: SwiperPagination( + builder: SwiperCustomPagination( + builder: (BuildContext context, SwiperPluginConfig config) { + return BottomNavBar(swipeController: config.controller); + }, + ), + ), + onIndexChanged: (newPageIndex) { + BlocProvider.of<BottomNavCubit>(context).updateIndex(newPageIndex); + }, + outer: true, + loop: false, ), + backgroundColor: Theme.of(context).colorScheme.background, ); } refresh() { - void rebuild(Element el) { - el.markNeedsBuild(); - el.visitChildren(rebuild); - } - - (context as Element).visitChildren(rebuild); + setState(() {}); } } diff --git a/lib/ui/widgets/cards/counts_by_day.dart b/lib/ui/widgets/cards/counts_by_day.dart index 2251ffdeeb32f03f50be7a12c517a5ab10509f69..43c72498e602726a43d65e5477030af82beb40b2 100644 --- a/lib/ui/widgets/cards/counts_by_day.dart +++ b/lib/ui/widgets/cards/counts_by_day.dart @@ -19,25 +19,22 @@ class CardCountsByDay extends StatelessWidget { Widget build(BuildContext context) { final int daysCount = Settings.countsByDayDaysCount; - return BlocProvider<DataCountsByDayCubit>( - create: (BuildContext context) => DataCountsByDayCubit(), - child: BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>( - builder: (BuildContext context, DataCountsByDayState state) { - return CardContent( - color: Theme.of(context).colorScheme.surface, - title: 'counts_by_day'.tr( - namedArgs: { - 'daysCount': daysCount.toString(), - }, - ), - loader: updateCountsByDay(Settings.countsByDayDaysCount), - content: ChartCountsByDay( - chartData: CountsByDayData.fromJson(jsonDecode(state.countsByDay.toString())), - isLoading: false, - ), - ); - }, - ), + return BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>( + builder: (BuildContext context, DataCountsByDayState state) { + return CardContent( + color: Theme.of(context).colorScheme.surface, + title: 'counts_by_day'.tr( + namedArgs: { + 'daysCount': daysCount.toString(), + }, + ), + loader: updateCountsByDay(Settings.countsByDayDaysCount), + content: ChartCountsByDay( + chartData: CountsByDayData.fromJson(jsonDecode(state.countsByDay.toString())), + isLoading: false, + ), + ); + }, ); } @@ -47,23 +44,21 @@ class CardCountsByDay extends StatelessWidget { late Future<CountsByDayData> futureCountsByDay = ScrobblesApi.fetchCountsByDay(daysCount); - return BlocProvider<DataCountsByDayCubit>( - create: (BuildContext context) => DataCountsByDayCubit(), - child: BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>( - builder: (BuildContext context, DataCountsByDayState state) { - return FutureBuilder<CountsByDayData>( - future: futureCountsByDay, - builder: (context, snapshot) { - if (snapshot.hasError) { - return ShowErrorWidget(message: '${snapshot.error}'); - } + return BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>( + builder: (BuildContext context, DataCountsByDayState state) { + return FutureBuilder<CountsByDayData>( + future: futureCountsByDay, + builder: (context, snapshot) { + if (snapshot.hasError) { + return ShowErrorWidget(message: '${snapshot.error}'); + } - BlocProvider.of<DataCountsByDayCubit>(context).setValue(snapshot.data); - return !snapshot.hasData ? loading : done; - }, - ); - }, - ), + BlocProvider.of<DataCountsByDayCubit>(context).update(snapshot.data); + + return !snapshot.hasData ? loading : done; + }, + ); + }, ); } } diff --git a/lib/ui/widgets/cards/counts_by_hour.dart b/lib/ui/widgets/cards/counts_by_hour.dart index 68b28b2cdced4ba7183eeec652ff6a9cf8ea9b8c..319748b353c2fd26d23832de570044f5c1a35f88 100644 --- a/lib/ui/widgets/cards/counts_by_hour.dart +++ b/lib/ui/widgets/cards/counts_by_hour.dart @@ -19,25 +19,22 @@ class CardCountsByHour extends StatelessWidget { Widget build(BuildContext context) { final int daysCount = Settings.countsByHourDaysCount; - return BlocProvider<DataCountsByHourCubit>( - create: (BuildContext context) => DataCountsByHourCubit(), - child: BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>( - builder: (BuildContext context, DataCountsByHourState state) { - return CardContent( - color: Theme.of(context).colorScheme.surface, - title: 'counts_by_hour'.tr( - namedArgs: { - 'daysCount': daysCount.toString(), - }, - ), - loader: updateCountsByHour(Settings.countsByHourDaysCount), - content: ChartCountsByHour( - chartData: CountsByHourData.fromJson(jsonDecode(state.countsByHour.toString())), - isLoading: false, - ), - ); - }, - ), + return BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>( + builder: (BuildContext context, DataCountsByHourState state) { + return CardContent( + color: Theme.of(context).colorScheme.surface, + title: 'counts_by_hour'.tr( + namedArgs: { + 'daysCount': daysCount.toString(), + }, + ), + loader: updateCountsByHour(Settings.countsByHourDaysCount), + content: ChartCountsByHour( + chartData: CountsByHourData.fromJson(jsonDecode(state.countsByHour.toString())), + isLoading: false, + ), + ); + }, ); } @@ -48,23 +45,21 @@ class CardCountsByHour extends StatelessWidget { late Future<CountsByHourData> futureCountsByHour = ScrobblesApi.fetchCountsByHour(daysCount); - return BlocProvider<DataCountsByHourCubit>( - create: (BuildContext context) => DataCountsByHourCubit(), - child: BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>( - builder: (BuildContext context, DataCountsByHourState state) { - return FutureBuilder<CountsByHourData>( - future: futureCountsByHour, - builder: (context, snapshot) { - if (snapshot.hasError) { - return ShowErrorWidget(message: '${snapshot.error}'); - } + return BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>( + builder: (BuildContext context, DataCountsByHourState state) { + return FutureBuilder<CountsByHourData>( + future: futureCountsByHour, + builder: (context, snapshot) { + if (snapshot.hasError) { + return ShowErrorWidget(message: '${snapshot.error}'); + } - BlocProvider.of<DataCountsByHourCubit>(context).setValue(snapshot.data); - return !snapshot.hasData ? loading : done; - }, - ); - }, - ), + BlocProvider.of<DataCountsByHourCubit>(context).update(snapshot.data); + + return !snapshot.hasData ? loading : done; + }, + ); + }, ); } } diff --git a/lib/ui/widgets/cards/discoveries.dart b/lib/ui/widgets/cards/discoveries.dart index 891c03a349ba72ebcb017056644c9eecfc53494f..c2856277ad73e22a28f62823eb05f32380c3f45b 100644 --- a/lib/ui/widgets/cards/discoveries.dart +++ b/lib/ui/widgets/cards/discoveries.dart @@ -20,50 +20,45 @@ class CardDiscoveries extends StatelessWidget { Widget build(BuildContext context) { final int daysCount = Settings.discoveriesDaysCount; - return BlocProvider<DataDiscoveriesCubit>( - create: (BuildContext context) => DataDiscoveriesCubit(), - child: BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>( - builder: (BuildContext context, DataDiscoveriesState state) { - final TextTheme textTheme = Theme.of(context).primaryTextTheme; + return BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>( + builder: (BuildContext context, DataDiscoveriesState state) { + final TextTheme textTheme = Theme.of(context).primaryTextTheme; - return CardContent( - color: Theme.of(context).colorScheme.surface, - title: 'discoveries_title'.tr( - namedArgs: { - 'daysCount': daysCount.toString(), - }, - ), - loader: updateDiscoveries(Settings.discoveriesDaysCount), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'discoveries_artists_title', - style: textTheme.titleMedium!.apply(fontWeightDelta: 2), - ).tr(), - const SizedBox(height: 8), - ChartDiscoveriesArtists( - chartData: - DiscoveriesData.fromJson(jsonDecode(state.discoveries.toString())), - isLoading: false, - ), - const SizedBox(height: 8), - Text( - 'discoveries_tracks_title', - style: textTheme.titleMedium!.apply(fontWeightDelta: 2), - ).tr(), - const SizedBox(height: 8), - ChartDiscoveriesTracks( - chartData: - DiscoveriesData.fromJson(jsonDecode(state.discoveries.toString())), - isLoading: false, - ), - ], - ), - ); - }, - ), + return CardContent( + color: Theme.of(context).colorScheme.surface, + title: 'discoveries_title'.tr( + namedArgs: { + 'daysCount': daysCount.toString(), + }, + ), + loader: updateDiscoveries(Settings.discoveriesDaysCount), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'discoveries_artists_title', + style: textTheme.titleMedium!.apply(fontWeightDelta: 2), + ).tr(), + const SizedBox(height: 8), + ChartDiscoveriesArtists( + chartData: DiscoveriesData.fromJson(jsonDecode(state.discoveries.toString())), + isLoading: false, + ), + const SizedBox(height: 8), + Text( + 'discoveries_tracks_title', + style: textTheme.titleMedium!.apply(fontWeightDelta: 2), + ).tr(), + const SizedBox(height: 8), + ChartDiscoveriesTracks( + chartData: DiscoveriesData.fromJson(jsonDecode(state.discoveries.toString())), + isLoading: false, + ), + ], + ), + ); + }, ); } @@ -73,23 +68,21 @@ class CardDiscoveries extends StatelessWidget { late Future<DiscoveriesData> futureDiscoveries = ScrobblesApi.fetchDiscoveries(daysCount); - return BlocProvider<DataDiscoveriesCubit>( - create: (BuildContext context) => DataDiscoveriesCubit(), - child: BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>( - builder: (BuildContext context, DataDiscoveriesState state) { - return FutureBuilder<DiscoveriesData>( - future: futureDiscoveries, - builder: (context, snapshot) { - if (snapshot.hasError) { - return ShowErrorWidget(message: '${snapshot.error}'); - } + return BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>( + builder: (BuildContext context, DataDiscoveriesState state) { + return FutureBuilder<DiscoveriesData>( + future: futureDiscoveries, + builder: (context, snapshot) { + if (snapshot.hasError) { + return ShowErrorWidget(message: '${snapshot.error}'); + } - BlocProvider.of<DataDiscoveriesCubit>(context).setValue(snapshot.data); - return !snapshot.hasData ? loading : done; - }, - ); - }, - ), + BlocProvider.of<DataDiscoveriesCubit>(context).update(snapshot.data); + + return !snapshot.hasData ? loading : done; + }, + ); + }, ); } } diff --git a/lib/ui/widgets/cards/statistics_global.dart b/lib/ui/widgets/cards/statistics_global.dart index 30d082fdebc73584ffdd248230e9859817e210d8..bca1aa9e73813b362b4be5fc3062d9f2c5f3c1fe 100644 --- a/lib/ui/widgets/cards/statistics_global.dart +++ b/lib/ui/widgets/cards/statistics_global.dart @@ -16,22 +16,19 @@ class CardStatisticsGlobal extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocProvider<DataStatisticsGlobalCubit>( - create: (BuildContext context) => DataStatisticsGlobalCubit(), - child: BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>( - builder: (BuildContext context, DataStatisticsGlobalState state) { - return CardContent( - color: Theme.of(context).colorScheme.primary, - title: 'global_statistics'.tr(), - loader: updateStatisticsGlobal(), - content: ContentStatisticsGlobal( - statistics: - StatisticsGlobalData.fromJson(jsonDecode(state.statisticsGlobal.toString())), - isLoading: false, - ), - ); - }, - ), + return BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>( + builder: (BuildContext context, DataStatisticsGlobalState state) { + return CardContent( + color: Theme.of(context).colorScheme.primary, + title: 'global_statistics'.tr(), + loader: updateStatisticsGlobal(), + content: ContentStatisticsGlobal( + statistics: + StatisticsGlobalData.fromJson(jsonDecode(state.statisticsGlobal.toString())), + isLoading: false, + ), + ); + }, ); } @@ -42,23 +39,21 @@ class CardStatisticsGlobal extends StatelessWidget { late Future<StatisticsGlobalData> futureStatisticsGlobal = ScrobblesApi.fetchGlobalStatistics(); - return BlocProvider<DataStatisticsGlobalCubit>( - create: (BuildContext context) => DataStatisticsGlobalCubit(), - child: BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>( - builder: (BuildContext context, DataStatisticsGlobalState dataState) { - return FutureBuilder<StatisticsGlobalData>( - future: futureStatisticsGlobal, - builder: (context, snapshot) { - if (snapshot.hasError) { - return ShowErrorWidget(message: '${snapshot.error}'); - } - - BlocProvider.of<DataStatisticsGlobalCubit>(context).setValue(snapshot.data); - return !snapshot.hasData ? loading : done; - }, - ); - }, - ), + return BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>( + builder: (BuildContext context, DataStatisticsGlobalState dataState) { + return FutureBuilder<StatisticsGlobalData>( + future: futureStatisticsGlobal, + builder: (context, snapshot) { + if (snapshot.hasError) { + return ShowErrorWidget(message: '${snapshot.error}'); + } + + BlocProvider.of<DataStatisticsGlobalCubit>(context).update(snapshot.data); + + return !snapshot.hasData ? loading : done; + }, + ); + }, ); } } diff --git a/lib/ui/widgets/cards/statistics_recent.dart b/lib/ui/widgets/cards/statistics_recent.dart index 951f19ac84728e0d78aeb2bf6bd5c3d7137bf2d9..2c227fcc9b7f94bf934cf8b077dd0432b84f8250 100644 --- a/lib/ui/widgets/cards/statistics_recent.dart +++ b/lib/ui/widgets/cards/statistics_recent.dart @@ -19,27 +19,23 @@ class CardStatisticsRecent extends StatelessWidget { Widget build(BuildContext context) { final int daysCount = Settings.statisticsRecentDaysCount; - // data context - return BlocProvider<DataStatisticsRecentCubit>( - create: (BuildContext context) => DataStatisticsRecentCubit(), - child: BlocBuilder<DataStatisticsRecentCubit, DataStatisticsRecentState>( - builder: (BuildContext context, DataStatisticsRecentState dataState) { - return CardContent( - color: Theme.of(context).colorScheme.primary, - title: 'recent_statistics'.tr( - namedArgs: { - 'daysCount': daysCount.toString(), - }, - ), - loader: updateStatisticsRecent(Settings.statisticsRecentDaysCount), - content: ContentStatisticsRecent( - statistics: StatisticsRecentData.fromJson( - jsonDecode(dataState.statisticsRecent.toString())), - isLoading: false, - ), - ); - }, - ), + return BlocBuilder<DataStatisticsRecentCubit, DataStatisticsRecentState>( + builder: (BuildContext context, DataStatisticsRecentState dataState) { + return CardContent( + color: Theme.of(context).colorScheme.primary, + title: 'recent_statistics'.tr( + namedArgs: { + 'daysCount': daysCount.toString(), + }, + ), + loader: updateStatisticsRecent(Settings.statisticsRecentDaysCount), + content: ContentStatisticsRecent( + statistics: StatisticsRecentData.fromJson( + jsonDecode(dataState.statisticsRecent.toString())), + isLoading: false, + ), + ); + }, ); } @@ -50,23 +46,21 @@ class CardStatisticsRecent extends StatelessWidget { late Future<StatisticsRecentData> futureStatisticsRecent = ScrobblesApi.fetchRecentStatistics(daysCount); - return BlocProvider<DataStatisticsRecentCubit>( - create: (BuildContext context) => DataStatisticsRecentCubit(), - child: BlocBuilder<DataStatisticsRecentCubit, DataStatisticsRecentState>( - builder: (BuildContext context, DataStatisticsRecentState state) { - return FutureBuilder<StatisticsRecentData>( - future: futureStatisticsRecent, - builder: (context, snapshot) { - if (snapshot.hasError) { - return ShowErrorWidget(message: '${snapshot.error}'); - } + return BlocBuilder<DataStatisticsRecentCubit, DataStatisticsRecentState>( + builder: (BuildContext context, DataStatisticsRecentState state) { + return FutureBuilder<StatisticsRecentData>( + future: futureStatisticsRecent, + builder: (context, snapshot) { + if (snapshot.hasError) { + return ShowErrorWidget(message: '${snapshot.error}'); + } - BlocProvider.of<DataStatisticsRecentCubit>(context).setValue(snapshot.data); - return !snapshot.hasData ? loading : done; - }, - ); - }, - ), + BlocProvider.of<DataStatisticsRecentCubit>(context).update(snapshot.data); + + return !snapshot.hasData ? loading : done; + }, + ); + }, ); } } diff --git a/lib/ui/widgets/cards/timeline.dart b/lib/ui/widgets/cards/timeline.dart index 9e61b20a8ce9c787c5b8047db11cc084d1b35bf6..1ac2cf4c6404e5eadf1b3f360670794382e55239 100644 --- a/lib/ui/widgets/cards/timeline.dart +++ b/lib/ui/widgets/cards/timeline.dart @@ -20,33 +20,30 @@ class CardTimeline extends StatelessWidget { Widget build(BuildContext context) { final int daysCount = Settings.timelineDaysCount; - return BlocProvider<DataTimelineCubit>( - create: (BuildContext context) => DataTimelineCubit(), - child: BlocBuilder<DataTimelineCubit, DataTimelineState>( - builder: (BuildContext context, DataTimelineState state) { - return CardContent( - color: Theme.of(context).colorScheme.surface, - title: 'timeline_title'.tr( - namedArgs: { - 'daysCount': daysCount.toString(), - }, - ), - loader: updateTimeline(Settings.timelineDaysCount), - content: Stack( - children: [ - ChartTimelineCounts( - chartData: TimelineData.fromJson(jsonDecode(state.timeline.toString())), - isLoading: false, - ), - ChartTimelineEclecticism( - chartData: TimelineData.fromJson(jsonDecode(state.timeline.toString())), - isLoading: false, - ), - ], - ), - ); - }, - ), + return BlocBuilder<DataTimelineCubit, DataTimelineState>( + builder: (BuildContext context, DataTimelineState state) { + return CardContent( + color: Theme.of(context).colorScheme.surface, + title: 'timeline_title'.tr( + namedArgs: { + 'daysCount': daysCount.toString(), + }, + ), + loader: updateTimeline(Settings.timelineDaysCount), + content: Stack( + children: [ + ChartTimelineCounts( + chartData: TimelineData.fromJson(jsonDecode(state.timeline.toString())), + isLoading: false, + ), + ChartTimelineEclecticism( + chartData: TimelineData.fromJson(jsonDecode(state.timeline.toString())), + isLoading: false, + ), + ], + ), + ); + }, ); } @@ -56,23 +53,21 @@ class CardTimeline extends StatelessWidget { late Future<TimelineData> futureTimeline = ScrobblesApi.fetchTimeline(daysCount); - return BlocProvider<DataTimelineCubit>( - create: (BuildContext context) => DataTimelineCubit(), - child: BlocBuilder<DataTimelineCubit, DataTimelineState>( - builder: (BuildContext context, DataTimelineState state) { - return FutureBuilder<TimelineData>( - future: futureTimeline, - builder: (context, snapshot) { - if (snapshot.hasError) { - return ShowErrorWidget(message: '${snapshot.error}'); - } + return BlocBuilder<DataTimelineCubit, DataTimelineState>( + builder: (BuildContext context, DataTimelineState dataTimelineState) { + return FutureBuilder<TimelineData>( + future: futureTimeline, + builder: (context, snapshot) { + if (snapshot.hasError) { + return ShowErrorWidget(message: '${snapshot.error}'); + } - BlocProvider.of<DataTimelineCubit>(context).setValue(snapshot.data); - return !snapshot.hasData ? loading : done; - }, - ); - }, - ), + BlocProvider.of<DataTimelineCubit>(context).update(snapshot.data); + + return !snapshot.hasData ? loading : done; + }, + ); + }, ); } } diff --git a/lib/ui/widgets/cards/top_artists.dart b/lib/ui/widgets/cards/top_artists.dart index 9488cbd140630baef5f03884a759813e450147a8..176c6731413b74243f9baa41dc76726e84389d4e 100644 --- a/lib/ui/widgets/cards/top_artists.dart +++ b/lib/ui/widgets/cards/top_artists.dart @@ -19,25 +19,22 @@ class CardTopArtists extends StatelessWidget { Widget build(BuildContext context) { final int daysCount = Settings.topArtistsDaysCount; - return BlocProvider<DataTopArtistsCubit>( - create: (BuildContext context) => DataTopArtistsCubit(), - child: BlocBuilder<DataTopArtistsCubit, DataTopArtistsState>( - builder: (BuildContext context, DataTopArtistsState state) { - return CardContent( - color: Theme.of(context).colorScheme.surface, - title: 'top_artists_title'.tr( - namedArgs: { - 'daysCount': daysCount.toString(), - }, - ), - loader: updateTopArtists(Settings.topArtistsDaysCount), - content: ChartTopArtists( - chartData: TopArtistsData.fromJson(jsonDecode(state.topArtists.toString())), - isLoading: false, - ), - ); - }, - ), + return BlocBuilder<DataTopArtistsCubit, DataTopArtistsState>( + builder: (BuildContext context, DataTopArtistsState state) { + return CardContent( + color: Theme.of(context).colorScheme.surface, + title: 'top_artists_title'.tr( + namedArgs: { + 'daysCount': daysCount.toString(), + }, + ), + loader: updateTopArtists(Settings.topArtistsDaysCount), + content: ChartTopArtists( + chartData: TopArtistsData.fromJson(jsonDecode(state.topArtists.toString())), + isLoading: false, + ), + ); + }, ); } @@ -47,23 +44,21 @@ class CardTopArtists extends StatelessWidget { late Future<TopArtistsData> futureTopArtists = ScrobblesApi.fetchTopArtists(daysCount); - return BlocProvider<DataTopArtistsCubit>( - create: (BuildContext context) => DataTopArtistsCubit(), - child: BlocBuilder<DataTopArtistsCubit, DataTopArtistsState>( - builder: (BuildContext context, DataTopArtistsState state) { - return FutureBuilder<TopArtistsData>( - future: futureTopArtists, - builder: (context, snapshot) { - if (snapshot.hasError) { - return ShowErrorWidget(message: '${snapshot.error}'); - } + return BlocBuilder<DataTopArtistsCubit, DataTopArtistsState>( + builder: (BuildContext context, DataTopArtistsState state) { + return FutureBuilder<TopArtistsData>( + future: futureTopArtists, + builder: (context, snapshot) { + if (snapshot.hasError) { + return ShowErrorWidget(message: '${snapshot.error}'); + } - BlocProvider.of<DataTopArtistsCubit>(context).setValue(snapshot.data); - return !snapshot.hasData ? loading : done; - }, - ); - }, - ), + BlocProvider.of<DataTopArtistsCubit>(context).update(snapshot.data); + + return !snapshot.hasData ? loading : done; + }, + ); + }, ); } } diff --git a/lib/ui/widgets/charts/counts_by_day.dart b/lib/ui/widgets/charts/counts_by_day.dart index 19492b4a201c9d5b25aa90c6b89c3921c6fa2b28..9fb37210e2da3622408add7c9afe11fc0c7c7f31 100644 --- a/lib/ui/widgets/charts/counts_by_day.dart +++ b/lib/ui/widgets/charts/counts_by_day.dart @@ -17,6 +17,12 @@ class ChartCountsByDay extends CustomBarChart { @override Widget build(BuildContext context) { + if (this.chartData.data.keys.length == 0) { + return SizedBox( + height: this.chartHeight, + ); + } + return Container( height: this.chartHeight, child: this.isLoading diff --git a/lib/ui/widgets/charts/counts_by_hour.dart b/lib/ui/widgets/charts/counts_by_hour.dart index 79c8167f87e2ff45e96c14cfd10743a88e4d79ff..de66a75080a8d4de9835d930f72b351516da485c 100644 --- a/lib/ui/widgets/charts/counts_by_hour.dart +++ b/lib/ui/widgets/charts/counts_by_hour.dart @@ -17,6 +17,12 @@ class ChartCountsByHour extends CustomBarChart { @override Widget build(BuildContext context) { + if (this.chartData.data.keys.length == 0) { + return SizedBox( + height: this.chartHeight, + ); + } + return Container( height: this.chartHeight, child: this.isLoading diff --git a/lib/ui/widgets/charts/discoveries_artists.dart b/lib/ui/widgets/charts/discoveries_artists.dart index d441c275cf80edbc67a28fd60eb95de7f525a044..96a5a7838e0c3bec06ca21391ceb30980e1eccbe 100644 --- a/lib/ui/widgets/charts/discoveries_artists.dart +++ b/lib/ui/widgets/charts/discoveries_artists.dart @@ -14,6 +14,12 @@ class ChartDiscoveriesArtists extends CustomBarChart { @override Widget build(BuildContext context) { + if (this.chartData.data.keys.length == 0) { + return SizedBox( + height: this.chartHeight, + ); + } + return Container( height: this.chartHeight, child: this.isLoading diff --git a/lib/ui/widgets/charts/discoveries_tracks.dart b/lib/ui/widgets/charts/discoveries_tracks.dart index 343c02d29f62b7691d6167773f1465c8d2be27d7..44d9d6fc6823b7ca449f49458a4cd7bb6f99b909 100644 --- a/lib/ui/widgets/charts/discoveries_tracks.dart +++ b/lib/ui/widgets/charts/discoveries_tracks.dart @@ -14,6 +14,12 @@ class ChartDiscoveriesTracks extends CustomBarChart { @override Widget build(BuildContext context) { + if (this.chartData.data.keys.length == 0) { + return SizedBox( + height: this.chartHeight, + ); + } + return Container( height: this.chartHeight, child: this.isLoading diff --git a/lib/ui/widgets/charts/timeline_counts.dart b/lib/ui/widgets/charts/timeline_counts.dart index 8e5fec0b82c53f51065acb6e55fe813fab104a3f..5b7399f46ea99868ac75248fa9be38dd383a504b 100644 --- a/lib/ui/widgets/charts/timeline_counts.dart +++ b/lib/ui/widgets/charts/timeline_counts.dart @@ -15,6 +15,12 @@ class ChartTimelineCounts extends CustomBarChart { @override Widget build(BuildContext context) { + if (this.chartData.data.keys.length == 0) { + return SizedBox( + height: this.chartHeight, + ); + } + return Container( height: this.chartHeight, child: this.isLoading diff --git a/lib/ui/widgets/charts/timeline_eclecticism.dart b/lib/ui/widgets/charts/timeline_eclecticism.dart index f5ddd96261d04c600a75e6516991a6fa51f40a70..dea2a0d9d1c6ac91384b9a68bc5955b334caf4ac 100644 --- a/lib/ui/widgets/charts/timeline_eclecticism.dart +++ b/lib/ui/widgets/charts/timeline_eclecticism.dart @@ -16,6 +16,12 @@ class ChartTimelineEclecticism extends CustomLineChart { Widget build(BuildContext context) { final horizontalScale = getHorizontalScale(); + if (this.chartData.data.keys.length == 0) { + return SizedBox( + height: this.chartHeight, + ); + } + return Container( height: this.chartHeight, child: this.isLoading diff --git a/pubspec.yaml b/pubspec.yaml index edd2e489336ed3819133f6e8c2a06640d889be30..8c8dc91094df1092d75a2305961405c996af1fae 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: Display scrobbles data and charts publish_to: 'none' -version: 0.0.33+33 +version: 0.0.34+34 environment: sdk: '^3.0.0'