save more images

This commit is contained in:
niuhuan 2021-11-12 13:41:26 +08:00
parent 84f1f05f89
commit 15435bc602
7 changed files with 127 additions and 141 deletions

View File

@ -44,17 +44,20 @@ Future<dynamic> saveImage(String path, BuildContext context) async {
if (folder != null) {
future = method.convertImageToJPEG100(path, folder);
}
}
if (future != null) {
try {
await future;
defaultToast(context, '保存成功');
} catch (e, s) {
print("$e\n$s");
defaultToast(context, '保存失败');
}
} else {
defaultToast(context, '暂不支持该平台');
return;
}
if (future == null) {
defaultToast(context, '保存取消');
return;
}
try {
await future;
defaultToast(context, '保存成功');
} catch (e, s) {
print("$e\n$s");
defaultToast(context, '保存失败');
}
}

View File

@ -1,10 +1,10 @@
///
class OssImage {
class RemoteImageInfo {
late String originalName;
late String path;
late String fileServer;
OssImage.fromJson(Map<String, dynamic> json) {
RemoteImageInfo.fromJson(Map<String, dynamic> json) {
this.originalName = json["originalName"];
this.path = json["path"];
this.fileServer = json["fileServer"];
@ -21,7 +21,7 @@ class BasicUser {
late int exp;
late int level;
late List<String> characters;
late OssImage avatar;
late RemoteImageInfo avatar;
BasicUser.fromJson(Map<String, dynamic> json) {
this.id = json["_id"];
@ -34,7 +34,8 @@ class BasicUser {
this.characters = json["characters"] == null
? []
: List.of(json["characters"]).map((e) => "$e").toList();
this.avatar = OssImage.fromJson(Map<String, dynamic>.of(json["avatar"]));
this.avatar =
RemoteImageInfo.fromJson(Map<String, dynamic>.of(json["avatar"]));
}
}
@ -75,7 +76,7 @@ class Category {
late String id;
late String title;
late String description;
late OssImage thumb;
late RemoteImageInfo thumb;
late bool isWeb;
late bool active;
late String link;
@ -84,7 +85,7 @@ class Category {
this.id = json["_id"];
this.title = json["title"];
this.description = json["description"];
this.thumb = OssImage.fromJson(json["thumb"]);
this.thumb = RemoteImageInfo.fromJson(json["thumb"]);
this.isWeb = json["isWeb"];
this.active = json["active"];
this.link = json["link"];
@ -112,7 +113,7 @@ class ComicSimple {
late int epsCount;
late bool finished;
late List<String> categories;
late OssImage thumb;
late RemoteImageInfo thumb;
late int likesCount;
ComicSimple.fromJson(Map<String, dynamic> json) {
@ -123,7 +124,7 @@ class ComicSimple {
this.epsCount = json["epsCount"];
this.finished = json["finished"];
this.categories = List<String>.from(json["categories"]);
this.thumb = OssImage.fromJson(json["thumb"]);
this.thumb = RemoteImageInfo.fromJson(json["thumb"]);
this.likesCount = json["likesCount"];
}
}
@ -212,11 +213,11 @@ class PicturePage extends Page {
///
class Picture {
late String id;
late OssImage media;
late RemoteImageInfo media;
Picture.fromJson(Map<String, dynamic> json) {
this.id = json["_id"];
this.media = OssImage.fromJson(json["media"]);
this.media = RemoteImageInfo.fromJson(json["media"]);
}
}
@ -504,7 +505,7 @@ class GameSimple {
late String id;
late String title;
late String version;
late OssImage icon;
late RemoteImageInfo icon;
late String publisher;
late bool adult;
late bool suggest;
@ -516,7 +517,7 @@ class GameSimple {
this.id = json["_id"];
this.title = json["title"];
this.version = json["version"];
this.icon = OssImage.fromJson(json["icon"]);
this.icon = RemoteImageInfo.fromJson(json["icon"]);
this.publisher = json["publisher"];
this.adult = json["adult"];
this.suggest = json["suggest"];
@ -531,7 +532,7 @@ class GameInfo extends GameSimple {
late String description;
late String updateContent;
late String videoLink;
late List<OssImage> screenshots;
late List<RemoteImageInfo> screenshots;
late int commentsCount;
late int downloadsCount;
late bool isLiked;
@ -548,7 +549,7 @@ class GameInfo extends GameSimple {
this.videoLink = json["videoLink"];
this.screenshots = List.of(json["screenshots"])
.map((e) => Map<String, dynamic>.of(e))
.map((e) => OssImage.fromJson(e))
.map((e) => RemoteImageInfo.fromJson(e))
.toList();
this.commentsCount = json["commentsCount"];
this.downloadsCount = json["downloadsCount"];
@ -658,8 +659,9 @@ class GameCommentChildrenPage extends Page {
: super.fromJson(json) {
this.docs = [];
if (json["docs"] != null) {
docs.addAll(
List.of(json["docs"]).map((e) => GameCommentChild.fromJson(e)).toList());
docs.addAll(List.of(json["docs"])
.map((e) => GameCommentChild.fromJson(e))
.toList());
}
}
}

View File

@ -40,15 +40,15 @@ class ComicReaderScreen extends StatefulWidget {
class _ComicReaderScreenState extends State<ComicReaderScreen> {
late Ep _ep;
late bool _fullScreen = false;
late Future<List<OssImage>> _future;
late Future<List<RemoteImageInfo>> _future;
int? _lastChangeRank;
bool _replacement = false;
Future<List<OssImage>> _load() async {
Future<List<RemoteImageInfo>> _load() async {
if (widget.initPictureRank == null) {
await method.storeViewEp(widget.comicInfo.id, _ep.order, _ep.title, 1);
}
List<OssImage> list = [];
List<RemoteImageInfo> list = [];
var _needLoadPage = 0;
late PicturePage page;
do {
@ -165,7 +165,7 @@ class _ComicReaderScreenState extends State<ComicReaderScreen> {
});
},
successBuilder:
(BuildContext context, AsyncSnapshot<List<OssImage>> snapshot) {
(BuildContext context, AsyncSnapshot<List<RemoteImageInfo>> snapshot) {
return ImageReader(
ImageReaderStruct(
images: snapshot.data!

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'package:pikapika/basic/Common.dart';
import 'package:pikapika/basic/Cross.dart';
import 'package:pikapika/screens/components/Images.dart';
@ -13,8 +14,19 @@ class FilePhotoViewScreen extends StatelessWidget {
Widget build(BuildContext context) => Scaffold(
body: Stack(
children: [
PhotoView(
imageProvider: ResourceFileImageProvider(filePath),
GestureDetector(
onLongPress: () async {
String? choose =
await chooseListDialog(context, '请选择', ['保存图片']);
switch (choose) {
case '保存图片':
saveImage(filePath, context);
break;
}
},
child: PhotoView(
imageProvider: ResourceFileImageProvider(filePath),
),
),
InkWell(
onTap: () => Navigator.of(context).pop(),
@ -31,26 +43,6 @@ class FilePhotoViewScreen extends StatelessWidget {
child: Icon(Icons.keyboard_backspace, color: Colors.white),
),
),
Align(
alignment: Alignment.topRight,
child: InkWell(
onTap: () {
saveImage(filePath, context);
},
child: Container(
margin: EdgeInsets.only(top: 30),
padding: EdgeInsets.only(left: 4, right: 4),
decoration: BoxDecoration(
color: Colors.black.withOpacity(.75),
borderRadius: BorderRadius.only(
topRight: Radius.circular(8),
bottomRight: Radius.circular(8),
),
),
child: Icon(Icons.save, color: Colors.white),
),
),
),
],
),
);

View File

@ -8,28 +8,12 @@ const double _avatarMargin = 5;
const double _avatarBorderSize = 1.5;
//
class Avatar extends StatefulWidget {
final OssImage avatarImage;
class Avatar extends StatelessWidget {
final RemoteImageInfo avatarImage;
final double size;
const Avatar(this.avatarImage, {this.size = 50});
@override
State<StatefulWidget> createState() => _AvatarState();
}
class _AvatarState extends State<Avatar> {
late Future<String> _future = _load();
Future<String> _load() async {
if (widget.avatarImage.fileServer == '') {
return '';
}
return method
.remoteImageData(widget.avatarImage.fileServer, widget.avatarImage.path)
.then((value) => value.finalPath);
}
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
@ -43,34 +27,14 @@ class _AvatarState extends State<Avatar> {
width: _avatarBorderSize,
)),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(widget.size)),
child: _image(),
borderRadius: BorderRadius.all(Radius.circular(this.size)),
child: RemoteImage(
fileServer: this.avatarImage.fileServer,
path: this.avatarImage.path,
width: this.size,
height: this.size,
),
),
);
}
Widget _image() {
return FutureBuilder(
future: _future,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasError) {
return buildError(widget.size, widget.size);
}
if (snapshot.connectionState != ConnectionState.done) {
return buildLoading(widget.size, widget.size);
}
if (snapshot.data == '' || snapshot.data == null) {
return buildMock(widget.size, widget.size);
}
return GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => FilePhotoViewScreen(snapshot.data!),
));
},
child: buildFile(snapshot.data!, widget.size, widget.size),
);
},
);
}
}

View File

@ -554,26 +554,11 @@ class _WebToonReaderImageState extends State<_WebToonReaderImage> {
return buildLoading(widget.size.width, widget.size.height);
}
var data = snapshot.data!;
return GestureDetector(
onLongPress: () async {
String? choose =
await chooseListDialog(context, '请选择', ['预览图片', '保存图片']);
switch (choose) {
case '预览图片':
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => FilePhotoViewScreen(data.finalPath),
));
break;
case '保存图片':
saveImage(data.finalPath, context);
break;
}
},
child: buildFile(
data.finalPath,
widget.size.width,
widget.size.height,
),
return buildFile(
data.finalPath,
widget.size.width,
widget.size.height,
context: context,
);
},
);
@ -726,7 +711,8 @@ class _GalleryReaderState extends State<_GalleryReader> {
);
}
return PhotoViewGalleryPageOptions(
imageProvider: ResourceRemoteImageProvider(item.fileServer, item.path),
imageProvider:
ResourceRemoteImageProvider(item.fileServer, item.path),
errorBuilder: (b, e, s) {
print("$e,$s");
return LayoutBuilder(

View File

@ -2,12 +2,16 @@ import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:pikapika/basic/Common.dart';
import 'package:pikapika/basic/Cross.dart';
import 'package:pikapika/basic/Method.dart';
import 'package:flutter_svg/svg.dart';
import 'package:pikapika/basic/config/ConvertToPNG.dart';
import 'dart:io';
import 'dart:ui' as ui show Codec;
import '../FilePhotoViewScreen.dart';
Future<Uint8List> _loadImageFile(String path) {
if (convertToPNG()) {
return method.convertToPNG(path);
@ -180,7 +184,12 @@ class _DownloadImageState extends State<DownloadImage> {
@override
Widget build(BuildContext context) {
return pathFutureImage(_future, widget.width, widget.height);
return pathFutureImage(
_future,
widget.width,
widget.height,
context: context,
);
}
}
@ -225,16 +234,44 @@ class _RemoteImageState extends State<RemoteImage> {
if (_mock) {
return buildMock(widget.width, widget.height);
}
return pathFutureImage(_future, widget.width, widget.height,
fit: widget.fit);
return pathFutureImage(
_future,
widget.width,
widget.height,
fit: widget.fit,
context: context,
);
}
}
Widget pathFutureImage(Future<String> future, double? width, double? height,
{BoxFit fit = BoxFit.cover, BuildContext? context}) {
return FutureBuilder(
future: future,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasError) {
print("${snapshot.error}");
print("${snapshot.stackTrace}");
return buildError(width, height);
}
if (snapshot.connectionState != ConnectionState.done) {
return buildLoading(width, height);
}
return buildFile(
snapshot.data!,
width,
height,
fit: fit,
context: context,
);
});
}
//
Widget buildSvg(String source, double? width, double? height,
{Color? color, double? margin}) {
return Container(
var widget = Container(
width: width,
height: height,
padding: margin != null ? EdgeInsets.all(10) : null,
@ -247,10 +284,11 @@ Widget buildSvg(String source, double? width, double? height,
),
),
);
return GestureDetector(onLongPress: () {}, child: widget);
}
Widget buildMock(double? width, double? height) {
return Container(
var widget = Container(
width: width,
height: height,
padding: EdgeInsets.all(10),
@ -263,6 +301,7 @@ Widget buildMock(double? width, double? height) {
),
),
);
return GestureDetector(onLongPress: () {}, child: widget);
}
Widget buildError(double? width, double? height) {
@ -292,8 +331,8 @@ Widget buildLoading(double? width, double? height) {
}
Widget buildFile(String file, double? width, double? height,
{BoxFit fit = BoxFit.cover}) {
return Image(
{BoxFit fit = BoxFit.cover, BuildContext? context}) {
var image = Image(
image: ResourceFileImageProvider(file),
width: width,
height: height,
@ -304,21 +343,21 @@ Widget buildFile(String file, double? width, double? height,
},
fit: fit,
);
}
Widget pathFutureImage(Future<String> future, double? width, double? height,
{BoxFit fit = BoxFit.cover}) {
return FutureBuilder(
future: future,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasError) {
print("${snapshot.error}");
print("${snapshot.stackTrace}");
return buildError(width, height);
}
if (snapshot.connectionState != ConnectionState.done) {
return buildLoading(width, height);
}
return buildFile(snapshot.data!, width, height, fit: fit);
});
if (context == null) return image;
return GestureDetector(
onLongPress: () async {
String? choose = await chooseListDialog(context, '请选择', ['预览图片', '保存图片']);
switch (choose) {
case '预览图片':
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => FilePhotoViewScreen(file),
));
break;
case '保存图片':
saveImage(file, context);
break;
}
},
child: image,
);
}