TetraStats/lib/widgets/news_thingy.dart

183 lines
6.9 KiB
Dart

import 'package:flutter/foundation.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/services/tetrio_crud.dart' show webVersionDomain;
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){
// 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),
children: [
t.newsEntries.leaderboard(
rank: TextSpan(text: news.data["rank"], style: const TextStyle(fontWeight: FontWeight.bold)),
gametype: TextSpan(text: t.gamemodes[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),
children: [
t.newsEntries.personalbest(
gametype: TextSpan(text: t.gamemodes[news.data["gametype"]], style: const TextStyle(fontWeight: FontWeight.bold)),
pb: 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),
children: [
t.newsEntries.badge(badge: TextSpan(text: news.data["label"], style: const TextStyle(fontWeight: FontWeight.bold)))
]
)
),
subtitle: Text(timestamp(news.timestamp)),
leading: Image.network(
kIsWeb ? "https://${webVersionDomain}/oskware_bridge.php?endpoint=TetrioBadge&badge=${news.data["type"]}" : "https://tetr.io/res/badges/${news.data["type"]}.png",
height: 48,
width: 48,
errorBuilder:(context, error, stackTrace) {
return Image.asset("res/icons/kagari.png", height: 32, width: 32);
}
)
);
case "rankup":
return ListTile(
title: RichText(
text: TextSpan(
style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16, color: Colors.white),
children: [
t.newsEntries.rankup(rank: TextSpan(text: t.rankupMiddle(r: news.data["rank"].toString().toUpperCase()), style: const TextStyle(fontWeight: FontWeight.bold)))
]
)
),
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),
children: [
t.newsEntries.supporter(s: (p0) => TextSpan(text: p0, 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),
children: [
t.newsEntries.supporter_gift(s: (p0) => TextSpan(text: p0, 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: RichText(
text: TextSpan(
style: const TextStyle(fontFamily: 'Eurostile Round', fontSize: 16, color: Colors.white),
children: [
t.newsEntries.unknown(type: TextSpan(text: news.type, style: const TextStyle(fontWeight: FontWeight.bold)))
]
)
),
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)
],
),
),
);
}
}