knight list
This commit is contained in:
parent
cc5b16ee33
commit
9c51033973
|
@ -1,3 +1,5 @@
|
||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
||||||
|
android.jetifier.blacklist=bcprov-jdk15on
|
||||||
|
|
|
@ -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()),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -234,7 +234,7 @@ class _DownloadExportToFileScreenState
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child:
|
child:
|
||||||
_buildButtonInner('导出到xxx.pkz\n(可直接打开观看的格式,不支持导入,可以躲避BD网盘或者TX的检测)'),
|
_buildButtonInner('导出到xxx.pkz\n(可直接打开观看的格式,不支持导入)\n(可以躲避网盘或者聊天软件的扫描)'),
|
||||||
));
|
));
|
||||||
widgets.add(Container(height: 10));
|
widgets.add(Container(height: 10));
|
||||||
/////////////////////
|
/////////////////////
|
||||||
|
|
|
@ -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;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import 'package:pikapika/basic/Channels.dart';
|
||||||
import 'package:pikapika/basic/Common.dart';
|
import 'package:pikapika/basic/Common.dart';
|
||||||
import 'package:pikapika/basic/Entities.dart';
|
import 'package:pikapika/basic/Entities.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
import 'package:pikapika/screens/DownloadExportGroupScreen.dart';
|
||||||
import 'DownloadImportScreen.dart';
|
import 'DownloadImportScreen.dart';
|
||||||
import 'DownloadInfoScreen.dart';
|
import 'DownloadInfoScreen.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
@ -59,6 +60,7 @@ class _DownloadListScreenState extends State<DownloadListScreen> {
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('下载列表'),
|
title: const Text('下载列表'),
|
||||||
actions: [
|
actions: [
|
||||||
|
exportButton(),
|
||||||
importButton(),
|
importButton(),
|
||||||
pauseButton(),
|
pauseButton(),
|
||||||
resetFailedButton(),
|
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() {
|
Widget importButton() {
|
||||||
return MaterialButton(
|
return MaterialButton(
|
||||||
minWidth: 0,
|
minWidth: 0,
|
||||||
|
|
|
@ -179,14 +179,13 @@ class _PkzComicInfoScreenState extends State<PkzComicInfoScreen>
|
||||||
chapters[c.id] = (c);
|
chapters[c.id] = (c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print("chapters : ${chapters}");
|
|
||||||
if (chapters.isEmpty) {
|
if (chapters.isEmpty) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
final width = constraints.maxWidth;
|
final width = constraints.maxWidth;
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.only(left: 10, right: 10),
|
padding: const EdgeInsets.only(left: 10, right: 10),
|
||||||
margin: const EdgeInsets.only(bottom: 10),
|
margin: const EdgeInsets.only(top: 10, bottom: 10),
|
||||||
width: width,
|
width: width,
|
||||||
child: MaterialButton(
|
child: MaterialButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
|
@ -3,8 +3,14 @@ import 'package:pikapika/basic/Entities.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
import 'package:pikapika/basic/config/ListLayout.dart';
|
import 'package:pikapika/basic/config/ListLayout.dart';
|
||||||
import 'package:pikapika/basic/config/ShadowCategories.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/ComicListBuilder.dart';
|
||||||
|
import 'components/FitButton.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 排行榜
|
// 排行榜
|
||||||
|
@ -31,7 +37,7 @@ class RankingsScreen extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: DefaultTabController(
|
body: DefaultTabController(
|
||||||
length: 3,
|
length: 4,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
|
@ -44,6 +50,7 @@ class RankingsScreen extends StatelessWidget {
|
||||||
Tab(text: '天'),
|
Tab(text: '天'),
|
||||||
Tab(text: '周'),
|
Tab(text: '周'),
|
||||||
Tab(text: '月'),
|
Tab(text: '月'),
|
||||||
|
Tab(text: '骑'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -53,6 +60,7 @@ class RankingsScreen extends StatelessWidget {
|
||||||
_Leaderboard("H24"),
|
_Leaderboard("H24"),
|
||||||
_Leaderboard("D7"),
|
_Leaderboard("D7"),
|
||||||
_Leaderboard("D30"),
|
_Leaderboard("D30"),
|
||||||
|
_KnightLeaderBoard(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -86,3 +94,127 @@ class _LeaderboardState extends State<_Leaderboard> {
|
||||||
return ComicListBuilder(_future, _reload);
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue