Files
Onsol-GO/lib/core/share_helper.dart
T
2026-04-23 23:58:59 -05:00

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 (_) {}
}
}
}