feat: make core pages local-first offline
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:miaoji_zhang/shared/api/api_client.dart';
|
||||
import 'package:miaoji_zhang/shared/api/business_api.dart';
|
||||
@@ -6,6 +8,7 @@ import 'package:miaoji_zhang/shared/services/current_ledger_store.dart';
|
||||
import 'package:miaoji_zhang/shared/theme/app_theme.dart';
|
||||
import 'package:miaoji_zhang/shared/widgets/app_icons.dart';
|
||||
import 'package:miaoji_zhang/shared/widgets/async_error_view.dart';
|
||||
import 'package:miaoji_zhang/shared/widgets/backend_status_icon.dart';
|
||||
import 'package:miaoji_zhang/shared/widgets/category_icon.dart';
|
||||
import 'package:miaoji_zhang/shared/services/shanghai_time.dart';
|
||||
import 'package:miaoji_zhang/shared/services/session_store.dart';
|
||||
@@ -25,13 +28,14 @@ class _ReportPageState extends State<ReportPage> {
|
||||
String? _error;
|
||||
DateTime _anchor = ShanghaiTime.now;
|
||||
_ReportKind _kind = _ReportKind.monthly;
|
||||
int _loadRevision = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
PublicConfigApi.companionNotifier.addListener(_refreshCompanion);
|
||||
CurrentLedgerStore.instance.addListener(_load);
|
||||
_load();
|
||||
unawaited(_load());
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -46,24 +50,33 @@ class _ReportPageState extends State<ReportPage> {
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
final revision = ++_loadRevision;
|
||||
setState(() {
|
||||
_loading = true;
|
||||
_error = null;
|
||||
});
|
||||
try {
|
||||
final report = switch (_kind) {
|
||||
_ReportKind.weekly => await ReportApi.weekly(_anchor),
|
||||
_ReportKind.monthly => await ReportApi.monthlyPeriod(
|
||||
_anchor.year,
|
||||
_anchor.month,
|
||||
),
|
||||
_ReportKind.yearly => await ReportApi.yearly(_anchor.year),
|
||||
final period = switch (_kind) {
|
||||
_ReportKind.weekly => 'week',
|
||||
_ReportKind.monthly => 'month',
|
||||
_ReportKind.yearly => 'year',
|
||||
};
|
||||
if (mounted) setState(() => _report = report);
|
||||
final local = ReportApi.local(period, _anchor);
|
||||
if (mounted && revision == _loadRevision) {
|
||||
setState(() => _report = local);
|
||||
}
|
||||
final remote = await ReportApi.remote(period, _anchor);
|
||||
if (mounted && revision == _loadRevision) {
|
||||
setState(() => _report = remote);
|
||||
}
|
||||
} catch (error) {
|
||||
if (mounted) setState(() => _error = apiErrorMessage(error));
|
||||
if (mounted && revision == _loadRevision && _report == null) {
|
||||
setState(() => _error = apiErrorMessage(error));
|
||||
}
|
||||
} finally {
|
||||
if (mounted) setState(() => _loading = false);
|
||||
if (mounted && revision == _loadRevision) {
|
||||
setState(() => _loading = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +121,7 @@ class _ReportPageState extends State<ReportPage> {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(SessionStore.instance.aiEnabled ? 'AI 报告' : '报告'),
|
||||
actions: [BackendStatusIcon(onRetry: _load)],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
|
||||
Reference in New Issue
Block a user