feat: 我的关注 正在直播

This commit is contained in:
guozhigq
2024-09-22 16:11:52 +08:00
parent 12aada6a3f
commit 913e9154f5
6 changed files with 323 additions and 5 deletions

View File

@ -571,4 +571,8 @@ class Api {
/// 直播间发送弹幕
static const String sendLiveMsg = '${HttpString.liveBaseUrl}/msg/send';
/// 我的关注 - 正在直播
static const String getFollowingLive =
'${HttpString.liveBaseUrl}/xlive/web-ucenter/user/following';
}

View File

@ -1,3 +1,5 @@
import 'package:pilipala/models/live/follow.dart';
import '../models/live/item.dart';
import '../models/live/room_info.dart';
import '../models/live/room_info_h5.dart';
@ -117,4 +119,27 @@ class LiveHttp {
};
}
}
// 我的关注 正在直播
static Future liveFollowing({int? pn, int? ps}) async {
var res = await Request().get(Api.getFollowingLive, data: {
'page': pn,
'page_size': ps,
'platform': 'web',
'ignoreRecord': 1,
'hit_ab': true,
});
if (res.data['code'] == 0) {
return {
'status': true,
'data': LiveFollowingModel.fromJson(res.data['data'])
};
} else {
return {
'status': false,
'data': [],
'msg': res.data['message'],
};
}
}
}

126
lib/models/live/follow.dart Normal file
View File

@ -0,0 +1,126 @@
class LiveFollowingModel {
int? count;
List<LiveFollowingItemModel>? list;
int? liveCount;
int? neverLivedCount;
List? neverLivedFaces;
int? pageSize;
String? title;
int? totalPage;
LiveFollowingModel({
this.count,
this.list,
this.liveCount,
this.neverLivedCount,
this.neverLivedFaces,
this.pageSize,
this.title,
this.totalPage,
});
LiveFollowingModel.fromJson(Map<String, dynamic> json) {
count = json['count'];
if (json['list'] != null) {
list = <LiveFollowingItemModel>[];
json['list'].forEach((v) {
list!.add(LiveFollowingItemModel.fromJson(v));
});
}
liveCount = json['live_count'];
neverLivedCount = json['never_lived_count'];
if (json['never_lived_faces'] != null) {
neverLivedFaces = <dynamic>[];
json['never_lived_faces'].forEach((v) {
neverLivedFaces!.add(v);
});
}
pageSize = json['pageSize'];
title = json['title'];
totalPage = json['totalPage'];
}
}
class LiveFollowingItemModel {
int? roomId;
int? uid;
String? uname;
String? title;
String? face;
int? liveStatus;
int? recordNum;
String? recentRecordId;
int? isAttention;
int? clipNum;
int? fansNum;
String? areaName;
String? areaValue;
String? tags;
String? recentRecordIdV2;
int? recordNumV2;
int? recordLiveTime;
String? areaNameV2;
String? roomNews;
String? watchIcon;
String? textSmall;
String? roomCover;
String? pic;
int? parentAreaId;
int? areaId;
LiveFollowingItemModel({
this.roomId,
this.uid,
this.uname,
this.title,
this.face,
this.liveStatus,
this.recordNum,
this.recentRecordId,
this.isAttention,
this.clipNum,
this.fansNum,
this.areaName,
this.areaValue,
this.tags,
this.recentRecordIdV2,
this.recordNumV2,
this.recordLiveTime,
this.areaNameV2,
this.roomNews,
this.watchIcon,
this.textSmall,
this.roomCover,
this.pic,
this.parentAreaId,
this.areaId,
});
LiveFollowingItemModel.fromJson(Map<String, dynamic> json) {
roomId = json['roomid'];
uid = json['uid'];
uname = json['uname'];
title = json['title'];
face = json['face'];
liveStatus = json['live_status'];
recordNum = json['record_num'];
recentRecordId = json['recent_record_id'];
isAttention = json['is_attention'];
clipNum = json['clipnum'];
fansNum = json['fans_num'];
areaName = json['area_name'];
areaValue = json['area_value'];
tags = json['tags'];
recentRecordIdV2 = json['recent_record_id_v2'];
recordNumV2 = json['record_num_v2'];
recordLiveTime = json['record_live_time'];
areaNameV2 = json['area_name_v2'];
roomNews = json['room_news'];
watchIcon = json['watch_icon'];
textSmall = json['text_small'];
roomCover = json['room_cover'];
pic = json['room_cover'];
parentAreaId = json['parent_area_id'];
areaId = json['area_id'];
}
}

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/http/live.dart';
import 'package:pilipala/models/live/follow.dart';
import 'package:pilipala/models/live/item.dart';
import 'package:pilipala/utils/storage.dart';
@ -11,6 +12,8 @@ class LiveController extends GetxController {
int _currentPage = 1;
RxInt crossAxisCount = 2.obs;
RxList<LiveItemModel> liveList = <LiveItemModel>[].obs;
RxList<LiveFollowingItemModel> liveFollowingList =
<LiveFollowingItemModel>[].obs;
bool flag = false;
OverlayEntry? popupDialog;
Box setting = GStrorage.setting;
@ -44,6 +47,7 @@ class LiveController extends GetxController {
// 下拉刷新
Future onRefresh() async {
queryLiveList('init');
fetchLiveFollowing();
}
// 上拉加载
@ -61,4 +65,17 @@ class LiveController extends GetxController {
duration: const Duration(milliseconds: 500), curve: Curves.easeInOut);
}
}
//
Future fetchLiveFollowing() async {
var res = await LiveHttp.liveFollowing(pn: 1, ps: 20);
if (res['status']) {
liveFollowingList.value = (res['data'].list
as List<LiveFollowingItemModel>)
.where(
(LiveFollowingItemModel item) => item.liveStatus == 1) // 根据条件过滤
.toList();
}
return res;
}
}

