feat(*): add sender to files pack result
This commit is contained in:
+19
-14
@@ -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<void> stopListeningConnectionInfo() async {
|
||||
await connectionInfoSubscription?.cancel();
|
||||
connectionInfoSubscription = null;
|
||||
}
|
||||
|
||||
Future<void> connect(NearbyDeviceBase device) async {
|
||||
try {
|
||||
await _nearbyService.connect(device);
|
||||
@@ -366,6 +361,11 @@ class AppService extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> stopListeningConnectionInfo() async {
|
||||
await connectionInfoSubscription?.cancel();
|
||||
connectionInfoSubscription = null;
|
||||
}
|
||||
|
||||
Future<void> startListeningConnectedDevice(NearbyDeviceBase device) async {
|
||||
updateState(AppState.loadingConnection);
|
||||
try {
|
||||
@@ -404,7 +404,7 @@ class AppService extends ChangeNotifier {
|
||||
|
||||
Future<void> startCommunicationChannel({
|
||||
ValueChanged<ReceivedNearbyMessage>? listener,
|
||||
ValueChanged<List<NearbyFileInfo>>? onFilesSaved,
|
||||
ValueChanged<ReceivedNearbyFilesPack>? 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<void> disconnect(NearbyDeviceBase device) async {
|
||||
Future<void> disconnect([NearbyDeviceBase? device]) async {
|
||||
try {
|
||||
await _nearbyService.disconnect(device);
|
||||
} catch (e) {
|
||||
@@ -883,10 +885,13 @@ class _ConnectedBody extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _onFileSaved(BuildContext context, List<NearbyFileInfo> 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<bool> disconnect(NearbyDeviceBase device);
|
||||
/// For IOS [device] is required!!!
|
||||
Future<bool> disconnect([NearbyDeviceBase? device]);
|
||||
|
||||
///
|
||||
/// If the device is already connected, it does not mean that you can
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export 'nearby_device_base.dart';
|
||||
export 'nearby_message_base.dart';
|
||||
export 'nearby_message_content_base.dart';
|
||||
export 'nearby_message_content_base.dart';
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export 'nearby_device_mapper.dart';
|
||||
export 'nearby_received_interface.dart';
|
||||
export 'nearby_outgoing_interface.dart';
|
||||
export 'nearby_outgoing_interface.dart';
|
||||
|
||||
@@ -32,5 +32,3 @@ abstract interface class NearbyDeviceMapper {
|
||||
///
|
||||
NearbyDeviceBase? mapToDevice(dynamic value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
///
|
||||
@@ -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<String, dynamic>? json) {
|
||||
return ReceivedNearbyFilesPack(
|
||||
sender: NearbyDeviceInfo.fromJson(json?['sender']),
|
||||
files: [
|
||||
...?(json?['files'] as List?)?.map(
|
||||
(e) => NearbyFileInfo.fromJson(e as Map<String, dynamic>),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
final NearbyDeviceInfo sender;
|
||||
|
||||
final List<NearbyFileInfo> files;
|
||||
|
||||
Map<String, dynamic> 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}';
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -65,9 +65,8 @@ class NearbyAndroidService extends NearbyService {
|
||||
/// Note! Requires [NearbyAndroidDevice] to be passed.
|
||||
///
|
||||
@override
|
||||
Future<bool> disconnect(NearbyDeviceBase device) {
|
||||
_requireAndroidDevice(device);
|
||||
return NearbyServiceAndroidPlatform.instance.disconnect(device.info.id);
|
||||
Future<bool> disconnect([NearbyDeviceBase? device]) {
|
||||
return NearbyServiceAndroidPlatform.instance.disconnect();
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -51,7 +51,7 @@ abstract class NearbyServiceAndroidPlatform extends PlatformInterface {
|
||||
throw UnimplementedError('connect() has not been implemented.');
|
||||
}
|
||||
|
||||
Future<bool> disconnect(String deviceAddress) {
|
||||
Future<bool> disconnect() {
|
||||
throw UnimplementedError('disconnect() has not been implemented.');
|
||||
}
|
||||
|
||||
|
||||
@@ -57,12 +57,8 @@ class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> disconnect(String deviceAddress) async {
|
||||
return (await methodChannel.invokeMethod<bool?>(
|
||||
"disconnect",
|
||||
{"deviceAddress": deviceAddress},
|
||||
)) ??
|
||||
false;
|
||||
Future<bool> disconnect() async {
|
||||
return (await methodChannel.invokeMethod<bool?>("disconnect")) ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -11,6 +11,7 @@ class FileSocketsManager {
|
||||
final _serverWaitingRequests = <String, HttpRequest>{};
|
||||
|
||||
NearbyServiceFilesListener? _filesListener;
|
||||
NearbyDeviceInfo? _sender;
|
||||
|
||||
void setListener(NearbyServiceFilesListener? listener) {
|
||||
_filesListener = listener;
|
||||
@@ -26,22 +27,30 @@ class FileSocketsManager {
|
||||
|
||||
Future<void> 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<void> _startFilesServer(
|
||||
NearbyMessageFilesContent content,
|
||||
) async {
|
||||
Future<void> _startFilesServer(NearbyMessageFilesContent content) async {
|
||||
final request = _serverWaitingRequests[content.id];
|
||||
|
||||
if (request != null) {
|
||||
@@ -130,8 +135,9 @@ class FileSocketsManager {
|
||||
required Future<WebSocket?> 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<void> _tryTransferData(NearbyMessageFilesContent content) async {
|
||||
Future<void> _startDataTransfer(NearbyMessageFilesContent content) async {
|
||||
final filesSocket = _filesSockets[content.id];
|
||||
if (filesSocket != null) {
|
||||
Logger.debug('Start transferring the files pack ${content.id}');
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,8 @@ class NearbyIOSService extends NearbyService {
|
||||
/// Note! Requires [NearbyIOSDevice] to be passed.
|
||||
///
|
||||
@override
|
||||
Future<bool> disconnect(NearbyDeviceBase device) async {
|
||||
Future<bool> 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<List<NearbyFile>>()
|
||||
.cast<ReceivedNearbyFilesPack>()
|
||||
.listen(
|
||||
(e) => filesListener?.onData.call(e),
|
||||
onDone: filesListener?.onDone,
|
||||
|
||||
@@ -46,7 +46,7 @@ class NearbyServiceMessagesListener
|
||||
/// Stream Subscription Listener.
|
||||
///
|
||||
class NearbyServiceFilesListener
|
||||
extends NearbyServiceSocketListener<List<NearbyFile>> {
|
||||
extends NearbyServiceSocketListener<ReceivedNearbyFilesPack> {
|
||||
///
|
||||
/// It is required to pass the [onData] parameter to process the
|
||||
/// data that came through the stream.
|
||||
|
||||
@@ -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',
|
||||
);
|
||||
|
||||
@@ -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 = <NearbyFile>[];
|
||||
final _files = <NearbyFileInfo>[];
|
||||
final _bytesTable = <String, List<int>>{'0': []};
|
||||
final _futures = <Future>[];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<NearbyFile>? toFiles(dynamic event) {
|
||||
static ReceivedNearbyFilesPack? toFilesPack(dynamic event) {
|
||||
try {
|
||||
final decoded = JSONDecoder.decodeList(event);
|
||||
final infoList = [
|
||||
...?decoded?.map(
|
||||
(e) => NearbyFileInfo.fromJson(e as Map<String, dynamic>),
|
||||
)
|
||||
];
|
||||
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',
|
||||
|
||||
Reference in New Issue
Block a user