diff --git a/lib/basic/Cross.dart b/lib/basic/Cross.dart index b70251a..d4733f9 100644 --- a/lib/basic/Cross.dart +++ b/lib/basic/Cross.dart @@ -44,17 +44,20 @@ Future 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, '保存失败'); } } diff --git a/lib/basic/Entities.dart b/lib/basic/Entities.dart index 7a275f4..8775c67 100644 --- a/lib/basic/Entities.dart +++ b/lib/basic/Entities.dart @@ -1,10 +1,10 @@ /// 图片 -class OssImage { +class RemoteImageInfo { late String originalName; late String path; late String fileServer; - OssImage.fromJson(Map json) { + RemoteImageInfo.fromJson(Map 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 characters; - late OssImage avatar; + late RemoteImageInfo avatar; BasicUser.fromJson(Map 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.of(json["avatar"])); + this.avatar = + RemoteImageInfo.fromJson(Map.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 categories; - late OssImage thumb; + late RemoteImageInfo thumb; late int likesCount; ComicSimple.fromJson(Map json) { @@ -123,7 +124,7 @@ class ComicSimple { this.epsCount = json["epsCount"]; this.finished = json["finished"]; this.categories = List.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 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 screenshots; + late List 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.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()); } } } diff --git a/lib/screens/ComicReaderScreen.dart b/lib/screens/ComicReaderScreen.dart index 47a4571..2ac8f0d 100644 --- a/lib/screens/ComicReaderScreen.dart +++ b/lib/screens/ComicReaderScreen.dart @@ -40,15 +40,15 @@ class ComicReaderScreen extends StatefulWidget { class _ComicReaderScreenState extends State { late Ep _ep; late bool _fullScreen = false; - late Future> _future; + late Future> _future; int? _lastChangeRank; bool _replacement = false; - Future> _load() async { + Future> _load() async { if (widget.initPictureRank == null) { await method.storeViewEp(widget.comicInfo.id, _ep.order, _ep.title, 1); } - List list = []; + List list = []; var _needLoadPage = 0; late PicturePage page; do { @@ -165,7 +165,7 @@ class _ComicReaderScreenState extends State { }); }, successBuilder: - (BuildContext context, AsyncSnapshot> snapshot) { + (BuildContext context, AsyncSnapshot> snapshot) { return ImageReader( ImageReaderStruct( images: snapshot.data! diff --git a/lib/screens/FilePhotoViewScreen.dart b/lib/screens/FilePhotoViewScreen.dart index a8d312e..5321ed0 100644 --- a/lib/screens/FilePhotoViewScreen.dart +++ b/lib/screens/FilePhotoViewScreen.dart @@ -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), - ), - ), - ), ], ), ); diff --git a/lib/screens/components/Avatar.dart b/lib/screens/components/Avatar.dart index 6b5dea4..5710fde 100644 --- a/lib/screens/components/Avatar.dart +++ b/lib/screens/components/Avatar.dart @@ -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 createState() => _AvatarState(); -} - -class _AvatarState extends State { - late Future _future = _load(); - - Future _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 { 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 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), - ); - }, - ); - } } diff --git a/lib/screens/components/ImageReader.dart b/lib/screens/components/ImageReader.dart index e04d825..5105f7e 100644 --- a/lib/screens/components/ImageReader.dart +++ b/lib/screens/components/ImageReader.dart @@ -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( diff --git a/lib/screens/components/Images.dart b/lib/screens/components/Images.dart index 00e0fa2..6d22734 100644 --- a/lib/screens/components/Images.dart +++ b/lib/screens/components/Images.dart @@ -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 _loadImageFile(String path) { if (convertToPNG()) { return method.convertToPNG(path); @@ -180,7 +184,12 @@ class _DownloadImageState extends State { @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 { 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 future, double? width, double? height, + {BoxFit fit = BoxFit.cover, BuildContext? context}) { + return FutureBuilder( + future: future, + builder: (BuildContext context, AsyncSnapshot 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 future, double? width, double? height, - {BoxFit fit = BoxFit.cover}) { - return FutureBuilder( - future: future, - builder: (BuildContext context, AsyncSnapshot 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, + ); }