@@ -17,6 +17,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
1717class MalaCounterState {
1818 const MalaCounterState ({
1919 this .total = 0 ,
20+ this .totalCounted = 0 ,
2021 this .beadsPerRound = kBeadsPerRound,
2122 this .isSeeding = true ,
2223 this .seedFailed = false ,
@@ -26,6 +27,9 @@ class MalaCounterState {
2627 });
2728
2829 final int total;
30+
31+ /// Lifetime `total_counted` baseline from `GET /accumulators/{parent_id}` .
32+ final int totalCounted;
2933 final int beadsPerRound;
3034
3135 /// Per-user bead artwork from the accumulator detail. Null falls back to the
@@ -50,6 +54,7 @@ class MalaCounterState {
5054
5155 MalaCounterState copyWith ({
5256 int ? total,
57+ int ? totalCounted,
5358 int ? beadsPerRound,
5459 bool ? isSeeding,
5560 bool ? seedFailed,
@@ -58,6 +63,7 @@ class MalaCounterState {
5863 Uint8List ? beadImageBytes,
5964 }) => MalaCounterState (
6065 total: total ?? this .total,
66+ totalCounted: totalCounted ?? this .totalCounted,
6167 beadsPerRound: beadsPerRound ?? this .beadsPerRound,
6268 isSeeding: isSeeding ?? this .isSeeding,
6369 seedFailed: seedFailed ?? this .seedFailed,
@@ -112,6 +118,27 @@ class MalaCounterNotifier extends StateNotifier<MalaCounterState> {
112118
113119 String get _presetId => _mantra.presetId;
114120
121+ /// Lifetime total for [GroupAccumulationsSheet] : API `total_counted` baseline
122+ /// plus any unsynced session taps.
123+ int get displayLifetimeCount {
124+ final userId = _userId;
125+ if (userId == null ) return state.totalCounted;
126+ final local = _local.read (userId, _presetId);
127+ final dirty = local.total - local.syncedTotal;
128+ if (dirty <= 0 ) return state.totalCounted;
129+ return state.totalCounted + dirty;
130+ }
131+
132+ /// Refreshes [MalaCounterState.totalCounted] after a successful personal sync.
133+ void handlePersonalCountSynced (String presetId) {
134+ if (presetId != _presetId || ! mounted) return ;
135+ final userId = _userId;
136+ if (userId == null ) return ;
137+ state = state.copyWith (
138+ totalCounted: _local.read (userId, _presetId).totalCounted,
139+ );
140+ }
141+
115142 static Future <List <int >> _emptyImageDownload (String _) async => const [];
116143
117144 /// Seed local state first, then reconcile remote state when available.
@@ -131,6 +158,7 @@ class MalaCounterNotifier extends StateNotifier<MalaCounterState> {
131158 final fallbackImageUrl = localState.beadImageUrl ?? _mantra.beadImageUrl;
132159 state = state.copyWith (
133160 total: localState.total,
161+ totalCounted: localState.totalCounted,
134162 isSeeding: false ,
135163 seedFailed: false ,
136164 beadImageUrl: fallbackImageUrl,
@@ -167,19 +195,22 @@ class MalaCounterNotifier extends StateNotifier<MalaCounterState> {
167195 final syncedTotal = serverAccId != null ? serverTotal : 0 ;
168196
169197 final beadImageUrl = detail.beadImageUrl ?? localState.beadImageUrl;
198+ final totalCounted = max (detail.totalCounted, localState.totalCounted);
170199 _local.write (
171200 userId,
172201 _presetId,
173202 localState.copyWith (
174203 total: total,
175204 syncedTotal: syncedTotal,
205+ totalCounted: totalCounted,
176206 accumulatorId: serverAccId ?? localState.accumulatorId,
177207 beadImageUrl: beadImageUrl,
178208 ),
179209 );
180210
181211 state = state.copyWith (
182212 total: total,
213+ totalCounted: totalCounted,
183214 isSeeding: false ,
184215 seedFailed: false ,
185216 beadImageUrl: beadImageUrl,
0 commit comments