Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(share_plus): share XFile created using File.fromData() #1284

Merged
merged 10 commits into from Oct 24, 2022
Expand Up @@ -6,6 +6,8 @@

import 'dart:io';

import 'package:file_selector/file_selector.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:share_plus/share_plus.dart';
import 'package:integration_test/integration_test.dart';
Expand All @@ -24,4 +26,13 @@ void main() {
testWidgets('Can launch shareWithResult', (WidgetTester tester) async {
expect(Share.shareWithResult('message', subject: 'title'), isNotNull);
});

testWidgets('Can shareXFile created using File.fromData()',
(WidgetTester tester) async {
final bytes = Uint8List.fromList([1, 2, 3, 4, 5, 6, 7, 8]);
final XFile file =
XFile.fromData(bytes, name: 'image.jpg', mimeType: 'image/jpeg');

expect(Share.shareXFiles([file], text: "example"), isNotNull);
});
}
Expand Up @@ -3,6 +3,8 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:io';

// Keep dart:ui for retrocompatiblity with Flutter <3.3.0
// ignore: unnecessary_import
import 'dart:ui';
Expand All @@ -12,6 +14,7 @@ import 'package:flutter/services.dart';
import 'package:meta/meta.dart' show visibleForTesting;
import 'package:mime/mime.dart' show lookupMimeType;
import 'package:share_plus_platform_interface/share_plus_platform_interface.dart';
import 'package:path_provider/path_provider.dart';

/// Plugin for summoning a platform share sheet.
class MethodChannelShare extends SharePlatform {
Expand Down Expand Up @@ -141,19 +144,56 @@ class MethodChannelShare extends SharePlatform {
String? subject,
String? text,
Rect? sharePositionOrigin,
}) {
final mimeTypes =
files.map((e) => e.mimeType ?? _mimeTypeForPath(e.path)).toList();
}) async {
final filesWithPath = await _getFiles(files);

final mimeTypes = filesWithPath
.map((e) => e.mimeType ?? _mimeTypeForPath(e.path))
.toList();

return shareFilesWithResult(
files.map((e) => e.path).toList(),
filesWithPath.map((e) => e.path).toList(),
mimeTypes: mimeTypes,
subject: subject,
text: text,
sharePositionOrigin: sharePositionOrigin,
);
}

/// if file doesn't contain path
/// then make new file in TemporaryDirectory and return with path
///
/// the system will automatically delete files in this
/// TemporaryDirectory as disk space is needed elsewhere on the device
Future<List<XFile>> _getFiles(List<XFile> files) async {
int count = 1;

if (!files.every((element) => element.path.isNotEmpty)) {
miquelbeltran marked this conversation as resolved.
Show resolved Hide resolved
final newFiles = <XFile>[];

final String tempPath = (await getTemporaryDirectory()).path;

for (final XFile element in files) {
if (element.path.isEmpty) {
final path = '$tempPath/${element.name}$count';
miquelbeltran marked this conversation as resolved.
Show resolved Hide resolved
final file = File(path);

await file.writeAsBytes(await element.readAsBytes());

newFiles.add(XFile(path));

count++;
} else {
newFiles.add(element);
}
}

return newFiles;
} else {
return files;
}
}

static String _mimeTypeForPath(String path) {
return lookupMimeType(path) ?? 'application/octet-stream';
}
Expand Down
Expand Up @@ -11,6 +11,7 @@ dependencies:
meta: ^1.7.0
mime: ^1.0.2
plugin_platform_interface: ^2.0.0
path_provider: ^2.0.11

dev_dependencies:
flutter_test:
Expand Down
Expand Up @@ -163,10 +163,7 @@ void main() {
() => SharePlatform.instance.shareFilesWithResult(['']),
throwsA(const TypeMatcher<AssertionError>()),
);
expect(
() => sharePlatform.shareXFiles([XFile('')]),
throwsA(const TypeMatcher<AssertionError>()),
);

verifyZeroInteractions(mockChannel);
});

Expand Down