From e1143f71e126c6ab611536f51f4b6a4e97288f1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Tue, 28 Nov 2023 16:15:59 +0100
Subject: [PATCH] Improve loading charts data

---
 android/gradle.properties                     |   4 +-
 .../metadata/android/en-US/changelogs/33.txt  |   1 +
 .../metadata/android/fr-FR/changelogs/33.txt  |   1 +
 lib/ui/widgets/app_bar.dart                   |   2 -
 lib/ui/widgets/card_content.dart              |  16 +-
 lib/ui/widgets/cards/counts_by_day.dart       |  29 +++
 lib/ui/widgets/cards/counts_by_hour.dart      |  30 +++
 lib/ui/widgets/cards/discoveries.dart         |  29 +++
 lib/ui/widgets/cards/statistics_global.dart   |  30 +++
 lib/ui/widgets/cards/statistics_recent.dart   |  30 +++
 lib/ui/widgets/cards/timeline.dart            |  29 +++
 lib/ui/widgets/cards/top_artists.dart         |  29 +++
 lib/ui/widgets/update_data.dart               | 209 ------------------
 pubspec.yaml                                  |   2 +-
 14 files changed, 224 insertions(+), 217 deletions(-)
 create mode 100644 fastlane/metadata/android/en-US/changelogs/33.txt
 create mode 100644 fastlane/metadata/android/fr-FR/changelogs/33.txt
 delete mode 100644 lib/ui/widgets/update_data.dart

diff --git a/android/gradle.properties b/android/gradle.properties
index 4878903..9dfcc42 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.32
-app.versionCode=32
+app.versionName=0.0.33
+app.versionCode=33
diff --git a/fastlane/metadata/android/en-US/changelogs/33.txt b/fastlane/metadata/android/en-US/changelogs/33.txt
new file mode 100644
index 0000000..ed3f552
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/33.txt
@@ -0,0 +1 @@
+Improve loading charts data.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/33.txt b/fastlane/metadata/android/fr-FR/changelogs/33.txt
new file mode 100644
index 0000000..b0e4adf
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/33.txt
@@ -0,0 +1 @@
+Amélioration du chargement des données des graphiques.
diff --git a/lib/ui/widgets/app_bar.dart b/lib/ui/widgets/app_bar.dart
index 63256fb..6db981e 100644
--- a/lib/ui/widgets/app_bar.dart
+++ b/lib/ui/widgets/app_bar.dart
@@ -1,7 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:unicons/unicons.dart';
 
-import 'package:scrobbles/ui/widgets/update_data.dart';
 import 'package:scrobbles/ui/widgets/header_app.dart';
 
 class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
