Files
fanuzu/app/lib/features/planet/planet_history_screen.dart
T

138 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import 'planet_data.dart';
import '../../core/i18n/app_locale.dart';
class PlanetHistoryScreen extends StatefulWidget {
const PlanetHistoryScreen({
super.key,
required this.repository,
required this.fandomName,
});
final PlanetRepository repository;
final String fandomName;
@override
State<PlanetHistoryScreen> createState() => _PlanetHistoryScreenState();
}
class _PlanetHistoryScreenState extends State<PlanetHistoryScreen> {
final _items = <PlanetHistoryEntry>[];
String? _cursor;
bool _loading = false;
bool _loaded = false;
bool _failed = false;
bool _personal = false;
@override
void initState() {
super.initState();
_load();
}
Future<void> _load() async {
if (_loading) return;
setState(() {
_loading = true;
_failed = false;
});
try {
final page = await widget.repository.history(
cursor: _cursor,
personal: _personal,
);
if (!mounted) return;
setState(() {
final ids = _items.map((item) => item.id).toSet();
_items.addAll(page.items.where((item) => ids.add(item.id)));
_cursor = page.nextCursor;
_loaded = true;
});
} catch (_) {
if (mounted) setState(() => _failed = true);
} finally {
if (mounted) setState(() => _loading = false);
}
}
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: Text(context.l10n.historyTitle)),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
Text(widget.fandomName, style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 16),
SegmentedButton<bool>(
segments: [
ButtonSegment(
value: false,
label: Text(context.l10n.homeFandomHistory),
),
ButtonSegment(value: true, label: Text(context.l10n.historyMine)),
],
selected: {_personal},
onSelectionChanged: _loading
? null
: (selection) {
if (selection.single == _personal) return;
setState(() {
_personal = selection.single;
_items.clear();
_cursor = null;
_loaded = false;
});
_load();
},
),
const SizedBox(height: 16),
for (final item in _items)
ListTile(
contentPadding: EdgeInsets.zero,
leading: Icon(switch (item.kind) {
PlanetHistoryKind.evolution => Icons.auto_awesome,
PlanetHistoryKind.hibernation => Icons.bedtime_outlined,
PlanetHistoryKind.wakeUp => Icons.wb_sunny_outlined,
PlanetHistoryKind.zap => Icons.bolt,
PlanetHistoryKind.questReward => Icons.task_alt,
PlanetHistoryKind.companyAdBonus => Icons.play_circle_outline,
PlanetHistoryKind.funding => Icons.favorite_border,
}),
title: Text(switch (item.kind) {
PlanetHistoryKind.evolution => context.l10n.historyEvolution(
'${item.fromStage}',
'${item.toStage}',
),
PlanetHistoryKind.hibernation => context.l10n.historyHibernation,
PlanetHistoryKind.wakeUp => context.l10n.historyWakeUp,
PlanetHistoryKind.zap => context.l10n.historyZap,
PlanetHistoryKind.questReward => context.l10n.historyQuest,
PlanetHistoryKind.companyAdBonus => context.l10n.historyAdBonus,
PlanetHistoryKind.funding => context.l10n.historyFunding,
}),
subtitle: Text(
[
MaterialLocalizations.of(
context,
).formatMediumDate(item.occurredAt.toLocal()),
if (item.amount != null)
context.l10n.historyGrowthPop('${item.amount}'),
if (item.participationConfirmed) context.l10n.historyJoined,
].join('\n'),
),
),
if (_loading) const Center(child: CircularProgressIndicator()),
if (_failed) ...[
Text(context.l10n.historyLoadFailed),
TextButton(onPressed: _load, child: Text(context.l10n.commonRetry)),
] else if (_loaded && _items.isEmpty && _cursor == null)
Text(
_personal
? context.l10n.historyMineEmpty
: context.l10n.historyFandomEmpty,
),
if (!_loading && !_failed && _cursor != null)
TextButton(onPressed: _load, child: Text(context.l10n.historyMore)),
],
),
);
}