recipe-manager/mobile/lib/features/share_receiver/share_receiver_service.dart

77 lines
2.3 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'quick_share_sheet.dart';
class ShareReceiverService {
StreamSubscription? _intentSub;
void init(BuildContext context) {
// 1. Listen to shared text/links while app is in memory
_intentSub = ReceiveSharingIntent.getTextStream().listen((String value) {
if (value.isNotEmpty) {
_handleSharedText(context, value);
}
}, onError: (err) {
debugPrint("getLinkStream error: $err");
});
// 2. Get the shared text/link when the app is launched from closed state
ReceiveSharingIntent.getInitialText().then((String? value) {
if (value != null && value.isNotEmpty) {
_handleSharedText(context, value);
}
});
// 3. Listen to shared files/images (e.g. sharing photo from Gallery)
ReceiveSharingIntent.getImageStream().listen((List<SharedMediaFile> value) {
if (value.isNotEmpty) {
_handleSharedFiles(context, value);
}
}, onError: (err) {
debugPrint("getImageStream error: $err");
});
ReceiveSharingIntent.getInitialImage().then((List<SharedMediaFile> value) {
if (value.isNotEmpty) {
_handleSharedFiles(context, value);
}
});
}
void _handleSharedText(BuildContext context, String rawText) {
// Sanitize and extract URL from messy text (e.g. Instagram caption + link)
final urlRegex = RegExp(r'https?://[^\s]+');
final match = urlRegex.firstMatch(rawText);
final url = match?.group(0);
final rawCaption = rawText.replaceFirst(url ?? '', '').trim();
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (ctx) => QuickShareSheet(
url: url,
rawCaption: rawCaption.isNotEmpty ? rawCaption : null,
),
);
}
void _handleSharedFiles(BuildContext context, List<SharedMediaFile> files) {
if (files.isEmpty) return;
final firstFile = files.first;
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (ctx) => QuickShareSheet(
imagePath: firstFile.path,
),
);
}
void dispose() {
_intentSub?.cancel();
}
}