feat: home: cinema

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-01-10 10:33:58 +08:00
parent c9fe3c6485
commit 0ece0bd7fa
9 changed files with 76 additions and 29 deletions

View File

@@ -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']);

View File

@@ -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,

View File

@@ -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),
}, },
]; ];

View File

@@ -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

View File

@@ -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;

View File

@@ -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),
), ),
), ),

View File

@@ -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,

View File

@@ -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,
); );

View File

@@ -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 {