From 22d2e99400ff7331a877e6a1320904707e42bff6 Mon Sep 17 00:00:00 2001 From: Mikkeli Matlock Date: Sat, 23 Aug 2025 22:56:03 +0900 Subject: [PATCH] Fix score preservation to maintain visual positions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes score preservation logic to keep scores in their visual row positions rather than logical end positions when switching arrow count modes. Example: End #4 scores in 3-arrow mode now move to second row of End #2 in 6-arrow mode, then auto-sort to first row as expected. - Flattens scores by visual row order (1-12) before mode switch - Redistributes scores to new structure maintaining visual positions - Temporarily disables parent notifications during preservation - Applies per-end sorting after redistribution completes 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- lib/presentation/pages/scoring_page.dart | 74 ++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/lib/presentation/pages/scoring_page.dart b/lib/presentation/pages/scoring_page.dart index 34eff05..d561bd1 100644 --- a/lib/presentation/pages/scoring_page.dart +++ b/lib/presentation/pages/scoring_page.dart @@ -33,6 +33,7 @@ class _ScoringPageState extends State with SingleTickerProviderStat int? activeEndIndex; late AnimationController _animationController; late Animation _keypadAnimation; + bool _isPreservingScores = false; @override void initState() { @@ -146,18 +147,77 @@ class _ScoringPageState extends State with SingleTickerProviderStat } void _preserveScoresWithNewArrowCount(List> oldScores, int oldArrowsPerEnd) { + _isPreservingScores = true; // Disable parent notifications during preservation + // Initialize new score structure scores = List.generate( endsPerSet, (index) => List.generate(arrowsPerEnd, (index) => ''), ); - // Copy over existing scores, respecting the new structure - for (int endIndex = 0; endIndex < oldScores.length && endIndex < scores.length; endIndex++) { - for (int arrowIndex = 0; arrowIndex < oldScores[endIndex].length && arrowIndex < arrowsPerEnd; arrowIndex++) { - scores[endIndex][arrowIndex] = oldScores[endIndex][arrowIndex]; + // Flatten old scores by visual rows, then redistribute to new structure + List allOldScores = []; + + // Extract all scores in visual row order (12 rows total) + for (int visualRow = 0; visualRow < 12; visualRow++) { + if (oldArrowsPerEnd == 3) { + // 3-arrow mode: 1 visual row = 1 logical end + if (visualRow < oldScores.length) { + for (int col = 0; col < 3 && col < oldScores[visualRow].length; col++) { + allOldScores.add(oldScores[visualRow][col]); + } + } + } else { + // 6-arrow mode: 2 visual rows = 1 logical end + int logicalEnd = visualRow ~/ 2; + int rowInEnd = visualRow % 2; + if (logicalEnd < oldScores.length) { + for (int col = 0; col < 3; col++) { + int arrowIndex = (rowInEnd * 3) + col; + if (arrowIndex < oldScores[logicalEnd].length) { + allOldScores.add(oldScores[logicalEnd][arrowIndex]); + } + } + } } } + + // Redistribute to new structure by visual rows + int scoreIndex = 0; + for (int visualRow = 0; visualRow < 12; visualRow++) { + if (arrowsPerEnd == 3) { + // 3-arrow mode: 1 visual row = 1 logical end + if (visualRow < scores.length) { + for (int col = 0; col < 3; col++) { + if (scoreIndex < allOldScores.length && allOldScores[scoreIndex].isNotEmpty) { + scores[visualRow][col] = allOldScores[scoreIndex]; + } + scoreIndex++; + } + // Sort the end after adding scores + _sortEndScores(visualRow); + } + } else { + // 6-arrow mode: 2 visual rows = 1 logical end + int logicalEnd = visualRow ~/ 2; + int rowInEnd = visualRow % 2; + if (logicalEnd < scores.length) { + for (int col = 0; col < 3; col++) { + int arrowIndex = (rowInEnd * 3) + col; + if (arrowIndex < arrowsPerEnd && scoreIndex < allOldScores.length && allOldScores[scoreIndex].isNotEmpty) { + scores[logicalEnd][arrowIndex] = allOldScores[scoreIndex]; + } + scoreIndex++; + } + // Sort the end after completing both rows of the logical end + if (rowInEnd == 1) { + _sortEndScores(logicalEnd); + } + } + } + } + + _isPreservingScores = false; // Re-enable parent notifications } void _sortEndScores(int endIndex) { @@ -185,8 +245,10 @@ class _ScoringPageState extends State with SingleTickerProviderStat // Update scores array scores[endIndex] = sortedScores; - // Notify parent of score changes - widget.onScoresUpdated(scores); + // Notify parent of score changes (unless we're preserving scores) + if (!_isPreservingScores) { + widget.onScoresUpdated(scores); + } } int _findFirstEmptyCellInEnd(int endIndex) {