knight list

This commit is contained in:
niuhuan 2022-06-30 19:16:10 +08:00
parent cc5b16ee33
commit 9c51033973
7 changed files with 470 additions and 4 deletions

View File

@ -1,3 +1,5 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
android.jetifier.blacklist=bcprov-jdk15on

View File

@ -0,0 +1,177 @@
import 'package:flutter/material.dart';
import 'package:pikapika/basic/Common.dart';
import '../basic/Entities.dart';
import '../basic/Method.dart';
import 'DownloadExportingGroupScreen.dart';
import 'components/ContentLoading.dart';
import 'components/DownloadInfoCard.dart';
class DownloadExportGroupScreen extends StatefulWidget {
const DownloadExportGroupScreen({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _DownloadExportGroupScreenState();
}
class _DownloadExportGroupScreenState extends State<DownloadExportGroupScreen> {
late Future<List<DownloadComic>> _f = method.allDownloads();
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _f,
builder:
(BuildContext context, AsyncSnapshot<List<DownloadComic>> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Scaffold(
appBar: AppBar(
title: const Text("批量导出"),
),
body: const ContentLoading(label: '加载中'),
);
}
if (snapshot.hasError) {
print("${snapshot.error}");
print("${snapshot.stackTrace}");
return Scaffold(
appBar: AppBar(
title: const Text("批量导出"),
),
body: const Center(child: Text('加载失败')),
);
}
var data = snapshot.data!;
List<Widget> ws = [];
List<DownloadComic> exportable = [];
List<String> exportableIds = [];
for (var value in data) {
if (!value.deleting && value.downloadFinished) {
ws.add(downloadWidget(value));
exportable.add(value);
exportableIds.add(value.id);
}
}
return Scaffold(
appBar: AppBar(
title: const Text("批量导出"),
actions: [
_selectAllButton(exportableIds),
_goToExport(),
],
),
body: RefreshIndicator(
onRefresh: () async {
setState(() {
selected.clear();
_f = method.allDownloads();
});
},
child: ListView(
children: ws,
),
),
);
},
);
}
List<String> selected = [];
Widget downloadWidget(DownloadComic e) {
return InkWell(
onTap: () {
if (selected.contains(e.id)) {
selected.remove(e.id);
} else {
selected.add(e.id);
}
setState(() {});
},
child: Stack(children: [
DownloadInfoCard(
task: e,
),
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,
),
),
]),
]),
);
}
Widget _selectAllButton(List<String> exportableIds) {
return MaterialButton(
minWidth: 0,
onPressed: () async {
setState(() {
if (selected.length >= exportableIds.length) {
selected.clear();
} else {
selected.clear();
selected.addAll(exportableIds);
}
});
},
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()),
],
));
}
Widget _goToExport() {
return MaterialButton(
minWidth: 0,
onPressed: () async {
if (selected.isEmpty) {
defaultToast(context, "请选择导出的内容");
return;
}
final exported = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DownloadExportingGroupScreen(
idList: selected,
),
),
);
},
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()),
],
));
}
}

View File

@ -234,7 +234,7 @@ class _DownloadExportToFileScreenState
}
},
child:
_buildButtonInner('导出到xxx.pkz\n(可直接打开观看的格式,不支持导入,可以躲避BD网盘或者TX的检测)'),
_buildButtonInner('导出到xxx.pkz\n(可直接打开观看的格式,不支持导入)\n(可以躲避网盘或者聊天软件的扫描)'),
));
widgets.add(Container(height: 10));
/////////////////////

View File

@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import 'package:pikapika/basic/Common.dart';
import '../basic/Channels.dart';
import '../basic/Cross.dart';
import '../basic/Method.dart';
import '../basic/config/ExportRename.dart';
import 'components/ContentLoading.dart';
class DownloadExportingGroupScreen extends StatefulWidget {
final List<String> idList;
const DownloadExportingGroupScreen({Key? key, required this.idList})
: super(key: key);
@override
State<StatefulWidget> createState() => _DownloadExportingGroupScreenState();
}
class _DownloadExportingGroupScreenState
extends State<DownloadExportingGroupScreen> {
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;
});
}
Widget _body() {
if (exporting) {
return ContentLoading(label: exportMessage);
}
if (exportFail) {
return Center(child: Text("导出失败\n$e"));
}
if (exported) {
return Center(child: Text("导出成功"));
}
return Center(
child: MaterialButton(
onPressed: _export,
child: const Text("选择导出位置"),
),
);
}
_export() async {
late String? path;
try {
path = await chooseFolder(context);
} catch (e) {
defaultToast(context, "$e");
return;
}
var name = "";
if (currentExportRename()) {
var rename = await inputString(
context,
"请输入保存后的名称",
defaultValue: "${DateTime.now().millisecondsSinceEpoch}.pkz",
);
if (rename != null && rename.isNotEmpty) {
name = rename;
} else {
return;
}
}
print("path $path");
if (path != null) {
try {
setState(() {
exporting = true;
});
await method.exportComicDownloadToPkz(
widget.idList,
path,
name,
);
exported = true;
} catch (err) {
e = err;
exportFail = true;
} finally {
setState(() {
exporting = false;
});
}
}
}
@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;
},
);
}
}

View File

