From 7814a4d20a215e802e8bc017654cade2f3277dce Mon Sep 17 00:00:00 2001 From: lifegpc Date: Mon, 4 Sep 2023 23:00:01 +0800 Subject: [PATCH] Add support to copy image url to clipboard --- lib/components/image.dart | 28 +++++++++++++++++++++++----- lib/components/thumbnail.dart | 8 ++++++-- lib/l10n/app_en.arb | 3 ++- lib/l10n/app_zh.arb | 3 ++- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/lib/components/image.dart b/lib/components/image.dart index 4e21c48..1ab9a5f 100644 --- a/lib/components/image.dart +++ b/lib/components/image.dart @@ -1,25 +1,43 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:logging/logging.dart'; import 'package:super_clipboard/super_clipboard.dart'; import 'package:super_context_menu/super_context_menu.dart'; +final _log = Logger("ImageWithContextMenu"); + class ImageWithContextMenu extends StatelessWidget { - const ImageWithContextMenu(this.data, {Key? key}) : super(key: key); + const ImageWithContextMenu(this.data, {Key? key, this.uri}) : super(key: key); final Uint8List data; + final String? uri; @override Widget build(BuildContext context) { return ContextMenuWidget( menuProvider: (_) { - return Menu(children: [ + var list = [ MenuAction( title: AppLocalizations.of(context)!.copyImage, callback: () { final item = DataWriterItem(); item.add(Formats.jpeg(data)); - ClipboardWriter.instance.write([item]); - }), - ]); + ClipboardWriter.instance.write([item]).catchError((err) { + _log.warning("Failed to copy image to clipboard:", err); + }); + }) + ]; + if (uri != null) { + list.add(MenuAction( + title: AppLocalizations.of(context)!.copyImgUrl, + callback: () { + final item = DataWriterItem(); + item.add(Formats.plainText(uri!)); + ClipboardWriter.instance.write([item]).catchError((err) { + _log.warning("Failed to copy image to clipboard:", err); + }); + })); + } + return Menu(children: list); }, child: Image.memory(data)); } diff --git a/lib/components/thumbnail.dart b/lib/components/thumbnail.dart index 8dd2c91..600fa41 100644 --- a/lib/components/thumbnail.dart +++ b/lib/components/thumbnail.dart @@ -46,6 +46,7 @@ class _Thumbnail extends State { Object? _error; int? _fileId; bool _showNsfw = false; + String? _uri; Future _fetchData() async { try { _isLoading = true; @@ -63,6 +64,7 @@ class _Thumbnail extends State { throw Exception( 'Failed to get thumbnail: ${re.response.statusCode} ${re.response.statusMessage}'); } + _uri = re.response.realUri.toString(); final data = Uint8List.fromList(re.data); setState(() { _isLoading = false; @@ -84,6 +86,7 @@ class _Thumbnail extends State { _error = null; _fileId = widget._fileId; _showNsfw = false; + _uri = null; super.initState(); } @@ -111,7 +114,8 @@ class _Thumbnail extends State { sigmaX: 10, sigmaY: 10, tileMode: TileMode.decal), - child: ImageWithContextMenu(_data!))), + child: + ImageWithContextMenu(_data!, uri: _uri))), SizedBox( width: widget.width.toDouble(), height: widget.height.toDouble(), @@ -127,7 +131,7 @@ class _Thumbnail extends State { )) ], ) - : ImageWithContextMenu(_data!) + : ImageWithContextMenu(_data!, uri: _uri) : Text("Error $_error")); } } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 5d7239c..363c629 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -27,5 +27,6 @@ "read": "Read", "download": "Download", "colon": ":", - "copyImage": "Copy image to clipboard" + "copyImage": "Copy image to clipboard", + "copyImgUrl": "Copy image URL to clipboard" } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index a49cbc1..e95c500 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -27,5 +27,6 @@ "read": "阅读", "download": "下载", "colon": ":", - "copyImage": "复制图片到剪贴板" + "copyImage": "复制图片到剪贴板", + "copyImgUrl": "复制图片链接到剪贴板" }