feat(android) multiple files support
This commit is contained in:
+50
-34
@@ -379,7 +379,7 @@ class AppService extends ChangeNotifier {
|
||||
|
||||
Future<void> startCommunicationChannel({
|
||||
ValueChanged<ReceivedNearbyMessage>? listener,
|
||||
ValueChanged<File>? onFileSaved,
|
||||
ValueChanged<List<File>>? onFilesSaved,
|
||||
}) async {
|
||||
final messagesListener = NearbyServiceMessagesListener(
|
||||
onCreated: () {
|
||||
@@ -394,12 +394,16 @@ class AppService extends ChangeNotifier {
|
||||
);
|
||||
final filesListener = NearbyServiceFilesListener(
|
||||
onData: (event) async {
|
||||
final content = event.content;
|
||||
final downloadsDir = Directory('storage/emulated/0/Download');
|
||||
final newFile = await event.file.copy(
|
||||
'${downloadsDir.path}/${content.id}_${content.fileName}',
|
||||
);
|
||||
onFileSaved?.call(newFile);
|
||||
final files = <File>[];
|
||||
for (final nearbyFile in event) {
|
||||
final content = nearbyFile.info;
|
||||
final downloadsDir = Directory('storage/emulated/0/Download');
|
||||
final newFile = await nearbyFile.file.copy(
|
||||
'${downloadsDir.path}/${content.name}',
|
||||
);
|
||||
files.add(newFile);
|
||||
}
|
||||
onFilesSaved?.call(files);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -413,26 +417,33 @@ class AppService extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void sendMessage(String message) {
|
||||
try {
|
||||
if (connectedDevice == null) return;
|
||||
_nearbyService.send(
|
||||
OutgoingNearbyMessage(
|
||||
content: NearbyMessageTextContent(value: message),
|
||||
receiver: connectedDevice!.info,
|
||||
),
|
||||
);
|
||||
} catch (e, s) {
|
||||
print(e);
|
||||
print(s);
|
||||
}
|
||||
}
|
||||
|
||||
void sendFilesRequest(List<String> paths) {
|
||||
if (connectedDevice == null) return;
|
||||
_nearbyService.send(
|
||||
OutgoingNearbyMessage(
|
||||
content: NearbyMessageTextContent(value: message),
|
||||
content: NearbyMessageFileRequest(
|
||||
files: [...paths.map((e) => NearbyFileInfo(path: e))],
|
||||
),
|
||||
receiver: connectedDevice!.info,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void sendFileRequest(String filePath) {
|
||||
if (connectedDevice == null) return;
|
||||
_nearbyService.send(
|
||||
OutgoingNearbyMessage(
|
||||
content: NearbyMessageFileRequest(filePath: filePath),
|
||||
receiver: connectedDevice!.info,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void sendFileAccept(NearbyMessageFileRequest request) {
|
||||
void sendFilesAccept(NearbyMessageFileRequest request) {
|
||||
if (connectedDevice == null) return;
|
||||
_nearbyService.send(
|
||||
OutgoingNearbyMessage(
|
||||
@@ -788,7 +799,7 @@ class _ConnectedBody extends StatelessWidget {
|
||||
title: 'Start communicate',
|
||||
onTap: () => service.startCommunicationChannel(
|
||||
listener: (event) => _listener(context, event),
|
||||
onFileSaved: (file) => _onFileSaved(context, file),
|
||||
onFilesSaved: (files) => _onFileSaved(context, files),
|
||||
),
|
||||
)
|
||||
else
|
||||
@@ -818,21 +829,21 @@ class _ConnectedBody extends StatelessWidget {
|
||||
onFileRequest: (content) {
|
||||
ActionDialog.show(
|
||||
context,
|
||||
title: 'File request ${content.fileName}',
|
||||
title: 'Files request. Files count: ${content.files.length}',
|
||||
subtitle: senderSubtitle,
|
||||
).then((value) {
|
||||
if (value == true) {
|
||||
context.read<AppService>().sendFileAccept(content);
|
||||
context.read<AppService>().sendFilesAccept(content);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _onFileSaved(BuildContext context, File file) {
|
||||
void _onFileSaved(BuildContext context, List<File> files) {
|
||||
AppShackBar.show(
|
||||
Scaffold.of(context).context,
|
||||
'File saved to ${file.path}',
|
||||
'${files.length} files saved! \n ${files.map((e) => e.path).join('\n')}',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -846,7 +857,7 @@ class _ConnectedSocketBody extends StatefulWidget {
|
||||
|
||||
class _ConnectedSocketBodyState extends State<_ConnectedSocketBody> {
|
||||
String message = '';
|
||||
String filePath = '';
|
||||
List<String> filePaths = [];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -905,14 +916,18 @@ class _ConnectedSocketBodyState extends State<_ConnectedSocketBody> {
|
||||
flex: 2,
|
||||
child: _ActionButton(
|
||||
type: _ActionButtonType.warning,
|
||||
title: 'Choose a file',
|
||||
title: 'Choose files',
|
||||
onTap: () async {
|
||||
final result = await FilePicker.platform.pickFiles();
|
||||
if (result != null && result.isSinglePick) {
|
||||
setState(() {
|
||||
filePath = result.paths.first!;
|
||||
});
|
||||
}
|
||||
final result = await FilePicker.platform.pickFiles(
|
||||
allowMultiple: true,
|
||||
);
|
||||
setState(() {
|
||||
filePaths = [
|
||||
...?result?.paths
|
||||
.where((e) => e != null)
|
||||
.cast<String>(),
|
||||
];
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -921,7 +936,7 @@ class _ConnectedSocketBodyState extends State<_ConnectedSocketBody> {
|
||||
child: _ActionButton(
|
||||
title: 'Send',
|
||||
onTap: () {
|
||||
service.sendFileRequest(filePath);
|
||||
service.sendFilesRequest(filePaths);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -929,7 +944,8 @@ class _ConnectedSocketBodyState extends State<_ConnectedSocketBody> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text('Selected file: $filePath'),
|
||||
const Text('Selected files:', style: TextStyle(fontSize: 18)),
|
||||
Text(filePaths.join('\n')),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
||||
@@ -5,24 +5,22 @@ import 'package:nearby_service/nearby_service.dart';
|
||||
/// A representation of a file that can be got from the Nearby Service's
|
||||
/// communication channel.
|
||||
///
|
||||
/// You can use [id] to compare it to the id from [NearbyMessageFileRequest.id].
|
||||
///
|
||||
/// From the communication channel, you usually get
|
||||
/// the [NearbyMessageFileRequest] request first. After that, you get [NearbyFile].
|
||||
///
|
||||
class NearbyFile {
|
||||
///
|
||||
/// Pass [content] assigned to file to be sent.
|
||||
/// Pass [info] assigned to file to be sent.
|
||||
///
|
||||
const NearbyFile({
|
||||
required this.content,
|
||||
required this.info,
|
||||
required this.file,
|
||||
});
|
||||
|
||||
///
|
||||
/// Quick info about the file
|
||||
///
|
||||
final NearbyMessageFileContent content;
|
||||
final NearbyFileInfo info;
|
||||
|
||||
///
|
||||
/// A file that you can save in your phone if needed
|
||||
@@ -34,14 +32,56 @@ class NearbyFile {
|
||||
identical(this, other) ||
|
||||
other is NearbyFile &&
|
||||
runtimeType == other.runtimeType &&
|
||||
content == other.content &&
|
||||
info == other.info &&
|
||||
file == other.file;
|
||||
|
||||
@override
|
||||
int get hashCode => content.hashCode ^ file.hashCode;
|
||||
int get hashCode => info.hashCode ^ file.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NearbyFile{content: $content, file: $file}';
|
||||
return 'NearbyFile{info: $info, file: $file}';
|
||||
}
|
||||
}
|
||||
|
||||
class NearbyFileInfo {
|
||||
const NearbyFileInfo({required this.path, this.sizeBytes});
|
||||
|
||||
factory NearbyFileInfo.fromJson(Map<String, dynamic>? json) {
|
||||
return NearbyFileInfo(
|
||||
path: json?['path'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
final String path;
|
||||
final int? sizeBytes;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is NearbyFileInfo &&
|
||||
runtimeType == other.runtimeType &&
|
||||
path == other.path;
|
||||
|
||||
@override
|
||||
int get hashCode => path.hashCode;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'path': path,
|
||||
};
|
||||
}
|
||||
|
||||
String get name {
|
||||
try {
|
||||
return path.split('/').last;
|
||||
} catch (e) {
|
||||
throw NearbyServiceException('Can\'t get fileName from $path');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NearbyFileInfo{path: $path}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,70 +157,61 @@ class NearbyMessageTextContent extends NearbyMessageContent {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class NearbyMessageFileContent extends NearbyMessageContent {
|
||||
const NearbyMessageFileContent(
|
||||
abstract class NearbyMessageFilesContent extends NearbyMessageContent {
|
||||
const NearbyMessageFilesContent(
|
||||
super.type, {
|
||||
required this.id,
|
||||
required this.filePath,
|
||||
required this.files,
|
||||
});
|
||||
|
||||
///
|
||||
/// ID for comparing file requests.
|
||||
///
|
||||
final List<NearbyFileInfo> files;
|
||||
|
||||
final String id;
|
||||
|
||||
///
|
||||
/// The name of the file to be sent or received.
|
||||
///
|
||||
final String filePath;
|
||||
|
||||
String get fileName {
|
||||
try {
|
||||
return filePath.split('/').last;
|
||||
} catch (e) {
|
||||
throw NearbyServiceException('Can\'t get fileName from $filePath');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is NearbyMessageFileContent &&
|
||||
runtimeType == other.runtimeType &&
|
||||
id == other.id &&
|
||||
filePath == other.filePath;
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode ^ filePath.hashCode;
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'filePath': filePath,
|
||||
'files': [
|
||||
...files.map((e) => e.toJson()),
|
||||
],
|
||||
...super.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is NearbyMessageFilesContent &&
|
||||
runtimeType == other.runtimeType &&
|
||||
files == other.files &&
|
||||
id == other.id;
|
||||
|
||||
@override
|
||||
int get hashCode => files.hashCode ^ id.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NearbyMessageFilesContent{files: $files, id: $id}';
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Nearby message File content. Used for file sending requests.
|
||||
/// Does not contain file bytes!
|
||||
///
|
||||
/// Contains [filePath] - the name of file to be sent or received.
|
||||
///
|
||||
class NearbyMessageFileRequest extends NearbyMessageFileContent {
|
||||
class NearbyMessageFileRequest extends NearbyMessageFilesContent {
|
||||
const NearbyMessageFileRequest._({
|
||||
required super.id,
|
||||
required super.filePath,
|
||||
required super.files,
|
||||
}) : super(
|
||||
NearbyMessageContentType.fileRequest,
|
||||
);
|
||||
|
||||
///
|
||||
/// Basic constructor with [filePath] to be sent or received.
|
||||
/// Basic constructor with [files] to be sent or received.
|
||||
///
|
||||
NearbyMessageFileRequest({required super.filePath})
|
||||
NearbyMessageFileRequest({required super.files})
|
||||
: super(
|
||||
NearbyMessageContentType.fileRequest,
|
||||
id: RandomUtils.instance.nextInt(1000000, 9999999).toString(),
|
||||
@@ -232,23 +223,27 @@ class NearbyMessageFileRequest extends NearbyMessageFileContent {
|
||||
factory NearbyMessageFileRequest.fromJson(Map<String, dynamic>? json) {
|
||||
return NearbyMessageFileRequest._(
|
||||
id: json?['id'] ?? '',
|
||||
filePath: json?['filePath'] ?? '',
|
||||
files: [
|
||||
...?(json?['files'] as List?)?.map(
|
||||
(e) => NearbyFileInfo.fromJson(e),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isValid => filePath.isNotEmpty;
|
||||
bool get isValid => files.every((element) => element.path.isNotEmpty);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NearbyMessageFileRequest{id: $id, filePath: $filePath}';
|
||||
return 'NearbyMessageFileRequest{id: $id, files: $files}';
|
||||
}
|
||||
}
|
||||
|
||||
class NearbyMessageFileResponse extends NearbyMessageFileContent {
|
||||
class NearbyMessageFileResponse extends NearbyMessageFilesContent {
|
||||
NearbyMessageFileResponse({
|
||||
required super.id,
|
||||
required super.filePath,
|
||||
required super.files,
|
||||
required this.response,
|
||||
}) : super(
|
||||
NearbyMessageContentType.fileResponse,
|
||||
@@ -260,7 +255,7 @@ class NearbyMessageFileResponse extends NearbyMessageFileContent {
|
||||
}) {
|
||||
return NearbyMessageFileResponse(
|
||||
id: request.id,
|
||||
filePath: request.filePath,
|
||||
files: request.files,
|
||||
response: response,
|
||||
);
|
||||
}
|
||||
@@ -268,7 +263,11 @@ class NearbyMessageFileResponse extends NearbyMessageFileContent {
|
||||
factory NearbyMessageFileResponse.fromJson(Map<String, dynamic>? json) {
|
||||
return NearbyMessageFileResponse(
|
||||
id: json?['id'] ?? '',
|
||||
filePath: json?['filePath'] ?? '',
|
||||
files: [
|
||||
...?(json?['files'] as List?)?.map(
|
||||
(e) => NearbyFileInfo.fromJson(e),
|
||||
),
|
||||
],
|
||||
response: json?['response'] ?? false,
|
||||
);
|
||||
}
|
||||
@@ -276,7 +275,7 @@ class NearbyMessageFileResponse extends NearbyMessageFileContent {
|
||||
final bool response;
|
||||
|
||||
@override
|
||||
bool get isValid => filePath.isNotEmpty;
|
||||
bool get isValid => files.every((element) => element.path.isNotEmpty);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
@@ -288,6 +287,6 @@ class NearbyMessageFileResponse extends NearbyMessageFileContent {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NearbyMessageFileResponse{response: $response, id: $id, filePath: $filePath}';
|
||||
return 'NearbyMessageFileResponse{response: $response, id: $id, files: $files}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class FileSocketsManager {
|
||||
}
|
||||
|
||||
Future<void> handleFileMessageContent(
|
||||
NearbyMessageFileContent content, {
|
||||
NearbyMessageFilesContent content, {
|
||||
required NearbyAndroidCommunicationChannelData androidData,
|
||||
required bool isReceived,
|
||||
}) async {
|
||||
@@ -56,7 +56,7 @@ class FileSocketsManager {
|
||||
}
|
||||
|
||||
Future<void> _handleClientFileContent(
|
||||
NearbyMessageFileContent content, {
|
||||
NearbyMessageFilesContent content, {
|
||||
required NearbyAndroidCommunicationChannelData connectionData,
|
||||
required String ownerIpAddress,
|
||||
}) async {
|
||||
@@ -86,7 +86,7 @@ class FileSocketsManager {
|
||||
),
|
||||
);
|
||||
Logger.info(
|
||||
'The file socket was created for the file ${content.fileName}',
|
||||
'The file socket was created for the files pack ${content.id}',
|
||||
);
|
||||
} else {
|
||||
await Future.delayed(
|
||||
@@ -105,7 +105,7 @@ class FileSocketsManager {
|
||||
}
|
||||
|
||||
Future<void> _handleServerFileContent(
|
||||
NearbyMessageFileContent content,
|
||||
NearbyMessageFilesContent content,
|
||||
) async {
|
||||
MapEntry<String, HttpRequest>? request;
|
||||
try {
|
||||
@@ -127,30 +127,47 @@ class FileSocketsManager {
|
||||
),
|
||||
);
|
||||
_serverWaitingContents.remove(content.id);
|
||||
Logger.info('Created file socket for ${content.fileName}');
|
||||
Logger.info('Created a socket for the files pack ${content.id}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _tryTransferData(NearbyMessageFileContent content) async {
|
||||
final fileSocket = _find(content.id);
|
||||
if (fileSocket != null) {
|
||||
Logger.info('Start transferring a file ${content.fileName}');
|
||||
final file = File(content.filePath);
|
||||
Future<void> _tryTransferData(NearbyMessageFilesContent content) async {
|
||||
Logger.debug('Start transferring the files pack ${content.id}');
|
||||
final filesSocket = _find(content.id);
|
||||
if (filesSocket != null) {
|
||||
for (var i = 0; i < content.files.length; i++) {
|
||||
try {
|
||||
final fileInfo = content.files[i];
|
||||
await _streamFile(
|
||||
content.id,
|
||||
filesSocket: filesSocket,
|
||||
file: File(fileInfo.path),
|
||||
)?.asFuture();
|
||||
|
||||
file.openRead().listen(
|
||||
(data) {
|
||||
fileSocket.sendData(data);
|
||||
},
|
||||
onDone: () {
|
||||
Logger.debug('Sent finished command for ${content.fileName}');
|
||||
fileSocket.sendData(
|
||||
FilesSocket.generateFinishCommand(fileSocket.content.id),
|
||||
);
|
||||
},
|
||||
);
|
||||
filesSocket.sendData(FilesSocket.separateCommandOf(i));
|
||||
Logger.debug('Sent separate command for file №$i');
|
||||
} catch (e) {
|
||||
Logger.error(e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
filesSocket.sendData(FilesSocket.finishCommand);
|
||||
Logger.debug('Sent finish command for the pack ${content.id}');
|
||||
}
|
||||
}
|
||||
|
||||
StreamSubscription? _streamFile(
|
||||
String id, {
|
||||
required FilesSocket filesSocket,
|
||||
required File file,
|
||||
}) {
|
||||
return file.openRead().listen(
|
||||
(data) {
|
||||
filesSocket.sendData(data);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
FilesSocket? _find(String id) {
|
||||
FilesSocket? fileSocket;
|
||||
try {
|
||||
|
||||
@@ -92,9 +92,9 @@ class NearbySocketService {
|
||||
},
|
||||
),
|
||||
);
|
||||
if (message.content is NearbyMessageFileContent) {
|
||||
if (message.content is NearbyMessageFilesContent) {
|
||||
_fileSocketsManager.handleFileMessageContent(
|
||||
message.content as NearbyMessageFileContent,
|
||||
message.content as NearbyMessageFilesContent,
|
||||
androidData: _androidData,
|
||||
isReceived: false,
|
||||
);
|
||||
@@ -220,9 +220,9 @@ class NearbySocketService {
|
||||
message,
|
||||
_connectedDeviceId!,
|
||||
);
|
||||
if (newMessage.content is NearbyMessageFileContent) {
|
||||
if (newMessage.content is NearbyMessageFilesContent) {
|
||||
_fileSocketsManager.handleFileMessageContent(
|
||||
newMessage.content as NearbyMessageFileContent,
|
||||
newMessage.content as NearbyMessageFilesContent,
|
||||
androidData: _androidData,
|
||||
isReceived: true,
|
||||
);
|
||||
|
||||
@@ -46,7 +46,7 @@ class NearbyServiceMessagesListener
|
||||
/// Stream Subscription Listener.
|
||||
///
|
||||
class NearbyServiceFilesListener
|
||||
extends NearbyServiceSocketListener<NearbyFile> {
|
||||
extends NearbyServiceSocketListener<List<NearbyFile>> {
|
||||
///
|
||||
/// It is required to pass the [onData] parameter to process the
|
||||
/// data that came through the stream.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
@@ -15,15 +16,16 @@ class FilesSocket {
|
||||
_socket.listen(
|
||||
(event) async {
|
||||
if (event is List<int>) {
|
||||
saveChunk(event);
|
||||
addChunk(event);
|
||||
} else if (event == separateCommandOf(_currentFileIndex)) {
|
||||
_futures.add(_createFile(_currentFileIndex));
|
||||
_currentFileIndex = _currentFileIndex + 1;
|
||||
_bytesTable['$_currentFileIndex'] = [];
|
||||
} else if (event == finishCommand) {
|
||||
final file = await getFile().whenComplete(
|
||||
() {
|
||||
onDestroy(this);
|
||||
},
|
||||
);
|
||||
Logger.info('File ${file.content.fileName} was created');
|
||||
listener?.onData.call(file);
|
||||
await Future.wait(_futures);
|
||||
Logger.info('Files pack ${content.id} was created');
|
||||
listener?.onData.call(_files);
|
||||
onDestroy(this);
|
||||
}
|
||||
},
|
||||
onError: listener?.onError,
|
||||
@@ -33,43 +35,52 @@ class FilesSocket {
|
||||
listener?.onCreated?.call();
|
||||
}
|
||||
|
||||
static const _finishCommand = '@@FINISH_SENDING_FILE_';
|
||||
static const finishCommand = '_@@FINISH_SENDING_FILE_';
|
||||
|
||||
static String generateFinishCommand(String id) {
|
||||
return '$_finishCommand$id';
|
||||
}
|
||||
static const separateCommand = '_@@SEPARATE_SENDING_FILE_';
|
||||
|
||||
static String separateCommandOf(int index) => '$separateCommand$index';
|
||||
|
||||
final NearbyMessageFilesContent content;
|
||||
|
||||
final WebSocket _socket;
|
||||
final NearbyMessageFileContent content;
|
||||
final _bytes = <int>[];
|
||||
final _files = <NearbyFile>[];
|
||||
final _bytesTable = <String, List<int>>{'0': []};
|
||||
final _futures = <Future>[];
|
||||
|
||||
int chunksCount = 0;
|
||||
|
||||
String get finishCommand => '$_finishCommand${content.id}';
|
||||
int _chunksCount = 0;
|
||||
int _currentFileIndex = 0;
|
||||
|
||||
void sendData(dynamic event) {
|
||||
_socket.add(event);
|
||||
}
|
||||
|
||||
void saveChunk(List<int> value) {
|
||||
_bytes.addAll(value);
|
||||
chunksCount = chunksCount + 1;
|
||||
final logStep = min(pow(10, chunksCount.toString().length - 1), 100);
|
||||
if (chunksCount % logStep == 0) {
|
||||
Logger.debug('Got $chunksCount chunks for the file ${content.fileName}');
|
||||
void addChunk(List<int> value) {
|
||||
_bytesTable['$_currentFileIndex']?.addAll(value);
|
||||
_chunksCount = _chunksCount + 1;
|
||||
final logStep = min(pow(10, _chunksCount.toString().length - 1), 100);
|
||||
if (_chunksCount % logStep == 0) {
|
||||
Logger.debug(
|
||||
'Got $_chunksCount chunks for the file ${content.files[_currentFileIndex].name}',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<NearbyFile> getFile() async {
|
||||
Future<void> _createFile(int index) async {
|
||||
try {
|
||||
final bytes = _bytesTable['$index']!;
|
||||
final fileInfo = content.files[index];
|
||||
final directory = await getTemporaryDirectory();
|
||||
final file = File('${directory.path}/${content.fileName}');
|
||||
final file = File('${directory.path}/${fileInfo.name}');
|
||||
|
||||
await file.writeAsBytes(_bytes);
|
||||
return NearbyFile(file: file, content: content);
|
||||
await file.writeAsBytes(bytes);
|
||||
|
||||
final nearbyFile = NearbyFile(file: file, info: fileInfo);
|
||||
_files.add(nearbyFile);
|
||||
|
||||
Logger.info('File ${nearbyFile.info.name} was created');
|
||||
} catch (e) {
|
||||
Logger.error(e);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user