@@ -9,28 +9,8 @@ import 'package:transparent_image/transparent_image.dart';
99import 'package:flutter/services.dart' ; // Import for clipboard functionality
1010import 'Config.dart' ;
1111import '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
3515class 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+ }
5234class _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
529469class Message {
0 commit comments