From d6840a4313a0058a147d25e78e403441fe27cba8 Mon Sep 17 00:00:00 2001 From: ksenia312 Date: Sun, 4 Feb 2024 22:25:57 +0100 Subject: [PATCH] feat(*): add sender to files pack result --- example/lib/main.dart | 33 +++++++----- ios/Classes/Models/NearbyCommand.swift | 15 +++--- ios/Classes/Models/NearbySession.swift | 6 ++- ios/Classes/NearbyManager.swift | 9 +++- ios/Classes/NearbyNotificationReceiver.swift | 6 ++- ios/Classes/Store/NearbyFilesStore.swift | 36 +++++++++---- lib/nearby_service.dart | 3 +- lib/src/base/base.dart | 2 +- lib/src/interface/interface.dart | 2 +- lib/src/interface/nearby_device_mapper.dart | 2 - lib/src/model/model.dart | 3 +- ...nearby_file.dart => nearby_file_info.dart} | 42 +-------------- lib/src/model/nearby_files_pack.dart | 54 +++++++++++++++++++ .../android/model/nearby_connection_info.dart | 2 +- .../android/model/nearby_device.dart | 14 ++--- .../android/nearby_android_service.dart | 5 +- .../nearby_service_android_interface.dart | 2 +- ...nearby_service_android_method_channel.dart | 8 +-- .../socket_service/file_sockets_manager.dart | 30 ++++++----- .../socket_service/nearby_socket_service.dart | 27 +++++----- lib/src/platforms/ios/nearby_ios_service.dart | 7 +-- .../types/nearby_service_stream_listener.dart | 2 +- lib/src/utils/exception.dart | 3 +- lib/src/utils/file_socket.dart | 19 ++++--- lib/src/utils/stream_mapper.dart | 19 +++---- 25 files changed, 199 insertions(+), 152 deletions(-) rename lib/src/model/{nearby_file.dart => nearby_file_info.dart} (65%) create mode 100644 lib/src/model/nearby_files_pack.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index b042cd3..4a40d36 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -270,6 +270,7 @@ class AppService extends ChangeNotifier { final result = await _nearbyService.android?.checkWifiService(); if (result ?? false) { updateState(AppState.readyToDiscover); + startListeningConnectionInfo(); return true; } return false; @@ -289,7 +290,6 @@ class AppService extends ChangeNotifier { final result = await _nearbyService.discover(); if (result) { updateState(AppState.discoveringPeers); - startListeningConnectionInfo(); } } catch (e) { if (kDebugMode) { @@ -333,11 +333,6 @@ class AppService extends ChangeNotifier { updateState(AppState.discoveringPeers); } - Future stopListeningConnectionInfo() async { - await connectionInfoSubscription?.cancel(); - connectionInfoSubscription = null; - } - Future connect(NearbyDeviceBase device) async { try { await _nearbyService.connect(device); @@ -366,6 +361,11 @@ class AppService extends ChangeNotifier { notifyListeners(); } + Future stopListeningConnectionInfo() async { + await connectionInfoSubscription?.cancel(); + connectionInfoSubscription = null; + } + Future startListeningConnectedDevice(NearbyDeviceBase device) async { updateState(AppState.loadingConnection); try { @@ -404,7 +404,7 @@ class AppService extends ChangeNotifier { Future startCommunicationChannel({ ValueChanged? listener, - ValueChanged>? onFilesSaved, + ValueChanged? onFilesSaved, }) async { final messagesListener = NearbyServiceMessagesListener( onCreated: () { @@ -424,16 +424,18 @@ class AppService extends ChangeNotifier { ? Directory('storage/emulated/0/Download') : await getApplicationDocumentsDirectory(); - for (final nearbyFile in event) { - final newFile = await nearbyFile.file.copy( - '${directory.path}/${DateTime.now().microsecondsSinceEpoch}.${nearbyFile.info.extension}', + for (final nearbyFile in event.files) { + final newFile = await File(nearbyFile.path).copy( + '${directory.path}/${DateTime.now().microsecondsSinceEpoch}.${nearbyFile.extension}', ); if (!await newFile.exists()) { await newFile.create(); } files.add(NearbyFileInfo(path: newFile.path)); } - onFilesSaved?.call(files); + onFilesSaved?.call( + ReceivedNearbyFilesPack(sender: event.sender, files: files), + ); }, ); @@ -492,7 +494,7 @@ class AppService extends ChangeNotifier { ); } - Future disconnect(NearbyDeviceBase device) async { + Future disconnect([NearbyDeviceBase? device]) async { try { await _nearbyService.disconnect(device); } catch (e) { @@ -883,10 +885,13 @@ class _ConnectedBody extends StatelessWidget { ); } - void _onFileSaved(BuildContext context, List files) { + void _onFileSaved(BuildContext context, ReceivedNearbyFilesPack pack) { + final senderSubtitle = 'From ${pack.sender.displayName} ' + '(ID: ${pack.sender.id})'; AppShackBar.show( Scaffold.of(context).context, - '${files.length} files saved! \n${files.map((e) => e.name).join('\n')}', + '${pack.files.length} files saved! \n${pack.files.map((e) => e.name).join('\n')}', + subtitle: senderSubtitle, ); } } diff --git a/ios/Classes/Models/NearbyCommand.swift b/ios/Classes/Models/NearbyCommand.swift index 0881b2f..e083431 100644 --- a/ios/Classes/Models/NearbyCommand.swift +++ b/ios/Classes/Models/NearbyCommand.swift @@ -6,30 +6,29 @@ // import Foundation +import MultipeerConnectivity class NearbyStartCommand { - init( id: String, filesCount: Int) { - self.id = id + init(senderName: String, filesCount: Int) { + self.senderName = senderName self.filesCount = filesCount } static func fromUserInfo(userInfo: NearbyUserInfo)-> NearbyStartCommand? { - if let id = userInfo.dictionary["id"] as? String , + if let name = userInfo.dictionary["name"] as? String, let filesCount = userInfo.dictionary["filesCount"] as? Int { - return NearbyStartCommand( - id: id, filesCount: filesCount - ) + return NearbyStartCommand(senderName: name, filesCount: filesCount) } return nil } func toDictionary() -> [String: Any] { - return ["id": id, "filesCount": filesCount] + return ["name": senderName, "filesCount": filesCount] } - let id: String + let senderName: String let filesCount: Int } diff --git a/ios/Classes/Models/NearbySession.swift b/ios/Classes/Models/NearbySession.swift index fadc7ca..65d0265 100644 --- a/ios/Classes/Models/NearbySession.swift +++ b/ios/Classes/Models/NearbySession.swift @@ -47,15 +47,17 @@ extension NearbySession: MCSessionDelegate { func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) { guard let localURL = localURL else { return } - let destinationURL = localURL.deletingLastPathComponent().appendingPathComponent("\(resourceName)") + var destinationURL = localURL.deletingLastPathComponent().appendingPathComponent("\(resourceName)") + if FileManager.default.fileExists(atPath: destinationURL.path) { + destinationURL = localURL.deletingLastPathComponent().appendingPathComponent("New_\(resourceName)") + } do { try FileManager.default.moveItem(at: localURL, to: destinationURL) } catch { Logger.error(message: "Error moving file: \(error)") } - NotificationCenter.default.post( name: ON_RESOURCE_RECEIVED, object: nil, diff --git a/ios/Classes/NearbyManager.swift b/ios/Classes/NearbyManager.swift index f738bd6..4fdfcca 100644 --- a/ios/Classes/NearbyManager.swift +++ b/ios/Classes/NearbyManager.swift @@ -124,8 +124,13 @@ class NearbyManager: NSObject { do { let device = NearbyDevicesStore.instance.find(for: receiverId) if let requireDevice = device { - try requireDevice.session?.session?.send( - try JSONSerialization.data(withJSONObject: NearbyStartCommand( id: id, filesCount: paths.count).toDictionary()), + let command = NearbyStartCommand( + senderName: requireDevice.name, + filesCount: paths.count + ).toDictionary() + + try requireDevice.session?.session?.send( + try JSONSerialization.data(withJSONObject: command), toPeers: [requireDevice.peerID], with: MCSessionSendDataMode.reliable ) diff --git a/ios/Classes/NearbyNotificationReceiver.swift b/ios/Classes/NearbyNotificationReceiver.swift index 820d0e5..0a63ddd 100644 --- a/ios/Classes/NearbyNotificationReceiver.swift +++ b/ios/Classes/NearbyNotificationReceiver.swift @@ -33,13 +33,17 @@ extension NearbyServicePlugin { } @objc func onResourceReceived(notification: Notification) { + DispatchQueue.main.async { if let userInfo = NearbyUserInfo.fromDictionary(userInfo: notification.userInfo) { if let url = userInfo.dictionary["url"] as? URL { NearbyFilesStore.instance.add(url: url) + if (NearbyFilesStore.instance.checkIsFull()) { - self.channel.invokeMethod(DART_COMMAND_RESOURCES_RECEIVED, arguments: NearbyFilesStore.instance.toDartFormat()) + + self.channel.invokeMethod(DART_COMMAND_RESOURCES_RECEIVED, arguments: NearbyFilesStore.instance.toDartFormat(peerID: userInfo.peerID)) + NearbyFilesStore.instance.clear() } } } diff --git a/ios/Classes/Store/NearbyFilesStore.swift b/ios/Classes/Store/NearbyFilesStore.swift index b043c7e..65e83c8 100644 --- a/ios/Classes/Store/NearbyFilesStore.swift +++ b/ios/Classes/Store/NearbyFilesStore.swift @@ -6,18 +6,19 @@ // import Foundation +import MultipeerConnectivity class NearbyFilesStore { static let instance = NearbyFilesStore() private var paths : [String] = [] - private var id: String? = nil + private var senderName: String? = nil private var maxCount: Int = 0 private var count: Int = 0 func startReceiving(command: NearbyStartCommand) { self.paths.removeAll() - self.id = command.id + self.senderName = command.senderName self.maxCount = command.filesCount self.count = 0 } @@ -31,16 +32,29 @@ class NearbyFilesStore { return maxCount <= count } - func toDartFormat() -> String? { - let pathsObject = paths.map { ["path": $0]} - do { - let jsonData = try JSONSerialization.data(withJSONObject: pathsObject) - if let jsonString = String(data: jsonData, encoding: .utf8) { - return jsonString + func clear() { + self.paths.removeAll() + self.senderName = nil + self.maxCount = 0 + self.count = 0 + } + + func toDartFormat(peerID: MCPeerID) -> String? { + if (senderName != nil) { + let object = [ + "files": paths.map { ["path": $0]}, + "sender": ["id": peerID.displayName, "displayName": senderName!] + ] as [String : Any] + do { + let jsonData = try JSONSerialization.data(withJSONObject: object) + if let jsonString = String(data: jsonData, encoding: .utf8) { + return jsonString + } + } catch { + return nil } - } catch { - return "[]" + return nil } - return "[]" + return nil } } diff --git a/lib/nearby_service.dart b/lib/nearby_service.dart index 1bb5510..3251d58 100644 --- a/lib/nearby_service.dart +++ b/lib/nearby_service.dart @@ -195,7 +195,8 @@ abstract class NearbyService { /// Note that if [Platform.isIOS] == true, [NearbyIOSDevice] should be passed. /// If [Platform.isAndroid] == true, [NearbyAndroidDevice] should be passed. /// - Future disconnect(NearbyDeviceBase device); + /// For IOS [device] is required!!! + Future disconnect([NearbyDeviceBase? device]); /// /// If the device is already connected, it does not mean that you can diff --git a/lib/src/base/base.dart b/lib/src/base/base.dart index 45dfcba..a9b1e4c 100644 --- a/lib/src/base/base.dart +++ b/lib/src/base/base.dart @@ -1,3 +1,3 @@ export 'nearby_device_base.dart'; export 'nearby_message_base.dart'; -export 'nearby_message_content_base.dart'; \ No newline at end of file +export 'nearby_message_content_base.dart'; diff --git a/lib/src/interface/interface.dart b/lib/src/interface/interface.dart index 9f05a4a..6fb4579 100644 --- a/lib/src/interface/interface.dart +++ b/lib/src/interface/interface.dart @@ -1,3 +1,3 @@ export 'nearby_device_mapper.dart'; export 'nearby_received_interface.dart'; -export 'nearby_outgoing_interface.dart'; \ No newline at end of file +export 'nearby_outgoing_interface.dart'; diff --git a/lib/src/interface/nearby_device_mapper.dart b/lib/src/interface/nearby_device_mapper.dart index 6571a77..5e65d9c 100644 --- a/lib/src/interface/nearby_device_mapper.dart +++ b/lib/src/interface/nearby_device_mapper.dart @@ -32,5 +32,3 @@ abstract interface class NearbyDeviceMapper { /// NearbyDeviceBase? mapToDevice(dynamic value); } - - diff --git a/lib/src/model/model.dart b/lib/src/model/model.dart index 008efce..e4fc1ac 100644 --- a/lib/src/model/model.dart +++ b/lib/src/model/model.dart @@ -3,5 +3,6 @@ export 'nearby_device_status.dart'; export 'nearby_message.dart'; export 'nearby_message_content.dart'; export 'communication_channel_state.dart'; -export 'nearby_file.dart'; +export 'nearby_file_info.dart'; export 'nearby_message_content_type.dart'; +export 'nearby_files_pack.dart'; diff --git a/lib/src/model/nearby_file.dart b/lib/src/model/nearby_file_info.dart similarity index 65% rename from lib/src/model/nearby_file.dart rename to lib/src/model/nearby_file_info.dart index 272747f..b59e3fe 100644 --- a/lib/src/model/nearby_file.dart +++ b/lib/src/model/nearby_file_info.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'package:nearby_service/nearby_service.dart'; /// @@ -8,46 +7,7 @@ import 'package:nearby_service/nearby_service.dart'; /// From the communication channel, you usually get /// the [NearbyMessageFilesRequest] request first. /// After that, you can send positive [NearbyMessageFilesResponse] and -/// get the list of [NearbyFile]. -/// -final class NearbyFile { - /// - /// Pass [info] assigned to file to be sent. - /// - const NearbyFile({ - required this.info, - required this.file, - }); - - /// - /// Quick info about the file - /// - final NearbyFileInfo info; - - /// - /// A file that you can save in your phone if needed - /// - final File file; - - @override - bool operator ==(Object other) => - identical(this, other) || - other is NearbyFile && - runtimeType == other.runtimeType && - info == other.info && - file == other.file; - - @override - int get hashCode => info.hashCode ^ file.hashCode; - - @override - String toString() { - return 'NearbyFile{info: $info, file: $file}'; - } -} - -/// -/// Quick info about the file +/// get the list of [NearbyFileInfo]. /// class NearbyFileInfo { /// diff --git a/lib/src/model/nearby_files_pack.dart b/lib/src/model/nearby_files_pack.dart new file mode 100644 index 0000000..b1d0434 --- /dev/null +++ b/lib/src/model/nearby_files_pack.dart @@ -0,0 +1,54 @@ +import 'package:nearby_service/nearby_service.dart'; + +/// +/// Used to provide result [files] that was got from [sender]. +/// +/// Can be received from [NearbyServiceFilesListener] only. +/// +class ReceivedNearbyFilesPack implements NearbyReceivedInterface { + const ReceivedNearbyFilesPack({ + required this.sender, + required this.files, + }); + + factory ReceivedNearbyFilesPack.fromJson(Map? json) { + return ReceivedNearbyFilesPack( + sender: NearbyDeviceInfo.fromJson(json?['sender']), + files: [ + ...?(json?['files'] as List?)?.map( + (e) => NearbyFileInfo.fromJson(e as Map), + ), + ], + ); + } + + @override + final NearbyDeviceInfo sender; + + final List files; + + Map toJson() { + return { + 'sender': sender.toJson(), + 'files': [ + ...files.map((e) => e.toJson()), + ], + }; + } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is ReceivedNearbyFilesPack && + runtimeType == other.runtimeType && + sender == other.sender && + files == other.files; + + @override + int get hashCode => sender.hashCode ^ files.hashCode; + + @override + String toString() { + return 'NearbyFilesPack{sender: $sender, files: $files}'; + } +} diff --git a/lib/src/platforms/android/model/nearby_connection_info.dart b/lib/src/platforms/android/model/nearby_connection_info.dart index 289f40d..b1e5803 100644 --- a/lib/src/platforms/android/model/nearby_connection_info.dart +++ b/lib/src/platforms/android/model/nearby_connection_info.dart @@ -42,7 +42,7 @@ class NearbyConnectionAndroidInfo { final bool isGroupOwner; /// - /// Indicates if the current device is the group owner. + /// Indicates if a p2p group has been successfully formed. /// Source [WifiP2pInfo documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pInfo) /// final bool groupFormed; diff --git a/lib/src/platforms/android/model/nearby_device.dart b/lib/src/platforms/android/model/nearby_device.dart index 666e6a2..94fb079 100644 --- a/lib/src/platforms/android/model/nearby_device.dart +++ b/lib/src/platforms/android/model/nearby_device.dart @@ -18,15 +18,15 @@ final class NearbyAndroidDevice extends NearbyDeviceBase { /// NearbyAndroidDevice({ required String deviceName, - required super.status, required this.deviceAddress, - required this.isGroupOwner, - required this.isServiceDiscoveryCapable, - required this.primaryDeviceType, - required this.wpsKeypadSupported, - required this.wpsPbcSupported, - required this.wpsDisplaySupported, + this.isGroupOwner = false, + this.isServiceDiscoveryCapable = false, + this.primaryDeviceType = kNearbyUnknown, + this.wpsKeypadSupported = false, + this.wpsPbcSupported = false, + this.wpsDisplaySupported = false, this.secondaryDeviceType, + super.status = NearbyDeviceStatus.unavailable, }) : super( info: NearbyDeviceInfo( displayName: deviceName, diff --git a/lib/src/platforms/android/nearby_android_service.dart b/lib/src/platforms/android/nearby_android_service.dart index 65c10ba..37ee92f 100644 --- a/lib/src/platforms/android/nearby_android_service.dart +++ b/lib/src/platforms/android/nearby_android_service.dart @@ -65,9 +65,8 @@ class NearbyAndroidService extends NearbyService { /// Note! Requires [NearbyAndroidDevice] to be passed. /// @override - Future disconnect(NearbyDeviceBase device) { - _requireAndroidDevice(device); - return NearbyServiceAndroidPlatform.instance.disconnect(device.info.id); + Future disconnect([NearbyDeviceBase? device]) { + return NearbyServiceAndroidPlatform.instance.disconnect(); } /// diff --git a/lib/src/platforms/android/nearby_service_android_interface.dart b/lib/src/platforms/android/nearby_service_android_interface.dart index 204302b..48cd98d 100644 --- a/lib/src/platforms/android/nearby_service_android_interface.dart +++ b/lib/src/platforms/android/nearby_service_android_interface.dart @@ -51,7 +51,7 @@ abstract class NearbyServiceAndroidPlatform extends PlatformInterface { throw UnimplementedError('connect() has not been implemented.'); } - Future disconnect(String deviceAddress) { + Future disconnect() { throw UnimplementedError('disconnect() has not been implemented.'); } diff --git a/lib/src/platforms/android/nearby_service_android_method_channel.dart b/lib/src/platforms/android/nearby_service_android_method_channel.dart index 8fc9454..b760580 100644 --- a/lib/src/platforms/android/nearby_service_android_method_channel.dart +++ b/lib/src/platforms/android/nearby_service_android_method_channel.dart @@ -57,12 +57,8 @@ class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform { } @override - Future disconnect(String deviceAddress) async { - return (await methodChannel.invokeMethod( - "disconnect", - {"deviceAddress": deviceAddress}, - )) ?? - false; + Future disconnect() async { + return (await methodChannel.invokeMethod("disconnect")) ?? false; } @override diff --git a/lib/src/platforms/android/socket_service/file_sockets_manager.dart b/lib/src/platforms/android/socket_service/file_sockets_manager.dart index cf5b624..aef7780 100644 --- a/lib/src/platforms/android/socket_service/file_sockets_manager.dart +++ b/lib/src/platforms/android/socket_service/file_sockets_manager.dart @@ -11,6 +11,7 @@ class FileSocketsManager { final _serverWaitingRequests = {}; NearbyServiceFilesListener? _filesListener; + NearbyDeviceInfo? _sender; void setListener(NearbyServiceFilesListener? listener) { _filesListener = listener; @@ -26,22 +27,30 @@ class FileSocketsManager { Future handleFileMessageContent( NearbyMessageFilesContent content, { + required NearbyDeviceInfo? sender, required NearbyAndroidCommunicationChannelData androidData, required bool isReceived, }) async { + if (sender != null) { + _sender = sender; + Logger.debug('Sender was set to $_sender'); + } + final shouldStartSocket = content.byType( onFilesResponse: (response) => response.response, onFilesRequest: (_) => true, ) ?? false; - if (shouldStartSocket) { + final alreadyExists = _filesSockets[content.id] != null; + + if (shouldStartSocket && !alreadyExists) { final info = await _service.getConnectionInfo(); if (info != null && info.groupFormed) { if (info.isGroupOwner) { await _startFilesServer(content); - if (content is NearbyMessageFilesResponse && isReceived) { - await _tryTransferData(content); + if (isReceived && content is NearbyMessageFilesResponse) { + await _startDataTransfer(content); } } else { await _connectToFilesSocket( @@ -49,13 +58,11 @@ class FileSocketsManager { connectionData: androidData, ownerIpAddress: info.ownerIpAddress, ); - if (content is NearbyMessageFilesRequest && !isReceived) { - await _tryTransferData(content); + if (!isReceived && content is NearbyMessageFilesRequest) { + await _startDataTransfer(content); } } } - } else { - _filesSockets.remove(content.id); } } @@ -107,9 +114,7 @@ class FileSocketsManager { } } - Future _startFilesServer( - NearbyMessageFilesContent content, - ) async { + Future _startFilesServer(NearbyMessageFilesContent content) async { final request = _serverWaitingRequests[content.id]; if (request != null) { @@ -130,8 +135,9 @@ class FileSocketsManager { required Future Function() onCreateSocket, }) async { final socket = await onCreateSocket(); - if (socket != null) { + if (socket != null && _sender != null) { _filesSockets[content.id] = FilesSocket.startListening( + sender: _sender!, content: content, socket: socket, listener: _filesListener, @@ -143,7 +149,7 @@ class FileSocketsManager { return false; } - Future _tryTransferData(NearbyMessageFilesContent content) async { + Future _startDataTransfer(NearbyMessageFilesContent content) async { final filesSocket = _filesSockets[content.id]; if (filesSocket != null) { Logger.debug('Start transferring the files pack ${content.id}'); diff --git a/lib/src/platforms/android/socket_service/nearby_socket_service.dart b/lib/src/platforms/android/socket_service/nearby_socket_service.dart index 00e4ec3..0053e5f 100644 --- a/lib/src/platforms/android/socket_service/nearby_socket_service.dart +++ b/lib/src/platforms/android/socket_service/nearby_socket_service.dart @@ -96,13 +96,7 @@ class NearbySocketService { }, ), ); - if (message.content is NearbyMessageFilesContent) { - _fileSocketsManager.handleFileMessageContent( - message.content as NearbyMessageFilesContent, - androidData: _androidData, - isReceived: false, - ); - } + _handleMessage(message); } return true; } @@ -211,13 +205,7 @@ class NearbySocketService { .listen( (message) async { try { - if (message.content is NearbyMessageFilesContent) { - _fileSocketsManager.handleFileMessageContent( - message.content as NearbyMessageFilesContent, - androidData: _androidData, - isReceived: true, - ); - } + _handleMessage(message); socketListener.onData(message); } catch (e) { Logger.error(e); @@ -244,4 +232,15 @@ class NearbySocketService { state.value = CommunicationChannelState.notConnected; } } + + void _handleMessage(NearbyMessageBase message) { + if (message.content is NearbyMessageFilesContent) { + _fileSocketsManager.handleFileMessageContent( + message.content as NearbyMessageFilesContent, + isReceived: message is ReceivedNearbyMessage, + sender: message is ReceivedNearbyMessage ? message.sender : null, + androidData: _androidData, + ); + } + } } diff --git a/lib/src/platforms/ios/nearby_ios_service.dart b/lib/src/platforms/ios/nearby_ios_service.dart index e7b6640..d5a684c 100644 --- a/lib/src/platforms/ios/nearby_ios_service.dart +++ b/lib/src/platforms/ios/nearby_ios_service.dart @@ -140,7 +140,8 @@ class NearbyIOSService extends NearbyService { /// Note! Requires [NearbyIOSDevice] to be passed. /// @override - Future disconnect(NearbyDeviceBase device) async { + Future disconnect([NearbyDeviceBase? device]) async { + if (device == null) return false; _requireIOSDevice(device); final result = await NearbyServiceIOSPlatform.instance.disconnect( device.info.id, @@ -185,9 +186,9 @@ class NearbyIOSService extends NearbyService { cancelOnError: eventListener.cancelOnError, ); _resourcesSubscription = NearbyServiceIOSPlatform.instance.resourcesStream - .map(ResourcesStreamMapper.toFiles) + .map(ResourcesStreamMapper.toFilesPack) .where((event) => event != null) - .cast>() + .cast() .listen( (e) => filesListener?.onData.call(e), onDone: filesListener?.onDone, diff --git a/lib/src/types/nearby_service_stream_listener.dart b/lib/src/types/nearby_service_stream_listener.dart index 62a513d..fe2d9b7 100644 --- a/lib/src/types/nearby_service_stream_listener.dart +++ b/lib/src/types/nearby_service_stream_listener.dart @@ -46,7 +46,7 @@ class NearbyServiceMessagesListener /// Stream Subscription Listener. /// class NearbyServiceFilesListener - extends NearbyServiceSocketListener> { + extends NearbyServiceSocketListener { /// /// It is required to pass the [onData] parameter to process the /// data that came through the stream. diff --git a/lib/src/utils/exception.dart b/lib/src/utils/exception.dart index 9e693fb..0f0a3a5 100644 --- a/lib/src/utils/exception.dart +++ b/lib/src/utils/exception.dart @@ -31,7 +31,8 @@ class NearbyServiceException implements Exception { ); } - factory NearbyServiceException.invalidMessage(NearbyMessageContentBase content) { + factory NearbyServiceException.invalidMessage( + NearbyMessageContentBase content) { return NearbyServiceException( 'The message="$content" is not valid', ); diff --git a/lib/src/utils/file_socket.dart b/lib/src/utils/file_socket.dart index 98cce0f..b59078c 100644 --- a/lib/src/utils/file_socket.dart +++ b/lib/src/utils/file_socket.dart @@ -8,6 +8,7 @@ import 'package:path_provider/path_provider.dart'; class FilesSocket { FilesSocket.startListening({ + required this.sender, required this.content, required this.listener, required this.onDestroy, @@ -31,9 +32,10 @@ class FilesSocket { final NearbyMessageFilesContent content; final void Function(String) onDestroy; final NearbyServiceFilesListener? listener; + final NearbyDeviceInfo sender; final WebSocket _socket; - final _files = []; + final _files = []; final _bytesTable = >{'0': []}; final _futures = []; @@ -65,7 +67,13 @@ class FilesSocket { } else if (event == finishCommand) { await Future.wait(_futures); Logger.info('Files pack ${content.id} was created'); - listener?.onData.call(_files); + + listener?.onData.call( + ReceivedNearbyFilesPack( + sender: sender, + files: _files, + ), + ); onDestroy(content.id); } } @@ -76,13 +84,12 @@ class FilesSocket { final fileInfo = content.files[index]; final directory = await getTemporaryDirectory(); final file = File('${directory.path}/${fileInfo.name}'); - await file.writeAsBytes(bytes); + final updatedFileInfo = NearbyFileInfo(path: file.path); - final nearbyFile = NearbyFile(file: file, info: fileInfo); - _files.add(nearbyFile); + _files.add(updatedFileInfo); - Logger.info('File ${nearbyFile.info.name} was created'); + Logger.info('File ${updatedFileInfo.name} was created'); } catch (e) { Logger.error(e); } diff --git a/lib/src/utils/stream_mapper.dart b/lib/src/utils/stream_mapper.dart index 2e1d772..e18c6d6 100644 --- a/lib/src/utils/stream_mapper.dart +++ b/lib/src/utils/stream_mapper.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:nearby_service/nearby_service.dart'; import 'package:nearby_service/src/utils/json_decoder.dart'; @@ -20,6 +18,8 @@ abstract class MessagesStreamMapper { static ReceivedNearbyMessage? toMessage(dynamic event) { try { final decoded = JSONDecoder.decodeMap(event); + if (decoded == null) return null; + return ReceivedNearbyMessage.fromJson(decoded); } catch (e) { throw NearbyServiceException( @@ -30,17 +30,12 @@ abstract class MessagesStreamMapper { } abstract class ResourcesStreamMapper { - static List? toFiles(dynamic event) { + static ReceivedNearbyFilesPack? toFilesPack(dynamic event) { try { - final decoded = JSONDecoder.decodeList(event); - final infoList = [ - ...?decoded?.map( - (e) => NearbyFileInfo.fromJson(e as Map), - ) - ]; - return [ - ...infoList.map((e) => NearbyFile(info: e, file: File(e.path))), - ]; + final decoded = JSONDecoder.decodeMap(event); + if (decoded == null) return null; + + return ReceivedNearbyFilesPack.fromJson(decoded); } catch (e) { throw NearbyServiceException( 'Can\'t convert $event to ReceivedNearbyMessage',