@@ -12,23 +12,29 @@ class ChatController extends ChangeNotifier {
1212 List <Conversation > inbox = [];
1313 List <Message > activeChat = [];
1414 List <dynamic > contactSearchResults = [];
15-
1615 String ? currentChatUserId;
1716 bool isPeerTyping = false ;
1817 bool isPeerOnline = false ;
1918 bool isSearchLoading = false ;
2019
2120 Future <void > initSession (String token) async {
21+ _ws.disconnect ();
22+
23+ inbox.clear ();
24+ activeChat.clear ();
25+ contactSearchResults.clear ();
26+ currentChatUserId = null ;
27+ isPeerTyping = false ;
28+ isPeerOnline = false ;
29+ notifyListeners ();
30+
2231 await _ws.connect (token);
2332 _ws.stream? .listen (
2433 (rawFrame) {
2534 try {
26- final decoded = jsonDecode (rawFrame);
27- if (decoded is Map <String , dynamic >) {
28- _handleIncomingWebSocketEvent (decoded);
29- }
35+ _handleIncomingWebSocketEvent (jsonDecode (rawFrame));
3036 } catch (e) {
31- debugPrint ("WebSocket payload error: $e " );
37+ debugPrint ("WebSocket stream payload error: $e " );
3238 }
3339 },
3440 onError: (err) => debugPrint ("WS Pipeline Error: $err " ),
@@ -37,13 +43,32 @@ class ChatController extends ChangeNotifier {
3743 await loadInbox ();
3844 }
3945
46+ void clearSessionData () {
47+ _ws.disconnect ();
48+ inbox.clear ();
49+ activeChat.clear ();
50+ contactSearchResults.clear ();
51+ currentChatUserId = null ;
52+ isPeerTyping = false ;
53+ isPeerOnline = false ;
54+ notifyListeners ();
55+ }
56+
4057 Future <void > loadInbox () async {
4158 try {
4259 final res = await _api.getConversations ();
43- final targetList = _extractDataList (res.data, [ 'conversations' ]) ;
60+ dynamic targetData ;
4461
45- inbox = targetList.map ((json) => Conversation .fromJson (json)).toList ();
46- notifyListeners ();
62+ if (res.data is List ) {
63+ targetData = res.data;
64+ } else if (res.data is Map ) {
65+ targetData = res.data['data' ] ?? res.data['conversations' ] ?? res.data;
66+ }
67+
68+ if (targetData is List ) {
69+ inbox = targetData.map ((json) => Conversation .fromJson (json)).toList ();
70+ notifyListeners ();
71+ }
4772 } catch (e) {
4873 debugPrint ("Inbox read error: $e " );
4974 }
@@ -58,34 +83,33 @@ class ChatController extends ChangeNotifier {
5883
5984 try {
6085 final res = await _api.getChatHistory (targetUid);
61- final targetList = _extractDataList (res.data, [ 'messages' ]) ;
86+ dynamic targetData ;
6287
63- activeChat = targetList
64- .map ((json) => Message .fromJson (json))
65- .toList ()
66- .reversed
67- .toList ();
88+ if (res.data is List ) {
89+ targetData = res.data;
90+ } else if (res.data is Map ) {
91+ targetData = res.data['data' ] ?? res.data['messages' ] ?? res.data;
92+ }
93+
94+ if (targetData is List ) {
95+ activeChat = targetData
96+ .map ((json) => Message .fromJson (json))
97+ .toList ()
98+ .reversed
99+ .toList ();
100+ }
68101
69102 _ws.sendReadReceipt (targetId: targetUid);
70103 _ws.sendRequestStatus (targetId: targetUid);
71-
72- notifyListeners ();
73104 await loadInbox ();
74105 } catch (e) {
75106 debugPrint ("Timeline tracking fail: $e " );
76- notifyListeners ();
77107 }
108+ notifyListeners ();
78109 }
79110
80111 Future <void > queryUsers (String term) async {
81112 final String cleanTerm = term.trim ();
82-
83- if (cleanTerm.isEmpty) {
84- contactSearchResults.clear ();
85- notifyListeners ();
86- return ;
87- }
88-
89113 if (cleanTerm.length < 3 ) {
90114 contactSearchResults.clear ();
91115 notifyListeners ();
@@ -96,10 +120,22 @@ class ChatController extends ChangeNotifier {
96120 notifyListeners ();
97121
98122 try {
99- final res = await _api.searchUsers (term);
100- contactSearchResults = _extractDataList (res.data, ['users' ]);
123+ final res = await _api.searchUsers (cleanTerm);
124+ if (res.data == null ) {
125+ contactSearchResults = [];
126+ } else if (res.data is List ) {
127+ contactSearchResults = res.data;
128+ } else if (res.data is Map ) {
129+ if (res.data['data' ] != null && res.data['data' ] is List ) {
130+ contactSearchResults = res.data['data' ];
131+ } else if (res.data['users' ] != null && res.data['users' ] is List ) {
132+ contactSearchResults = res.data['users' ];
133+ } else {
134+ contactSearchResults = [];
135+ }
136+ }
101137 } catch (e) {
102- debugPrint ("User query failure: $e " );
138+ debugPrint ("User query pipeline failure: $e " );
103139 contactSearchResults.clear ();
104140 } finally {
105141 isSearchLoading = false ;
@@ -116,15 +152,16 @@ class ChatController extends ChangeNotifier {
116152 }
117153
118154 void sendTextMessage (String text) {
119- final cleanContent = text.trim ();
120- if (currentChatUserId == null || cleanContent.isEmpty) return ;
155+ if (currentChatUserId == null || text.trim ().isEmpty) return ;
121156
122- final targetId = currentChatUserId! ;
123- final clientMessageId = "cli_${DateTime .now ().millisecondsSinceEpoch }" ;
157+ final String clientMessageId =
158+ "cli_${DateTime .now ().millisecondsSinceEpoch }" ;
159+ final String targetId = currentChatUserId! ;
160+ final String cleanContent = text.trim ();
124161
125162 _ws.sendChat (messageId: "" , targetId: targetId, content: cleanContent);
126163
127- final optimisticMsg = Message (
164+ final Message optimisticMsg = Message (
128165 id: clientMessageId,
129166 senderId: "me" ,
130167 receiverId: targetId,
@@ -135,7 +172,6 @@ class ChatController extends ChangeNotifier {
135172
136173 activeChat.add (optimisticMsg);
137174 notifyListeners ();
138-
139175 loadInbox ();
140176 }
141177
@@ -147,14 +183,13 @@ class ChatController extends ChangeNotifier {
147183
148184 void _handleIncomingWebSocketEvent (Map <String , dynamic > data) {
149185 final String ? type = data['type' ];
150- if (type == null ) return ;
151-
152186 final String ? senderId =
153187 data['sender_id' ] ?? data['sender' ] ?? data['receiver_id' ];
188+
189+ if (type == null ) return ;
190+
154191 final String ? cleanSender = senderId? .trim ().toLowerCase ();
155192 final String ? cleanCurrentChat = currentChatUserId? .trim ().toLowerCase ();
156- final bool isCurrentChat =
157- cleanSender != null && cleanSender == cleanCurrentChat;
158193
159194 switch (type) {
160195 case 'user_status' :
@@ -168,54 +203,35 @@ class ChatController extends ChangeNotifier {
168203 notifyListeners ();
169204 }
170205 break ;
171-
172206 case 'chat' :
173207 case 'message' :
174- if (isCurrentChat ) {
208+ if (cleanSender != null && cleanSender == cleanCurrentChat ) {
175209 activeChat.add (Message .fromJson (data));
176210 _ws.sendReadReceipt (targetId: currentChatUserId! );
177211 notifyListeners ();
212+ } else {
213+ loadInbox ();
178214 }
179- loadInbox ();
180215 break ;
181-
182216 case 'typing' :
183- if (isCurrentChat ) {
217+ if (cleanSender != null && cleanSender == cleanCurrentChat ) {
184218 isPeerTyping = data['content' ] == 'true' ;
185219 notifyListeners ();
186220 }
187221 break ;
188-
189222 case 'read_receipt' :
190- if (isCurrentChat) {
191- bool updated = false ;
223+ if (cleanSender != null && cleanSender == cleanCurrentChat) {
192224 activeChat = activeChat.map ((msg) {
193225 final String sId = msg.senderId.trim ().toLowerCase ();
194- if (! msg.isRead && (sId == 'me' || sId != cleanCurrentChat)) {
195- updated = true ;
226+ if (sId == 'me' || sId != cleanCurrentChat) {
196227 return msg.copyWith (isRead: true );
197228 }
198229 return msg;
199230 }).toList ();
200-
201- if (updated) {
202- notifyListeners ();
203- loadInbox ();
204- }
231+ notifyListeners ();
232+ loadInbox ();
205233 }
206234 break ;
207235 }
208236 }
209-
210- List <dynamic > _extractDataList (dynamic data, List <String > fallbackKeys) {
211- if (data == null ) return [];
212- if (data is List ) return data;
213- if (data is Map ) {
214- if (data['data' ] is List ) return data['data' ];
215- for (final key in fallbackKeys) {
216- if (data[key] is List ) return data[key];
217- }
218- }
219- return [];
220- }
221237}
0 commit comments