Skip to content
Snippets Groups Projects
Commit 4a2d8639 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Improve refresh cards data and charts

parent 28142ac4
No related branches found
No related tags found
1 merge request!36Resolve "Improve refresh data and charts"
Pipeline #4652 passed
This commit is part of merge request !36. Comments created here will be created in the context of that merge request.
Showing
with 249 additions and 227 deletions
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
app.versionName=0.0.33 app.versionName=0.0.34
app.versionCode=33 app.versionCode=34
Improve update data and charts.
Amélioration de la mise à jour des données et des graphiques.
...@@ -17,6 +17,12 @@ class DataCountsByDayCubit extends HydratedCubit<DataCountsByDayState> { ...@@ -17,6 +17,12 @@ class DataCountsByDayCubit extends HydratedCubit<DataCountsByDayState> {
return state.countsByDay; return state.countsByDay;
} }
void update(CountsByDayData? countsByDay) {
if (state.countsByDay.toString() != countsByDay.toString()) {
setValue(countsByDay);
}
}
void setValue(CountsByDayData? countsByDay) { void setValue(CountsByDayData? countsByDay) {
emit(DataCountsByDayState( emit(DataCountsByDayState(
countsByDay: countsByDay, countsByDay: countsByDay,
......
...@@ -17,6 +17,12 @@ class DataCountsByHourCubit extends HydratedCubit<DataCountsByHourState> { ...@@ -17,6 +17,12 @@ class DataCountsByHourCubit extends HydratedCubit<DataCountsByHourState> {
return state.countsByHour; return state.countsByHour;
} }
void update(CountsByHourData? countsByHour) {
if (state.countsByHour.toString() != countsByHour.toString()) {
setValue(countsByHour);
}
}
void setValue(CountsByHourData? countsByHour) { void setValue(CountsByHourData? countsByHour) {
emit(DataCountsByHourState( emit(DataCountsByHourState(
countsByHour: countsByHour, countsByHour: countsByHour,
......
...@@ -17,6 +17,12 @@ class DataDiscoveriesCubit extends HydratedCubit<DataDiscoveriesState> { ...@@ -17,6 +17,12 @@ class DataDiscoveriesCubit extends HydratedCubit<DataDiscoveriesState> {
return state.discoveries; return state.discoveries;
} }
void update(DiscoveriesData? discoveries) {
if (state.discoveries.toString() != discoveries.toString()) {
setValue(discoveries);
}
}
void setValue(DiscoveriesData? discoveries) { void setValue(DiscoveriesData? discoveries) {
emit(DataDiscoveriesState( emit(DataDiscoveriesState(
discoveries: discoveries, discoveries: discoveries,
......
...@@ -17,6 +17,12 @@ class DataStatisticsGlobalCubit extends HydratedCubit<DataStatisticsGlobalState> ...@@ -17,6 +17,12 @@ class DataStatisticsGlobalCubit extends HydratedCubit<DataStatisticsGlobalState>
return state.statisticsGlobal; return state.statisticsGlobal;
} }
void update(StatisticsGlobalData? statisticsGlobal) {
if (state.statisticsGlobal.toString() != statisticsGlobal.toString()) {
setValue(statisticsGlobal);
}
}
void setValue(StatisticsGlobalData? statisticsGlobal) { void setValue(StatisticsGlobalData? statisticsGlobal) {
emit(DataStatisticsGlobalState( emit(DataStatisticsGlobalState(
statisticsGlobal: statisticsGlobal, statisticsGlobal: statisticsGlobal,
......
...@@ -17,6 +17,12 @@ class DataStatisticsRecentCubit extends HydratedCubit<DataStatisticsRecentState> ...@@ -17,6 +17,12 @@ class DataStatisticsRecentCubit extends HydratedCubit<DataStatisticsRecentState>
return state.statisticsRecent; return state.statisticsRecent;
} }
void update(StatisticsRecentData? statisticsRecent) {
if (state.statisticsRecent.toString() != statisticsRecent.toString()) {
setValue(statisticsRecent);
}
}
void setValue(StatisticsRecentData? statisticsRecent) { void setValue(StatisticsRecentData? statisticsRecent) {
emit(DataStatisticsRecentState( emit(DataStatisticsRecentState(
statisticsRecent: statisticsRecent, statisticsRecent: statisticsRecent,
......
...@@ -17,6 +17,12 @@ class DataTimelineCubit extends HydratedCubit<DataTimelineState> { ...@@ -17,6 +17,12 @@ class DataTimelineCubit extends HydratedCubit<DataTimelineState> {
return state.timeline; return state.timeline;
} }
void update(TimelineData? timeline) {
if (state.timeline.toString() != timeline.toString()) {
setValue(timeline);
}
}
void setValue(TimelineData? timeline) { void setValue(TimelineData? timeline) {
emit(DataTimelineState( emit(DataTimelineState(
timeline: timeline, timeline: timeline,
......
...@@ -17,6 +17,12 @@ class DataTopArtistsCubit extends HydratedCubit<DataTopArtistsState> { ...@@ -17,6 +17,12 @@ class DataTopArtistsCubit extends HydratedCubit<DataTopArtistsState> {
return state.topArtists; return state.topArtists;
} }
void update(TopArtistsData? topArtists) {
if (state.topArtists.toString() != topArtists.toString()) {
setValue(topArtists);
}
}
void setValue(TopArtistsData? topArtists) { void setValue(TopArtistsData? topArtists) {
emit(DataTopArtistsState( emit(DataTopArtistsState(
topArtists: topArtists, topArtists: topArtists,
......
...@@ -2,11 +2,20 @@ import 'dart:io'; ...@@ -2,11 +2,20 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:scrobbles/config/theme.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'; import 'package:scrobbles/ui/skeleton.dart';
void main() async { void main() async {
...@@ -38,16 +47,30 @@ class MyApp extends StatelessWidget { ...@@ -38,16 +47,30 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MultiBlocProvider(
title: 'Scrobbles', providers: [
theme: appTheme, BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
home: const SkeletonScreen(), 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 // Localization stuff
localizationsDelegates: context.localizationDelegates, localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales, supportedLocales: context.supportedLocales,
locale: context.locale, locale: context.locale,
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
),
); );
} }
} }
...@@ -18,6 +18,7 @@ class ScrobblesApi { ...@@ -18,6 +18,7 @@ class ScrobblesApi {
final response = await http.get(Uri.parse(url)); final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) { if (response.statusCode == 200) {
print('ok - fetched ' + url);
return StatisticsGlobalData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); return StatisticsGlobalData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else { } else {
throw Exception('Failed to get data from API.'); throw Exception('Failed to get data from API.');
...@@ -30,6 +31,7 @@ class ScrobblesApi { ...@@ -30,6 +31,7 @@ class ScrobblesApi {
final response = await http.get(Uri.parse(url)); final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) { if (response.statusCode == 200) {
print('ok - fetched ' + url);
return StatisticsRecentData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); return StatisticsRecentData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else { } else {
throw Exception('Failed to get data from API.'); throw Exception('Failed to get data from API.');
...@@ -42,6 +44,7 @@ class ScrobblesApi { ...@@ -42,6 +44,7 @@ class ScrobblesApi {
final response = await http.get(Uri.parse(url)); final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) { if (response.statusCode == 200) {
print('ok - fetched ' + url);
return TimelineData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); return TimelineData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else { } else {
throw Exception('Failed to get data from API.'); throw Exception('Failed to get data from API.');
...@@ -54,6 +57,7 @@ class ScrobblesApi { ...@@ -54,6 +57,7 @@ class ScrobblesApi {
final response = await http.get(Uri.parse(url)); final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) { if (response.statusCode == 200) {
print('ok - fetched ' + url);
return CountsByDayData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); return CountsByDayData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else { } else {
throw Exception('Failed to get data from API.'); throw Exception('Failed to get data from API.');
...@@ -66,6 +70,7 @@ class ScrobblesApi { ...@@ -66,6 +70,7 @@ class ScrobblesApi {
final response = await http.get(Uri.parse(url)); final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) { if (response.statusCode == 200) {
print('ok - fetched ' + url);
return CountsByHourData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); return CountsByHourData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else { } else {
throw Exception('Failed to get data from API.'); throw Exception('Failed to get data from API.');
...@@ -78,6 +83,7 @@ class ScrobblesApi { ...@@ -78,6 +83,7 @@ class ScrobblesApi {
final response = await http.get(Uri.parse(url)); final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) { if (response.statusCode == 200) {
print('ok - fetched ' + url);
return DiscoveriesData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); return DiscoveriesData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else { } else {
throw Exception('Failed to get data from API.'); throw Exception('Failed to get data from API.');
...@@ -90,6 +96,7 @@ class ScrobblesApi { ...@@ -90,6 +96,7 @@ class ScrobblesApi {
final response = await http.get(Uri.parse(url)); final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) { if (response.statusCode == 200) {
print('ok - fetched ' + url);
return TopArtistsData.fromJson(jsonDecode(response.body) as Map<String, dynamic>); return TopArtistsData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else { } else {
throw Exception('Failed to get data from API.'); throw Exception('Failed to get data from API.');
......
...@@ -2,14 +2,9 @@ import 'package:flutter/material.dart'; ...@@ -2,14 +2,9 @@ import 'package:flutter/material.dart';
import 'package:scrobbles/ui/widgets/cards/discoveries.dart'; import 'package:scrobbles/ui/widgets/cards/discoveries.dart';
class ScreenDiscoveries extends StatefulWidget { class ScreenDiscoveries extends StatelessWidget {
const ScreenDiscoveries({super.key}); const ScreenDiscoveries({super.key});
@override
State<ScreenDiscoveries> createState() => _ScreenDiscoveriesState();
}
class _ScreenDiscoveriesState extends State<ScreenDiscoveries> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Material( return Material(
......
...@@ -5,14 +5,9 @@ import 'package:scrobbles/ui/widgets/cards/statistics_recent.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/timeline.dart';
import 'package:scrobbles/ui/widgets/cards/top_artists.dart'; import 'package:scrobbles/ui/widgets/cards/top_artists.dart';
class ScreenHome extends StatefulWidget { class ScreenHome extends StatelessWidget {
const ScreenHome({super.key}); const ScreenHome({super.key});
@override
State<ScreenHome> createState() => _ScreenHomeState();
}
class _ScreenHomeState extends State<ScreenHome> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Material( return Material(
......
...@@ -3,14 +3,9 @@ import 'package:flutter/material.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_day.dart';
import 'package:scrobbles/ui/widgets/cards/counts_by_hour.dart'; import 'package:scrobbles/ui/widgets/cards/counts_by_hour.dart';
class ScreenStatistics extends StatefulWidget { class ScreenStatistics extends StatelessWidget {
const ScreenStatistics({super.key}); const ScreenStatistics({super.key});
@override
State<ScreenStatistics> createState() => _ScreenStatisticsState();
}
class _ScreenStatisticsState extends State<ScreenStatistics> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Material( return Material(
......
...@@ -25,47 +25,32 @@ class _SkeletonScreenState extends State<SkeletonScreen> { ...@@ -25,47 +25,32 @@ class _SkeletonScreenState extends State<SkeletonScreen> {
const ScreenStatistics(), const ScreenStatistics(),
]; ];
return BlocProvider<BottomNavCubit>( return Scaffold(
create: (BuildContext context) => BottomNavCubit(), appBar: StandardAppBar(notifyParent: refresh),
child: BlocBuilder<BottomNavCubit, int>( extendBodyBehindAppBar: false,
builder: (BuildContext context, int state) { body: Swiper(
return Scaffold( itemCount: BlocProvider.of<BottomNavCubit>(context).pagesCount,
appBar: StandardAppBar(notifyParent: refresh), itemBuilder: (BuildContext context, int index) {
extendBodyBehindAppBar: false, return pageNavigation.elementAt(index);
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,
);
}, },
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() { refresh() {
void rebuild(Element el) { setState(() {});
el.markNeedsBuild();
el.visitChildren(rebuild);
}
(context as Element).visitChildren(rebuild);
} }
} }
...@@ -19,25 +19,22 @@ class CardCountsByDay extends StatelessWidget { ...@@ -19,25 +19,22 @@ class CardCountsByDay extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final int daysCount = Settings.countsByDayDaysCount; final int daysCount = Settings.countsByDayDaysCount;
return BlocProvider<DataCountsByDayCubit>( return BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>(
create: (BuildContext context) => DataCountsByDayCubit(), builder: (BuildContext context, DataCountsByDayState state) {
child: BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>( return CardContent(
builder: (BuildContext context, DataCountsByDayState state) { color: Theme.of(context).colorScheme.surface,
return CardContent( title: 'counts_by_day'.tr(
color: Theme.of(context).colorScheme.surface, namedArgs: {
title: 'counts_by_day'.tr( 'daysCount': daysCount.toString(),
namedArgs: { },
'daysCount': daysCount.toString(), ),
}, loader: updateCountsByDay(Settings.countsByDayDaysCount),
), content: ChartCountsByDay(
loader: updateCountsByDay(Settings.countsByDayDaysCount), chartData: CountsByDayData.fromJson(jsonDecode(state.countsByDay.toString())),
content: ChartCountsByDay( isLoading: false,
chartData: CountsByDayData.fromJson(jsonDecode(state.countsByDay.toString())), ),
isLoading: false, );
), },
);
},
),
); );
} }
...@@ -47,23 +44,21 @@ class CardCountsByDay extends StatelessWidget { ...@@ -47,23 +44,21 @@ class CardCountsByDay extends StatelessWidget {
late Future<CountsByDayData> futureCountsByDay = ScrobblesApi.fetchCountsByDay(daysCount); late Future<CountsByDayData> futureCountsByDay = ScrobblesApi.fetchCountsByDay(daysCount);
return BlocProvider<DataCountsByDayCubit>( return BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>(
create: (BuildContext context) => DataCountsByDayCubit(), builder: (BuildContext context, DataCountsByDayState state) {
child: BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>( return FutureBuilder<CountsByDayData>(
builder: (BuildContext context, DataCountsByDayState state) { future: futureCountsByDay,
return FutureBuilder<CountsByDayData>( builder: (context, snapshot) {
future: futureCountsByDay, if (snapshot.hasError) {
builder: (context, snapshot) { return ShowErrorWidget(message: '${snapshot.error}');
if (snapshot.hasError) { }
return ShowErrorWidget(message: '${snapshot.error}');
}
BlocProvider.of<DataCountsByDayCubit>(context).setValue(snapshot.data); BlocProvider.of<DataCountsByDayCubit>(context).update(snapshot.data);
return !snapshot.hasData ? loading : done;
}, return !snapshot.hasData ? loading : done;
); },
}, );
), },
); );
} }
} }
...@@ -19,25 +19,22 @@ class CardCountsByHour extends StatelessWidget { ...@@ -19,25 +19,22 @@ class CardCountsByHour extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final int daysCount = Settings.countsByHourDaysCount; final int daysCount = Settings.countsByHourDaysCount;
return BlocProvider<DataCountsByHourCubit>( return BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>(
create: (BuildContext context) => DataCountsByHourCubit(), builder: (BuildContext context, DataCountsByHourState state) {
child: BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>( return CardContent(
builder: (BuildContext context, DataCountsByHourState state) { color: Theme.of(context).colorScheme.surface,
return CardContent( title: 'counts_by_hour'.tr(
color: Theme.of(context).colorScheme.surface, namedArgs: {
title: 'counts_by_hour'.tr( 'daysCount': daysCount.toString(),
namedArgs: { },
'daysCount': daysCount.toString(), ),
}, loader: updateCountsByHour(Settings.countsByHourDaysCount),
), content: ChartCountsByHour(
loader: updateCountsByHour(Settings.countsByHourDaysCount), chartData: CountsByHourData.fromJson(jsonDecode(state.countsByHour.toString())),
content: ChartCountsByHour( isLoading: false,
chartData: CountsByHourData.fromJson(jsonDecode(state.countsByHour.toString())), ),
isLoading: false, );
), },
);
},
),
); );
} }
...@@ -48,23 +45,21 @@ class CardCountsByHour extends StatelessWidget { ...@@ -48,23 +45,21 @@ class CardCountsByHour extends StatelessWidget {
late Future<CountsByHourData> futureCountsByHour = late Future<CountsByHourData> futureCountsByHour =
ScrobblesApi.fetchCountsByHour(daysCount); ScrobblesApi.fetchCountsByHour(daysCount);
return BlocProvider<DataCountsByHourCubit>( return BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>(
create: (BuildContext context) => DataCountsByHourCubit(), builder: (BuildContext context, DataCountsByHourState state) {
child: BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>( return FutureBuilder<CountsByHourData>(
builder: (BuildContext context, DataCountsByHourState state) { future: futureCountsByHour,
return FutureBuilder<CountsByHourData>( builder: (context, snapshot) {
future: futureCountsByHour, if (snapshot.hasError) {
builder: (context, snapshot) { return ShowErrorWidget(message: '${snapshot.error}');
if (snapshot.hasError) { }
return ShowErrorWidget(message: '${snapshot.error}');
}
BlocProvider.of<DataCountsByHourCubit>(context).setValue(snapshot.data); BlocProvider.of<DataCountsByHourCubit>(context).update(snapshot.data);
return !snapshot.hasData ? loading : done;
}, return !snapshot.hasData ? loading : done;
); },
}, );
), },
); );
} }
} }
...@@ -20,50 +20,45 @@ class CardDiscoveries extends StatelessWidget { ...@@ -20,50 +20,45 @@ class CardDiscoveries extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final int daysCount = Settings.discoveriesDaysCount; final int daysCount = Settings.discoveriesDaysCount;
return BlocProvider<DataDiscoveriesCubit>( return BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>(
create: (BuildContext context) => DataDiscoveriesCubit(), builder: (BuildContext context, DataDiscoveriesState state) {
child: BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>( final TextTheme textTheme = Theme.of(context).primaryTextTheme;
builder: (BuildContext context, DataDiscoveriesState state) {
final TextTheme textTheme = Theme.of(context).primaryTextTheme;
return CardContent( return CardContent(
color: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.surface,
title: 'discoveries_title'.tr( title: 'discoveries_title'.tr(
namedArgs: { namedArgs: {
'daysCount': daysCount.toString(), 'daysCount': daysCount.toString(),
}, },
), ),
loader: updateDiscoveries(Settings.discoveriesDaysCount), loader: updateDiscoveries(Settings.discoveriesDaysCount),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'discoveries_artists_title', 'discoveries_artists_title',
style: textTheme.titleMedium!.apply(fontWeightDelta: 2), style: textTheme.titleMedium!.apply(fontWeightDelta: 2),
).tr(), ).tr(),
const SizedBox(height: 8), const SizedBox(height: 8),
ChartDiscoveriesArtists( ChartDiscoveriesArtists(
chartData: chartData: DiscoveriesData.fromJson(jsonDecode(state.discoveries.toString())),
DiscoveriesData.fromJson(jsonDecode(state.discoveries.toString())), isLoading: false,
isLoading: false, ),
), const SizedBox(height: 8),
const SizedBox(height: 8), Text(
Text( 'discoveries_tracks_title',
'discoveries_tracks_title', style: textTheme.titleMedium!.apply(fontWeightDelta: 2),
style: textTheme.titleMedium!.apply(fontWeightDelta: 2), ).tr(),
).tr(), const SizedBox(height: 8),
const SizedBox(height: 8), ChartDiscoveriesTracks(
ChartDiscoveriesTracks( chartData: DiscoveriesData.fromJson(jsonDecode(state.discoveries.toString())),
chartData: isLoading: false,
DiscoveriesData.fromJson(jsonDecode(state.discoveries.toString())), ),
isLoading: false, ],
), ),
], );
), },
);
},
),
); );
} }
...@@ -73,23 +68,21 @@ class CardDiscoveries extends StatelessWidget { ...@@ -73,23 +68,21 @@ class CardDiscoveries extends StatelessWidget {
late Future<DiscoveriesData> futureDiscoveries = ScrobblesApi.fetchDiscoveries(daysCount); late Future<DiscoveriesData> futureDiscoveries = ScrobblesApi.fetchDiscoveries(daysCount);
return BlocProvider<DataDiscoveriesCubit>( return BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>(
create: (BuildContext context) => DataDiscoveriesCubit(), builder: (BuildContext context, DataDiscoveriesState state) {
child: BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>( return FutureBuilder<DiscoveriesData>(
builder: (BuildContext context, DataDiscoveriesState state) { future: futureDiscoveries,
return FutureBuilder<DiscoveriesData>( builder: (context, snapshot) {
future: futureDiscoveries, if (snapshot.hasError) {
builder: (context, snapshot) { return ShowErrorWidget(message: '${snapshot.error}');
if (snapshot.hasError) { }
return ShowErrorWidget(message: '${snapshot.error}');
}
BlocProvider.of<DataDiscoveriesCubit>(context).setValue(snapshot.data); BlocProvider.of<DataDiscoveriesCubit>(context).update(snapshot.data);
return !snapshot.hasData ? loading : done;
}, return !snapshot.hasData ? loading : done;
); },
}, );
), },
); );
} }
} }
...@@ -16,22 +16,19 @@ class CardStatisticsGlobal extends StatelessWidget { ...@@ -16,22 +16,19 @@ class CardStatisticsGlobal extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider<DataStatisticsGlobalCubit>( return BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>(
create: (BuildContext context) => DataStatisticsGlobalCubit(), builder: (BuildContext context, DataStatisticsGlobalState state) {
child: BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>( return CardContent(
builder: (BuildContext context, DataStatisticsGlobalState state) { color: Theme.of(context).colorScheme.primary,
return CardContent( title: 'global_statistics'.tr(),
color: Theme.of(context).colorScheme.primary, loader: updateStatisticsGlobal(),
title: 'global_statistics'.tr(), content: ContentStatisticsGlobal(
loader: updateStatisticsGlobal(), statistics:
content: ContentStatisticsGlobal( StatisticsGlobalData.fromJson(jsonDecode(state.statisticsGlobal.toString())),
statistics: isLoading: false,
StatisticsGlobalData.fromJson(jsonDecode(state.statisticsGlobal.toString())), ),
isLoading: false, );
), },
);
},
),
); );
} }
...@@ -42,23 +39,21 @@ class CardStatisticsGlobal extends StatelessWidget { ...@@ -42,23 +39,21 @@ class CardStatisticsGlobal extends StatelessWidget {
late Future<StatisticsGlobalData> futureStatisticsGlobal = late Future<StatisticsGlobalData> futureStatisticsGlobal =
ScrobblesApi.fetchGlobalStatistics(); ScrobblesApi.fetchGlobalStatistics();
return BlocProvider<DataStatisticsGlobalCubit>( return BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>(
create: (BuildContext context) => DataStatisticsGlobalCubit(), builder: (BuildContext context, DataStatisticsGlobalState dataState) {
child: BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>( return FutureBuilder<StatisticsGlobalData>(
builder: (BuildContext context, DataStatisticsGlobalState dataState) { future: futureStatisticsGlobal,
return FutureBuilder<StatisticsGlobalData>( builder: (context, snapshot) {
future: futureStatisticsGlobal, if (snapshot.hasError) {
builder: (context, snapshot) { return ShowErrorWidget(message: '${snapshot.error}');
if (snapshot.hasError) { }
return ShowErrorWidget(message: '${snapshot.error}');
} BlocProvider.of<DataStatisticsGlobalCubit>(context).update(snapshot.data);
BlocProvider.of<DataStatisticsGlobalCubit>(context).setValue(snapshot.data); return !snapshot.hasData ? loading : done;
return !snapshot.hasData ? loading : done; },
}, );
); },
},
),
); );
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment