import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_nearby_connections/flutter_nearby_connections.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:pointycastle/export.dart'; import '../database/database_helper.dart'; import '../p2p/adhoc_housekeeping.dart'; import 'msg.dart'; class Global extends ChangeNotifier { static RSAPrivateKey? myPrivateKey; static RSAPublicKey? myPublicKey; static NearbyService? nearbyService; static StreamSubscription? deviceSubscription; static StreamSubscription? receivedDataSubscription; List devices = []; List connectedDevices = []; static List messages = []; static Map publicKeys = {}; Map> conversations = {}; static String myName = ''; static Map cache = {}; static final GlobalKey scaffoldKey = GlobalKey(); void sentToConversations(Msg msg, String converser, {bool addToTable = true}) { conversations.putIfAbsent(converser, () => {}); conversations[converser]![msg.id] = msg; if (addToTable) { insertIntoConversationsTable(msg, converser); } notifyListeners(); broadcast(scaffoldKey.currentContext!); } Future receivedToConversations(dynamic decodedMessage, BuildContext context) async { var sender = decodedMessage['sender']; var message = json.decode(decodedMessage['message']); if (kDebugMode) { print("Received Message: $message"); } //file decoding and saving if(message['type'] == 'file') { String filePath = await decodeAndStoreFile( message['data'], message['fileName']); conversations.putIfAbsent(sender, () => {}); if (!conversations[sender]!.containsKey(decodedMessage['id'])) { decodedMessage['message'] = json.encode({ 'type': 'file', 'filePath': filePath, 'fileName': message['fileName'] }); var msg = Msg( decodedMessage['message'], "received", decodedMessage['Timestamp'], decodedMessage['id']); conversations[sender]![decodedMessage["id"]] = msg; insertIntoConversationsTable(msg, sender); notifyListeners(); } } else { conversations.putIfAbsent(sender, () => {}); if (!conversations[sender]!.containsKey(decodedMessage['id'])) { var msg = Msg( decodedMessage['message'], "received", decodedMessage['Timestamp'], decodedMessage['id']); conversations[sender]![decodedMessage["id"]] = msg; insertIntoConversationsTable(msg, sender); notifyListeners(); } } } Future decodeAndStoreFile(String encodedFile, String fileName) async { Uint8List fileBytes = base64.decode(encodedFile); //to send files encrypted using RSA // Uint8List fileData = rsaDecrypt(Global.myPrivateKey!, fileBytes); Directory documents ; if (Platform.isAndroid) { documents = (await getExternalStorageDirectory())!; } else { documents = await getApplicationDocumentsDirectory(); } PermissionStatus status = await Permission.storage.request(); if (status.isGranted) { final path = '${documents.path}/$fileName'; File(path).writeAsBytes(fileBytes); if (kDebugMode) { print("File saved at: $path"); } return path; } else { throw const FileSystemException('Storage permission not granted'); } } void updateDevices(List devices) { this.devices = devices; notifyListeners(); } void updateConnectedDevices(List devices) { connectedDevices = devices; notifyListeners(); } }