Showing
5 changed files
with
106 additions
and
34 deletions
| @@ -38,6 +38,7 @@ class ActivityBurnReportLogic extends ReportPeriodLogic { | @@ -38,6 +38,7 @@ class ActivityBurnReportLogic extends ReportPeriodLogic { | ||
| 38 | final weeklyReport = Rxn<WeeklyActivityBurnReport>(); | 38 | final weeklyReport = Rxn<WeeklyActivityBurnReport>(); |
| 39 | final monthlyReport = Rxn<MonthlyActivityBurnReport>(); | 39 | final monthlyReport = Rxn<MonthlyActivityBurnReport>(); |
| 40 | final _myUserId = Get.find<UserStateService>().userId; | 40 | final _myUserId = Get.find<UserStateService>().userId; |
| 41 | + int _reportRequestId = 0; | ||
| 41 | bool get isMySelf => | 42 | bool get isMySelf => |
| 42 | targetUserId.value == null || _myUserId == targetUserId.value; | 43 | targetUserId.value == null || _myUserId == targetUserId.value; |
| 43 | 44 | ||
| @@ -50,28 +51,40 @@ class ActivityBurnReportLogic extends ReportPeriodLogic { | @@ -50,28 +51,40 @@ class ActivityBurnReportLogic extends ReportPeriodLogic { | ||
| 50 | 51 | ||
| 51 | @override | 52 | @override |
| 52 | Future<void> loadReport() async { | 53 | Future<void> loadReport() async { |
| 53 | - isLoading.value = !isMySelf; | 54 | + final requestId = ++_reportRequestId; |
| 55 | + final period = selectedPeriod.value; | ||
| 56 | + final currentTargetUserId = targetUserId.value; | ||
| 57 | + final isCurrentUser = | ||
| 58 | + currentTargetUserId == null || _myUserId == currentTargetUserId; | ||
| 59 | + isLoading.value = !isCurrentUser; | ||
| 54 | 60 | ||
| 55 | try { | 61 | try { |
| 56 | - if (selectedPeriod.value == ReportPeriod.week) { | ||
| 57 | - weeklyReport.value = await repository.getWeeklyReport( | 62 | + if (period == ReportPeriod.week) { |
| 63 | + final result = await repository.getWeeklyReport( | ||
| 58 | weekStart, | 64 | weekStart, |
| 59 | - targetUserId: targetUserId.value, | 65 | + targetUserId: currentTargetUserId, |
| 60 | ); | 66 | ); |
| 61 | - } else if (selectedPeriod.value == ReportPeriod.month) { | 67 | + if (requestId != _reportRequestId) return; |
| 68 | + weeklyReport.value = result; | ||
| 69 | + } else if (period == ReportPeriod.month) { | ||
| 62 | final result = await repository.getMonthlyReport( | 70 | final result = await repository.getMonthlyReport( |
| 63 | monthStart, | 71 | monthStart, |
| 64 | - targetUserId: targetUserId.value, | 72 | + targetUserId: currentTargetUserId, |
| 65 | ); | 73 | ); |
| 74 | + if (requestId != _reportRequestId) return; | ||
| 66 | monthlyReport.value = result; | 75 | monthlyReport.value = result; |
| 67 | } else { | 76 | } else { |
| 68 | - report.value = await repository.getDailyReport( | 77 | + final result = await repository.getDailyReport( |
| 69 | selectedDate.value, | 78 | selectedDate.value, |
| 70 | - targetUserId: targetUserId.value, | 79 | + targetUserId: currentTargetUserId, |
| 71 | ); | 80 | ); |
| 81 | + if (requestId != _reportRequestId) return; | ||
| 82 | + report.value = result; | ||
| 72 | } | 83 | } |
| 73 | } finally { | 84 | } finally { |
| 74 | - isLoading.value = false; | 85 | + if (requestId == _reportRequestId) { |
| 86 | + isLoading.value = false; | ||
| 87 | + } | ||
| 75 | } | 88 | } |
| 76 | } | 89 | } |
| 77 | 90 |
| @@ -265,6 +265,8 @@ class _HrvTrendSectionState extends State<_HrvTrendSection> { | @@ -265,6 +265,8 @@ class _HrvTrendSectionState extends State<_HrvTrendSection> { | ||
| 265 | 265 | ||
| 266 | Future<void> _syncExternalQuery() async { | 266 | Future<void> _syncExternalQuery() async { |
| 267 | _syncingExternalQuery = true; | 267 | _syncingExternalQuery = true; |
| 268 | + final targetUserChanged = | ||
| 269 | + _logic.targetUserId.value != widget.query.targetUserId; | ||
| 268 | _logic.targetUserId.value = widget.query.targetUserId; | 270 | _logic.targetUserId.value = widget.query.targetUserId; |
| 269 | _logHrvTrend( | 271 | _logHrvTrend( |
| 270 | 'section_syncExternalQuery_start period=${widget.query.period.name} ' | 272 | 'section_syncExternalQuery_start period=${widget.query.period.name} ' |
| @@ -276,7 +278,9 @@ class _HrvTrendSectionState extends State<_HrvTrendSection> { | @@ -276,7 +278,9 @@ class _HrvTrendSectionState extends State<_HrvTrendSection> { | ||
| 276 | await _logic.selectQuery( | 278 | await _logic.selectQuery( |
| 277 | widget.query.period, | 279 | widget.query.period, |
| 278 | widget.query.date, | 280 | widget.query.date, |
| 279 | - forceRefresh: false, | 281 | + // A user switch can keep the same period and date. Refresh in that |
| 282 | + // case so the report is not left showing the previous user's data. | ||
| 283 | + forceRefresh: targetUserChanged, | ||
| 280 | ); | 284 | ); |
| 281 | } else { | 285 | } else { |
| 282 | _logic.initializeQuery(widget.query.period, widget.query.date); | 286 | _logic.initializeQuery(widget.query.period, widget.query.date); |
| @@ -391,9 +395,15 @@ class _ActivityBurnTrendSectionState extends State<_ActivityBurnTrendSection> { | @@ -391,9 +395,15 @@ class _ActivityBurnTrendSectionState extends State<_ActivityBurnTrendSection> { | ||
| 391 | 395 | ||
| 392 | Future<void> _syncExternalQuery() async { | 396 | Future<void> _syncExternalQuery() async { |
| 393 | _syncingExternalQuery = true; | 397 | _syncingExternalQuery = true; |
| 398 | + final targetUserChanged = | ||
| 399 | + _logic.targetUserId.value != widget.query.targetUserId; | ||
| 394 | _logic.targetUserId.value = widget.query.targetUserId; | 400 | _logic.targetUserId.value = widget.query.targetUserId; |
| 395 | try { | 401 | try { |
| 396 | - await _logic.selectQuery(widget.query.period, widget.query.date); | 402 | + await _logic.selectQuery( |
| 403 | + widget.query.period, | ||
| 404 | + widget.query.date, | ||
| 405 | + forceRefresh: targetUserChanged, | ||
| 406 | + ); | ||
| 397 | } finally { | 407 | } finally { |
| 398 | _syncingExternalQuery = false; | 408 | _syncingExternalQuery = false; |
| 399 | } | 409 | } |
| @@ -494,9 +504,15 @@ class _SleepTrendSectionState extends State<_SleepTrendSection> { | @@ -494,9 +504,15 @@ class _SleepTrendSectionState extends State<_SleepTrendSection> { | ||
| 494 | 504 | ||
| 495 | Future<void> _syncExternalQuery() async { | 505 | Future<void> _syncExternalQuery() async { |
| 496 | _syncingExternalQuery = true; | 506 | _syncingExternalQuery = true; |
| 507 | + final targetUserChanged = | ||
| 508 | + _logic.targetUserId.value != widget.query.targetUserId; | ||
| 497 | _logic.targetUserId.value = widget.query.targetUserId; | 509 | _logic.targetUserId.value = widget.query.targetUserId; |
| 498 | try { | 510 | try { |
| 499 | - await _logic.selectQuery(widget.query.period, widget.query.date); | 511 | + await _logic.selectQuery( |
| 512 | + widget.query.period, | ||
| 513 | + widget.query.date, | ||
| 514 | + forceRefresh: targetUserChanged, | ||
| 515 | + ); | ||
| 500 | } finally { | 516 | } finally { |
| 501 | _syncingExternalQuery = false; | 517 | _syncingExternalQuery = false; |
| 502 | } | 518 | } |
| @@ -63,6 +63,10 @@ class TrendController extends GetxController with HealthTrendControl { | @@ -63,6 +63,10 @@ class TrendController extends GetxController with HealthTrendControl { | ||
| 63 | final previousIndex = selectedTypeIndex.value; | 63 | final previousIndex = selectedTypeIndex.value; |
| 64 | super.changeType(index); | 64 | super.changeType(index); |
| 65 | if (_isPageVisible && selectedTypeIndex.value != previousIndex) { | 65 | if (_isPageVisible && selectedTypeIndex.value != previousIndex) { |
| 66 | + // The other report sections may have loaded while this tab was hidden. | ||
| 67 | + // Refresh only the newly selected section through its selected-state | ||
| 68 | + // guard so it does not show stale preloaded data. | ||
| 69 | + refreshToken.value++; | ||
| 66 | _trackEnterPage(); | 70 | _trackEnterPage(); |
| 67 | } | 71 | } |
| 68 | } | 72 | } |
| @@ -32,6 +32,7 @@ class HrvReportLogic extends ReportPeriodLogic { | @@ -32,6 +32,7 @@ class HrvReportLogic extends ReportPeriodLogic { | ||
| 32 | final yearlyReport = Rxn<YearlyHrvReport>(); | 32 | final yearlyReport = Rxn<YearlyHrvReport>(); |
| 33 | final HrvReportRepository repository; | 33 | final HrvReportRepository repository; |
| 34 | final _myUserId = Get.find<UserStateService>().userId; | 34 | final _myUserId = Get.find<UserStateService>().userId; |
| 35 | + int _reportRequestId = 0; | ||
| 35 | static const _logMarker = '[OHOS_HRV_TREND_PROFILE]'; | 36 | static const _logMarker = '[OHOS_HRV_TREND_PROFILE]'; |
| 36 | bool get isMySelf => | 37 | bool get isMySelf => |
| 37 | targetUserId.value == null || _myUserId == targetUserId.value; | 38 | targetUserId.value == null || _myUserId == targetUserId.value; |
| @@ -51,41 +52,51 @@ class HrvReportLogic extends ReportPeriodLogic { | @@ -51,41 +52,51 @@ class HrvReportLogic extends ReportPeriodLogic { | ||
| 51 | 52 | ||
| 52 | @override | 53 | @override |
| 53 | Future<void> loadReport() async { | 54 | Future<void> loadReport() async { |
| 55 | + final requestId = ++_reportRequestId; | ||
| 54 | final stopwatch = Stopwatch()..start(); | 56 | final stopwatch = Stopwatch()..start(); |
| 55 | final period = selectedPeriod.value; | 57 | final period = selectedPeriod.value; |
| 56 | final date = selectedDate.value; | 58 | final date = selectedDate.value; |
| 59 | + final currentTargetUserId = targetUserId.value; | ||
| 60 | + final isCurrentUser = | ||
| 61 | + currentTargetUserId == null || _myUserId == currentTargetUserId; | ||
| 57 | _log( | 62 | _log( |
| 58 | 'logic_load_start period=${period.name} date=$date ' | 63 | 'logic_load_start period=${period.name} date=$date ' |
| 59 | - 'targetUserId=${targetUserId.value} isMySelf=$isMySelf', | 64 | + 'targetUserId=$currentTargetUserId isMySelf=$isCurrentUser', |
| 60 | ); | 65 | ); |
| 61 | - isLoading.value = !isMySelf; | 66 | + isLoading.value = !isCurrentUser; |
| 62 | 67 | ||
| 63 | try { | 68 | try { |
| 64 | if (period == ReportPeriod.year) { | 69 | if (period == ReportPeriod.year) { |
| 65 | - yearlyReport.value = await repository.getYearlyReport( | 70 | + final result = await repository.getYearlyReport( |
| 66 | date.year, | 71 | date.year, |
| 67 | - targetUserId: targetUserId.value, | 72 | + targetUserId: currentTargetUserId, |
| 68 | ); | 73 | ); |
| 74 | + if (requestId != _reportRequestId) return; | ||
| 75 | + yearlyReport.value = result; | ||
| 69 | _log( | 76 | _log( |
| 70 | 'logic_assign_finish period=${period.name} ' | 77 | 'logic_assign_finish period=${period.name} ' |
| 71 | 'days=${yearlyReport.value?.days.length ?? 0} ' | 78 | 'days=${yearlyReport.value?.days.length ?? 0} ' |
| 72 | 'elapsedMs=${stopwatch.elapsedMilliseconds}', | 79 | 'elapsedMs=${stopwatch.elapsedMilliseconds}', |
| 73 | ); | 80 | ); |
| 74 | } else if (period == ReportPeriod.month) { | 81 | } else if (period == ReportPeriod.month) { |
| 75 | - monthlyReport.value = await repository.getMonthlyReport( | 82 | + final result = await repository.getMonthlyReport( |
| 76 | monthStart, | 83 | monthStart, |
| 77 | - targetUserId: targetUserId.value, | 84 | + targetUserId: currentTargetUserId, |
| 78 | ); | 85 | ); |
| 86 | + if (requestId != _reportRequestId) return; | ||
| 87 | + monthlyReport.value = result; | ||
| 79 | _log( | 88 | _log( |
| 80 | 'logic_assign_finish period=${period.name} ' | 89 | 'logic_assign_finish period=${period.name} ' |
| 81 | 'days=${monthlyReport.value?.days.length ?? 0} ' | 90 | 'days=${monthlyReport.value?.days.length ?? 0} ' |
| 82 | 'elapsedMs=${stopwatch.elapsedMilliseconds}', | 91 | 'elapsedMs=${stopwatch.elapsedMilliseconds}', |
| 83 | ); | 92 | ); |
| 84 | } else { | 93 | } else { |
| 85 | - weeklyReport.value = await repository.getWeeklyReport( | 94 | + final result = await repository.getWeeklyReport( |
| 86 | weekStart, | 95 | weekStart, |
| 87 | - targetUserId: targetUserId.value, | 96 | + targetUserId: currentTargetUserId, |
| 88 | ); | 97 | ); |
| 98 | + if (requestId != _reportRequestId) return; | ||
| 99 | + weeklyReport.value = result; | ||
| 89 | _log( | 100 | _log( |
| 90 | 'logic_assign_finish period=${period.name} ' | 101 | 'logic_assign_finish period=${period.name} ' |
| 91 | 'days=${weeklyReport.value?.days.length ?? 0} ' | 102 | 'days=${weeklyReport.value?.days.length ?? 0} ' |
| @@ -93,7 +104,9 @@ class HrvReportLogic extends ReportPeriodLogic { | @@ -93,7 +104,9 @@ class HrvReportLogic extends ReportPeriodLogic { | ||
| 93 | ); | 104 | ); |
| 94 | } | 105 | } |
| 95 | } finally { | 106 | } finally { |
| 96 | - isLoading.value = false; | 107 | + if (requestId == _reportRequestId) { |
| 108 | + isLoading.value = false; | ||
| 109 | + } | ||
| 97 | _log( | 110 | _log( |
| 98 | 'logic_load_finish period=$period date=$date ' | 111 | 'logic_load_finish period=$period date=$date ' |
| 99 | 'elapsedMs=${stopwatch.elapsedMilliseconds}', | 112 | 'elapsedMs=${stopwatch.elapsedMilliseconds}', |
| @@ -38,6 +38,7 @@ class SleepReportLogic extends ReportPeriodLogic { | @@ -38,6 +38,7 @@ class SleepReportLogic extends ReportPeriodLogic { | ||
| 38 | final weeklyReport = Rxn<WeeklySleepReport>(); | 38 | final weeklyReport = Rxn<WeeklySleepReport>(); |
| 39 | final monthlyReport = Rxn<MonthlySleepReport>(); | 39 | final monthlyReport = Rxn<MonthlySleepReport>(); |
| 40 | final _myUserId = Get.find<UserStateService>().userId; | 40 | final _myUserId = Get.find<UserStateService>().userId; |
| 41 | + int _reportRequestId = 0; | ||
| 41 | bool get isMySelf => | 42 | bool get isMySelf => |
| 42 | targetUserId.value == null || _myUserId == targetUserId.value; | 43 | targetUserId.value == null || _myUserId == targetUserId.value; |
| 43 | 44 | ||
| @@ -60,39 +61,64 @@ class SleepReportLogic extends ReportPeriodLogic { | @@ -60,39 +61,64 @@ class SleepReportLogic extends ReportPeriodLogic { | ||
| 60 | } | 61 | } |
| 61 | 62 | ||
| 62 | Future<void> loadDailyReport() async { | 63 | Future<void> loadDailyReport() async { |
| 63 | - isLoading.value = !isMySelf; | 64 | + final requestId = ++_reportRequestId; |
| 65 | + final date = selectedDate.value; | ||
| 66 | + final currentTargetUserId = targetUserId.value; | ||
| 67 | + final isCurrentUser = | ||
| 68 | + currentTargetUserId == null || _myUserId == currentTargetUserId; | ||
| 69 | + isLoading.value = !isCurrentUser; | ||
| 64 | try { | 70 | try { |
| 65 | - report.value = await repository.getDailyReport( | ||
| 66 | - selectedDate.value, | ||
| 67 | - targetUserId: targetUserId.value, | 71 | + final result = await repository.getDailyReport( |
| 72 | + date, | ||
| 73 | + targetUserId: currentTargetUserId, | ||
| 68 | ); | 74 | ); |
| 75 | + if (requestId != _reportRequestId) return; | ||
| 76 | + report.value = result; | ||
| 69 | } finally { | 77 | } finally { |
| 70 | - isLoading.value = false; | 78 | + if (requestId == _reportRequestId) { |
| 79 | + isLoading.value = false; | ||
| 80 | + } | ||
| 71 | } | 81 | } |
| 72 | } | 82 | } |
| 73 | 83 | ||
| 74 | Future<void> loadWeeklyReport() async { | 84 | Future<void> loadWeeklyReport() async { |
| 75 | - isLoading.value = !isMySelf; | 85 | + final requestId = ++_reportRequestId; |
| 86 | + final currentTargetUserId = targetUserId.value; | ||
| 87 | + final isCurrentUser = | ||
| 88 | + currentTargetUserId == null || _myUserId == currentTargetUserId; | ||
| 89 | + isLoading.value = !isCurrentUser; | ||
| 76 | try { | 90 | try { |
| 77 | - weeklyReport.value = await repository.getWeeklyReport( | 91 | + final result = await repository.getWeeklyReport( |
| 78 | weekStart, | 92 | weekStart, |
| 79 | - targetUserId: targetUserId.value, | 93 | + targetUserId: currentTargetUserId, |
| 80 | ); | 94 | ); |
| 95 | + if (requestId != _reportRequestId) return; | ||
| 96 | + weeklyReport.value = result; | ||
| 81 | } finally { | 97 | } finally { |
| 82 | - isLoading.value = false; | 98 | + if (requestId == _reportRequestId) { |
| 99 | + isLoading.value = false; | ||
| 100 | + } | ||
| 83 | } | 101 | } |
| 84 | } | 102 | } |
| 85 | 103 | ||
| 86 | Future<void> loadMonthlyReport() async { | 104 | Future<void> loadMonthlyReport() async { |
| 87 | - isLoading.value = !isMySelf; | 105 | + final requestId = ++_reportRequestId; |
| 106 | + final currentTargetUserId = targetUserId.value; | ||
| 107 | + final isCurrentUser = | ||
| 108 | + currentTargetUserId == null || _myUserId == currentTargetUserId; | ||
| 109 | + isLoading.value = !isCurrentUser; | ||
| 88 | monthlyReport.value = null; | 110 | monthlyReport.value = null; |
| 89 | try { | 111 | try { |
| 90 | - monthlyReport.value = await repository.getMonthlyReport( | 112 | + final result = await repository.getMonthlyReport( |
| 91 | monthStart, | 113 | monthStart, |
| 92 | - targetUserId: targetUserId.value, | 114 | + targetUserId: currentTargetUserId, |
| 93 | ); | 115 | ); |
| 116 | + if (requestId != _reportRequestId) return; | ||
| 117 | + monthlyReport.value = result; | ||
| 94 | } finally { | 118 | } finally { |
| 95 | - isLoading.value = false; | 119 | + if (requestId == _reportRequestId) { |
| 120 | + isLoading.value = false; | ||
| 121 | + } | ||
| 96 | } | 122 | } |
| 97 | } | 123 | } |
| 98 | 124 |
-
Please register or login to post a comment