@@ -14,7 +13,6 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
     return AppBar(
       title: const AppHeader(text: 'app_name'),
       actions: [
-        UpdateData(),
         IconButton(
           onPressed: () {
             this.notifyParent();
diff --git a/lib/ui/widgets/card_content.dart b/lib/ui/widgets/card_content.dart
index 2694475..46d6970 100644
--- a/lib/ui/widgets/card_content.dart
+++ b/lib/ui/widgets/card_content.dart
@@ -5,11 +5,13 @@ class CardContent extends StatelessWidget {
     super.key,
     required this.title,
     required this.color,
+    required this.loader,
     required this.content,
   });
 
   final String title;
   final Color color;
+  final Widget loader;
   final Widget content;
 
   @override
@@ -29,9 +31,17 @@ class CardContent extends StatelessWidget {
           mainAxisSize: MainAxisSize.min,
           crossAxisAlignment: CrossAxisAlignment.start,
           children: <Widget>[
-            Text(
-              this.title,
-              style: Theme.of(context).primaryTextTheme.titleLarge!.apply(fontWeightDelta: 2),
+            Row(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisAlignment: MainAxisAlignment.start,
+              children: [
+                Text(
+                  this.title,
+                  style:
+                      Theme.of(context).primaryTextTheme.titleLarge!.apply(fontWeightDelta: 2),
+                ),
+                this.loader,
+              ],
             ),
             const SizedBox(height: 8),
             this.content,
diff --git a/lib/ui/widgets/cards/counts_by_day.dart b/lib/ui/widgets/cards/counts_by_day.dart
index 8110b8d..2251ffd 100644
--- a/lib/ui/widgets/cards/counts_by_day.dart
+++ b/lib/ui/widgets/cards/counts_by_day.dart
@@ -7,8 +7,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:scrobbles/config/settings.dart';
 import 'package:scrobbles/cubit/data_counts_by_day_cubit.dart';
 import 'package:scrobbles/models/counts_by_day.dart';
+import 'package:scrobbles/network/scrobbles.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
 import 'package:scrobbles/ui/widgets/charts/counts_by_day.dart';
+import 'package:scrobbles/ui/widgets/error.dart';
 
 class CardCountsByDay extends StatelessWidget {
   const CardCountsByDay({super.key});
@@ -28,6 +30,7 @@ class CardCountsByDay extends StatelessWidget {
                 'daysCount': daysCount.toString(),
               },
             ),
+            loader: updateCountsByDay(Settings.countsByDayDaysCount),
             content: ChartCountsByDay(
               chartData: CountsByDayData.fromJson(jsonDecode(state.countsByDay.toString())),
               isLoading: false,
@@ -37,4 +40,30 @@ class CardCountsByDay extends StatelessWidget {
       ),
     );
   }
+
+  Widget updateCountsByDay(int daysCount) {
+    final Widget loading = const Text('⏳');
+    final Widget done = const Text('');
+
+    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}');
+              }
+
+              BlocProvider.of<DataCountsByDayCubit>(context).setValue(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 c255143..68b28b2 100644
--- a/lib/ui/widgets/cards/counts_by_hour.dart
+++ b/lib/ui/widgets/cards/counts_by_hour.dart
@@ -7,8 +7,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:scrobbles/config/settings.dart';
 import 'package:scrobbles/cubit/data_counts_by_hour_cubit.dart';
 import 'package:scrobbles/models/counts_by_hour.dart';
+import 'package:scrobbles/network/scrobbles.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
 import 'package:scrobbles/ui/widgets/charts/counts_by_hour.dart';
+import 'package:scrobbles/ui/widgets/error.dart';
 
 class CardCountsByHour extends StatelessWidget {
   const CardCountsByHour({super.key});
@@ -28,6 +30,7 @@ class CardCountsByHour extends StatelessWidget {
                 'daysCount': daysCount.toString(),
               },
             ),
+            loader: updateCountsByHour(Settings.countsByHourDaysCount),
             content: ChartCountsByHour(
               chartData: CountsByHourData.fromJson(jsonDecode(state.countsByHour.toString())),
               isLoading: false,
@@ -37,4 +40,31 @@ class CardCountsByHour extends StatelessWidget {
       ),
     );
   }
+
+  Widget updateCountsByHour(int daysCount) {
+    final Widget loading = const Text('⏳');
+    final Widget done = const Text('');
+
+    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}');
+              }
+
+              BlocProvider.of<DataCountsByHourCubit>(context).setValue(snapshot.data);
+              return !snapshot.hasData ? loading : done;
+            },
+          );
+        },
+      ),
+    );
+  }
 }
diff --git a/lib/ui/widgets/cards/discoveries.dart b/lib/ui/widgets/cards/discoveries.dart
index ffa3e8c..891c03a 100644
--- a/lib/ui/widgets/cards/discoveries.dart
+++ b/lib/ui/widgets/cards/discoveries.dart
@@ -7,9 +7,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:scrobbles/config/settings.dart';
 import 'package:scrobbles/cubit/data_discoveries_cubit.dart';
 import 'package:scrobbles/models/discoveries.dart';
+import 'package:scrobbles/network/scrobbles.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
 import 'package:scrobbles/ui/widgets/charts/discoveries_artists.dart';
 import 'package:scrobbles/ui/widgets/charts/discoveries_tracks.dart';
+import 'package:scrobbles/ui/widgets/error.dart';
 
 class CardDiscoveries extends StatelessWidget {
   const CardDiscoveries({super.key});
@@ -31,6 +33,7 @@ class CardDiscoveries extends StatelessWidget {
                 'daysCount': daysCount.toString(),
               },
             ),
+            loader: updateDiscoveries(Settings.discoveriesDaysCount),
             content: Column(
               mainAxisSize: MainAxisSize.min,
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -63,4 +66,30 @@ class CardDiscoveries extends StatelessWidget {
       ),
     );
   }
+
+  Widget updateDiscoveries(int daysCount) {
+    final Widget loading = const Text('⏳');
+    final Widget done = const Text('');
+
+    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}');
+              }
+
+              BlocProvider.of<DataDiscoveriesCubit>(context).setValue(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 4980d5c..30d082f 100644
--- a/lib/ui/widgets/cards/statistics_global.dart
+++ b/lib/ui/widgets/cards/statistics_global.dart
@@ -6,8 +6,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:scrobbles/cubit/data_statistics_global_cubit.dart';
 import 'package:scrobbles/models/statistics_global.dart';
+import 'package:scrobbles/network/scrobbles.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
 import 'package:scrobbles/ui/widgets/content/statistics_global.dart';
+import 'package:scrobbles/ui/widgets/error.dart';
 
 class CardStatisticsGlobal extends StatelessWidget {
   const CardStatisticsGlobal({super.key});
@@ -21,6 +23,7 @@ class CardStatisticsGlobal extends StatelessWidget {
           return CardContent(
             color: Theme.of(context).colorScheme.primary,
             title: 'global_statistics'.tr(),
+            loader: updateStatisticsGlobal(),
             content: ContentStatisticsGlobal(
               statistics:
                   StatisticsGlobalData.fromJson(jsonDecode(state.statisticsGlobal.toString())),
@@ -31,4 +34,31 @@ class CardStatisticsGlobal extends StatelessWidget {
       ),
     );
   }
+
+  Widget updateStatisticsGlobal() {
+    final Widget loading = const Text('⏳');
+    final Widget done = const Text('');
+
+    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;
+            },
+          );
+        },
+      ),
+    );
+  }
 }
