:sparkless: Add comics to download list
This commit is contained in:
parent
ccae23ed75
commit
2c30885bc3
|
@ -1014,13 +1014,86 @@ class PkzComicViewLog {
|
|||
}
|
||||
}
|
||||
|
||||
class IsPro {
|
||||
late bool isPro;
|
||||
late int expire;
|
||||
class ProInfoAll {
|
||||
ProInfoAll({
|
||||
required this.proInfoAf,
|
||||
required this.proInfoPat,
|
||||
});
|
||||
late final ProInfoAf proInfoAf;
|
||||
late final ProInfoPat proInfoPat;
|
||||
|
||||
IsPro.fromJson(Map<String, dynamic> json) {
|
||||
this.isPro = json["isPro"];
|
||||
this.expire = json["expire"];
|
||||
ProInfoAll.fromJson(Map<String, dynamic> json){
|
||||
proInfoAf = ProInfoAf.fromJson(json['pro_info_af']);
|
||||
proInfoPat = ProInfoPat.fromJson(json['pro_info_pat']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final _data = <String, dynamic>{};
|
||||
_data['pro_info_normal'] = proInfoAf.toJson();
|
||||
_data['pro_info_pat'] = proInfoPat.toJson();
|
||||
return _data;
|
||||
}
|
||||
}
|
||||
|
||||
class ProInfoAf {
|
||||
ProInfoAf({
|
||||
required this.isPro,
|
||||
required this.expire,
|
||||
});
|
||||
late final bool isPro;
|
||||
late final int expire;
|
||||
|
||||
ProInfoAf.fromJson(Map<String, dynamic> json){
|
||||
isPro = json['is_pro'];
|
||||
expire = json['expire'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final _data = <String, dynamic>{};
|
||||
_data['is_pro'] = isPro;
|
||||
_data['expire'] = expire;
|
||||
return _data;
|
||||
}
|
||||
}
|
||||
|
||||
class ProInfoPat {
|
||||
ProInfoPat({
|
||||
required this.isPro,
|
||||
required this.patId,
|
||||
required this.bindUid,
|
||||
required this.requestDelete,
|
||||
required this.reBind,
|
||||
required this.errorType,
|
||||
required this.errorMsg,
|
||||
});
|
||||
late final bool isPro;
|
||||
late final String patId;
|
||||
late final String bindUid;
|
||||
late final int requestDelete;
|
||||
late final int reBind;
|
||||
late final int errorType;
|
||||
late final String errorMsg;
|
||||
|
||||
ProInfoPat.fromJson(Map<String, dynamic> json){
|
||||
isPro = json['is_pro'];
|
||||
patId = json['pat_id'];
|
||||
bindUid = json['bind_uid'];
|
||||
requestDelete = json['request_delete'];
|
||||
reBind = json['re_bind'];
|
||||
errorType = json['error_type'];
|
||||
errorMsg = json['error_msg'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final _data = <String, dynamic>{};
|
||||
_data['is_pro'] = isPro;
|
||||
_data['pat_id'] = patId;
|
||||
_data['bind_uid'] = bindUid;
|
||||
_data['request_delete'] = requestDelete;
|
||||
_data['re_bind'] = reBind;
|
||||
_data['error_type'] = errorType;
|
||||
_data['error_msg'] = errorMsg;
|
||||
return _data;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -910,8 +910,8 @@ class Method {
|
|||
.toList();
|
||||
}
|
||||
|
||||
Future<IsPro> isPro() async {
|
||||
return IsPro.fromJson(jsonDecode(await _flatInvoke("isPro", "")));
|
||||
Future<ProInfoAll> proInfoAll() async {
|
||||
return ProInfoAll.fromJson(jsonDecode(await _flatInvoke("proInfoAll", "")));
|
||||
}
|
||||
|
||||
Future reloadPro() {
|
||||
|
@ -1009,4 +1009,8 @@ class Method {
|
|||
Future androidMkdirs(String path) async {
|
||||
return await _channel.invokeMethod("androidMkdirs", path);
|
||||
}
|
||||
|
||||
Future downloadAll(List<String> comicIds) {
|
||||
return _flatInvoke("downloadAll", comicIds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
import 'package:event/event.dart';
|
||||
import 'package:pikapika/basic/Method.dart';
|
||||
|
||||
var isPro = false;
|
||||
var isProEx = 0;
|
||||
import '../Entities.dart';
|
||||
|
||||
bool get isPro {
|
||||
return _proInfoAll.proInfoAf.isPro || _proInfoAll.proInfoPat.isPro;
|
||||
}
|
||||
|
||||
ProInfoAf get proInfoAf => _proInfoAll.proInfoAf;
|
||||
ProInfoPat get proInfoPat => _proInfoAll.proInfoPat;
|
||||
|
||||
final proEvent = Event();
|
||||
late ProInfoAll _proInfoAll;
|
||||
|
||||
Future reloadIsPro() async {
|
||||
final p = await method.isPro();
|
||||
isPro = p.isPro;
|
||||
isProEx = p.expire;
|
||||
_proInfoAll = await method.proInfoAll();
|
||||
proEvent.broadcast();
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_search_bar/flutter_search_bar.dart';
|
||||
import 'package:pikapika/basic/Common.dart';
|
||||
import 'package:pikapika/basic/config/PagerAction.dart';
|
||||
import 'package:pikapika/basic/config/ShadowCategories.dart';
|
||||
import 'package:pikapika/basic/config/ShadowCategoriesMode.dart';
|
||||
import 'package:pikapika/basic/store/Categories.dart';
|
||||
import 'package:pikapika/basic/config/ListLayout.dart';
|
||||
import 'package:pikapika/basic/Method.dart';
|
||||
import 'package:pikapika/screens/components/ComicList.dart';
|
||||
import '../basic/Entities.dart';
|
||||
import '../basic/config/Address.dart';
|
||||
import '../basic/config/IconLoading.dart';
|
||||
import 'SearchScreen.dart';
|
||||
import 'components/ComicPager.dart';
|
||||
import 'components/Common.dart';
|
||||
import 'components/GoDownloadSelect.dart';
|
||||
import 'components/RightClickPop.dart';
|
||||
|
||||
// 漫画列表
|
||||
|
@ -36,6 +38,7 @@ class ComicsScreen extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _ComicsScreenState extends State<ComicsScreen> {
|
||||
late final _comicListController = ComicListController();
|
||||
late final SearchBar _categorySearchBar = SearchBar(
|
||||
hintText: '搜索分类 - ${categoryTitle(widget.category)}',
|
||||
inBar: false,
|
||||
|
@ -55,7 +58,11 @@ class _ComicsScreenState extends State<ComicsScreen> {
|
|||
return AppBar(
|
||||
title: Text(categoryTitle(widget.category)),
|
||||
actions: [
|
||||
commonPopMenu(context),
|
||||
commonPopMenu(
|
||||
context,
|
||||
setState: setState,
|
||||
comicListController: _comicListController,
|
||||
),
|
||||
addressPopMenu(context),
|
||||
_chooseCategoryAction(),
|
||||
_categorySearchBar.getSearchAction(context),
|
||||
|
@ -104,6 +111,12 @@ class _ComicsScreenState extends State<ComicsScreen> {
|
|||
);
|
||||
|
||||
Future<ComicsPage> _load(String _currentSort, int _currentPage) {
|
||||
if (currentPagerAction() == PagerAction.CONTROLLER &&
|
||||
_comicListController.selecting) {
|
||||
setState(() {
|
||||
_comicListController.selecting = false;
|
||||
});
|
||||
}
|
||||
return method.comics(
|
||||
_currentSort,
|
||||
_currentPage,
|
||||
|
@ -115,7 +128,7 @@ class _ComicsScreenState extends State<ComicsScreen> {
|
|||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context){
|
||||
Widget build(BuildContext context) {
|
||||
return rightClickPop(
|
||||
child: buildScreen(context),
|
||||
context: context,
|
||||
|
@ -154,10 +167,15 @@ class _ComicsScreenState extends State<ComicsScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
if (_comicListController.selecting) {
|
||||
appBar = downAppBar(context, _comicListController, setState);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: appBar,
|
||||
body: ComicPager(
|
||||
fetchPage: _load,
|
||||
comicListController: _comicListController,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -68,13 +68,26 @@ class _ProScreenState extends State<ProScreen> {
|
|||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
title: const Text("发电详情"),
|
||||
title: const Text("签到或礼物卡"),
|
||||
subtitle: Text(
|
||||
isPro
|
||||
? "发电中 (${DateTime.fromMillisecondsSinceEpoch(1000 * isProEx).toString()})"
|
||||
proInfoAf.isPro
|
||||
? "发电中 (${DateTime.fromMillisecondsSinceEpoch(1000 * proInfoAf.expire).toString()})"
|
||||
: "未发电",
|
||||
),
|
||||
),
|
||||
...(proInfoPat.patId.isNotEmpty ? [
|
||||
ListTile(
|
||||
onTap: () {
|
||||
managementPat();
|
||||
},
|
||||
title: const Text("P站支持"),
|
||||
subtitle: Text((
|
||||
proInfoPat.isPro
|
||||
? "发电中"
|
||||
: "未发电") + ("(点击管理)"),
|
||||
),
|
||||
),
|
||||
] : []),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
title: const Text("我曾经发过电"),
|
||||
|
@ -111,4 +124,8 @@ class _ProScreenState extends State<ProScreen> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
void managementPat() {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,17 +13,34 @@ import 'ComicInfoCard.dart';
|
|||
import 'Images.dart';
|
||||
import 'LinkToComicInfo.dart';
|
||||
|
||||
class ComicListController {
|
||||
_ComicListState? _state;
|
||||
|
||||
bool get selecting => _state?._selecting ?? false;
|
||||
|
||||
set selecting(bool value) => _state?._setSelect(value);
|
||||
|
||||
List<String> get selected => _state?._selected ?? [];
|
||||
|
||||
selectAll() {
|
||||
_state?._selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
// 漫画列表页
|
||||
class ComicList extends StatefulWidget {
|
||||
final Widget? appendWidget;
|
||||
final List<ComicSimple> comicList;
|
||||
final ScrollController? controller;
|
||||
final ScrollController? scrollController;
|
||||
final ComicListController? listController;
|
||||
|
||||
const ComicList(
|
||||
this.comicList, {
|
||||
this.appendWidget,
|
||||
this.controller,
|
||||
this.scrollController,
|
||||
Key? key,
|
||||
// required
|
||||
this.listController,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -32,6 +49,25 @@ class ComicList extends StatefulWidget {
|
|||
|
||||
class _ComicListState extends State<ComicList> {
|
||||
final List<String> viewedList = [];
|
||||
bool _selecting = false;
|
||||
List<String> _selected = [];
|
||||
|
||||
_selectAll() {
|
||||
setState(() {
|
||||
if (_selected.length == widget.comicList.length) {
|
||||
_selected.clear();
|
||||
} else {
|
||||
_selected.addAll(widget.comicList.map((e) => e.id));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_setSelect(bool value) {
|
||||
setState(() {
|
||||
_selected.clear();
|
||||
_selecting = value;
|
||||
});
|
||||
}
|
||||
|
||||
Future _loadViewed() async {
|
||||
if (widget.comicList.isNotEmpty) {
|
||||
|
@ -43,6 +79,7 @@ class _ComicListState extends State<ComicList> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
widget.listController?._state = this;
|
||||
_loadViewed();
|
||||
listLayoutEvent.subscribe(_onLayoutChange);
|
||||
super.initState();
|
||||
|
@ -50,6 +87,9 @@ class _ComicListState extends State<ComicList> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
if (widget.listController?._state == this) {
|
||||
widget.listController?._state = null;
|
||||
}
|
||||
listLayoutEvent.unsubscribe(_onLayoutChange);
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -74,7 +114,7 @@ class _ComicListState extends State<ComicList> {
|
|||
|
||||
Widget _buildInfoCardList() {
|
||||
return ListView(
|
||||
controller: widget.controller,
|
||||
controller: widget.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
children: [
|
||||
...widget.comicList.map((e) {
|
||||
|
@ -122,6 +162,42 @@ class _ComicListState extends State<ComicList> {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (_selecting) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
if (_selected.contains(e.id)) {
|
||||
_selected.remove(e.id);
|
||||
} else {
|
||||
_selected.add(e.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Stack(children: [
|
||||
AbsorbPointer(
|
||||
child: LinkToComicInfo(
|
||||
comicId: e.id,
|
||||
child: ComicInfoCard(
|
||||
e,
|
||||
viewed: viewedList.contains(e.id),
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(children: [
|
||||
Expanded(child: Container()),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Icon(
|
||||
_selected.contains(e.id)
|
||||
? Icons.check_circle_sharp
|
||||
: Icons.circle_outlined,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
]),
|
||||
]),
|
||||
);
|
||||
}
|
||||
return LinkToComicInfo(
|
||||
comicId: e.id,
|
||||
child: ComicInfoCard(
|
||||
|
@ -242,7 +318,7 @@ class _ComicListState extends State<ComicList> {
|
|||
}
|
||||
// 返回
|
||||
return ListView(
|
||||
controller: widget.controller,
|
||||
controller: widget.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.only(top: gap, bottom: gap),
|
||||
children: wraps,
|
||||
|
@ -380,7 +456,7 @@ class _ComicListState extends State<ComicList> {
|
|||
}
|
||||
// 返回
|
||||
return ListView(
|
||||
controller: widget.controller,
|
||||
controller: widget.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.only(top: gap, bottom: gap),
|
||||
children: wraps,
|
||||
|
|
|
@ -14,9 +14,15 @@ import 'ContentLoading.dart';
|
|||
|
||||
// 漫画列页
|
||||
class ComicPager extends StatefulWidget {
|
||||
final ComicListController? comicListController;
|
||||
final Future<ComicsPage> Function(String sort, int page) fetchPage;
|
||||
|
||||
const ComicPager({required this.fetchPage, Key? key}) : super(key: key);
|
||||
const ComicPager({
|
||||
required this.fetchPage,
|
||||
Key? key,
|
||||
// required
|
||||
this.comicListController,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _ComicPagerState();
|
||||
|
@ -43,9 +49,15 @@ class _ComicPagerState extends State<ComicPager> {
|
|||
Widget build(BuildContext context) {
|
||||
switch (currentPagerAction()) {
|
||||
case PagerAction.CONTROLLER:
|
||||
return ControllerComicPager(fetchPage: widget.fetchPage);
|
||||
return ControllerComicPager(
|
||||
fetchPage: widget.fetchPage,
|
||||
comicListController: widget.comicListController,
|
||||
);
|
||||
case PagerAction.STREAM:
|
||||
return StreamComicPager(fetchPage: widget.fetchPage);
|
||||
return StreamComicPager(
|
||||
fetchPage: widget.fetchPage,
|
||||
comicListController: widget.comicListController,
|
||||
);
|
||||
default:
|
||||
return Container();
|
||||
}
|
||||
|
@ -53,11 +65,13 @@ class _ComicPagerState extends State<ComicPager> {
|
|||
}
|
||||
|
||||
class ControllerComicPager extends StatefulWidget {
|
||||
final ComicListController? comicListController;
|
||||
final Future<ComicsPage> Function(String sort, int page) fetchPage;
|
||||
|
||||
const ControllerComicPager({
|
||||
Key? key,
|
||||
required this.fetchPage,
|
||||
required this.comicListController,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -107,6 +121,7 @@ class _ControllerComicPagerState extends State<ControllerComicPager> {
|
|||
body: ComicList(
|
||||
comicsPage.docs,
|
||||
appendWidget: _buildNextButton(comicsPage),
|
||||
listController: widget.comicListController,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -255,11 +270,13 @@ class _ControllerComicPagerState extends State<ControllerComicPager> {
|
|||
}
|
||||
|
||||
class StreamComicPager extends StatefulWidget {
|
||||
final ComicListController? comicListController;
|
||||
final Future<ComicsPage> Function(String sort, int page) fetchPage;
|
||||
|
||||
const StreamComicPager({
|
||||
Key? key,
|
||||
required this.fetchPage,
|
||||
required this.comicListController,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -351,8 +368,9 @@ class _StreamComicPagerState extends State<StreamComicPager> {
|
|||
appBar: _buildAppBar(context),
|
||||
body: ComicList(
|
||||
_list,
|
||||
controller: _scrollController,
|
||||
scrollController: _scrollController,
|
||||
appendWidget: _buildLoadingCell(),
|
||||
listController: widget.comicListController,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:pikapika/screens/components/ComicList.dart';
|
||||
|
||||
import '../../basic/config/IsPro.dart';
|
||||
import '../../basic/config/ListLayout.dart';
|
||||
import '../../basic/config/ShadowCategories.dart';
|
||||
import '../../basic/config/ShadowCategoriesMode.dart';
|
||||
|
||||
Widget commonPopMenu(BuildContext context) {
|
||||
Widget commonPopMenu(
|
||||
BuildContext context, {
|
||||
ComicListController? comicListController,
|
||||
void Function(VoidCallback fn)? setState,
|
||||
}) {
|
||||
return PopupMenuButton<int>(
|
||||
itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[
|
||||
const PopupMenuItem<int>(
|
||||
|
@ -28,6 +34,22 @@ Widget commonPopMenu(BuildContext context) {
|
|||
title: Text("封印列表"),
|
||||
),
|
||||
),
|
||||
...comicListController != null && setState != null
|
||||
? [
|
||||
PopupMenuItem<int>(
|
||||
value: 3,
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.download),
|
||||
title: Text(
|
||||
"下载" + (isPro ? "" : "Pro"),
|
||||
style: TextStyle(
|
||||
color: isPro ? null : Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
]
|
||||
: [],
|
||||
],
|
||||
onSelected: (int value) {
|
||||
switch (value) {
|
||||
|
@ -40,6 +62,15 @@ Widget commonPopMenu(BuildContext context) {
|
|||
case 2:
|
||||
chooseShadowCategories(context);
|
||||
break;
|
||||
case 3:
|
||||
if (setState != null) {
|
||||
if (comicListController != null) {
|
||||
setState(() {
|
||||
comicListController.selecting = !comicListController.selecting;
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../basic/Channels.dart';
|
||||
import '../../basic/Common.dart';
|
||||
import '../../basic/Method.dart';
|
||||
import 'ContentLoading.dart';
|
||||
|
||||
class DownloadComicsScreen extends StatefulWidget {
|
||||
final List<String> comicIds;
|
||||
|
||||
const DownloadComicsScreen(this.comicIds, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _DownloadComicsScreenState();
|
||||
}
|
||||
|
||||
class _DownloadComicsScreenState extends State<DownloadComicsScreen> {
|
||||
bool exporting = false;
|
||||
bool exported = false;
|
||||
bool exportFail = false;
|
||||
dynamic e;
|
||||
String exportMessage = "正在创建下载任务";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
registerEvent(_onMessageChange, "EXPORT");
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
unregisterEvent(_onMessageChange);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onMessageChange(event) {
|
||||
setState(() {
|
||||
exportMessage = event;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("批量下载"),
|
||||
),
|
||||
body: _body(),
|
||||
),
|
||||
onWillPop: () async {
|
||||
if (exporting) {
|
||||
defaultToast(context, "创建下载任务中, 请稍后");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _body() {
|
||||
if (exporting) {
|
||||
return ContentLoading(label: exportMessage);
|
||||
}
|
||||
if (exportFail) {
|
||||
return Center(child: Text("失败\n$e"));
|
||||
}
|
||||
if (exported) {
|
||||
return const Center(child: Text("成功"));
|
||||
}
|
||||
return ListView(
|
||||
children: [
|
||||
Container(height: 20),
|
||||
Container(height: 20),
|
||||
_buildButtonInner("您即将下载${widget.comicIds.length}部漫画, 如果漫画已经存在, 则补充新增加的章节"),
|
||||
Container(height: 20),
|
||||
Container(height: 20),
|
||||
MaterialButton(
|
||||
onPressed: _create,
|
||||
child: _buildButtonInner("确认"),
|
||||
),
|
||||
Container(height: 20),
|
||||
Container(height: 20),
|
||||
Container(height: 20),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_create() async {
|
||||
var name = "";
|
||||
try {
|
||||
setState(() {
|
||||
exporting = true;
|
||||
});
|
||||
await method.downloadAll(
|
||||
widget.comicIds,
|
||||
);
|
||||
exported = true;
|
||||
} catch (err) {
|
||||
e = err;
|
||||
exportFail = true;
|
||||
} finally {
|
||||
setState(() {
|
||||
exporting = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildButtonInner(String text) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return Container(
|
||||
width: constraints.maxWidth,
|
||||
padding: const EdgeInsets.all(15),
|
||||
color: (Theme.of(context).textTheme.bodyText1?.color ?? Colors.black)
|
||||
.withOpacity(.05),
|
||||
child: Text(
|
||||
text,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:pikapika/basic/Common.dart';
|
||||
import 'package:pikapika/screens/components/ComicList.dart';
|
||||
|
||||
import 'DownloadComicsScreen.dart';
|
||||
|
||||
AppBar downAppBar(
|
||||
BuildContext context,
|
||||
ComicListController _comicListController,
|
||||
void Function(VoidCallback fn) setState,
|
||||
) {
|
||||
return AppBar(
|
||||
actions: [
|
||||
MaterialButton(
|
||||
minWidth: 0,
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
_comicListController.selecting = false;
|
||||
});
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
const Icon(
|
||||
Icons.cancel_outlined,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
const Text(
|
||||
'取消',
|
||||
style: TextStyle(fontSize: 14, color: Colors.white),
|
||||
),
|
||||
Expanded(child: Container()),
|
||||
],
|
||||
),
|
||||
),
|
||||
MaterialButton(
|
||||
minWidth: 0,
|
||||
onPressed: () async {
|
||||
_comicListController.selectAll();
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
const Icon(
|
||||
Icons.select_all,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
const Text(
|
||||
'全选',
|
||||
style: TextStyle(fontSize: 14, color: Colors.white),
|
||||
),
|
||||
Expanded(child: Container()),
|
||||
],
|
||||
),
|
||||
),
|
||||
MaterialButton(
|
||||
minWidth: 0,
|
||||
onPressed: () async {
|
||||
// todo
|
||||
final list = _comicListController.selected;
|
||||
if (list.isEmpty) {
|
||||
defaultToast(context, "请选择漫画");
|
||||
return;
|
||||
}
|
||||
_comicListController.selecting = false;
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return DownloadComicsScreen(list);
|
||||
},
|
||||
));
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
const Icon(
|
||||
Icons.check,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
const Text(
|
||||
'确认',
|
||||
style: TextStyle(fontSize: 14, color: Colors.white),
|
||||
),
|
||||
Expanded(child: Container()),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue