188 lines
6.9 KiB
Dart
188 lines
6.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:tetra_stats/data_objects/news.dart';
|
|
import 'package:tetra_stats/data_objects/news_entry.dart';
|
|
import 'package:tetra_stats/gen/strings.g.dart';
|
|
import 'package:tetra_stats/utils/numers_formats.dart';
|
|
import 'package:tetra_stats/utils/relative_timestamps.dart';
|
|
import 'package:tetra_stats/widgets/text_timestamp.dart';
|
|
|
|
class NewsThingy extends StatelessWidget{
|
|
final News news;
|
|
|
|
const NewsThingy(this.news, {super.key});
|
|
|
|
ListTile getNewsTile(NewsEntry news){
|
|
Map<String, String> gametypes = {
|
|
"40l": t.sprint,
|
|
"blitz": t.blitz,
|
|
"5mblast": "5,000,000 Blast",
|
|
"zenith": "Quick Play",
|
|
"zenithex": "Quick Play Expert",
|
|
};
|
|
|
|
// Individuly handle each entry type
|
|
switch (news.type) {
|
|
case "leaderboard":
|
|
return ListTile(
|
|
title: RichText(
|
|
text: TextSpan(
|
|
style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16, color: Colors.white),
|
|
text: t.newsParts.leaderboardStart,
|
|
children: [
|
|
TextSpan(text: "№${news.data["rank"]} ", style: const TextStyle(fontWeight: FontWeight.bold)),
|
|
TextSpan(text: t.newsParts.leaderboardMiddle),
|
|
TextSpan(text: "№${gametypes[news.data["gametype"]]}", style: const TextStyle(fontWeight: FontWeight.bold)),
|
|
]
|
|
)
|
|
),
|
|
subtitle: Text(timestamp(news.timestamp)),
|
|
);
|
|
case "personalbest":
|
|
return ListTile(
|
|
title: RichText(
|
|
text: TextSpan(
|
|
style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16, color: Colors.white),
|
|
text: t.newsParts.personalbest,
|
|
children: [
|
|
TextSpan(text: "${gametypes[news.data["gametype"]]} ", style: const TextStyle(fontWeight: FontWeight.bold)),
|
|
TextSpan(text: t.newsParts.personalbestMiddle),
|
|
TextSpan(text: switch (news.data["gametype"]){
|
|
"blitz" => NumberFormat.decimalPattern().format(news.data["result"]),
|
|
"40l" => get40lTime((news.data["result"]*1000).floor()),
|
|
"5mblast" => get40lTime((news.data["result"]*1000).floor()),
|
|
"zenith" => "${f2.format(news.data["result"])} m.",
|
|
"zenithex" => "${f2.format(news.data["result"])} m.",
|
|
_ => "unknown"
|
|
},
|
|
style: const TextStyle(fontWeight: FontWeight.bold)
|
|
),
|
|
]
|
|
)
|
|
),
|
|
subtitle: Text(timestamp(news.timestamp)),
|
|
leading: Image.asset(
|
|
"res/icons/improvement-local.png",
|
|
height: 48,
|
|
width: 48,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Image.asset("res/icons/kagari.png", height: 64, width: 64);
|
|
},
|
|
),
|
|
);
|
|
case "badge":
|
|
return ListTile(
|
|
title: RichText(
|
|
text: TextSpan(
|
|
style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16, color: Colors.white),
|
|
text: t.newsParts.badgeStart,
|
|
children: [
|
|
TextSpan(text: "${news.data["label"]} ", style: const TextStyle(fontWeight: FontWeight.bold)),
|
|
TextSpan(text: t.newsParts.badgeEnd)
|
|
]
|
|
)
|
|
),
|
|
subtitle: Text(timestamp(news.timestamp)),
|
|
leading: Image.asset(
|
|
"res/tetrio_badges/${news.data["type"]}.png",
|
|
height: 48,
|
|
width: 48,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Image.asset("res/icons/kagari.png", height: 64, width: 64);
|
|
},
|
|
),
|
|
);
|
|
case "rankup":
|
|
return ListTile(
|
|
title: RichText(
|
|
text: TextSpan(
|
|
style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16, color: Colors.white),
|
|
text: t.newsParts.rankupStart,
|
|
children: [
|
|
TextSpan(text: t.newsParts.rankupMiddle(r: news.data["rank"].toString().toUpperCase()), style: const TextStyle(fontWeight: FontWeight.bold)),
|
|
TextSpan(text: t.newsParts.rankupEnd)
|
|
]
|
|
)
|
|
),
|
|
subtitle: Text(timestamp(news.timestamp)),
|
|
leading: Image.asset(
|
|
"res/tetrio_tl_alpha_ranks/${news.data["rank"]}.png",
|
|
height: 48,
|
|
width: 48,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Image.asset("res/icons/kagari.png", height: 64, width: 64);
|
|
},
|
|
),
|
|
);
|
|
case "supporter":
|
|
return ListTile(
|
|
title: RichText(
|
|
text: TextSpan(
|
|
style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16, color: Colors.white),
|
|
text: t.newsParts.supporterStart,
|
|
children: [
|
|
TextSpan(text: t.newsParts.tetoSupporter, style: const TextStyle(fontWeight: FontWeight.bold))
|
|
]
|
|
)
|
|
),
|
|
subtitle: Text(timestamp(news.timestamp)),
|
|
leading: Image.asset(
|
|
"res/icons/supporter-tag.png",
|
|
height: 48,
|
|
width: 48,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Image.asset("res/icons/kagari.png", height: 64, width: 64);
|
|
},
|
|
),
|
|
);
|
|
case "supporter_gift":
|
|
return ListTile(
|
|
title: RichText(
|
|
text: TextSpan(
|
|
style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16, color: Colors.white),
|
|
text: t.newsParts.supporterGiftStart,
|
|
children: [
|
|
TextSpan(text: t.newsParts.tetoSupporter, style: const TextStyle(fontWeight: FontWeight.bold))
|
|
]
|
|
)
|
|
),
|
|
subtitle: Text(timestamp(news.timestamp)),
|
|
leading: Image.asset(
|
|
"res/icons/supporter-tag.png",
|
|
height: 48,
|
|
width: 48,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Image.asset("res/icons/kagari.png", height: 64, width: 64);
|
|
},
|
|
),
|
|
);
|
|
default: // if type is unknown
|
|
return ListTile(
|
|
title: Text(t.newsParts.unknownNews(type: news.type)),
|
|
subtitle: Text(timestamp(news.timestamp)),
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Card(
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
children: [
|
|
Row(
|
|
children: [
|
|
const Spacer(),
|
|
Text(t.news, style: const TextStyle(fontFamily: "Eurostile Round Extended")),
|
|
const Spacer()
|
|
]
|
|
),
|
|
if (news.news.isEmpty) const Center(child: Text("Empty list"))
|
|
else for (NewsEntry entry in news.news) getNewsTile(entry)
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
} |