mirror of
https://github.com/lifegpc/eh_downloader_flutter.git
synced 2026-06-18 00:44:58 +08:00
Update
This commit is contained in:
@@ -2,19 +2,11 @@ import 'package:flutter/foundation.dart';
|
||||
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';
|
||||
import '../platform/to_png_none.dart'
|
||||
if (dart.library.html) '../platform/to_png.dart';
|
||||
import '../utils/clipboard.dart';
|
||||
|
||||
final _log = Logger("ImageWithContextMenu");
|
||||
|
||||
enum ImageFmt {
|
||||
jpg,
|
||||
png,
|
||||
gif,
|
||||
}
|
||||
|
||||
class ImageWithContextMenu extends StatelessWidget {
|
||||
const ImageWithContextMenu(this.data,
|
||||
{Key? key, this.uri, this.fmt = ImageFmt.jpg})
|
||||
@@ -31,16 +23,7 @@ class ImageWithContextMenu extends StatelessWidget {
|
||||
title: AppLocalizations.of(context)!.copyImage,
|
||||
callback: () async {
|
||||
try {
|
||||
final item = DataWriterItem();
|
||||
if (!kIsWeb) {
|
||||
item.add(fmt == ImageFmt.jpg
|
||||
? Formats.jpeg(data)
|
||||
: Formats.png(data));
|
||||
} else {
|
||||
item.add(Formats.png(
|
||||
fmt == ImageFmt.jpg ? await jpgToPng(data) : data));
|
||||
}
|
||||
await ClipboardWriter.instance.write([item]);
|
||||
await copyImageToClipboard(data, fmt);
|
||||
} catch (err) {
|
||||
_log.warning("Failed to copy image to clipboard:", err);
|
||||
}
|
||||
@@ -50,9 +33,7 @@ class ImageWithContextMenu extends StatelessWidget {
|
||||
list.add(MenuAction(
|
||||
title: AppLocalizations.of(context)!.copyImgUrl,
|
||||
callback: () {
|
||||
final item = DataWriterItem();
|
||||
item.add(Formats.plainText(uri!));
|
||||
ClipboardWriter.instance.write([item]).catchError((err) {
|
||||
copyTextToClipboard(uri!).catchError((err) {
|
||||
_log.warning("Failed to copy image to clipboard:", err);
|
||||
});
|
||||
}));
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:logging/logging.dart';
|
||||
import '../api/client.dart';
|
||||
import '../api/gallery.dart';
|
||||
import '../globals.dart';
|
||||
import '../utils/clipboard.dart';
|
||||
import 'image.dart';
|
||||
|
||||
final _log = Logger("Thumbnail");
|
||||
@@ -41,6 +42,11 @@ class Thumbnail extends StatefulWidget {
|
||||
State<Thumbnail> createState() => _Thumbnail();
|
||||
}
|
||||
|
||||
enum _ThumbnailMenu {
|
||||
copyImage,
|
||||
copyImgUrl,
|
||||
}
|
||||
|
||||
class _Thumbnail extends State<Thumbnail> {
|
||||
Uint8List? _data;
|
||||
bool _isLoading = false;
|
||||
@@ -111,11 +117,52 @@ class _Thumbnail extends State<Thumbnail> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> onItemSelected(_ThumbnailMenu v) async {
|
||||
switch (v) {
|
||||
case _ThumbnailMenu.copyImage:
|
||||
try {
|
||||
copyImageToClipboard(_data!, ImageFmt.jpg);
|
||||
} catch (err) {
|
||||
_log.warning("Failed to copy image to clipboard:", err);
|
||||
}
|
||||
break;
|
||||
case _ThumbnailMenu.copyImgUrl:
|
||||
try {
|
||||
copyTextToClipboard(_uri!);
|
||||
} catch (err) {
|
||||
_log.warning("Failed to copy image url to clipboard:", err);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isLoading = _data == null && _error == null;
|
||||
final isNsfw = widget._pMeta.isNsfw;
|
||||
if (isLoading && !_isLoading) _fetchData();
|
||||
final iconSize = Theme.of(context).iconTheme.size;
|
||||
final moreVertMenu = Positioned(
|
||||
right: 0,
|
||||
top: 0,
|
||||
width: iconSize,
|
||||
height: iconSize,
|
||||
child: PopupMenuButton(
|
||||
icon: const Icon(Icons.more_vert),
|
||||
onSelected: (v) {
|
||||
onItemSelected(v);
|
||||
},
|
||||
itemBuilder: (context) {
|
||||
var list = <PopupMenuEntry<_ThumbnailMenu>>[
|
||||
PopupMenuItem(
|
||||
value: _ThumbnailMenu.copyImage,
|
||||
child: Text(AppLocalizations.of(context)!.copyImage)),
|
||||
PopupMenuItem(
|
||||
value: _ThumbnailMenu.copyImgUrl,
|
||||
child: Text(AppLocalizations.of(context)!.copyImgUrl)),
|
||||
];
|
||||
return list;
|
||||
}));
|
||||
return SizedBox(
|
||||
width: widget.width.toDouble(),
|
||||
height: widget.height.toDouble(),
|
||||
@@ -147,10 +194,17 @@ class _Thumbnail extends State<Thumbnail> {
|
||||
},
|
||||
icon: const Icon(Icons.visibility),
|
||||
),
|
||||
))
|
||||
)),
|
||||
moreVertMenu
|
||||
],
|
||||
)
|
||||
: ImageWithContextMenu(_data!, uri: _uri)
|
||||
: Stack(children: [
|
||||
SizedBox(
|
||||
width: widget.width.toDouble(),
|
||||
height: widget.height.toDouble(),
|
||||
child: ImageWithContextMenu(_data!, uri: _uri)),
|
||||
moreVertMenu
|
||||
])
|
||||
: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
||||
32
lib/utils/clipboard.dart
Normal file
32
lib/utils/clipboard.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:super_clipboard/super_clipboard.dart';
|
||||
import '../platform/to_png_none.dart'
|
||||
if (dart.library.html) '../platform/to_png.dart';
|
||||
|
||||
enum ImageFmt {
|
||||
jpg,
|
||||
png,
|
||||
gif,
|
||||
}
|
||||
|
||||
Future<void> copyImageToClipboard(Uint8List data, ImageFmt fmt) async {
|
||||
final item = DataWriterItem();
|
||||
if (!kIsWeb) {
|
||||
item.add(fmt == ImageFmt.jpg
|
||||
? Formats.jpeg(data)
|
||||
: fmt == ImageFmt.gif
|
||||
? Formats.gif(data)
|
||||
: Formats.png(data));
|
||||
} else {
|
||||
item.add(fmt == ImageFmt.gif
|
||||
? Formats.gif(data)
|
||||
: Formats.png(fmt == ImageFmt.jpg ? await jpgToPng(data) : data));
|
||||
}
|
||||
await ClipboardWriter.instance.write([item]);
|
||||
}
|
||||
|
||||
Future<void> copyTextToClipboard(String text) async {
|
||||
final item = DataWriterItem();
|
||||
item.add(Formats.plainText(text));
|
||||
await ClipboardWriter.instance.write([item]);
|
||||
}
|
||||
Reference in New Issue
Block a user