pikapika/lib/screens/ComicReaderScreen.dart

245 lines
6.7 KiB
Dart
Raw Permalink Normal View History

2021-09-29 23:57:09 +00:00
import 'dart:async';
2021-12-07 15:53:19 +00:00
import 'dart:io';
2021-09-29 23:57:09 +00:00
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
2021-11-11 03:00:38 +00:00
import 'package:pikapika/basic/Entities.dart';
import 'package:pikapika/basic/Method.dart';
import 'package:pikapika/basic/config/AutoFullScreen.dart';
import 'package:pikapika/basic/config/FullScreenUI.dart';
import 'package:pikapika/basic/config/Quality.dart';
2021-12-01 01:17:15 +00:00
import 'package:pikapika/screens/components/ContentError.dart';
import 'package:pikapika/screens/components/ContentLoading.dart';
2021-12-04 01:06:52 +00:00
import 'DownloadConfirmScreen.dart';
2021-09-29 23:57:09 +00:00
import 'components/ImageReader.dart';
2022-03-19 04:12:27 +00:00
import 'components/RightClickPop.dart';
2021-09-29 23:57:09 +00:00
// 在线阅读漫画
class ComicReaderScreen extends StatefulWidget {
final ComicInfo comicInfo;
final List<Ep> epList;
2022-03-03 02:38:44 +00:00
final int currentEpOrder;
2021-11-30 10:49:51 +00:00
final int? initPicturePosition;
2021-09-29 23:57:09 +00:00
late final bool autoFullScreen;
ComicReaderScreen({
Key? key,
required this.comicInfo,
required this.epList,
required this.currentEpOrder,
2021-11-30 10:49:51 +00:00
this.initPicturePosition,
2021-09-29 23:57:09 +00:00
bool? autoFullScreen,
}) : super(key: key) {
2021-10-21 04:08:51 +00:00
this.autoFullScreen = autoFullScreen ?? currentAutoFullScreen();
2021-09-29 23:57:09 +00:00
}
@override
State<StatefulWidget> createState() => _ComicReaderScreenState();
}
class _ComicReaderScreenState extends State<ComicReaderScreen> {
late Ep _ep;
late bool _fullScreen = false;
2021-11-12 05:41:26 +00:00
late Future<List<RemoteImageInfo>> _future;
2021-09-29 23:57:09 +00:00
int? _lastChangeRank;
bool _replacement = false;
2021-11-12 05:41:26 +00:00
Future<List<RemoteImageInfo>> _load() async {
2021-11-30 10:49:51 +00:00
if (widget.initPicturePosition == null) {
await method.storeViewEp(widget.comicInfo.id, _ep.order, _ep.title, 0);
2021-09-29 23:57:09 +00:00
}
2021-11-12 05:41:26 +00:00
List<RemoteImageInfo> list = [];
2021-09-29 23:57:09 +00:00
var _needLoadPage = 0;
late PicturePage page;
do {
page = await method.comicPicturePageWithQuality(
widget.comicInfo.id,
widget.currentEpOrder,
++_needLoadPage,
2021-10-21 04:08:51 +00:00
currentQualityCode(),
2021-09-29 23:57:09 +00:00
);
list.addAll(page.docs.map((element) => element.media));
} while (page.pages > page.page);
if (widget.autoFullScreen) {
setState(() {
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.manual,
overlays: [],
);
2021-09-29 23:57:09 +00:00
_fullScreen = true;
});
}
return list;
}
Future _onPositionChange(int position) async {
2021-11-30 10:49:51 +00:00
_lastChangeRank = position;
2021-09-29 23:57:09 +00:00
return method.storeViewEp(
2021-11-30 10:49:51 +00:00
widget.comicInfo.id, _ep.order, _ep.title, position);
2021-09-29 23:57:09 +00:00
}
FutureOr<dynamic> _onChangeEp(int epOrder) {
2022-03-17 03:31:25 +00:00
var orderMap = <int, Ep>{};
for (var element in widget.epList) {
2021-09-29 23:57:09 +00:00
orderMap[element.order] = element;
2022-03-17 03:31:25 +00:00
}
if (orderMap.containsKey(epOrder)) {
_replacement = true;
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => ComicReaderScreen(
comicInfo: widget.comicInfo,
epList: widget.epList,
currentEpOrder: epOrder,
autoFullScreen: _fullScreen,
2021-09-29 23:57:09 +00:00
),
),
);
2021-09-29 23:57:09 +00:00
}
}
FutureOr<dynamic> _onReloadEp() {
_replacement = true;
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => ComicReaderScreen(
comicInfo: widget.comicInfo,
epList: widget.epList,
currentEpOrder: widget.currentEpOrder,
initPicturePosition: _lastChangeRank ?? widget.initPicturePosition,
// maybe null
autoFullScreen: _fullScreen,
),
));
}
2021-12-04 01:06:52 +00:00
FutureOr<dynamic> _onDownload() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DownloadConfirmScreen(
comicInfo: widget.comicInfo,
epList: widget.epList.reversed.toList(),
),
),
);
}
@override
void initState() {
2021-09-29 23:57:09 +00:00
// EP
2022-03-17 03:31:25 +00:00
for (var element in widget.epList) {
2021-09-29 23:57:09 +00:00
if (element.order == widget.currentEpOrder) {
_ep = element;
}
2022-03-17 03:31:25 +00:00
}
2021-09-29 23:57:09 +00:00
// INIT
_future = _load();
super.initState();
}
@override
void dispose() {
if (!_replacement) {
switchFullScreenUI();
}
super.dispose();
}
@override
2022-03-19 04:12:27 +00:00
Widget build(BuildContext context){
2022-03-25 14:57:30 +00:00
return rightClickPop(
child: buildScreen(context),
context: context,
canPop: true,
);
2022-03-19 04:12:27 +00:00
}
Widget buildScreen(BuildContext context) {
2021-09-29 23:57:09 +00:00
return readerKeyboardHolder(_build(context));
}
Widget _build(BuildContext context) {
2021-12-01 01:17:15 +00:00
return FutureBuilder(
future: _future,
builder: (BuildContext context,
AsyncSnapshot<List<RemoteImageInfo>> snapshot) {
if (snapshot.hasError) {
return Scaffold(
appBar: _fullScreen
? null
: AppBar(
title: Text("${_ep.title} - ${widget.comicInfo.title}"),
),
body: ContentError(
error: snapshot.error,
stackTrace: snapshot.stackTrace,
onRefresh: () async {
setState(() {
_future = _load();
});
},
2021-09-29 23:57:09 +00:00
),
2021-12-01 01:17:15 +00:00
);
}
if (snapshot.connectionState != ConnectionState.done) {
return Scaffold(
appBar: _fullScreen
? null
: AppBar(
title: Text("${_ep.title} - ${widget.comicInfo.title}"),
),
2022-03-17 03:31:25 +00:00
body: const ContentLoading(label: '加载中'),
2021-12-01 01:17:15 +00:00
);
}
2022-03-17 03:31:25 +00:00
var epNameMap = <int, String>{};
for (var element in widget.epList) {
2021-12-01 01:17:15 +00:00
epNameMap[element.order] = element.title;
2022-03-17 03:31:25 +00:00
}
2021-12-01 01:17:15 +00:00
return Scaffold(
body: ImageReader(
2021-09-29 23:57:09 +00:00
ImageReaderStruct(
images: snapshot.data!
.map((e) => ReaderImageInfo(
e.fileServer,
e.path,
null,
null,
null,
null,
null,
))
2021-09-29 23:57:09 +00:00
.toList(),
fullScreen: _fullScreen,
onFullScreenChange: _onFullScreenChange,
onPositionChange: _onPositionChange,
2021-11-30 10:49:51 +00:00
initPosition: widget.initPicturePosition,
2021-12-01 01:17:15 +00:00
epNameMap: epNameMap,
epOrder: _ep.order,
comicTitle: widget.comicInfo.title,
onChangeEp: _onChangeEp,
onReloadEp: _onReloadEp,
2021-12-04 01:06:52 +00:00
onDownload: _onDownload,
2021-09-29 23:57:09 +00:00
),
2021-12-01 01:17:15 +00:00
),
);
},
2021-09-29 23:57:09 +00:00
);
}
Future _onFullScreenChange(bool fullScreen) async {
setState(() {
2021-12-07 15:53:19 +00:00
if (fullScreen) {
if (Platform.isAndroid || Platform.isIOS) {
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.manual,
overlays: [],
);
2021-12-07 15:53:19 +00:00
}
} else {
switchFullScreenUI();
}
2021-09-29 23:57:09 +00:00
_fullScreen = fullScreen;
});
}
}