mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-31 08:08:19 +08:00
feat: home: cinema
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -4,9 +4,14 @@ import '../models/bangumi/list.dart';
|
|||||||
import 'index.dart';
|
import 'index.dart';
|
||||||
|
|
||||||
class BangumiHttp {
|
class BangumiHttp {
|
||||||
static Future<LoadingState> bangumiList({int? page}) async {
|
static Future<LoadingState> bangumiList({
|
||||||
var res =
|
int? page,
|
||||||
await Request().get(Api.bangumiList, queryParameters: {'page': page});
|
int? indexType,
|
||||||
|
}) async {
|
||||||
|
var res = await Request().get(Api.bangumiList, queryParameters: {
|
||||||
|
'page': page,
|
||||||
|
if (indexType != null) 'index_type': indexType,
|
||||||
|
});
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
BangumiListDataModel data =
|
BangumiListDataModel data =
|
||||||
BangumiListDataModel.fromJson(res.data['data']);
|
BangumiListDataModel.fromJson(res.data['data']);
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ class SearchHttp {
|
|||||||
}
|
}
|
||||||
final dynamic res = await Request()
|
final dynamic res = await Request()
|
||||||
.get(Api.bangumiInfo, queryParameters: <String, dynamic>{...data});
|
.get(Api.bangumiInfo, queryParameters: <String, dynamic>{...data});
|
||||||
|
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
return {
|
return {
|
||||||
'status': true,
|
'status': true,
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import 'package:PiliPlus/pages/bangumi/index.dart';
|
|||||||
import 'package:PiliPlus/pages/hot/index.dart';
|
import 'package:PiliPlus/pages/hot/index.dart';
|
||||||
import 'package:PiliPlus/pages/live/index.dart';
|
import 'package:PiliPlus/pages/live/index.dart';
|
||||||
import 'package:PiliPlus/pages/rcmd/index.dart';
|
import 'package:PiliPlus/pages/rcmd/index.dart';
|
||||||
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
|
|
||||||
enum TabType { live, rcmd, hot, rank, bangumi }
|
enum TabType { live, rcmd, hot, rank, bangumi, cinema }
|
||||||
|
|
||||||
extension TabTypeDesc on TabType {
|
extension TabTypeDesc on TabType {
|
||||||
String get description => ['直播', '推荐', '热门', '分区', '番剧'][index];
|
String get description => ['直播', '推荐', '热门', '分区', '番剧', '影视'][index];
|
||||||
String get id => ['live', 'rcmd', 'hot', 'rank', 'bangumi'][index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List get tabsConfig => [
|
List get tabsConfig => [
|
||||||
@@ -62,6 +62,16 @@ List get tabsConfig => [
|
|||||||
'label': '番剧',
|
'label': '番剧',
|
||||||
'type': TabType.bangumi,
|
'type': TabType.bangumi,
|
||||||
'ctr': Get.find<BangumiController>,
|
'ctr': Get.find<BangumiController>,
|
||||||
'page': const BangumiPage(),
|
'page': const BangumiPage(tabType: TabType.bangumi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'icon': Icon(
|
||||||
|
MdiIcons.theater,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
'label': '影视',
|
||||||
|
'type': TabType.cinema,
|
||||||
|
'ctr': Get.find<BangumiController>,
|
||||||
|
'page': const BangumiPage(tabType: TabType.cinema),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/bangumi/list.dart';
|
import 'package:PiliPlus/models/bangumi/list.dart';
|
||||||
|
import 'package:PiliPlus/models/common/tab_type.dart';
|
||||||
import 'package:PiliPlus/pages/common/common_controller.dart';
|
import 'package:PiliPlus/pages/common/common_controller.dart';
|
||||||
import 'package:PiliPlus/utils/extension.dart';
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -8,6 +9,9 @@ import 'package:PiliPlus/http/bangumi.dart';
|
|||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
|
|
||||||
class BangumiController extends CommonController {
|
class BangumiController extends CommonController {
|
||||||
|
BangumiController({required this.tabType});
|
||||||
|
final TabType tabType;
|
||||||
|
|
||||||
bool isLoadingMore = true;
|
bool isLoadingMore = true;
|
||||||
RxBool isLogin = false.obs;
|
RxBool isLogin = false.obs;
|
||||||
int? mid;
|
int? mid;
|
||||||
@@ -33,6 +37,7 @@ class BangumiController extends CommonController {
|
|||||||
followPage = 1;
|
followPage = 1;
|
||||||
followEnd = false;
|
followEnd = false;
|
||||||
}
|
}
|
||||||
|
queryBangumiFollow();
|
||||||
return super.onRefresh();
|
return super.onRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +56,7 @@ class BangumiController extends CommonController {
|
|||||||
followLoading = true;
|
followLoading = true;
|
||||||
dynamic res = await BangumiHttp.bangumiFollow(
|
dynamic res = await BangumiHttp.bangumiFollow(
|
||||||
mid: mid,
|
mid: mid,
|
||||||
type: 1,
|
type: tabType == TabType.bangumi ? 1 : 2,
|
||||||
pn: followPage,
|
pn: followPage,
|
||||||
);
|
);
|
||||||
if (res is Success) {
|
if (res is Success) {
|
||||||
@@ -75,6 +80,7 @@ class BangumiController extends CommonController {
|
|||||||
@override
|
@override
|
||||||
Future<LoadingState> customGetData() => BangumiHttp.bangumiList(
|
Future<LoadingState> customGetData() => BangumiHttp.bangumiList(
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
|
indexType: tabType == TabType.cinema ? 102 : null, // TODO: sort
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ class BangumiIntroController extends CommonController {
|
|||||||
? int.tryParse(Get.parameters['epId']!)
|
? int.tryParse(Get.parameters['epId']!)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
late dynamic type = Get.parameters['type'] == '1' ? '追番' : '追剧';
|
||||||
|
|
||||||
// 是否预渲染 骨架屏
|
// 是否预渲染 骨架屏
|
||||||
bool preRender = false;
|
bool preRender = false;
|
||||||
|
|
||||||
|
|||||||
@@ -343,8 +343,8 @@ class _BangumiInfoState extends State<BangumiInfo>
|
|||||||
child: Text(
|
child: Text(
|
||||||
bangumiIntroController
|
bangumiIntroController
|
||||||
.isFollowed.value
|
.isFollowed.value
|
||||||
? '已追番'
|
? '已${bangumiIntroController.type}'
|
||||||
: '追番',
|
: '${bangumiIntroController.type}',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -632,10 +632,10 @@ class _BangumiInfoState extends State<BangumiInfo>
|
|||||||
_followDialogItem(1, '想看'),
|
_followDialogItem(1, '想看'),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: true,
|
dense: true,
|
||||||
title: const Padding(
|
title: Padding(
|
||||||
padding: EdgeInsets.only(left: 10),
|
padding: EdgeInsets.only(left: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
'取消追番',
|
'取消${bangumiIntroController.type}',
|
||||||
style: TextStyle(fontSize: 14),
|
style: TextStyle(fontSize: 14),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:async';
|
|||||||
import 'package:PiliPlus/common/widgets/loading_widget.dart';
|
import 'package:PiliPlus/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
|
import 'package:PiliPlus/models/common/tab_type.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -16,7 +17,12 @@ import 'controller.dart';
|
|||||||
import 'widgets/bangumi_card_v.dart';
|
import 'widgets/bangumi_card_v.dart';
|
||||||
|
|
||||||
class BangumiPage extends StatefulWidget {
|
class BangumiPage extends StatefulWidget {
|
||||||
const BangumiPage({super.key});
|
const BangumiPage({
|
||||||
|
super.key,
|
||||||
|
required this.tabType,
|
||||||
|
});
|
||||||
|
|
||||||
|
final TabType tabType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<BangumiPage> createState() => _BangumiPageState();
|
State<BangumiPage> createState() => _BangumiPageState();
|
||||||
@@ -24,7 +30,10 @@ class BangumiPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _BangumiPageState extends State<BangumiPage>
|
class _BangumiPageState extends State<BangumiPage>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin {
|
||||||
final BangumiController _bangumiController = Get.put(BangumiController());
|
late final BangumiController _bangumiController = Get.put(
|
||||||
|
BangumiController(tabType: widget.tabType),
|
||||||
|
tag: widget.tabType.name,
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
@@ -84,7 +93,7 @@ class _BangumiPageState extends State<BangumiPage>
|
|||||||
children: [
|
children: [
|
||||||
Obx(
|
Obx(
|
||||||
() => Text(
|
() => Text(
|
||||||
'最近追番${_bangumiController.followCount.value == -1 ? '' : ' ${_bangumiController.followCount.value}'}',
|
'最近${widget.tabType == TabType.bangumi ? '追番' : '追剧'}${_bangumiController.followCount.value == -1 ? '' : ' ${_bangumiController.followCount.value}'}',
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -210,7 +219,9 @@ class _BangumiPageState extends State<BangumiPage>
|
|||||||
Loading() => loadingWidget,
|
Loading() => loadingWidget,
|
||||||
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
? _buildFollowList(loadingState)
|
? _buildFollowList(loadingState)
|
||||||
: const Center(child: Text('还没有追番')),
|
: Center(
|
||||||
|
child: Text(
|
||||||
|
'还没有${widget.tabType == TabType.bangumi ? '追番' : '追剧'}')),
|
||||||
Error() => Container(
|
Error() => Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|||||||
@@ -52,7 +52,13 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
|
|||||||
try {
|
try {
|
||||||
int index = tabController.index;
|
int index = tabController.index;
|
||||||
var ctr = tabsCtrList[index];
|
var ctr = tabsCtrList[index];
|
||||||
ctr().onRefresh();
|
ctr(
|
||||||
|
tag: tabs[index]['type'] == TabType.bangumi
|
||||||
|
? TabType.bangumi.name
|
||||||
|
: tabs[index]['type'] == TabType.cinema
|
||||||
|
? TabType.cinema.name
|
||||||
|
: null)
|
||||||
|
.onRefresh();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +66,13 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
|
|||||||
try {
|
try {
|
||||||
int index = tabController.index;
|
int index = tabController.index;
|
||||||
var ctr = tabsCtrList[index];
|
var ctr = tabsCtrList[index];
|
||||||
ctr().animateToTop();
|
ctr(
|
||||||
|
tag: tabs[index]['type'] == TabType.bangumi
|
||||||
|
? TabType.bangumi.name
|
||||||
|
: tabs[index]['type'] == TabType.cinema
|
||||||
|
? TabType.cinema.name
|
||||||
|
: null)
|
||||||
|
.animateToTop();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,14 +80,14 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
|
|||||||
defaultTabs = [...tabsConfig];
|
defaultTabs = [...tabsConfig];
|
||||||
tabbarSort = GStorage.setting
|
tabbarSort = GStorage.setting
|
||||||
.get(SettingBoxKey.tabbarSort,
|
.get(SettingBoxKey.tabbarSort,
|
||||||
defaultValue: ['live', 'rcmd', 'hot', 'rank', 'bangumi'])
|
defaultValue: TabType.values.map((item) => item.name).toList())
|
||||||
.map<String>((i) => i.toString())
|
.map<String>((i) => i.toString())
|
||||||
.toList();
|
.toList();
|
||||||
defaultTabs.retainWhere(
|
defaultTabs.retainWhere(
|
||||||
(item) => tabbarSort.contains((item['type'] as TabType).id));
|
(item) => tabbarSort.contains((item['type'] as TabType).name));
|
||||||
defaultTabs.sort((a, b) => tabbarSort
|
defaultTabs.sort((a, b) => tabbarSort
|
||||||
.indexOf((a['type'] as TabType).id)
|
.indexOf((a['type'] as TabType).name)
|
||||||
.compareTo(tabbarSort.indexOf((b['type'] as TabType).id)));
|
.compareTo(tabbarSort.indexOf((b['type'] as TabType).name)));
|
||||||
|
|
||||||
tabs.value = defaultTabs;
|
tabs.value = defaultTabs;
|
||||||
|
|
||||||
@@ -83,7 +95,7 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
|
|||||||
tabsPageList = tabs.map<Widget>((e) => e['page']).toList();
|
tabsPageList = tabs.map<Widget>((e) => e['page']).toList();
|
||||||
|
|
||||||
tabController = TabController(
|
tabController = TabController(
|
||||||
initialIndex: max(0, tabbarSort.indexOf(TabType.rcmd.id)),
|
initialIndex: max(0, tabbarSort.indexOf(TabType.rcmd.name)),
|
||||||
length: tabs.length,
|
length: tabs.length,
|
||||||
vsync: this,
|
vsync: this,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ class _TabbarSetPageState extends State<TabbarSetPage> {
|
|||||||
.toList();
|
.toList();
|
||||||
// 对 tabData 进行排序
|
// 对 tabData 进行排序
|
||||||
defaultTabs.sort((a, b) {
|
defaultTabs.sort((a, b) {
|
||||||
int indexA = tabbarSort.indexOf((a['type'] as TabType).id);
|
int indexA = tabbarSort.indexOf((a['type'] as TabType).name);
|
||||||
int indexB = tabbarSort.indexOf((b['type'] as TabType).id);
|
int indexB = tabbarSort.indexOf((b['type'] as TabType).name);
|
||||||
|
|
||||||
// 如果类型在 sortOrder 中不存在,则放在末尾
|
// 如果类型在 sortOrder 中不存在,则放在末尾
|
||||||
if (indexA == -1) indexA = tabbarSort.length;
|
if (indexA == -1) indexA = tabbarSort.length;
|
||||||
@@ -38,8 +38,8 @@ class _TabbarSetPageState extends State<TabbarSetPage> {
|
|||||||
|
|
||||||
void saveEdit() {
|
void saveEdit() {
|
||||||
List<String> sortedTabbar = defaultTabs
|
List<String> sortedTabbar = defaultTabs
|
||||||
.where((i) => tabbarSort.contains((i['type'] as TabType).id))
|
.where((i) => tabbarSort.contains((i['type'] as TabType).name))
|
||||||
.map<String>((i) => (i['type'] as TabType).id)
|
.map<String>((i) => (i['type'] as TabType).name)
|
||||||
.toList();
|
.toList();
|
||||||
GStorage.setting.put(SettingBoxKey.tabbarSort, sortedTabbar);
|
GStorage.setting.put(SettingBoxKey.tabbarSort, sortedTabbar);
|
||||||
SmartDialog.showToast('保存成功,下次启动时生效');
|
SmartDialog.showToast('保存成功,下次启动时生效');
|
||||||
@@ -61,9 +61,9 @@ class _TabbarSetPageState extends State<TabbarSetPage> {
|
|||||||
for (int i = 0; i < defaultTabs.length; i++) ...[
|
for (int i = 0; i < defaultTabs.length; i++) ...[
|
||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
key: Key(defaultTabs[i]['label']),
|
key: Key(defaultTabs[i]['label']),
|
||||||
value: tabbarSort.contains((defaultTabs[i]['type'] as TabType).id),
|
value: tabbarSort.contains((defaultTabs[i]['type'] as TabType).name),
|
||||||
onChanged: (bool? newValue) {
|
onChanged: (bool? newValue) {
|
||||||
String tabTypeId = (defaultTabs[i]['type'] as TabType).id;
|
String tabTypeId = (defaultTabs[i]['type'] as TabType).name;
|
||||||
if (!newValue!) {
|
if (!newValue!) {
|
||||||
tabbarSort.remove(tabTypeId);
|
tabbarSort.remove(tabTypeId);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user