diff --git a/mobile/lib/services/im_service.dart b/mobile/lib/services/im_service.dart index 2ef2446..a523047 100644 --- a/mobile/lib/services/im_service.dart +++ b/mobile/lib/services/im_service.dart @@ -254,7 +254,21 @@ class IMService extends ChangeNotifier { loggedIn = true; notifyListeners(); // SDK 登录期间会话同步回调可能先于 loggedIn=true 触发,refreshConversations - // 会因登录态守卫而提前返回,导致会话列表停在空态。登录完成后主动补一次刷新。 + // 会因登录态守卫而提前返回,导致会话列表停在空态。登录完成后等会话同步 + // (onSyncServerFinish 置 conversationsLoaded)真正结束再刷新一次。 + await _waitSyncThenRefresh(); + } + + /// 等待 SDK 会话同步完成(最多约 10s),随后拉取会话列表。 + Future _waitSyncThenRefresh() async { + for (var i = 0; i < 12; i++) { + if (conversationsLoaded) { + await refreshConversations(); + return; + } + await Future.delayed(const Duration(milliseconds: 800)); + } + // 超时兜底:仍补一次(refreshConversations 内部有重试) await refreshConversations(); } @@ -296,22 +310,27 @@ class IMService extends ChangeNotifier { notifyListeners(); } - /// 重新拉取全部会话并排序(置顶在前,其余按最新消息时间倒序) + /// 重新拉取全部会话并排序(置顶在前,其余按最新消息时间倒序)。 + /// SDK 登录刚完成时立刻调用可能拿到 10009「登录未完成」,这里做短重试。 Future refreshConversations() async { if (!loggedIn) return; - try { - final list = await OpenIM.iMManager.conversationManager.getAllConversationList(); - list.sort((a, b) { - final ap = a.isPinned == true ? 0 : 1; - final bp = b.isPinned == true ? 0 : 1; - if (ap != bp) return ap - bp; - return (b.latestMsgSendTime ?? 0).compareTo(a.latestMsgSendTime ?? 0); - }); - conversations = list; - conversationsLoaded = true; - notifyListeners(); - } catch (_) { - // 拉取失败保留现有列表 + for (var attempt = 0; attempt < 5; attempt++) { + try { + final list = await OpenIM.iMManager.conversationManager.getAllConversationList(); + list.sort((a, b) { + final ap = a.isPinned == true ? 0 : 1; + final bp = b.isPinned == true ? 0 : 1; + if (ap != bp) return ap - bp; + return (b.latestMsgSendTime ?? 0).compareTo(a.latestMsgSendTime ?? 0); + }); + conversations = list; + conversationsLoaded = true; + notifyListeners(); + return; + } catch (_) { + // 登录尚未完成或瞬时失败,短暂等待后重试 + await Future.delayed(const Duration(milliseconds: 800)); + } } }