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

Improve / clean some code

parent f09c06f8
No related branches found
No related tags found
No related merge requests found
Pipeline #4748 passed
Showing
with 346 additions and 382 deletions
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
app.versionName=0.0.49
app.versionCode=49
app.versionName=0.0.50
app.versionCode=50
Improve / clean some code.
Amélioration / nettoyage de code.
import 'package:easy_localization/easy_localization.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:scrobbles/config/app_colors.dart';
import 'package:scrobbles/ui/widgets/abstracts/custom_chart.dart';
import 'package:scrobbles/utils/color_extensions.dart';
class CustomBarChart extends StatelessWidget {
class CustomBarChart extends CustomChart {
const CustomBarChart({super.key});
final double chartHeight = 150.0;
final double verticalTicksInterval = 10;
final String verticalAxisTitleSuffix = '';
final double titleFontSize = 9;
@override
Widget build(BuildContext context) {
return Container(
child: SizedBox(
height: this.chartHeight,
),
return SizedBox(
height: this.chartHeight,
);
}
......@@ -27,8 +19,8 @@ class CustomBarChart extends StatelessWidget {
BarChartData(
barGroups: getDataCounts(barWidth),
backgroundColor: backgroundColor,
borderData: getBorderData(),
gridData: getGridData(),
borderData: simpleBorderData,
gridData: horizontalGridData,
titlesData: getTitlesData(),
barTouchData: BarTouchData(enabled: false),
maxY: getNextRoundNumber(getMaxCountsValue(), this.verticalTicksInterval),
......@@ -36,6 +28,10 @@ class CustomBarChart extends StatelessWidget {
);
}
double getMaxCountsValue() {
return 0.0;
}
double getBarWidth(double containerWidth, int barsCount) {
return 0.65 * (containerWidth / barsCount);
}
......@@ -44,12 +40,19 @@ class CustomBarChart extends StatelessWidget {
return [];
}
double getMaxCountsValue() {
return 0.0;
}
LinearGradient getGradient(Color baseColor, double value, double maxValue) {
double alignmentTopValue = value != 0.0 ? -2 * maxValue / value + 1 : 0;
double getNextRoundNumber(double number, double scale) {
return scale * ((number ~/ scale).toInt() + 1);
return LinearGradient(
begin: Alignment(-1, alignmentTopValue),
end: Alignment(1, 1),
colors: <Color>[
baseColor.lighten(30),
baseColor,
baseColor.darken(30),
],
tileMode: TileMode.mirror,
);
}
BarChartGroupData getBarItem(
......@@ -86,39 +89,6 @@ class CustomBarChart extends StatelessWidget {
);
}
LinearGradient getGradient(Color baseColor, double value, double maxValue) {
double alignmentTopValue = value != 0.0 ? -2 * maxValue / value + 1 : 0;
return LinearGradient(
begin: Alignment(-1, alignmentTopValue),
end: Alignment(1, 1),
colors: <Color>[
baseColor.lighten(30),
baseColor,
baseColor.darken(30),
],
tileMode: TileMode.mirror,
);
}
FlBorderData getBorderData() {
return FlBorderData(
show: true,
border: Border.all(
color: AppColors.borderColor,
width: 2,
),
);
}
FlGridData getGridData() {
return const FlGridData(
show: true,
drawHorizontalLine: true,
drawVerticalLine: false,
);
}
FlTitlesData getTitlesData() {
const AxisTitles none = const AxisTitles(
sideTitles: SideTitles(showTitles: false),
......@@ -159,53 +129,7 @@ class CustomBarChart extends StatelessWidget {
);
}
Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
String suffix =
this.verticalAxisTitleSuffix != '' ? ' ' + this.verticalAxisTitleSuffix : '';
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Text(
value.toInt().toString() + suffix,
style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
),
);
}
Widget getVerticalTitlesSpacerWidget(double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Text(''),
);
}
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
final DateFormat formatter = DateFormat('dd/MM');
final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
final String text = formatter.format(date);
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Padding(
padding: EdgeInsets.only(right: 10),
child: RotationTransition(
turns: new AlwaysStoppedAnimation(-30 / 360),
child: Text(
text,
style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
),
),
),
);
return getHorizontalTitlesWidgetWithDate(value, meta);
}
}
import 'package:easy_localization/easy_localization.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:scrobbles/config/app_colors.dart';
import 'package:scrobbles/utils/color_extensions.dart';
class CustomChart extends StatelessWidget {
const CustomChart({super.key});
final double chartHeight = 150.0;
final double verticalTicksInterval = 10;
final String verticalAxisTitleSuffix = '';
final double titleFontSize = 9;
@override
Widget build(BuildContext context) {
return SizedBox(
height: this.chartHeight,
);
}
double getNextRoundNumber(double number, double scale) {
return scale * ((number ~/ scale).toInt() + 1);
}
Color getColorFromIndex(int index) {
const List<int> hexValues = [
0x8dd3c7,
0xffffb3,
0xbebada,
0xfb8072,
0x80b1d3,
0xfdb462,
0xb3de69,
0xfccde5,
0xd9d9d9,
0xbc80bd,
0xccebc5,
0xffed6f,
];
return Color(hexValues[index % hexValues.length] + 0xff000000);
}
String getDayShortName(int dayIndex) {
switch (dayIndex) {
case 1:
return 'MON';
case 2:
return 'TUE';
case 3:
return 'WED';
case 4:
return 'THU';
case 5:
return 'FRI';
case 6:
return 'SAT';
case 7:
return 'SUN';
default:
}
return '';
}
FlBorderData get noBorderData {
return FlBorderData(
show: false,
);
}
FlBorderData get simpleBorderData {
return FlBorderData(
show: true,
border: Border.all(
color: AppColors.borderColor,
width: 2,
),
);
}
FlGridData get noGridData {
return const FlGridData(
show: false,
);
}
FlGridData get horizontalGridData {
return const FlGridData(
show: true,
drawHorizontalLine: true,
drawVerticalLine: false,
);
}
FlTitlesData getTitlesData() {
return FlTitlesData(
show: false,
);
}
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
return Text('');
}
Widget getHorizontalTitlesWidgetWithDate(double value, TitleMeta meta) {
final DateFormat formatter = DateFormat('dd/MM');
final DateTime date = DateTime.fromMillisecondsSinceEpoch(value.toInt());
final String text = formatter.format(date);
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Padding(
padding: EdgeInsets.only(right: 10),
child: RotationTransition(
turns: new AlwaysStoppedAnimation(-30 / 360),
child: Text(
text,
style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
),
),
),
);
}
Widget getHorizontalTitlesWidgetWithDay(double value, TitleMeta meta) {
final String dayShortName = getDayShortName(value.toInt());
return SideTitleWidget(
axisSide: meta.axisSide,
space: 2,
child: Text(
tr(dayShortName),
style: const TextStyle(
color: AppColors.mainTextColor1,
fontSize: 11,
),
),
);
}
Widget getHorizontalTitlesWidgetWithHour(double value, TitleMeta meta) {
String text = '';
if (value % 4 == 0 || value == 23) {
text = value.toInt().toString().padLeft(2, '0');
}
return SideTitleWidget(
axisSide: meta.axisSide,
space: 2,
child: Text(
text,
style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
),
);
}
Widget getVerticalTitlesSpacerWidget(double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Text(''),
);
}
Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
String suffix =
this.verticalAxisTitleSuffix != '' ? ' ' + this.verticalAxisTitleSuffix : '';
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Text(
value.toInt().toString() + suffix,
style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
),
);
}
}
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:scrobbles/config/app_colors.dart';
import 'package:scrobbles/ui/widgets/abstracts/custom_chart.dart';
class CustomLineChart extends StatelessWidget {
class CustomLineChart extends CustomChart {
const CustomLineChart({super.key});
final double chartHeight = 150.0;
final double titleFontSize = 9;
@override
Widget build(BuildContext context) {
return Container(
child: SizedBox(
height: this.chartHeight,
),
return SizedBox(
height: this.chartHeight,
);
}
FlBorderData getBorderData() {
return FlBorderData(
show: false,
);
}
Map<String, double> getHorizontalScaleFromDates(Iterable datesAsString) {
double minDateAsDouble = double.maxFinite;
double maxDateAsDouble = -double.maxFinite;
FlGridData getGridData() {
return const FlGridData(
show: false,
);
datesAsString.forEach((element) {
final double date = DateTime.parse(element).millisecondsSinceEpoch.toDouble();
if (date < minDateAsDouble) {
minDateAsDouble = date;
}
if (date > maxDateAsDouble) {
maxDateAsDouble = date;
}
});
return {
'min': minDateAsDouble,
'max': maxDateAsDouble,
};
}
FlTitlesData getTitlesData() {
......@@ -40,7 +44,7 @@ class CustomLineChart extends StatelessWidget {
showTitles: true,
reservedSize: 35,
getTitlesWidget: getVerticalTitlesWidget,
interval: 25,
interval: this.verticalTicksInterval,
),
);
......@@ -68,30 +72,4 @@ class CustomLineChart extends StatelessWidget {
rightTitles: verticalTitles,
);
}
Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Text(
value.toInt().toString() + ' %',
style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
),
);
}
Widget getVerticalTitlesSpacerWidget(double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Text(''),
);
}
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
return Text('');
}
}
......@@ -20,7 +20,9 @@ class CardCountsByDay extends StatelessWidget {
final int daysCount = settings.getDistributionDaysCount();
return BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>(
builder: (BuildContext context, DataCountsByDayState state) {
builder: (BuildContext context, DataCountsByDayState data) {
final CountsByDayData counts = data.countsByDay ?? CountsByDayData.fromJson({});
return CardContent(
color: Theme.of(context).colorScheme.surface,
title: 'counts_by_day'.tr(
......@@ -28,25 +30,23 @@ class CardCountsByDay extends StatelessWidget {
'daysCount': daysCount.toString(),
},
),
loader: updateCountsByDay(daysCount),
content: ChartCountsByDay(
chartData: CountsByDayData.fromJson(state.countsByDay?.toJson()),
),
loader: update(daysCount),
content: ChartCountsByDay(chartData: counts),
);
},
);
}
Widget updateCountsByDay(int daysCount) {
Widget update(int daysCount) {
final Widget loading = const Text('⏳');
final Widget done = const Text('');
late Future<CountsByDayData> futureCountsByDay = ScrobblesApi.fetchCountsByDay(daysCount);
late Future<CountsByDayData> future = ScrobblesApi.fetchCountsByDay(daysCount);
return BlocBuilder<DataCountsByDayCubit, DataCountsByDayState>(
builder: (BuildContext context, DataCountsByDayState state) {
builder: (BuildContext context, DataCountsByDayState data) {
return FutureBuilder<CountsByDayData>(
future: futureCountsByDay,
future: future,
builder: (context, snapshot) {
if (snapshot.hasError) {
return ShowErrorWidget(message: '${snapshot.error}');
......
......@@ -20,7 +20,9 @@ class CardCountsByHour extends StatelessWidget {
final int daysCount = settings.getDistributionDaysCount();
return BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>(
builder: (BuildContext context, DataCountsByHourState state) {
builder: (BuildContext context, DataCountsByHourState data) {
final CountsByHourData counts = data.countsByHour ?? CountsByHourData.fromJson({});
return CardContent(
color: Theme.of(context).colorScheme.surface,
title: 'counts_by_hour'.tr(
......@@ -28,26 +30,23 @@ class CardCountsByHour extends StatelessWidget {
'daysCount': daysCount.toString(),
},
),
loader: updateCountsByHour(daysCount),
content: ChartCountsByHour(
chartData: CountsByHourData.fromJson(state.countsByHour?.toJson()),
),
loader: update(daysCount),
content: ChartCountsByHour(chartData: counts),
);
},
);
}
Widget updateCountsByHour(int daysCount) {
Widget update(int daysCount) {
final Widget loading = const Text('⏳');
final Widget done = const Text('');
late Future<CountsByHourData> futureCountsByHour =
ScrobblesApi.fetchCountsByHour(daysCount);
late Future<CountsByHourData> future = ScrobblesApi.fetchCountsByHour(daysCount);
return BlocBuilder<DataCountsByHourCubit, DataCountsByHourState>(
builder: (BuildContext context, DataCountsByHourState state) {
builder: (BuildContext context, DataCountsByHourState data) {
return FutureBuilder<CountsByHourData>(
future: futureCountsByHour,
future: future,
builder: (context, snapshot) {
if (snapshot.hasError) {
return ShowErrorWidget(message: '${snapshot.error}');
......
......@@ -21,9 +21,11 @@ class CardDiscoveries extends StatelessWidget {
final int daysCount = settings.getDiscoveriesDaysCount();
return BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>(
builder: (BuildContext context, DataDiscoveriesState state) {
builder: (BuildContext context, DataDiscoveriesState data) {
final TextTheme textTheme = Theme.of(context).primaryTextTheme;
final DiscoveriesData discoveries = data.discoveries ?? DiscoveriesData.fromJson({});
return CardContent(
color: Theme.of(context).colorScheme.surface,
title: 'discoveries_title'.tr(
......@@ -31,7 +33,7 @@ class CardDiscoveries extends StatelessWidget {
'daysCount': daysCount.toString(),
},
),
loader: updateDiscoveries(daysCount),
loader: update(daysCount),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
......@@ -41,18 +43,14 @@ class CardDiscoveries extends StatelessWidget {
style: textTheme.titleMedium!.apply(fontWeightDelta: 2),
).tr(),
const SizedBox(height: 8),
ChartDiscoveriesArtists(
chartData: DiscoveriesData.fromJson(state.discoveries?.toJson()),
),
ChartDiscoveriesArtists(chartData: discoveries),
const SizedBox(height: 8),
Text(
'discoveries_tracks_title',
style: textTheme.titleMedium!.apply(fontWeightDelta: 2),
).tr(),
const SizedBox(height: 8),
ChartDiscoveriesTracks(
chartData: DiscoveriesData.fromJson(state.discoveries?.toJson()),
),
ChartDiscoveriesTracks(chartData: discoveries),
],
),
);
......@@ -60,16 +58,16 @@ class CardDiscoveries extends StatelessWidget {
);
}
Widget updateDiscoveries(int daysCount) {
Widget update(int daysCount) {
final Widget loading = const Text('⏳');
final Widget done = const Text('');
late Future<DiscoveriesData> futureDiscoveries = ScrobblesApi.fetchDiscoveries(daysCount);
late Future<DiscoveriesData> future = ScrobblesApi.fetchDiscoveries(daysCount);
return BlocBuilder<DataDiscoveriesCubit, DataDiscoveriesState>(
builder: (BuildContext context, DataDiscoveriesState state) {
builder: (BuildContext context, DataDiscoveriesState data) {
return FutureBuilder<DiscoveriesData>(
future: futureDiscoveries,
future: future,
builder: (context, snapshot) {
if (snapshot.hasError) {
return ShowErrorWidget(message: '${snapshot.error}');
......
......@@ -20,8 +20,8 @@ class CardHeatmap extends StatelessWidget {
final int daysCount = settings.getDistributionDaysCount();
return BlocBuilder<DataHeatmapCubit, DataHeatmapState>(
builder: (BuildContext context, DataHeatmapState state) {
HeatmapData heatmap = state.heatmap ?? HeatmapData.fromJson({});
builder: (BuildContext context, DataHeatmapState data) {
final HeatmapData heatmap = data.heatmap ?? HeatmapData.fromJson({});
return CardContent(
color: Theme.of(context).colorScheme.surface,
......@@ -30,25 +30,23 @@ class CardHeatmap extends StatelessWidget {
'daysCount': daysCount.toString(),
},
),
loader: updateHeatmapData(daysCount),
content: ChartHeatmap(
chartData: heatmap,
),
loader: update(daysCount),
content: ChartHeatmap(chartData: heatmap),
);
},
);
}
Widget updateHeatmapData(int daysCount) {
Widget update(int daysCount) {
final Widget loading = const Text('⏳');
final Widget done = const Text('');
late Future<HeatmapData> futureHeatmap = ScrobblesApi.fetchHeatmap(daysCount);
late Future<HeatmapData> future = ScrobblesApi.fetchHeatmap(daysCount);
return BlocBuilder<DataHeatmapCubit, DataHeatmapState>(
builder: (BuildContext context, DataHeatmapState state) {
builder: (BuildContext context, DataHeatmapState data) {
return FutureBuilder<HeatmapData>(
future: futureHeatmap,
future: future,
builder: (context, snapshot) {
if (snapshot.hasError) {
return ShowErrorWidget(message: '${snapshot.error}');
......
......@@ -19,7 +19,7 @@ class CardNewArtists extends StatelessWidget {
final int count = settings.getNewArtistsCount();
return BlocBuilder<DataNewArtistsCubit, DataNewArtistsState>(
builder: (BuildContext context, DataNewArtistsState state) {
builder: (BuildContext context, DataNewArtistsState data) {
return CardContent(
color: Theme.of(context).colorScheme.surface,
title: 'new_artists_title'.tr(),
......@@ -27,7 +27,7 @@ class CardNewArtists extends StatelessWidget {
content: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: state.newArtists?.data
children: data.newArtists?.data
.map((newArtist) => Text(newArtist.artist?.name ?? ''))
.toList() ??
[],
......@@ -44,7 +44,7 @@ class CardNewArtists extends StatelessWidget {
late Future<NewArtistsData> future = ScrobblesApi.fetchNewArtists(count);
return BlocBuilder<DataNewArtistsCubit, DataNewArtistsState>(
builder: (BuildContext context, DataNewArtistsState state) {
builder: (BuildContext context, DataNewArtistsState data) {
return FutureBuilder<NewArtistsData>(
future: future,
builder: (context, snapshot) {
......
......@@ -19,7 +19,7 @@ class CardNewTracks extends StatelessWidget {
final int count = settings.getNewTracksCount();
return BlocBuilder<DataNewTracksCubit, DataNewTracksState>(
builder: (BuildContext context, DataNewTracksState state) {
builder: (BuildContext context, DataNewTracksState data) {
return CardContent(
color: Theme.of(context).colorScheme.surface,
title: 'new_tracks_title'.tr(),
......@@ -27,7 +27,7 @@ class CardNewTracks extends StatelessWidget {
content: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: state.newTracks?.data
children: data.newTracks?.data
.map((newTrack) => Text((newTrack.track?.artist.name ?? '') +
' - ' +
(newTrack.track?.name ?? '')))
......@@ -46,7 +46,7 @@ class CardNewTracks extends StatelessWidget {
late Future<NewTracksData> future = ScrobblesApi.fetchNewTracks(count);
return BlocBuilder<DataNewTracksCubit, DataNewTracksState>(
builder: (BuildContext context, DataNewTracksState state) {
builder: (BuildContext context, DataNewTracksState data) {
return FutureBuilder<NewTracksData>(
future: future,
builder: (context, snapshot) {
......
......@@ -15,30 +15,30 @@ class CardStatisticsGlobal extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>(
builder: (BuildContext context, DataStatisticsGlobalState state) {
builder: (BuildContext context, DataStatisticsGlobalState data) {
final StatisticsGlobalData statistics =
data.statisticsGlobal ?? StatisticsGlobalData.fromJson({});
return CardContent(
color: Theme.of(context).colorScheme.primary,
title: 'global_statistics'.tr(),
loader: updateStatisticsGlobal(),
content: ContentStatisticsGlobal(
statistics: StatisticsGlobalData.fromJson(state.statisticsGlobal?.toJson()),
),
loader: update(),
content: ContentStatisticsGlobal(statistics: statistics),
);
},
);
}
Widget updateStatisticsGlobal() {
Widget update() {
final Widget loading = const Text('⏳');
final Widget done = const Text('');
late Future<StatisticsGlobalData> futureStatisticsGlobal =
ScrobblesApi.fetchGlobalStatistics();
late Future<StatisticsGlobalData> future = ScrobblesApi.fetchGlobalStatistics();
return BlocBuilder<DataStatisticsGlobalCubit, DataStatisticsGlobalState>(
builder: (BuildContext context, DataStatisticsGlobalState dataState) {
builder: (BuildContext context, DataStatisticsGlobalState data) {
return FutureBuilder<StatisticsGlobalData>(
future: futureStatisticsGlobal,
future: future,
builder: (context, snapshot) {
if (snapshot.hasError) {
return ShowErrorWidget(message: '${snapshot.error}');
......
......@@ -22,7 +22,10 @@ class CardStatisticsRecent extends StatelessWidget {
final int daysCount = settings.getStatisticsRecentDaysCount();
return BlocBuilder<DataStatisticsRecentCubit, DataStatisticsRecentState>(
builder: (BuildContext context, DataStatisticsRecentState dataState) {
builder: (BuildContext context, DataStatisticsRecentState data) {
final StatisticsRecentData statistics =
data.statisticsRecent ?? StatisticsRecentData.fromJson({});
return CardContent(
color: Theme.of(context).colorScheme.primary,
title: 'recent_statistics'.tr(
......@@ -30,27 +33,23 @@ class CardStatisticsRecent extends StatelessWidget {
'daysCount': daysCount.toString(),
},
),
loader: updateStatisticsRecent(daysCount),
content: ContentStatisticsRecent(
statistics: StatisticsRecentData.fromJson(
jsonDecode(dataState.statisticsRecent.toString())),
),
loader: update(daysCount),
content: ContentStatisticsRecent(statistics: statistics),
);
},
);
}
Widget updateStatisticsRecent(int daysCount) {
Widget update(int daysCount) {
final Widget loading = const Text('⏳');
final Widget done = const Text('');
late Future<StatisticsRecentData> futureStatisticsRecent =
ScrobblesApi.fetchRecentStatistics(daysCount);
late Future<StatisticsRecentData> future = ScrobblesApi.fetchRecentStatistics(daysCount);
return BlocBuilder<DataStatisticsRecentCubit, DataStatisticsRecentState>(
builder: (BuildContext context, DataStatisticsRecentState state) {
builder: (BuildContext context, DataStatisticsRecentState data) {
return FutureBuilder<StatisticsRecentData>(
future: futureStatisticsRecent,
future: future,
builder: (context, snapshot) {
if (snapshot.hasError) {
return ShowErrorWidget(message: '${snapshot.error}');
......
......@@ -21,7 +21,9 @@ class CardTimeline extends StatelessWidget {
final int daysCount = settings.getTimelineDaysCount();
return BlocBuilder<DataTimelineCubit, DataTimelineState>(
builder: (BuildContext context, DataTimelineState state) {
builder: (BuildContext context, DataTimelineState data) {
final TimelineData timeline = data.timeline ?? TimelineData.fromJson({});
return CardContent(
color: Theme.of(context).colorScheme.surface,
title: 'timeline_title'.tr(
......@@ -29,15 +31,11 @@ class CardTimeline extends StatelessWidget {
'daysCount': daysCount.toString(),
},
),
loader: updateTimeline(daysCount),
loader: update(daysCount),
content: Stack(
children: [
ChartTimelineCounts(
chartData: TimelineData.fromJson(state.timeline?.toJson()),
),
ChartTimelineEclecticism(
chartData: TimelineData.fromJson(state.timeline?.toJson()),
),
ChartTimelineCounts(chartData: timeline),
ChartTimelineEclecticism(chartData: timeline),
],
),
);
......@@ -45,16 +43,16 @@ class CardTimeline extends StatelessWidget {
);
}
Widget updateTimeline(int daysCount) {
Widget update(int daysCount) {
final Widget loading = const Text('⏳');
final Widget done = const Text('');
late Future<TimelineData> futureTimeline = ScrobblesApi.fetchTimeline(daysCount);
late Future<TimelineData> future = ScrobblesApi.fetchTimeline(daysCount);
return BlocBuilder<DataTimelineCubit, DataTimelineState>(
builder: (BuildContext context, DataTimelineState dataTimelineState) {
builder: (BuildContext context, DataTimelineState data) {
return FutureBuilder<TimelineData>(
future: futureTimeline,
future: future,
builder: (context, snapshot) {
if (snapshot.hasError) {
return ShowErrorWidget(message: '${snapshot.error}');
......
......@@ -21,8 +21,8 @@ class CardTopArtists extends StatelessWidget {
final int daysCount = settings.getTopArtistsDaysCount();
return BlocBuilder<DataTopArtistsCubit, DataTopArtistsState>(
builder: (BuildContext context, DataTopArtistsState state) {
TopArtistsData artistsData = state.topArtists ?? TopArtistsData.fromJson({});
builder: (BuildContext context, DataTopArtistsState data) {
final TopArtistsData artistsData = data.topArtists ?? TopArtistsData.fromJson({});
return CardContent(
color: Theme.of(context).colorScheme.surface,
......@@ -31,18 +31,14 @@ class CardTopArtists extends StatelessWidget {
'daysCount': daysCount.toString(),
},
),
loader: updateTopArtists(daysCount),
loader: update(daysCount),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ChartTopArtists(
chartData: artistsData,
),
ChartTopArtists(chartData: artistsData),
const SizedBox(height: 8),
ChartTopArtistsStream(
chartData: artistsData,
),
ChartTopArtistsStream(chartData: artistsData),
],
),
);
......@@ -50,16 +46,16 @@ class CardTopArtists extends StatelessWidget {
);
}
Widget updateTopArtists(int daysCount) {
Widget update(int daysCount) {
final Widget loading = const Text('⏳');
final Widget done = const Text('');
late Future<TopArtistsData> futureTopArtists = ScrobblesApi.fetchTopArtists(daysCount);
late Future<TopArtistsData> future = ScrobblesApi.fetchTopArtists(daysCount);
return BlocBuilder<DataTopArtistsCubit, DataTopArtistsState>(
builder: (BuildContext context, DataTopArtistsState state) {
builder: (BuildContext context, DataTopArtistsState update) {
return FutureBuilder<TopArtistsData>(
future: futureTopArtists,
future: future,
builder: (context, snapshot) {
if (snapshot.hasError) {
return ShowErrorWidget(message: '${snapshot.error}');
......
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:scrobbles/config/app_colors.dart';
import 'package:scrobbles/models/counts_by_day.dart';
import 'package:scrobbles/ui/widgets/abstracts/custom_bar_chart.dart';
......@@ -53,9 +51,9 @@ class ChartCountsByDay extends CustomBarChart {
return maxValue;
}
Color getColorFromIndex(int index) {
Color barColor = AppColors.contentColorBlack;
switch (index) {
Color getColorFromDayIndex(int dayIndex) {
Color barColor = Colors.black;
switch (dayIndex) {
case 1:
barColor = Color.fromARGB(255, 255, 99, 132);
break;
......@@ -89,7 +87,7 @@ class ChartCountsByDay extends CustomBarChart {
final double? counts = this.chartData.data[day];
if (counts != null) {
final Color barColor = this.getColorFromIndex(day);
final Color barColor = this.getColorFromDayIndex(day);
data.add(this.getBarItem(
x: day,
......@@ -104,43 +102,6 @@ class ChartCountsByDay extends CustomBarChart {
}
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
final int day = value.toInt();
String dayShortName = '';
switch (day) {
case 1:
dayShortName = 'MON';
break;
case 2:
dayShortName = 'TUE';
break;
case 3:
dayShortName = 'WED';
break;
case 4:
dayShortName = 'THU';
break;
case 5:
dayShortName = 'FRI';
break;
case 6:
dayShortName = 'SAT';
break;
case 7:
dayShortName = 'SUN';
break;
default:
}
return SideTitleWidget(
axisSide: meta.axisSide,
space: 2,
child: Text(
tr(dayShortName),
style: const TextStyle(
color: AppColors.mainTextColor1,
fontSize: 11,
),
),
);
return getHorizontalTitlesWidgetWithDay(value, meta);
}
}
......@@ -75,22 +75,6 @@ class ChartCountsByHour extends CustomBarChart {
}
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
String text = '';
if (value % 4 == 0 || value == 23) {
text = value.toInt().toString().padLeft(2, '0');
}
return SideTitleWidget(
axisSide: meta.axisSide,
space: 2,
child: Text(
text,
style: const TextStyle(
color: AppColors.mainTextColor1,
fontSize: 11,
),
),
);
return getHorizontalTitlesWidgetWithHour(value, meta);
}
}
import 'package:easy_localization/easy_localization.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:scrobbles/config/app_colors.dart';
import 'package:scrobbles/config/app_colors.dart';
import 'package:scrobbles/models/heatmap.dart';
import 'package:scrobbles/ui/widgets/abstracts/custom_chart.dart';
import 'package:scrobbles/utils/color_extensions.dart';
class ChartHeatmap extends StatelessWidget {
class ChartHeatmap extends CustomChart {
final HeatmapData chartData;
const ChartHeatmap({super.key, required this.chartData});
......@@ -100,7 +101,7 @@ class ChartHeatmap extends StatelessWidget {
sideTitles: SideTitles(
showTitles: true,
reservedSize: 20,
getTitlesWidget: getHorizontalTitlesWidget,
getTitlesWidget: getHorizontalTitlesWidgetWithHour,
interval: 4,
),
);
......@@ -115,32 +116,7 @@ class ChartHeatmap extends StatelessWidget {
}
Widget getVerticalTitlesWidget(double value, TitleMeta meta) {
final int day = 8 - value.toInt();
String dayShortName = '';
switch (day) {
case 1:
dayShortName = 'MON';
break;
case 2:
dayShortName = 'TUE';
break;
case 3:
dayShortName = 'WED';
break;
case 4:
dayShortName = 'THU';
break;
case 5:
dayShortName = 'FRI';
break;
case 6:
dayShortName = 'SAT';
break;
case 7:
dayShortName = 'SUN';
break;
default:
}
final String dayShortName = getDayShortName(8 - value.toInt());
return SideTitleWidget(
axisSide: meta.axisSide,
......@@ -154,24 +130,4 @@ class ChartHeatmap extends StatelessWidget {
),
);
}
Widget getHorizontalTitlesWidget(double value, TitleMeta meta) {
String text = '';
if (value % 4 == 0 || value == 23) {
text = value.toInt().toString().padLeft(2, '0');
}
return SideTitleWidget(
axisSide: meta.axisSide,
space: 2,
child: Text(
text,
style: TextStyle(
color: AppColors.mainTextColor1,
fontSize: this.titleFontSize,
),
),
);
}
}
......@@ -11,27 +11,32 @@ class ChartTimelineEclecticism extends CustomLineChart {
const ChartTimelineEclecticism({super.key, required this.chartData});
final String verticalAxisTitleSuffix = '%';
@override
Widget build(BuildContext context) {
final horizontalScale = getHorizontalScale();
if (this.chartData.data.keys.length == 0) {
return SizedBox(
height: this.chartHeight,
);
}
final horizontalScale = getHorizontalScaleFromDates(this.chartData.data.keys);
// Left/right margins: 12h, in milliseconds
const double margin = 12 * 60 * 60 * 1000;
return Container(
height: this.chartHeight,
child: LineChart(
LineChartData(
lineBarsData: getDataEclecticism(),
borderData: getBorderData(),
gridData: getGridData(),
borderData: noBorderData,
gridData: noGridData,
titlesData: getTitlesData(),
lineTouchData: const LineTouchData(enabled: false),
minX: horizontalScale['min'],
maxX: horizontalScale['max'],
minX: (horizontalScale['min'] ?? 0) - margin,
maxX: (horizontalScale['max'] ?? 0) + margin,
maxY: 100,
minY: 0,
),
......@@ -40,33 +45,6 @@ class ChartTimelineEclecticism extends CustomLineChart {
);
}
Map<String, double> getHorizontalScale() {
// Left/right margins: 12h, in milliseconds
int margin = 12 * 60 * 60 * 1000;
double minDateAsDouble = double.maxFinite;
double maxDateAsDouble = -double.maxFinite;
this.chartData.data.keys.forEach((element) {
TimelineDataValue? value = this.chartData.data[element];
if (value != null) {
final double date = DateTime.parse(element).millisecondsSinceEpoch.toDouble();
if (date < minDateAsDouble) {
minDateAsDouble = date;
}
if (date > maxDateAsDouble) {
maxDateAsDouble = date;
}
}
});
return {
'min': minDateAsDouble - margin,
'max': maxDateAsDouble + margin,
};
}
List<LineChartBarData> getDataEclecticism() {
List<FlSpot> spots = [];
......
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