View File

@ -6,6 +6,8 @@ import 'package:get/get.dart';
import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/skeleton/video_card_v.dart';
import 'package:pilipala/common/widgets/http_error.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/models/live/follow.dart';
import 'package:pilipala/utils/main_stream.dart';
import 'controller.dart';
@ -22,6 +24,7 @@ class _LivePageState extends State<LivePage>
with AutomaticKeepAliveClientMixin {
final LiveController _liveController = Get.put(LiveController());
late Future _futureBuilderFuture;
late Future _futureBuilderFuture2;
late ScrollController scrollController;
@override
@ -31,6 +34,7 @@ class _LivePageState extends State<LivePage>
void initState() {
super.initState();
_futureBuilderFuture = _liveController.queryLiveList('init');
_futureBuilderFuture2 = _liveController.fetchLiveFollowing();
scrollController = _liveController.scrollController;
scrollController.addListener(
() {
@ -69,6 +73,7 @@ class _LivePageState extends State<LivePage>
child: CustomScrollView(
controller: _liveController.scrollController,
slivers: [
buildFollowingList(),
SliverPadding(
// 单列布局 EdgeInsets.zero
padding:
@ -147,4 +152,144 @@ class _LivePageState extends State<LivePage>
),
);
}
// 关注的up直播
Widget buildFollowingList() {
return SliverPadding(
padding: const EdgeInsets.only(top: 16),
sliver: SliverToBoxAdapter(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(
() => Text.rich(
TextSpan(
children: [
const TextSpan(
text: ' 我的关注 ',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
TextSpan(
text: ' ${_liveController.liveFollowingList.length}',
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.primary,
),
),
TextSpan(
text: '人正在直播',
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.outline,
),
),
],
),
),
),
FutureBuilder(
future: _futureBuilderFuture2,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
Map? data = snapshot.data;
if (data?['status']) {
RxList list = _liveController.liveFollowingList;
return Obx(() => LiveFollowingListView(list: list.value));
} else {
return HttpError(
errMsg: data?['msg'] ?? '',
fn: () {
setState(() {
_futureBuilderFuture2 =
_liveController.fetchLiveFollowing();
});
},
);
}
} else {
return const SizedBox();
}
},
),
],
),
),
);
}
}
class LiveFollowingListView extends StatelessWidget {
final List list;
const LiveFollowingListView({super.key, required this.list});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final LiveFollowingItemModel item = list[index];
return Padding(
padding: const EdgeInsets.fromLTRB(3, 12, 3, 0),
child: Column(
children: [
InkWell(
onTap: () {
Get.toNamed(
'/liveRoom?roomid=${item.roomId}',
arguments: {
'liveItem': item,
'heroTag': item.roomId.toString()
},
);
},
child: Container(
width: 54,
height: 54,
padding: const EdgeInsets.all(2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(27),
border: Border.all(
color: Theme.of(context).colorScheme.primary,
width: 1.5,
),
),
child: NetworkImgLayer(
width: 50,
height: 50,
type: 'avatar',
src: list[index].face,
),
),
),
const SizedBox(height: 6),
SizedBox(
width: 62,
child: Text(
list[index].uname,
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 12,
),
),
),
],
),
);
},
itemCount: list.length,
),
);
}
}

View File

@ -58,11 +58,12 @@ class LiveRoomController extends GetxController {
if (Get.arguments != null) {
liveItem = Get.arguments['liveItem'];
heroTag = Get.arguments['heroTag'] ?? '';
if (liveItem != null && liveItem.pic != null && liveItem.pic != '') {
cover = liveItem.pic;
}
if (liveItem != null && liveItem.cover != null && liveItem.cover != '') {
cover = liveItem.cover;
if (liveItem != null) {
cover = (liveItem.pic != null && liveItem.pic != '')
? liveItem.pic
: (liveItem.cover != null && liveItem.cover != '')
? liveItem.cover
: null;
}
Request.getBuvid().then((value) => buvid = value);
}