HOME · GALAXY · 행성·성운 상세 · 팬덤 라운지 · 이클립스 화면
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
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)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user