diff --git a/lib/ui/widgets/cards/statistics_recent.dart b/lib/ui/widgets/cards/statistics_recent.dart
index a8f83a0..951f19a 100644
--- a/lib/ui/widgets/cards/statistics_recent.dart
+++ b/lib/ui/widgets/cards/statistics_recent.dart
@@ -7,8 +7,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:scrobbles/config/settings.dart';
 import 'package:scrobbles/cubit/data_statistics_recent_cubit.dart';
 import 'package:scrobbles/models/statistics_recent.dart';
+import 'package:scrobbles/network/scrobbles.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
 import 'package:scrobbles/ui/widgets/content/statistics_recent.dart';
+import 'package:scrobbles/ui/widgets/error.dart';
 
 class CardStatisticsRecent extends StatelessWidget {
   const CardStatisticsRecent({super.key});
@@ -29,6 +31,7 @@ class CardStatisticsRecent extends StatelessWidget {
                 'daysCount': daysCount.toString(),
               },
             ),
+            loader: updateStatisticsRecent(Settings.statisticsRecentDaysCount),
             content: ContentStatisticsRecent(
               statistics: StatisticsRecentData.fromJson(
                   jsonDecode(dataState.statisticsRecent.toString())),
@@ -39,4 +42,31 @@ class CardStatisticsRecent extends StatelessWidget {
       ),
     );
   }
+
+  Widget updateStatisticsRecent(int daysCount) {
+    final Widget loading = const Text('⏳');
+    final Widget done = const Text('');
+
+    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}');
+              }
+
+              BlocProvider.of<DataStatisticsRecentCubit>(context).setValue(snapshot.data);
+              return !snapshot.hasData ? loading : done;
+            },
+          );
+        },
+      ),
+    );
+  }
 }
diff --git a/lib/ui/widgets/cards/timeline.dart b/lib/ui/widgets/cards/timeline.dart
index 92fbda8..9e61b20 100644
--- a/lib/ui/widgets/cards/timeline.dart
+++ b/lib/ui/widgets/cards/timeline.dart
@@ -7,9 +7,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:scrobbles/config/settings.dart';
 import 'package:scrobbles/cubit/data_timeline_cubit.dart';
 import 'package:scrobbles/models/timeline.dart';
+import 'package:scrobbles/network/scrobbles.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
 import 'package:scrobbles/ui/widgets/charts/timeline_counts.dart';
 import 'package:scrobbles/ui/widgets/charts/timeline_eclecticism.dart';
+import 'package:scrobbles/ui/widgets/error.dart';
 
 class CardTimeline extends StatelessWidget {
   const CardTimeline({super.key});
@@ -29,6 +31,7 @@ class CardTimeline extends StatelessWidget {
                 'daysCount': daysCount.toString(),
               },
             ),
+            loader: updateTimeline(Settings.timelineDaysCount),
             content: Stack(
               children: [
                 ChartTimelineCounts(
@@ -46,4 +49,30 @@ class CardTimeline extends StatelessWidget {
       ),
     );
   }
+
+  Widget updateTimeline(int daysCount) {
+    final Widget loading = const Text('⏳');
+    final Widget done = const Text('');
+
+    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}');
+              }
+
+              BlocProvider.of<DataTimelineCubit>(context).setValue(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 568cbd7..9488cbd 100644
--- a/lib/ui/widgets/cards/top_artists.dart
+++ b/lib/ui/widgets/cards/top_artists.dart
@@ -7,8 +7,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:scrobbles/config/settings.dart';
 import 'package:scrobbles/cubit/data_top_artists_cubit.dart';
 import 'package:scrobbles/models/topartists.dart';
+import 'package:scrobbles/network/scrobbles.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
 import 'package:scrobbles/ui/widgets/charts/top_artists.dart';
+import 'package:scrobbles/ui/widgets/error.dart';
 
 class CardTopArtists extends StatelessWidget {
   const CardTopArtists({super.key});
@@ -28,6 +30,7 @@ class CardTopArtists extends StatelessWidget {
                 'daysCount': daysCount.toString(),
               },
             ),
+            loader: updateTopArtists(Settings.topArtistsDaysCount),
             content: ChartTopArtists(
               chartData: TopArtistsData.fromJson(jsonDecode(state.topArtists.toString())),
               isLoading: false,
@@ -37,4 +40,30 @@ class CardTopArtists extends StatelessWidget {
       ),
     );
   }
