Skip to content

Commit

Permalink
Merge pull request #1777 from EnsembleUI/Media-Support-for-shareAction
Browse files Browse the repository at this point in the history
Updated Share Action: added file sharing support
  • Loading branch information
mehsaandev authored Jan 14, 2025
2 parents b15a5ba + ca29973 commit bfb7511
Showing 1 changed file with 129 additions and 13 deletions.
142 changes: 129 additions & 13 deletions modules/ensemble/lib/action/misc_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:rate_my_app/rate_my_app.dart';
import 'package:share_plus/share_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:mime/mime.dart';

class CopyToClipboardAction extends EnsembleAction {
CopyToClipboardAction(this._value,
Expand Down Expand Up @@ -57,29 +59,143 @@ class CopyToClipboardAction extends EnsembleAction {
}
}

/// Share a text (an optionally a title) to external Apps
/// Share text and files (an optionally a title) to external Apps
class ShareAction extends EnsembleAction {
ShareAction(this._text, {String? title}) : _title = title;
ShareAction(this._text, {String? title, dynamic files})
: _title = title,
_files = files;
String? _title;
dynamic _text;
dynamic _files;

factory ShareAction.from({Map? payload}) {
if (payload == null || payload['text'] == null) {
throw LanguageError("${ActionType.share.name} requires 'text'");
if (payload == null ||
(payload['text'] == null && payload['files'] == null)) {
throw LanguageError(
"${ActionType.share.name} requires 'text' or 'files'");
}
return ShareAction(payload['text'], title: payload['title']?.toString());

return ShareAction(
payload['text'],
title: payload['title']?.toString(),
files: payload['files'],
);
}

// Helper method to create XFile from file data
XFile? createXFile(dynamic file) {
final mimeType =
lookupMimeType(file["path"] ?? '', headerBytes: file["bytes"]) ??
'application/octet-stream';
try {
if (file is Map) {
// Handle file with path
if (file['path'] != null && file['path'].toString().isNotEmpty) {
final String path = file['path'].toString();
final String name = file['name']?.toString() ?? path.split('/').last;
return XFile(path, name: name, mimeType: mimeType);
}

// Handle file with bytes (web)
if (file.containsKey('bytes') && file['bytes'] != null) {
final String name = file['name']?.toString() ?? 'file';

return XFile.fromData(
file['bytes'],
name: name,
mimeType: mimeType,
);
}
} else if (file is String) {
// Handle simple file path string
return XFile(file, name: file.split('/').last, mimeType: mimeType);
}
} catch (e) {
debugPrint('Error creating XFile: $e');
}
return null;
}

@override
Future execute(BuildContext context, ScopeManager scopeManager) {
final box = context.findRenderObject() as RenderBox?;
Future<void> execute(BuildContext context, ScopeManager scopeManager) async {
try {
final box = context.findRenderObject() as RenderBox?;
if (box == null) return;

Share.share(
scopeManager.dataContext.eval(_text),
subject: Utils.optionalString(scopeManager.dataContext.eval(_title)),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
);
return Future.value(null);
final sharePositionOrigin = box.localToGlobal(Offset.zero) & box.size;
final evaluatedText =
scopeManager.dataContext.eval(_text)?.toString() ?? '';
final evaluatedTitle =
Utils.optionalString(scopeManager.dataContext.eval(_title));

// Handle file sharing
if (_files != null) {
final evaluatedFiles = scopeManager.dataContext.eval(_files);
if (evaluatedFiles != null) {
final filesList =
evaluatedFiles is List ? evaluatedFiles : [evaluatedFiles];
final List<XFile> xFiles = [];

// Create XFiles
for (var file in filesList) {
final xFile = createXFile(file);
if (xFile != null) {
xFiles.add(xFile);
}
}

// Share files if any were created successfully
if (xFiles.isNotEmpty) {
try {
final result = await Share.shareXFiles(
xFiles,
text: evaluatedText,
subject: evaluatedTitle ?? '',
sharePositionOrigin: sharePositionOrigin,
);

// Handle share result
if (result.status == ShareResultStatus.success) {
debugPrint('Share completed successfully: ${result.raw}');
} else {
debugPrint('Share completed with status: ${result.status}');
}
return;
} catch (e) {
debugPrint('Error sharing files: $e');
if (kIsWeb) {
// On web, fall back to sharing just the text
await Share.share(
evaluatedText,
subject: evaluatedTitle ?? '',
sharePositionOrigin: sharePositionOrigin,
);
return;
}
rethrow;
}
}
}
}

// Fall back to sharing just text if no files or file sharing failed
if (evaluatedText.isNotEmpty) {
final result = await Share.share(
evaluatedText,
subject: evaluatedTitle ?? '',
sharePositionOrigin: sharePositionOrigin,
);

if (result.status == ShareResultStatus.success) {
debugPrint('Text share completed successfully: ${result.raw}');
} else {
debugPrint('Text share completed with status: ${result.status}');
}
}
} catch (e) {
debugPrint('ShareAction failed: $e');
rethrow;
}
}
}

Expand Down

0 comments on commit bfb7511

Please sign in to comment.