| .. | .. |
|---|
| 59 | 59 | bool _sessionReady = false; |
|---|
| 60 | 60 | final List<Map<String, dynamic>> _pendingMessages = []; |
|---|
| 61 | 61 | final Map<String, List<Message>> _catchUpPending = {}; |
|---|
| 62 | + List<String>? _cachedSessionOrder; |
|---|
| 62 | 63 | |
|---|
| 63 | 64 | @override |
|---|
| 64 | 65 | void initState() { |
|---|
| .. | .. |
|---|
| 72 | 73 | // Load persisted state BEFORE connecting |
|---|
| 73 | 74 | final prefs = await SharedPreferences.getInstance(); |
|---|
| 74 | 75 | _lastSeq = prefs.getInt('lastSeq') ?? 0; |
|---|
| 75 | | - // Restore last active session so catch_up routes to the right session |
|---|
| 76 | + // Restore saved session order and active session |
|---|
| 77 | + _cachedSessionOrder = prefs.getStringList('sessionOrder'); |
|---|
| 76 | 78 | final savedSessionId = prefs.getString('activeSessionId'); |
|---|
| 77 | 79 | if (savedSessionId != null && mounted) { |
|---|
| 78 | 80 | ref.read(activeSessionIdProvider.notifier).state = savedSessionId; |
|---|
| .. | .. |
|---|
| 364 | 366 | final sessionsJson = msg['sessions'] as List<dynamic>?; |
|---|
| 365 | 367 | if (sessionsJson == null) return; |
|---|
| 366 | 368 | |
|---|
| 367 | | - final sessions = sessionsJson |
|---|
| 369 | + var sessions = sessionsJson |
|---|
| 368 | 370 | .map((s) => Session.fromJson(s as Map<String, dynamic>)) |
|---|
| 369 | 371 | .toList(); |
|---|
| 372 | + // Apply saved custom order (reordered sessions persist across updates) |
|---|
| 373 | + sessions = _applyCustomOrder(sessions); |
|---|
| 370 | 374 | ref.read(sessionsProvider.notifier).state = sessions; |
|---|
| 371 | 375 | |
|---|
| 372 | 376 | final activeId = ref.read(activeSessionIdProvider); |
|---|
| .. | .. |
|---|
| 1242 | 1246 | final item = sessions.removeAt(oldIndex); |
|---|
| 1243 | 1247 | sessions.insert(newIndex, item); |
|---|
| 1244 | 1248 | ref.read(sessionsProvider.notifier).state = sessions; |
|---|
| 1249 | + // Persist custom order |
|---|
| 1250 | + _saveSessionOrder(sessions.map((s) => s.id).toList()); |
|---|
| 1251 | + } |
|---|
| 1252 | + |
|---|
| 1253 | + void _saveSessionOrder(List<String> ids) { |
|---|
| 1254 | + SharedPreferences.getInstance().then((p) => p.setStringList('sessionOrder', ids)); |
|---|
| 1255 | + } |
|---|
| 1256 | + |
|---|
| 1257 | + /// Apply saved custom order to a server-provided session list. |
|---|
| 1258 | + /// New sessions (not in saved order) are appended at the end. |
|---|
| 1259 | + List<Session> _applyCustomOrder(List<Session> sessions) { |
|---|
| 1260 | + if (_cachedSessionOrder == null || _cachedSessionOrder!.isEmpty) return sessions; |
|---|
| 1261 | + final order = _cachedSessionOrder!; |
|---|
| 1262 | + final byId = {for (final s in sessions) s.id: s}; |
|---|
| 1263 | + final ordered = <Session>[]; |
|---|
| 1264 | + for (final id in order) { |
|---|
| 1265 | + final s = byId.remove(id); |
|---|
| 1266 | + if (s != null) ordered.add(s); |
|---|
| 1267 | + } |
|---|
| 1268 | + // Append any new sessions not in saved order |
|---|
| 1269 | + ordered.addAll(byId.values); |
|---|
| 1270 | + return ordered; |
|---|
| 1245 | 1271 | } |
|---|
| 1246 | 1272 | |
|---|
| 1247 | 1273 | void _refreshSessions() { |
|---|