+
+  Widget updateTopArtists(int daysCount) {
+    final Widget loading = const Text('⏳');
+    final Widget done = const Text('');
+
+    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}');
+              }
+
+              BlocProvider.of<DataTopArtistsCubit>(context).setValue(snapshot.data);
+              return !snapshot.hasData ? loading : done;
+            },
+          );
+        },
+      ),
+    );
+  }
 }
diff --git a/lib/ui/widgets/update_data.dart b/lib/ui/widgets/update_data.dart
deleted file mode 100644
index 9e10bdf..0000000
--- a/lib/ui/widgets/update_data.dart
+++ /dev/null
@@ -1,209 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-import 'package:scrobbles/config/settings.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/models/counts_by_day.dart';
-import 'package:scrobbles/models/counts_by_hour.dart';
-import 'package:scrobbles/models/discoveries.dart';
-import 'package:scrobbles/models/statistics_global.dart';
-import 'package:scrobbles/models/statistics_recent.dart';
-import 'package:scrobbles/models/timeline.dart';
-import 'package:scrobbles/models/topartists.dart';
-import 'package:scrobbles/network/scrobbles.dart';
-import 'package:scrobbles/ui/widgets/error.dart';
-
-class UpdateData extends StatelessWidget {
-  const UpdateData({super.key});
-
-  final Widget loading = const Text('⏳');
-  final Widget done = const Text('');
-
-  @override
-  Widget build(BuildContext context) {
-    return Padding(
-      padding: EdgeInsets.all(4),
-      child: Stack(
-        children: [
-          updateCountsByDay(Settings.countsByDayDaysCount),
-          updateCountsByHour(Settings.countsByHourDaysCount),
-          updateDiscoveries(Settings.discoveriesDaysCount),
-          updateStatisticsGlobal(),
-          updateStatisticsRecent(Settings.statisticsRecentDaysCount),
-          updateTimeline(Settings.timelineDaysCount),
-          updateTopArtists(Settings.topArtistsDaysCount),
-        ],
-      ),
-    );
-  }
-
-  Widget updateCountsByDay(int daysCount) {
-    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}');
-              }
-
-              BlocProvider.of<DataCountsByDayCubit>(context).setValue(snapshot.data);
-              return !snapshot.hasData ? loading : done;
-            },
-          );
-        },
-      ),
-    );
-  }
-
-  Widget updateCountsByHour(int daysCount) {
-    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}');
-              }
-
-              BlocProvider.of<DataCountsByHourCubit>(context).setValue(snapshot.data);
-              return !snapshot.hasData ? loading : done;
-            },
-          );
-        },
-      ),
-    );
-  }
-
-  Widget updateDiscoveries(int daysCount) {
-    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}');
-              }
-
-              BlocProvider.of<DataDiscoveriesCubit>(context).setValue(snapshot.data);
-              return !snapshot.hasData ? loading : done;
-            },
-          );
-        },
-      ),
-    );
-  }
-
-  Widget updateStatisticsGlobal() {
-    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;
-            },
-          );
-        },
-      ),
-    );
-  }
-
-  Widget updateStatisticsRecent(int daysCount) {
-    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}');
-              }
-
-              BlocProvider.of<DataStatisticsRecentCubit>(context).setValue(snapshot.data);
-              return !snapshot.hasData ? loading : done;
-            },
-          );
-        },
-      ),
-    );
-  }
-
-  Widget updateTimeline(int daysCount) {
-    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}');
-              }
-
-              BlocProvider.of<DataTimelineCubit>(context).setValue(snapshot.data);
-              return !snapshot.hasData ? loading : done;
-            },
-          );
-        },
-      ),
-    );
-  }
-
-  Widget updateTopArtists(int daysCount) {
-    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}');
-              }
-
-              BlocProvider.of<DataTopArtistsCubit>(context).setValue(snapshot.data);
-              return !snapshot.hasData ? loading : done;
-            },
-          );
-        },
-      ),
-    );
-  }
-}
diff --git a/pubspec.yaml b/pubspec.yaml
index 0740c14..edd2e48 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: Display scrobbles data and charts
 
 publish_to: 'none'
 
-version: 0.0.32+32
+version: 0.0.33+33
 
 environment:
   sdk: '^3.0.0'
-- 
GitLab