@@ -14,6 +14,10 @@ class BadgeSlotProvider with ChangeNotifier {
1414 // Available slot numbers pool
1515 final Set <int > _availableSlots = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };
1616
17+ // Maps badge key -> visual order in the list (for display)
18+ // Visual order represents the target position where badge should appear
19+ final Map <String , int > _badgeKeyToVisualOrder = {};
20+
1721 static const int maxSelectedBadges = 8 ;
1822
1923 Set <String > get selectedBadges => _badgeKeyToSelectionOrder.keys.toSet ();
@@ -32,41 +36,90 @@ class BadgeSlotProvider with ChangeNotifier {
3236 return entries.map ((e) => e.key).toList ();
3337 }
3438
35- /// ✅ Updated reorderSlots to perform push-down insertion
39+ /// Swaps slot assignments between two badges when drag and drop occurs
3640 void reorderSlots (String fromBadgeKey, String toBadgeKey) {
3741 if (! _badgeKeyToSelectionOrder.containsKey (fromBadgeKey) ||
3842 ! _badgeKeyToSelectionOrder.containsKey (toBadgeKey)) {
3943 return ;
4044 }
4145
42- final orderedKeys = getSelectionsOrderedBySlot ();
43- orderedKeys.remove (fromBadgeKey);
44- final toIndex = orderedKeys.indexOf (toBadgeKey);
46+ // Swap the slot assignments
47+ final fromSlot = _badgeKeyToSlot[fromBadgeKey];
48+ final toSlot = _badgeKeyToSlot[toBadgeKey];
49+
50+ if (fromSlot != null && toSlot != null ) {
51+ _badgeKeyToSlot[fromBadgeKey] = toSlot;
52+ _badgeKeyToSlot[toBadgeKey] = fromSlot;
53+ }
54+
55+ // Swap the visual order assignments
56+ final fromVisual = _badgeKeyToVisualOrder[fromBadgeKey];
57+ final toVisual = _badgeKeyToVisualOrder[toBadgeKey];
58+
59+ if (fromVisual != null && toVisual != null ) {
60+ // Both have visual order, swap them
61+ _badgeKeyToVisualOrder[fromBadgeKey] = toVisual;
62+ _badgeKeyToVisualOrder[toBadgeKey] = fromVisual;
63+ } else if (fromVisual == null && toVisual == null ) {
64+ // Neither has visual order, assign them based on slots after swap
65+ // Use the swapped slot numbers as visual order
66+ if (fromSlot != null && toSlot != null ) {
67+ _badgeKeyToVisualOrder[fromBadgeKey] = toSlot;
68+ _badgeKeyToVisualOrder[toBadgeKey] = fromSlot;
69+ }
70+ } else if (fromVisual == null ) {
71+ // fromBadgeKey doesn't have visual order yet
72+ if (toSlot != null ) {
73+ _badgeKeyToVisualOrder[fromBadgeKey] = toSlot;
74+ }
75+ if (toVisual != null && fromSlot != null ) {
76+ _badgeKeyToVisualOrder[toBadgeKey] = fromSlot;
77+ } else if (fromSlot != null ) {
78+ _badgeKeyToVisualOrder[toBadgeKey] = fromSlot;
79+ }
80+ } else {
81+ // toBadgeKey doesn't have visual order yet
82+ if (fromSlot != null && toSlot != null ) {
83+ _badgeKeyToVisualOrder[fromBadgeKey] = toSlot;
84+ _badgeKeyToVisualOrder[toBadgeKey] = fromSlot;
85+ }
86+ }
4587
46- orderedKeys.insert (toIndex, fromBadgeKey);
88+ // Update selection order to reflect the slot positions
89+ // Sort badges by their slot numbers (1, 2, 3, etc.)
90+ final allBadgeKeys = _badgeKeyToSlot.keys.toList ();
91+ allBadgeKeys.sort ((a, b) {
92+ final slotA = _badgeKeyToSlot[a] ?? 0 ;
93+ final slotB = _badgeKeyToSlot[b] ?? 0 ;
94+ return slotA.compareTo (slotB);
95+ });
4796
48- // Update selection order
97+ // Reassign selection order based on sorted slot positions
4998 _badgeKeyToSelectionOrder.clear ();
50- for (int i = 0 ; i < orderedKeys .length; i++ ) {
51- _badgeKeyToSelectionOrder[orderedKeys [i]] = i;
99+ for (int i = 0 ; i < allBadgeKeys .length; i++ ) {
100+ _badgeKeyToSelectionOrder[allBadgeKeys [i]] = i;
52101 }
53102
54- // Keep original slot assignments - don't reassign slots
55- // The slot numbers should remain as they were originally assigned
56103 notifyListeners ();
57104 }
58105
59106 void toggleSelection (String badgeKey) {
60107 if (_badgeKeyToSelectionOrder.containsKey (badgeKey)) {
61- // Unselect: remove from selection order and slot
108+ // Unselect: remove from selection order but keep original slot and visual order assignments
62109 _badgeKeyToSelectionOrder.remove (badgeKey);
110+ // CRITICAL: Keep visual order so badge doesn't move in the list when deselected
111+ // _badgeKeyToVisualOrder stays intact
63112 final freedSlot = _badgeKeyToSlot.remove (badgeKey);
64113
114+ // Add the freed slot to available slots
65115 if (freedSlot != null ) {
66116 _availableSlots.add (freedSlot);
67117 }
68118
69- // Don't reassign slot numbers - keep original slots for remaining badges
119+ // CRITICAL: Do NOT reindex the remaining badges
120+ // This keeps A (slot 1), C (slot 3) in their original positions
121+ // even after B (slot 2) is deselected
122+
70123 notifyListeners ();
71124 return ;
72125 }
@@ -79,6 +132,10 @@ class BadgeSlotProvider with ChangeNotifier {
79132 final newOrder = _badgeKeyToSelectionOrder.length;
80133 _badgeKeyToSelectionOrder[badgeKey] = newOrder;
81134
135+ // CRITICAL: Do NOT assign visual order on selection
136+ // Visual order is only assigned when badges are swapped via drag-and-drop
137+ // This keeps selected badges in their original file position
138+
82139 // Assign lowest available slot number
83140 final smallest = _availableSlots.reduce ((a, b) => a < b ? a : b);
84141 _availableSlots.remove (smallest);
@@ -90,12 +147,15 @@ class BadgeSlotProvider with ChangeNotifier {
90147 void clearSelections () {
91148 _badgeKeyToSelectionOrder.clear ();
92149 _badgeKeyToSlot.clear ();
150+ _badgeKeyToVisualOrder.clear ();
93151 _availableSlots
94152 ..clear ()
95153 ..addAll ({1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 });
96154 notifyListeners ();
97155 }
98156
157+ int ? getVisualOrder (String badgeKey) => _badgeKeyToVisualOrder[badgeKey];
158+
99159 bool canTransfer (String badgeKey) {
100160 final slot = _badgeKeyToSlot[badgeKey];
101161 return slot != null && slot <= 8 ;
0 commit comments