105 lines
2.9 KiB
Dart
105 lines
2.9 KiB
Dart
import 'dart:ui' as ui;
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:share_plus/share_plus.dart';
|
|
import 'package:onsolgo/core/constants.dart';
|
|
|
|
/// Captures a [RepaintBoundary] (via [key]) as PNG and shares it with [text] and a [link]
|
|
/// (defaults to [kOnsolAppWebUrl]). Uses in-memory bytes only (no [dart:io]).
|
|
class OnsolShare {
|
|
static Future<void> share(GlobalKey key, String text, {String? link}) =>
|
|
_shareImpl(key, text, link: link);
|
|
}
|
|
|
|
Future<void> _shareImpl(GlobalKey key, String text, {String? link}) async {
|
|
final url = (link ?? kOnsolAppWebUrl).trim();
|
|
String bodyWithLink(String raw) {
|
|
final caption = raw.trim().isEmpty ? 'ONSOL-GO!' : raw.trim();
|
|
if (caption.contains(url)) return caption;
|
|
return '$caption\n\n$url';
|
|
}
|
|
|
|
final fallbackMessage = bodyWithLink(text);
|
|
|
|
Future<void> shareText(String value) async {
|
|
await SharePlus.instance.share(ShareParams(text: value));
|
|
}
|
|
|
|
Future<void> clipboard(String value) async {
|
|
await Clipboard.setData(ClipboardData(text: value));
|
|
}
|
|
|
|
try {
|
|
final ctx = key.currentContext;
|
|
if (ctx == null || !ctx.mounted) {
|
|
await shareText(fallbackMessage);
|
|
return;
|
|
}
|
|
|
|
await SchedulerBinding.instance.endOfFrame;
|
|
|
|
if (!ctx.mounted) {
|
|
await shareText(fallbackMessage);
|
|
return;
|
|
}
|
|
|
|
final boundary = ctx.findRenderObject();
|
|
if (boundary is! RenderRepaintBoundary) {
|
|
await shareText(fallbackMessage);
|
|
return;
|
|
}
|
|
|
|
final image = await boundary.toImage(pixelRatio: 3.0);
|
|
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
|
if (byteData == null) {
|
|
await shareText(fallbackMessage);
|
|
return;
|
|
}
|
|
|
|
final pngBytes = byteData.buffer.asUint8List();
|
|
final file = XFile.fromData(
|
|
pngBytes,
|
|
mimeType: 'image/png',
|
|
name: 'onsol_share.png',
|
|
);
|
|
|
|
try {
|
|
await SharePlus.instance.share(
|
|
ShareParams(files: [file], text: bodyWithLink(text)),
|
|
);
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
debugPrint('OnsolShare: file+caption share failed ($e), retrying file only');
|
|
}
|
|
try {
|
|
await SharePlus.instance.share(
|
|
ShareParams(files: [file], text: bodyWithLink(text)),
|
|
);
|
|
} catch (e2) {
|
|
if (kDebugMode) {
|
|
debugPrint('OnsolShare: file-only share failed ($e2), falling back to text');
|
|
}
|
|
await shareText(fallbackMessage);
|
|
}
|
|
}
|
|
} catch (e, st) {
|
|
if (kDebugMode) {
|
|
debugPrint('OnsolShare error: $e\n$st');
|
|
}
|
|
try {
|
|
await shareText(fallbackMessage);
|
|
} catch (e3) {
|
|
if (kDebugMode) {
|
|
debugPrint('OnsolShare text share failed: $e3');
|
|
}
|
|
try {
|
|
await clipboard(fallbackMessage);
|
|
} catch (_) {}
|
|
}
|
|
}
|
|
}
|