diff --git a/lib/common/widgets/self_sized_horizontal_list.dart b/lib/common/widgets/self_sized_horizontal_list.dart index ef8507e9d..673fb4708 100644 --- a/lib/common/widgets/self_sized_horizontal_list.dart +++ b/lib/common/widgets/self_sized_horizontal_list.dart @@ -42,10 +42,13 @@ class _SelfSizedHorizontalListState extends State { } if (widget.itemCount == 0) return const SizedBox.shrink(); if (isInit) { - return Container( - key: infoKey, - padding: widget.padding, - child: widget.childBuilder(0), + return Align( + alignment: Alignment.centerLeft, + child: Padding( + key: infoKey, + padding: widget.padding ?? EdgeInsets.zero, + child: widget.childBuilder(0), + ), ); } diff --git a/lib/http/api.dart b/lib/http/api.dart index 363b644b3..8902f1ed8 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -802,4 +802,7 @@ class Api { static const String liveFollow = '${HttpString.liveBaseUrl}/xlive/web-ucenter/user/following'; + + static const String liveSecondList = + '${HttpString.liveBaseUrl}/xlive/app-interface/v2/second/getList'; } diff --git a/lib/http/live.dart b/lib/http/live.dart index 096e27cd3..12ec3f4da 100644 --- a/lib/http/live.dart +++ b/lib/http/live.dart @@ -10,6 +10,7 @@ import 'package:PiliPlus/models/live/live_room/danmu_info.dart'; import 'package:PiliPlus/models/live/live_room/item.dart'; import 'package:PiliPlus/models/live/live_room/room_info.dart'; import 'package:PiliPlus/models/live/live_room/room_info_h5.dart'; +import 'package:PiliPlus/models/live/live_second_list/data.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/wbi_sign.dart'; @@ -172,6 +173,7 @@ class LiveHttp { static Future> liveFeedIndex({ required int pn, required bool isLogin, + bool? moduleSelect, }) async { final params = { if (isLogin) 'access_key': Accounts.main.accessKey, @@ -185,17 +187,16 @@ class LiveHttp { 'fnval': '912', 'disable_rcmd': '0', 'https_url_req': '1', - 'login_event': isLogin ? '1' : '0', + if (moduleSelect == true) 'module_select': '1', 'mobi_app': 'android_hd', - 'module_select': '0', 'network': 'wifi', - 'page': pn.toString(), + 'page': pn, 'platform': 'android', if (isLogin) 'relation_page': '1', 's_locale': 'zh_CN', 'scale': '2', 'statistics': Constants.statistics, - 'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(), + 'ts': DateTime.now().millisecondsSinceEpoch ~/ 1000, }; Utils.appSign( params, @@ -229,4 +230,53 @@ class LiveHttp { return LoadingState.error(res.data['message']); } } + + static Future> liveSecondList({ + required int pn, + required bool isLogin, + required int? areaId, + required int? parentAreaId, + }) async { + final params = { + if (isLogin) 'access_key': Accounts.main.accessKey, + 'appkey': Constants.appKey, + 'actionKey': 'appkey', + if (areaId != null) 'area_id': areaId, + if (parentAreaId != null) 'parent_area_id': parentAreaId, + 'build': '8350200', + 'c_locale': 'zh_CN', + 'device': 'pad', + 'device_name': 'vivo', + 'device_type': '0', + 'fnval': '912', + 'disable_rcmd': '0', + 'https_url_req': '1', + 'mobi_app': 'android_hd', + 'module_select': '0', + 'network': 'wifi', + 'page': pn, + 'page_size': '20', + 'platform': 'android', + 'qn': '0', + 'tag_version': '1', + 's_locale': 'zh_CN', + 'scale': '2', + 'statistics': Constants.statistics, + 'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(), + }; + Utils.appSign( + params, + Constants.appKey, + Constants.appSec, + ); + var res = await Request().get( + Api.liveSecondList, + queryParameters: params, + ); + if (res.data['code'] == 0) { + return LoadingState.success(LiveSecondData.fromJson(res.data['data'])); + } else { + return LoadingState.error(res.data['message']); + } + } } diff --git a/lib/models/live/live_feed_index/avatar.dart b/lib/models/live/live_feed_index/avatar.dart deleted file mode 100644 index 5edb7c89c..000000000 --- a/lib/models/live/live_feed_index/avatar.dart +++ /dev/null @@ -1,25 +0,0 @@ -class Avatar { - String? cover; - String? event; - String? text; - int? uid; - String? url; - - Avatar({this.cover, this.event, this.text, this.uid, this.url}); - - factory Avatar.fromJson(Map json) => Avatar( - cover: json['cover'] as String?, - event: json['event'] as String?, - text: json['text'] as String?, - uid: json['uid'] as int?, - url: json['url'] as String?, - ); - - Map toJson() => { - 'cover': cover, - 'event': event, - 'text': text, - 'uid': uid, - 'url': url, - }; -} diff --git a/lib/models/live/live_feed_index/calendar_button.dart b/lib/models/live/live_feed_index/calendar_button.dart deleted file mode 100644 index 585ea2c87..000000000 --- a/lib/models/live/live_feed_index/calendar_button.dart +++ /dev/null @@ -1,20 +0,0 @@ -class CalendarButton { - String? text; - String? link; - - CalendarButton({this.text, this.link}); - - factory CalendarButton.fromJson(Map json) { - return CalendarButton( - text: json['text'] as String?, - link: json['link'] as String?, - ); - } - - - - Map toJson() => { - 'text': text, - 'link': link, - }; -} diff --git a/lib/models/live/live_feed_index/card_data.dart b/lib/models/live/live_feed_index/card_data.dart index 1ff86f29f..4c01af748 100644 --- a/lib/models/live/live_feed_index/card_data.dart +++ b/lib/models/live/live_feed_index/card_data.dart @@ -5,11 +5,13 @@ import 'card_data_item.dart'; class CardData { CardDataItem? bannerV2; CardDataItem? myIdolV1; + CardDataItem? areaEntranceV3; CardLiveItem? smallCardV1; CardData({ this.bannerV2, this.myIdolV1, + this.areaEntranceV3, this.smallCardV1, }); @@ -20,6 +22,10 @@ class CardData { myIdolV1: json['my_idol_v1'] == null ? null : CardDataItem.fromJson(json['my_idol_v1'] as Map), + areaEntranceV3: json['area_entrance_v3'] == null + ? null + : CardDataItem.fromJson( + json['area_entrance_v3'] as Map), smallCardV1: json['small_card_v1'] == null ? null : CardLiveItem.fromJson( diff --git a/lib/models/live/live_feed_index/card_data_list_item.dart b/lib/models/live/live_feed_index/card_data_list_item.dart index 2a387f7f1..7c63ce561 100644 --- a/lib/models/live/live_feed_index/card_data_list_item.dart +++ b/lib/models/live/live_feed_index/card_data_list_item.dart @@ -1,8 +1,6 @@ -import 'quality_description.dart'; import 'watched_show.dart'; class CardLiveItem { - int? id; int? roomid; int? uid; String? uname; @@ -18,35 +16,14 @@ class CardLiveItem { int? areaV2ParentId; String? liveTagName; int? online; - String? playUrl; - String? playUrlH265; - List? acceptQuality; - int? currentQuality; - int? pkId; String? link; - int? specialAttention; - int? broadcastType; - String? pendentRu; - String? pendentRuColor; - String? pendentRuPic; int? officialVerify; int? currentQn; - List? qualityDescription; - String? playUrlCard; - int? flag; - List? pendentList; - int? p2pType; - String? sessionId; - int? groupId; WatchedShow? watchedShow; - int? isNft; - String? nftDmark; String? statusText; - String? darkFace; - String? trackid; + int? tagType; CardLiveItem({ - this.id, this.roomid, this.uid, this.uname, @@ -62,37 +39,16 @@ class CardLiveItem { this.areaV2ParentId, this.liveTagName, this.online, - this.playUrl, - this.playUrlH265, - this.acceptQuality, - this.currentQuality, - this.pkId, this.link, - this.specialAttention, - this.broadcastType, - this.pendentRu, - this.pendentRuColor, - this.pendentRuPic, this.officialVerify, this.currentQn, - this.qualityDescription, - this.playUrlCard, - this.flag, - this.pendentList, - this.p2pType, - this.sessionId, - this.groupId, this.watchedShow, - this.isNft, - this.nftDmark, this.statusText, - this.darkFace, - this.trackid, + this.tagType, }); factory CardLiveItem.fromJson(Map json) => CardLiveItem( - id: json['id'] as int?, - roomid: json['roomid'] as int?, + roomid: json['roomid'] ?? json['id'], uid: json['uid'] as int?, uname: json['uname'] as String?, face: json['face'] as String?, @@ -107,37 +63,15 @@ class CardLiveItem { areaV2ParentId: json['area_v2_parent_id'] as int?, liveTagName: json['live_tag_name'] as String?, online: json['online'] as int?, - playUrl: json['play_url'] as String?, - playUrlH265: json['play_url_h265'] as String?, - acceptQuality: json['accept_quality'], - currentQuality: json['current_quality'] as int?, - pkId: json['pk_id'] as int?, link: json['link'] as String?, - specialAttention: json['special_attention'] as int?, - broadcastType: json['broadcast_type'] as int?, - pendentRu: json['pendent_ru'] as String?, - pendentRuColor: json['pendent_ru_color'] as String?, - pendentRuPic: json['pendent_ru_pic'] as String?, officialVerify: json['official_verify'] as int?, currentQn: json['current_qn'] as int?, - qualityDescription: (json['quality_description'] as List?) - ?.map((e) => QualityDescription.fromJson(e as Map)) - .toList(), - playUrlCard: json['play_url_card'] as String?, - flag: json['flag'] as int?, - pendentList: json['pendent_list'] as List?, - p2pType: json['p2p_type'] as int?, - sessionId: json['session_id'] as String?, - groupId: json['group_id'] as int?, watchedShow: json['watched_show'] == null ? null : WatchedShow.fromJson( json['watched_show'] as Map), - isNft: json['is_nft'] as int?, - nftDmark: json['nft_dmark'] as String?, statusText: json['status_text'] as String?, - darkFace: json['dark_face'] as String?, - trackid: json['trackid'] as String?, + tagType: json['tag_type'], ); Map toJson() => { @@ -156,32 +90,10 @@ class CardLiveItem { 'area_v2_parent_id': areaV2ParentId, 'live_tag_name': liveTagName, 'online': online, - 'play_url': playUrl, - 'play_url_h265': playUrlH265, - 'accept_quality': acceptQuality, - 'current_quality': currentQuality, - 'pk_id': pkId, 'link': link, - 'special_attention': specialAttention, - 'broadcast_type': broadcastType, - 'pendent_ru': pendentRu, - 'pendent_ru_color': pendentRuColor, - 'pendent_ru_pic': pendentRuPic, 'official_verify': officialVerify, 'current_qn': currentQn, - 'quality_description': - qualityDescription?.map((e) => e.toJson()).toList(), - 'play_url_card': playUrlCard, - 'flag': flag, - 'pendent_list': pendentList, - 'p2p_type': p2pType, - 'session_id': sessionId, - 'group_id': groupId, 'watched_show': watchedShow?.toJson(), - 'is_nft': isNft, - 'nft_dmark': nftDmark, 'status_text': statusText, - 'dark_face': darkFace, - 'trackid': trackid, }; } diff --git a/lib/models/live/live_feed_index/data.dart b/lib/models/live/live_feed_index/data.dart index 9639f3d05..678993688 100644 --- a/lib/models/live/live_feed_index/data.dart +++ b/lib/models/live/live_feed_index/data.dart @@ -6,6 +6,8 @@ class LiveIndexData { int? hasMore; int? triggerTime; int? isNeedRefresh; + LiveCardList? followItem; + LiveCardList? areaItem; LiveIndexData({ this.cardList, @@ -17,14 +19,22 @@ class LiveIndexData { LiveIndexData.fromJson(Map json) { if ((json['card_list'] as List?)?.isNotEmpty == true) { - cardList = []; // banner_v2 // my_idol_v1 // area_entrance_v3 // small_card_v1 for (var json in json['card_list']) { - if (const ['my_idol_v1', 'small_card_v1'].contains(json['card_type'])) { - cardList!.add(LiveCardList.fromJson(json)); + switch (json['card_type']) { + case 'my_idol_v1': + followItem = LiveCardList.fromJson(json); + break; + case 'area_entrance_v3': + areaItem = LiveCardList.fromJson(json); + break; + case 'small_card_v1': + cardList ??= []; + cardList!.add(LiveCardList.fromJson(json)); + break; } } } diff --git a/lib/models/live/live_feed_index/in_live.dart b/lib/models/live/live_feed_index/in_live.dart deleted file mode 100644 index 5a66d98af..000000000 --- a/lib/models/live/live_feed_index/in_live.dart +++ /dev/null @@ -1,43 +0,0 @@ -class InLive { - int? alphaLight; - int? alphaNight; - String? animationUrl; - String? animationUrlHash; - String? backgroundColorLight; - String? backgroundColorNight; - String? fontColor; - String? text; - - InLive({ - this.alphaLight, - this.alphaNight, - this.animationUrl, - this.animationUrlHash, - this.backgroundColorLight, - this.backgroundColorNight, - this.fontColor, - this.text, - }); - - factory InLive.fromJson(Map json) => InLive( - alphaLight: json['alpha_light'] as int?, - alphaNight: json['alpha_night'] as int?, - animationUrl: json['animation_url'] as String?, - animationUrlHash: json['animation_url_hash'] as String?, - backgroundColorLight: json['background_color_light'] as String?, - backgroundColorNight: json['background_color_night'] as String?, - fontColor: json['font_color'] as String?, - text: json['text'] as String?, - ); - - Map toJson() => { - 'alpha_light': alphaLight, - 'alpha_night': alphaNight, - 'animation_url': animationUrl, - 'animation_url_hash': animationUrlHash, - 'background_color_light': backgroundColorLight, - 'background_color_night': backgroundColorNight, - 'font_color': fontColor, - 'text': text, - }; -} diff --git a/lib/models/live/live_feed_index/inline_live.dart b/lib/models/live/live_feed_index/inline_live.dart deleted file mode 100644 index 7c3b88590..000000000 --- a/lib/models/live/live_feed_index/inline_live.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'avatar.dart'; -import 'calendar_button.dart'; -import 'player_args.dart'; -import 'right_top_live_badge.dart'; - -class InlineLive { - Avatar? avatar; - String? cover; - int? inlineStartDelayTime; - int? inlineSustainDuration; - String? link; - PlayerArgs? playerArgs; - dynamic rankListInfo; - RightTopLiveBadge? rightTopLiveBadge; - String? title; - dynamic topViewInfo; - String? upName; - String? inlinePlayUrl; - CalendarButton? calendarButton; - - InlineLive({ - this.avatar, - this.cover, - this.inlineStartDelayTime, - this.inlineSustainDuration, - this.link, - this.playerArgs, - this.rankListInfo, - this.rightTopLiveBadge, - this.title, - this.topViewInfo, - this.upName, - this.inlinePlayUrl, - this.calendarButton, - }); - - factory InlineLive.fromJson(Map json) => InlineLive( - avatar: json['avatar'] == null - ? null - : Avatar.fromJson(json['avatar'] as Map), - cover: json['cover'] as String?, - inlineStartDelayTime: json['inline_start_delay_time'] as int?, - inlineSustainDuration: json['inline_sustain_duration'] as int?, - link: json['link'] as String?, - playerArgs: json['player_args'] == null - ? null - : PlayerArgs.fromJson(json['player_args'] as Map), - rankListInfo: json['rank_list_info'] as dynamic, - rightTopLiveBadge: json['right_top_live_badge'] == null - ? null - : RightTopLiveBadge.fromJson(json['right_top_live_badge'] as Map), - title: json['title'] as String?, - topViewInfo: json['top_view_info'] as dynamic, - upName: json['up_name'] as String?, - inlinePlayUrl: json['inline_play_url'] as String?, - calendarButton: json['calendar_button'] == null - ? null - : CalendarButton.fromJson(json['calendar_button'] as Map), - ); - - Map toJson() => { - 'avatar': avatar?.toJson(), - 'cover': cover, - 'inline_start_delay_time': inlineStartDelayTime, - 'inline_sustain_duration': inlineSustainDuration, - 'link': link, - 'player_args': playerArgs?.toJson(), - 'rank_list_info': rankListInfo, - 'right_top_live_badge': rightTopLiveBadge?.toJson(), - 'title': title, - 'top_view_info': topViewInfo, - 'up_name': upName, - 'inline_play_url': inlinePlayUrl, - 'calendar_button': calendarButton?.toJson(), - }; -} diff --git a/lib/models/live/live_feed_index/player_args.dart b/lib/models/live/live_feed_index/player_args.dart deleted file mode 100644 index a68f26c6f..000000000 --- a/lib/models/live/live_feed_index/player_args.dart +++ /dev/null @@ -1,39 +0,0 @@ -class PlayerArgs { - int? canPlay; - bool? hideDanmuSwitch; - int? liveStatus; - int? parentAreaId; - int? areaId; - int? roomId; - int? upId; - - PlayerArgs({ - this.canPlay, - this.hideDanmuSwitch, - this.liveStatus, - this.parentAreaId, - this.areaId, - this.roomId, - this.upId, - }); - - factory PlayerArgs.fromJson(Map json) => PlayerArgs( - canPlay: json['can_play'] as int?, - hideDanmuSwitch: json['hide_danmu_switch'] as bool?, - liveStatus: json['live_status'] as int?, - parentAreaId: json['parent_area_id'] as int?, - areaId: json['area_id'] as int?, - roomId: json['room_id'] as int?, - upId: json['up_id'] as int?, - ); - - Map toJson() => { - 'can_play': canPlay, - 'hide_danmu_switch': hideDanmuSwitch, - 'live_status': liveStatus, - 'parent_area_id': parentAreaId, - 'area_id': areaId, - 'room_id': roomId, - 'up_id': upId, - }; -} diff --git a/lib/models/live/live_feed_index/quality_description.dart b/lib/models/live/live_feed_index/quality_description.dart deleted file mode 100644 index 5b3f1326a..000000000 --- a/lib/models/live/live_feed_index/quality_description.dart +++ /dev/null @@ -1,20 +0,0 @@ -class QualityDescription { - int? qn; - String? desc; - - QualityDescription({this.qn, this.desc}); - - factory QualityDescription.fromJson(Map json) { - return QualityDescription( - qn: json['qn'] as int?, - desc: json['desc'] as String?, - ); - } - - - - Map toJson() => { - 'qn': qn, - 'desc': desc, - }; -} diff --git a/lib/models/live/live_feed_index/right_top_live_badge.dart b/lib/models/live/live_feed_index/right_top_live_badge.dart deleted file mode 100644 index fd54f2cfb..000000000 --- a/lib/models/live/live_feed_index/right_top_live_badge.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'in_live.dart'; - -class RightTopLiveBadge { - InLive? inLive; - int? liveStatus; - - RightTopLiveBadge({this.inLive, this.liveStatus}); - - factory RightTopLiveBadge.fromJson(Map json) { - return RightTopLiveBadge( - inLive: json['in_live'] == null - ? null - : InLive.fromJson(json['in_live'] as Map), - liveStatus: json['live_status'] as int?, - ); - } - - - - Map toJson() => { - 'in_live': inLive?.toJson(), - 'live_status': liveStatus, - }; -} diff --git a/lib/models/live/live_second_list/data.dart b/lib/models/live/live_second_list/data.dart new file mode 100644 index 000000000..799668c89 --- /dev/null +++ b/lib/models/live/live_second_list/data.dart @@ -0,0 +1,23 @@ +import 'package:PiliPlus/models/live/live_feed_index/card_data_list_item.dart'; + +class LiveSecondData { + int? count; + List? cardList; + + LiveSecondData({ + this.count, + this.cardList, + }); + + factory LiveSecondData.fromJson(Map json) => LiveSecondData( + count: json['count'] as int?, + cardList: (json['list'] as List?) + ?.map((e) => CardLiveItem.fromJson(e as Map)) + .toList(), + ); + + Map toJson() => { + 'count': count, + 'list': cardList?.map((e) => e.toJson()).toList(), + }; +} diff --git a/lib/pages/live/controller.dart b/lib/pages/live/controller.dart index 2faf4f09f..bfe06e8b5 100644 --- a/lib/pages/live/controller.dart +++ b/lib/pages/live/controller.dart @@ -1,26 +1,90 @@ +import 'package:PiliPlus/common/widgets/pair.dart'; import 'package:PiliPlus/http/live.dart'; import 'package:PiliPlus/http/loading_state.dart'; +import 'package:PiliPlus/models/live/live_feed_index/card_data_list_item.dart'; import 'package:PiliPlus/models/live/live_feed_index/card_list.dart'; -import 'package:PiliPlus/models/live/live_feed_index/data.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:get/get_rx/src/rx_types/rx_types.dart'; -class LiveController extends CommonListController { +class LiveController extends CommonListController { @override void onInit() { super.onInit(); queryData(); } + int? areaId; + int? parentAreaId; + final RxInt areaIndex = 0.obs; + final Rx> topState = + Pair(first: null, second: null).obs; final RxBool isLogin = Accounts.main.isLogin.obs; @override - List? getDataList(LiveIndexData response) { + List? getDataList(response) { return response.cardList; } @override - Future> customGetData() => - LiveHttp.liveFeedIndex(pn: currentPage, isLogin: isLogin.value); + bool customHandleResponse(bool isRefresh, Success response) { + if (isRefresh && areaIndex.value == 0) { + topState.value = Pair( + first: response.response.followItem, + second: response.response.areaItem, + ); + } + return false; + } + + @override + Future customGetData() { + if (areaIndex.value != 0) { + return LiveHttp.liveSecondList( + pn: currentPage, + isLogin: isLogin.value, + areaId: areaId, + parentAreaId: parentAreaId, + ); + } + return LiveHttp.liveFeedIndex(pn: currentPage, isLogin: isLogin.value); + } + + @override + Future onRefresh() async { + currentPage = 1; + isEnd = false; + if (areaIndex.value != 0) { + queryTop(); + } + await queryData(); + } + + Future queryTop() async { + final res = await LiveHttp.liveFeedIndex( + pn: currentPage, + isLogin: isLogin.value, + moduleSelect: true, + ); + if (res is Success) { + final data = res.data; + topState.value = Pair( + first: data.followItem, + second: data.areaItem, + ); + } + } + + void onSelectArea(int index, CardLiveItem? cardLiveItem) { + if (index == areaIndex.value) { + return; + } + areaIndex.value = index; + areaId = cardLiveItem?.areaV2Id; + parentAreaId = cardLiveItem?.areaV2ParentId; + + currentPage = 1; + isEnd = false; + queryData(); + } } diff --git a/lib/pages/live/view.dart b/lib/pages/live/view.dart index afd5964f5..f2a9293ed 100644 --- a/lib/pages/live/view.dart +++ b/lib/pages/live/view.dart @@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/skeleton/video_card_v.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; +import 'package:PiliPlus/common/widgets/pair.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/self_sized_horizontal_list.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -11,7 +12,7 @@ import 'package:PiliPlus/pages/common/common_page.dart'; import 'package:PiliPlus/pages/live/controller.dart'; import 'package:PiliPlus/pages/live/widgets/live_item_app.dart'; import 'package:PiliPlus/pages/live_follow/view.dart'; -import 'package:PiliPlus/utils/extension.dart'; +import 'package:PiliPlus/pages/search/widgets/search_text.dart'; import 'package:PiliPlus/utils/grid.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -54,7 +55,10 @@ class _LivePageState extends CommonPageState top: StyleString.cardSpace, bottom: MediaQuery.paddingOf(context).bottom + 80, ), - sliver: Obx(() => _buildBody(controller.loadingState.value)), + sliver: SliverMainAxisGroup(slivers: [ + Obx(() => _buildTop(controller.topState.value)), + Obx(() => _buildBody(controller.loadingState.value)), + ]), ), ], ), @@ -62,7 +66,51 @@ class _LivePageState extends CommonPageState ); } - Widget _buildBody(LoadingState?> loadingState) { + Widget _buildTop(Pair data) { + return SliverMainAxisGroup( + slivers: [ + if (data.first != null) + SliverToBoxAdapter(child: _buildFollowList(data.first!)), + if (data.second?.cardData?.areaEntranceV3?.list?.isNotEmpty == true) + SliverToBoxAdapter( + child: SelfSizedHorizontalList( + gapSize: 12, + padding: const EdgeInsets.only(bottom: 10), + childBuilder: (index) { + late final item = + data.second!.cardData!.areaEntranceV3!.list![index - 1]; + return Obx( + () => SearchText( + fontSize: 14, + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 3, + ), + text: index == 0 ? '推荐' : '${item.title}', + bgColor: index == controller.areaIndex.value + ? Theme.of(context).colorScheme.secondaryContainer + : Colors.transparent, + textColor: index == controller.areaIndex.value + ? Theme.of(context).colorScheme.onSecondaryContainer + : null, + onTap: (value) { + controller.onSelectArea( + index, + index == 0 ? null : item, + ); + }, + ), + ); + }, + itemCount: + data.second!.cardData!.areaEntranceV3!.list!.length + 1, + ), + ), + ], + ); + } + + Widget _buildBody(LoadingState loadingState) { return switch (loadingState) { Loading() => SliverGrid( gridDelegate: SliverGridDelegateWithExtentAndRatio( @@ -80,47 +128,30 @@ class _LivePageState extends CommonPageState ), ), Success() => loadingState.response?.isNotEmpty == true - ? Builder(builder: (context) { - List list = loadingState.response!; - LiveCardList? followItem; - if (list.first.cardType == 'my_idol_v1') { - followItem = list.first; - list = list.sublist(1); - } - return SliverMainAxisGroup( - slivers: [ - if (followItem != null) - SliverPadding( - padding: const EdgeInsets.only(bottom: 12), - sliver: SliverToBoxAdapter( - child: _buildFollowList(followItem), - ), - ), - if (list.isNotEmpty) - SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: - MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == list.length - 1) { - controller.onLoadMore(); - } - return LiveCardVApp( - item: list[index].cardData!.smallCardV1!, - ); - }, - childCount: list.length, - ), - ), - ], - ); - }) + ? SliverGrid( + gridDelegate: SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), + ), + delegate: SliverChildBuilderDelegate( + (context, index) { + if (index == loadingState.response!.length - 1) { + controller.onLoadMore(); + } + final item = loadingState.response![index]; + if (item is LiveCardList) { + return LiveCardVApp( + item: item.cardData!.smallCardV1!, + ); + } + return LiveCardVApp(item: item); + }, + childCount: loadingState.response!.length, + ), + ) : HttpError(onReload: controller.onReload), Error() => HttpError( errMsg: loadingState.errMsg, @@ -183,22 +214,21 @@ class _LivePageState extends CommonPageState ), ], ), - _buildFollowBody(theme, item.cardData?.myIdolV1?.list), + if (item.cardData?.myIdolV1?.list?.isNotEmpty == true) + _buildFollowBody(theme, item.cardData!.myIdolV1!.list!), + const SizedBox(height: 10), ], ); } - Widget _buildFollowBody(ThemeData theme, List? list) { - if (list.isNullOrEmpty) { - return const SizedBox.shrink(); - } + Widget _buildFollowBody(ThemeData theme, List followList) { return MediaQuery.removePadding( context: context, removeLeft: context.orientation == Orientation.landscape, child: SelfSizedHorizontalList( gapSize: 5, childBuilder: (index) { - final item = list[index]; + final item = followList[index]; return SizedBox( width: 65, child: GestureDetector( @@ -244,7 +274,7 @@ class _LivePageState extends CommonPageState ), ); }, - itemCount: list!.length, + itemCount: followList.length, ), ); } diff --git a/lib/pages/live/widgets/live_item_app.dart b/lib/pages/live/widgets/live_item_app.dart index c1c1831b4..b88c85b3d 100644 --- a/lib/pages/live/widgets/live_item_app.dart +++ b/lib/pages/live/widgets/live_item_app.dart @@ -17,13 +17,13 @@ class LiveCardVApp extends StatelessWidget { @override Widget build(BuildContext context) { - String heroTag = Utils.makeHeroTag(item.id); + String heroTag = Utils.makeHeroTag(item.roomid); return Card( clipBehavior: Clip.hardEdge, margin: EdgeInsets.zero, child: InkWell( onTap: () { - Get.toNamed('/liveRoom?roomid=${item.id}'); + Get.toNamed('/liveRoom?roomid=${item.roomid}'); }, onLongPress: () => imageSaveDialog( title: item.title,