Skip to content

Commit 2142eb5

Browse files
committed
fixed session
1 parent c56dff9 commit 2142eb5

2 files changed

Lines changed: 116 additions & 80 deletions

File tree

mobile/lib/controllers/chat.dart

Lines changed: 81 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

mobile/lib/pages/settings pages/accounts.dart

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:mobile/controllers/auth.dart';
3+
import 'package:mobile/controllers/chat.dart';
4+
import 'package:mobile/providers/basic_providers.dart';
35
import 'package:mobile/main.dart';
46
import 'package:provider/provider.dart';
57

@@ -9,37 +11,55 @@ class AccountsSettings extends StatelessWidget {
911
@override
1012
Widget build(BuildContext context) {
1113
return Scaffold(
12-
appBar: AppBar(title: Text('Accounts')),
14+
backgroundColor: Colors.white,
15+
appBar: AppBar(
16+
title: const Text('Accounts'),
17+
backgroundColor: Colors.white,
18+
elevation: 0,
19+
scrolledUnderElevation: 0,
20+
),
1321
body: ListView(
22+
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
1423
children: [
15-
SizedBox(
24+
const SizedBox(
1625
width: double.infinity,
1726
height: 150,
1827
child: Hero(
1928
tag: 'User Profile',
20-
child: const Padding(
29+
child: Padding(
2130
padding: EdgeInsets.only(left: 16.0, top: 10.0, bottom: 10.0),
2231
child: CircleAvatar(
2332
backgroundColor: Color(0xFFD6E4FF),
24-
child: Icon(Icons.person, color: Color(0xFF1890FF)),
33+
child: Icon(Icons.person, color: Color(0xFF1890FF), size: 40),
2534
),
2635
),
2736
),
2837
),
29-
SizedBox(height: 200),
38+
const SizedBox(height: 100),
3039
FilledButton(
31-
style: ButtonStyle(
32-
backgroundColor: WidgetStatePropertyAll(Colors.red),
40+
style: const ButtonStyle(
41+
backgroundColor: WidgetStatePropertyAll(Colors.redAccent),
3342
),
34-
onPressed: () {
35-
context.read<AuthState>().logout();
36-
Navigator.pushAndRemoveUntil(
37-
context,
38-
MaterialPageRoute(builder: (context) => SessionGateway()),
39-
(route) => false,
40-
);
43+
onPressed: () async {
44+
await context.read<AuthState>().logout();
45+
await context.read<BasicProviders>().logOutSave();
46+
47+
if (context.mounted) {
48+
context.read<ChatController>().clearSessionData();
49+
50+
Navigator.pushAndRemoveUntil(
51+
context,
52+
MaterialPageRoute(
53+
builder: (context) => const SessionGateway(),
54+
),
55+
(route) => false,
56+
);
57+
}
4158
},
42-
child: Text('Log out'),
59+
child: const Text(
60+
'Log out',
61+
style: TextStyle(fontWeight: FontWeight.bold),
62+
),
4363
),
4464
],
4565
),

0 commit comments

Comments
 (0)