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

Merge branch '3-get-and-display-simple-data-from-api' into 'master'

Resolve "Get and display simple data from API"

Closes #3

See merge request !2
parents 57c6f6f9 8dba8035
No related branches found
No related tags found
1 merge request!2Resolve "Get and display simple data from API"
Pipeline #4423 passed
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
app.versionName=0.0.1
app.versionCode=1
app.versionName=0.0.2
app.versionCode=2
{
"app_name": "Scrobbles",
"sample_content": "Fake sample content"
"global_statistics": "Global statistics",
"statistics_total_scrobbles_count": "Total scrobbles count:",
"statistics_selected_period": "On last {daysCount} days:",
"statistics_recent_scrobbles_count": "Scrobbles:",
"statistics_discoveries": "Discoveries:",
"statistics_discoveries_artists": "artists",
"statistics_discoveries_tracks": "tracks"
}
{
"app_name": "Scrobbles",
"sample_content": "Contenu provisoire "
"global_statistics": "Statistiques globales d'écoutes",
"statistics_total_scrobbles_count": "Nombre total d'écoutes :",
"statistics_selected_period": "Sur les {daysCount} derniers jours:",
"statistics_recent_scrobbles_count": "Écoutes :",
"statistics_discoveries": "Découvertes :",
"statistics_discoveries_artists": "artistes",
"statistics_discoveries_tracks": "morceaux"
}
Get and display simple statistics data from API
Récupère et affiche des statistiques simples depuis l'API
class StatisticsData {
final int totalCount;
final int recentCount;
final int firstPlayedArtistsCount;
final int firstPlayedTracksCount;
final int selectedPeriod;
const StatisticsData({
required this.totalCount,
required this.recentCount,
required this.firstPlayedArtistsCount,
required this.firstPlayedTracksCount,
required this.selectedPeriod,
});
factory StatisticsData.fromJson(Map<String, dynamic> json) {
return StatisticsData(
totalCount: json['totalCount'] as int,
recentCount: json['recentCount'] as int,
firstPlayedArtistsCount: json['firstPlayedArtistsCount'] as int,
firstPlayedTracksCount: json['firstPlayedTracksCount'] as int,
selectedPeriod: json['selectedPeriod'] as int,
);
}
}
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/statistics.dart';
class ScrobblesApi {
static String baseUrl = 'https://scrobble.harrault.fr';
static Future<StatisticsData> fetchStatistics() async {
final response = await http.get(Uri.parse(baseUrl + '/stats'));
if (response.statusCode == 200) {
return StatisticsData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to get data from API.');
}
}
}
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import '../widgets/header.dart';
import '../widgets/main_screen/statistics.dart';
class MainScreen extends StatelessWidget {
const MainScreen({super.key});
......@@ -15,8 +15,7 @@ class MainScreen extends StatelessWidget {
physics: const BouncingScrollPhysics(),
children: <Widget>[
const Header(text: 'app_name'),
const SizedBox(height: 8),
Text(tr('sample_content')),
const Statistics(),
const SizedBox(height: 36),
],
),
......
......
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import '../../../models/statistics.dart';
import '../../../network/scrobbles_api.dart';
class Statistics extends StatelessWidget {
const Statistics({super.key});
@override
Widget build(BuildContext context) {
late Future<StatisticsData> futureAlbum = ScrobblesApi.fetchStatistics();
return FutureBuilder<StatisticsData>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
final TextTheme textTheme = Theme.of(context).primaryTextTheme;
return Card(
elevation: 2,
shadowColor: Theme.of(context).colorScheme.shadow,
color: Theme.of(context).colorScheme.primary,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12))),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
tr('global_statistics'),
style: textTheme.titleLarge!.apply(fontWeightDelta: 2),
),
Text(
tr('statistics_total_scrobbles_count') +
' ' +
snapshot.data!.totalCount.toString(),
style: textTheme.bodyMedium,
),
Text(
'statistics_selected_period',
style: textTheme.bodyMedium,
).tr(namedArgs: {'daysCount': snapshot.data!.selectedPeriod.toString()}),
Text(
tr('statistics_recent_scrobbles_count') +
' ' +
snapshot.data!.recentCount.toString(),
style: textTheme.bodyMedium,
),
Text(
tr('statistics_discoveries') +
' ' +
snapshot.data!.firstPlayedArtistsCount.toString() +
' ' +
tr('statistics_discoveries_artists') +
' / ' +
snapshot.data!.firstPlayedTracksCount.toString() +
' ' +
tr('statistics_discoveries_tracks'),
style: textTheme.bodyMedium,
),
],
),
),
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
);
}
}
......@@ -9,6 +9,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
characters:
dependency: transitive
description:
......@@ -80,6 +88,22 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
http:
dependency: "direct main"
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
intl:
dependency: transitive
description:
......@@ -213,6 +237,38 @@ packages:
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math:
dependency: transitive
description:
......
......
......@@ -3,7 +3,7 @@ description: Display scrobbles data and charts
publish_to: 'none'
version: 0.0.1+1
version: 0.0.2+2
environment:
sdk: '^3.0.0'
......@@ -13,6 +13,7 @@ dependencies:
sdk: flutter
easy_localization: ^3.0.1
http: ^1.1.0
flutter:
uses-material-design: false
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment