Skip to content

Commit 07094ab

Browse files
committed
refactor
1 parent 7c9e437 commit 07094ab

File tree

3 files changed

+83
-78
lines changed

3 files changed

+83
-78
lines changed

lib/ChatScreen.dart

Lines changed: 18 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,8 @@ import 'package:transparent_image/transparent_image.dart';
99
import 'package:flutter/services.dart'; // Import for clipboard functionality
1010
import 'Config.dart';
1111
import 'LoginScreen.dart';
12-
import 'utils.dart';
13-
14-
class ChatApp extends StatelessWidget {
15-
const ChatApp({super.key});
16-
17-
@override
18-
Widget build(BuildContext context) {
19-
return MaterialApp(
20-
title: 'Chat App',
21-
theme: ThemeData(
22-
appBarTheme: const AppBarTheme(
23-
toolbarTextStyle: TextStyle(
24-
color: Colors.white,
25-
fontSize: 20,
26-
fontWeight: FontWeight.bold,
27-
),
28-
),
29-
),
30-
home: const LoginScreen(),
31-
);
32-
}
33-
}
12+
import 'utils/MessageUtils.dart';
13+
import 'utils/ApiHelper.dart';
3414

3515
class ChatScreen extends StatefulWidget {
3616
final String userId;
@@ -48,7 +28,9 @@ class ChatScreen extends StatefulWidget {
4828
@override
4929
_ChatScreenState createState() => _ChatScreenState();
5030
}
51-
31+
String decryptMessage(String encryptedText, String encryptionKey) {
32+
return ApiHelper.decryptMessage(encryptedText, encryptionKey);
33+
}
5234
class _ChatScreenState extends State<ChatScreen> {
5335
final TextEditingController messageController = TextEditingController();
5436
final ScrollController _scrollController = ScrollController();
@@ -141,35 +123,20 @@ class _ChatScreenState extends State<ChatScreen> {
141123
);
142124
}
143125

144-
String encryptMessage(String message) {
145-
final key = encrypt.Key.fromUtf8(
146-
widget.encryptionKey.padRight(32, '0').substring(0, 32));
147-
final iv = encrypt.IV.fromLength(16);
148-
final encrypter = encrypt.Encrypter(encrypt.AES(key));
149-
150-
final encrypted = encrypter.encrypt(message, iv: iv);
151-
final encryptedMessage = '${iv.base64}:${encrypted.base64}';
152-
153-
return encryptedMessage;
154-
}
155-
156126
Future<void> sendMessage() async {
157127
String message = _controller.text;
158128
if (message.isNotEmpty && message.length <= Config.maxMessageLength) {
159-
String encryptedMessage = encryptMessage(message);
129+
String encryptedMessage = ApiHelper.encryptMessage(message, widget.encryptionKey);
160130
setState(() {
161131
isSending = true; // Indicate that a message is being sent
162132
});
163133

164134
try {
165-
final response = await http.post(
166-
Uri.parse(Config.backendUrl + '/save.php'),
167-
body: {
168-
'user1Id': widget.userId,
169-
'user2Id': widget.recipientId,
170-
'message': encryptedMessage,
171-
'encryptionKey': widget.hashedKey,
172-
},
135+
final response = await ApiHelper.sendMessage(
136+
user1Id: widget.userId,
137+
user2Id: widget.recipientId,
138+
message: encryptedMessage,
139+
encryptionKey: widget.hashedKey,
173140
);
174141

175142
if (response.statusCode == 200) {
@@ -204,39 +171,10 @@ class _ChatScreenState extends State<ChatScreen> {
204171
}
205172
}
206173

207-
String decryptMessage(String encryptedMessage) {
208-
// Check if the encrypted message contains the expected delimiter
209-
if (!encryptedMessage.contains(':')) {
210-
print("Decryption error: Invalid format of encrypted message");
211-
return "Decryption error: Invalid format of encrypted message";
212-
}
213-
214-
try {
215-
// Ensure the encryption key is 32 characters long
216-
final key = encrypt.Key.fromUtf8(
217-
widget.encryptionKey.padRight(32, '0').substring(0, 32));
218-
final parts = encryptedMessage.split(':');
219-
220-
// Check if both parts (IV and encrypted text) are present
221-
if (parts.length != 2) {
222-
print("Decryption error: Expected 2 parts, but got ${parts.length}");
223-
return "Decryption error: Expected 2 parts, but got ${parts.length}";
224-
}
225-
226-
final iv = encrypt.IV.fromBase64(parts[0]);
227-
final encrypter = encrypt.Encrypter(encrypt.AES(key));
228-
final decrypted = encrypter.decrypt64(parts[1], iv: iv);
229-
230-
return decrypted;
231-
} catch (e) {
232-
print("Decryption error: $e");
233-
return "Decryption error: $e";
234-
}
235-
}
236174

237175
void copySelectedMessages() {
238176
final selectedTexts = selectedMessages
239-
.map((index) => decryptMessage(messages[index].text))
177+
.map((index) => ApiHelper.decryptMessage(messages[index].text, widget.encryptionKey))
240178
.join('\n');
241179
Clipboard.setData(ClipboardData(text: selectedTexts)).then((_) {
242180
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
@@ -370,9 +308,10 @@ class _ChatScreenState extends State<ChatScreen> {
370308
message: messages[index],
371309
currentUserId: widget.userId,
372310
isEncrypted: true,
373-
decryptMessage: decryptMessage,
311+
decryptMessage: ApiHelper.decryptMessage,
374312
isSelected: selectedMessages
375313
.contains(index), // Pass selection state to bubble
314+
encryptionKey: widget.encryptionKey,
376315
),
377316
],
378317
),
@@ -473,8 +412,9 @@ class MessageBubble extends StatelessWidget {
473412
final Message message;
474413
final String currentUserId;
475414
final bool isEncrypted;
476-
final Function decryptMessage;
415+
final String Function(String, String) decryptMessage;
477416
final bool isSelected;
417+
final String encryptionKey;
478418

479419
const MessageBubble({
480420
super.key,
@@ -483,13 +423,14 @@ class MessageBubble extends StatelessWidget {
483423
required this.isEncrypted,
484424
required this.decryptMessage,
485425
required this.isSelected,
426+
required this.encryptionKey,
486427
});
487428

488429
@override
489430
Widget build(BuildContext context) {
490431
final isMe = message.senderId == currentUserId;
491432
final decryptedText =
492-
isEncrypted ? decryptMessage(message.text) : message.text;
433+
isEncrypted ? decryptMessage(message.text, encryptionKey) : message.text;
493434

494435
return Align(
495436
alignment: isMe ? Alignment.centerRight : Alignment.centerLeft,
@@ -523,7 +464,6 @@ class MessageBubble extends StatelessWidget {
523464
),
524465
);
525466
}
526-
527467
}
528468

529469
class Message {

lib/utils/ApiHelper.dart

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import 'package:http/http.dart' as http;
2+
import 'package:encrypt/encrypt.dart' as encrypt;
3+
import '../Config.dart';
4+
5+
class ApiHelper {
6+
static Future<http.Response> sendMessage({
7+
required String user1Id,
8+
required String user2Id,
9+
required String message,
10+
required String encryptionKey,
11+
}) async {
12+
final response = await http.post(
13+
Uri.parse(Config.backendUrl + '/save.php'),
14+
body: {
15+
'user1Id': user1Id,
16+
'user2Id': user2Id,
17+
'message': message,
18+
'encryptionKey': encryptionKey,
19+
},
20+
);
21+
return response;
22+
}
23+
24+
static String encryptMessage(String message, String encryptionKey) {
25+
final key = encrypt.Key.fromUtf8(
26+
encryptionKey.padRight(32, '0').substring(0, 32));
27+
final iv = encrypt.IV.fromLength(16);
28+
final encrypter = encrypt.Encrypter(encrypt.AES(key));
29+
30+
final encrypted = encrypter.encrypt(message, iv: iv);
31+
final encryptedMessage = '${iv.base64}:${encrypted.base64}';
32+
33+
return encryptedMessage;
34+
}
35+
36+
static String decryptMessage(String encryptedMessage, String encryptionKey) {
37+
// Check if the encrypted message contains the expected delimiter
38+
if (!encryptedMessage.contains(':')) {
39+
print("Decryption error: Invalid format of encrypted message");
40+
return "Decryption error: Invalid format of encrypted message";
41+
}
42+
43+
try {
44+
// Ensure the encryption key is 32 characters long
45+
final key = encrypt.Key.fromUtf8(
46+
encryptionKey.padRight(32, '0').substring(0, 32));
47+
final parts = encryptedMessage.split(':');
48+
49+
// Check if both parts (IV and encrypted text) are present
50+
if (parts.length != 2) {
51+
print("Decryption error: Expected 2 parts, but got ${parts.length}");
52+
return "Decryption error: Expected 2 parts, but got ${parts.length}";
53+
}
54+
55+
final iv = encrypt.IV.fromBase64(parts[0]);
56+
final encrypter = encrypt.Encrypter(encrypt.AES(key));
57+
final decrypted = encrypter.decrypt64(parts[1], iv: iv);
58+
59+
return decrypted;
60+
} catch (e) {
61+
print("Decryption error: $e");
62+
return "Decryption error: $e";
63+
}
64+
}
65+
}
File renamed without changes.

0 commit comments

Comments
 (0)