1414 *
1515 */
1616
17+ import 'dart:typed_data' ;
18+
1719import 'package:dio/dio.dart' ;
1820import 'package:flutter/gestures.dart' ;
1921import 'package:flutter/material.dart' ;
22+ import 'package:pixez/er/hoster.dart' ;
2023import 'package:pixez/component/pixiv_image.dart' ;
2124import 'package:pixez/er/leader.dart' ;
2225import 'package:pixez/er/lprinter.dart' ;
2326import 'package:pixez/i18n.dart' ;
27+ import 'package:pixez/main.dart' ;
2428import 'package:pixez/models/illust.dart' ;
2529import 'package:pixez/models/novel_web_response.dart' ;
2630import 'package:pixez/network/api_client.dart' ;
@@ -37,10 +41,92 @@ class UploadedImageSpan extends WidgetSpan {
3741 : super (
3842 child: Builder (
3943 builder: (context) {
40- return Container (child: PixivImage (imageUrl));
44+ return GestureDetector (
45+ onLongPress: () async {
46+ final action = await showDialog <String >(
47+ context: context,
48+ builder: (context) {
49+ return SimpleDialog (
50+ children: < Widget > [
51+ SimpleDialogOption (
52+ onPressed: () {
53+ Navigator .of (context).pop ('save' );
54+ },
55+ child: Text (I18n .of (context).save),
56+ ),
57+ SimpleDialogOption (
58+ onPressed: () {
59+ Navigator .of (context).pop ();
60+ },
61+ child: Text (I18n .of (context).cancel),
62+ ),
63+ ],
64+ );
65+ },
66+ );
67+ if (action == 'save' && context.mounted) {
68+ await _saveUploadedImage (context, imageUrl);
69+ }
70+ },
71+ child: Container (child: PixivImage (imageUrl)),
72+ );
4173 },
4274 ),
4375 );
76+
77+ static Future <void > _saveUploadedImage (
78+ BuildContext context,
79+ String url,
80+ ) async {
81+ try {
82+ final fileInfo = await pixivCacheManager? .getFileFromCache (url);
83+ final bytes = fileInfo? .file.readAsBytesSync ();
84+ final Uint8List data;
85+ if (bytes != null ) {
86+ data = bytes;
87+ } else {
88+ final dio = Dio ();
89+ final response = await dio.get <List <int >>(
90+ url,
91+ options: Options (
92+ responseType: ResponseType .bytes,
93+ headers: {...Hoster .header (url: url)},
94+ ),
95+ );
96+ final list = response.data;
97+ if (list == null || list.isEmpty) {
98+ ScaffoldMessenger .of (
99+ context,
100+ ).showSnackBar (SnackBar (content: Text (I18n .of (context).failed)));
101+ return ;
102+ }
103+ data = Uint8List .fromList (list);
104+ }
105+
106+ final uri = Uri .tryParse (url);
107+ String fileName = (uri != null && uri.pathSegments.isNotEmpty)
108+ ? uri.pathSegments.last
109+ : '' ;
110+ if (fileName.isEmpty) {
111+ fileName = 'uploaded_${DateTime .now ().millisecondsSinceEpoch }.jpg' ;
112+ } else if (! fileName.contains ('.' )) {
113+ fileName = '$fileName .jpg' ;
114+ }
115+
116+ await saveStore.saveToGalleryWithUser (data, 'novel' , 0 , 0 , fileName);
117+ if (context.mounted) {
118+ ScaffoldMessenger .of (
119+ context,
120+ ).showSnackBar (SnackBar (content: Text (I18n .of (context).saved)));
121+ }
122+ } catch (e) {
123+ if (context.mounted) {
124+ ScaffoldMessenger .of (
125+ context,
126+ ).showSnackBar (SnackBar (content: Text (I18n .of (context).failed)));
127+ }
128+ }
129+ }
44130}
45131
46132//[pixivimage:12551-1]
0 commit comments