@ -6,6 +6,7 @@ import 'package:pikapika/basic/Channels.dart';
import 'package:pikapika/basic/Common.dart';
import 'package:pikapika/basic/Entities.dart';
import 'package:pikapika/basic/Method.dart';
import 'package:pikapika/screens/DownloadExportGroupScreen.dart';
import 'DownloadImportScreen.dart';
import 'DownloadInfoScreen.dart';
import 'components/ContentLoading.dart';
@ -59,6 +60,7 @@ class _DownloadListScreenState extends State<DownloadListScreen> {
appBar: AppBar(
title: const Text('下载列表'),
actions: [
exportButton(),
importButton(),
pauseButton(),
resetFailedButton(),
@ -144,6 +146,34 @@ class _DownloadListScreenState extends State<DownloadListScreen> {
);
}
Widget exportButton() {
return MaterialButton(
minWidth: 0,
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DownloadExportGroupScreen(),
),
);
},
child: Column(
children: [
Expanded(child: Container()),
const Icon(
Icons.send_to_mobile,
size: 18,
color: Colors.white,
),
const Text(
'导出',
style: TextStyle(fontSize: 14, color: Colors.white),
),
Expanded(child: Container()),
],
));
}
Widget importButton() {
return MaterialButton(
minWidth: 0,

View File

@ -179,14 +179,13 @@ class _PkzComicInfoScreenState extends State<PkzComicInfoScreen>
chapters[c.id] = (c);
}
}
print("chapters : ${chapters}");
if (chapters.isEmpty) {
return Container();
}
final width = constraints.maxWidth;
return Container(
padding: const EdgeInsets.only(left: 10, right: 10),
margin: const EdgeInsets.only(bottom: 10),
margin: const EdgeInsets.only(top: 10, bottom: 10),
width: width,
child: MaterialButton(
onPressed: () {

View File

@ -3,8 +3,14 @@ import 'package:pikapika/basic/Entities.dart';
import 'package:pikapika/basic/Method.dart';
import 'package:pikapika/basic/config/ListLayout.dart';
import 'package:pikapika/basic/config/ShadowCategories.dart';
import 'package:pikapika/screens/components/Avatar.dart';
import 'package:pikapika/screens/components/ContentBuilder.dart';
import '../basic/Cross.dart';
import '../basic/Navigator.dart';
import 'ComicsScreen.dart';
import 'components/ComicListBuilder.dart';
import 'components/FitButton.dart';
import 'components/RightClickPop.dart';
//
@ -31,7 +37,7 @@ class RankingsScreen extends StatelessWidget {
],
),
body: DefaultTabController(
length: 3,
length: 4,
child: Column(
children: [
Container(
@ -44,6 +50,7 @@ class RankingsScreen extends StatelessWidget {
Tab(text: ''),
Tab(text: ''),
Tab(text: ''),
Tab(text: ''),
],
),
),
@ -53,6 +60,7 @@ class RankingsScreen extends StatelessWidget {
_Leaderboard("H24"),
_Leaderboard("D7"),
_Leaderboard("D30"),
_KnightLeaderBoard(),
],
),
),
@ -86,3 +94,127 @@ class _LeaderboardState extends State<_Leaderboard> {
return ComicListBuilder(_future, _reload);
}
}
class _KnightLeaderBoard extends StatefulWidget {
const _KnightLeaderBoard();
@override
State<StatefulWidget> createState() => _KnightLeaderBoardState();
}
class _KnightLeaderBoardState extends State<_KnightLeaderBoard> {
Future<List<Knight>> _future = method.leaderboardOfKnight();
@override
Widget build(BuildContext context) {
return ContentBuilder(
future: _future,
onRefresh: () async {
setState(() {
_future = method.leaderboardOfKnight();
});
},
successBuilder: (
BuildContext context,
AsyncSnapshot<List<Knight>> snapshot,
) {
return RefreshIndicator(
onRefresh: () async {
setState(() {
_future = method.leaderboardOfKnight();
});
},
child: ListView(children: [
...snapshot.requireData.map(_knightCard).toList(),
SizedBox(
height: 80,
child: FitButton(
text: '刷新',
onPressed: () async {
setState(() {
_future = method.leaderboardOfKnight();
});
},
),
),
]),
);
},
);
}
Widget _knightCard(Knight e) {
final theme = Theme.of(context);
var nameStyle = const TextStyle(fontWeight: FontWeight.bold);
var levelStyle = TextStyle(
fontSize: 12, color: theme.colorScheme.secondary.withOpacity(.8));
var connectStyle =
TextStyle(color: theme.textTheme.bodyText1?.color?.withOpacity(.8));
var datetimeStyle = TextStyle(
color: theme.textTheme.bodyText1?.color?.withOpacity(.6), fontSize: 12);
final card = Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border(
top: BorderSide(
width: .25,
style: BorderStyle.solid,
color: Colors.grey.shade500.withOpacity(.5),
),
bottom: BorderSide(
width: .25,
style: BorderStyle.solid,
color: Colors.grey.shade500.withOpacity(.5),
),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Avatar(e.avatar),
Container(width: 5),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(e.name, style: nameStyle),
Expanded(child: Container()),
Text(
"${e.comicsUploaded}",
style: datetimeStyle,
),
],
),
Text("Lv. ${e.level} (${e.title})", style: levelStyle),
Text(e.slogan ?? "", style: connectStyle),
],
),
),
],
),
);
return InkWell(
onTap: () {
navPushOrReplace(
context,
(context) => ComicsScreen(
creatorId: e.id,
creatorName: e.name,
),
);
},
onLongPress: () {
confirmCopy(
context,
e.name,
);
},
child: card,
);
}
}