feat: 我的关注 正在直播
This commit is contained in:
@ -571,4 +571,8 @@ class Api {
|
|||||||
|
|
||||||
/// 直播间发送弹幕
|
/// 直播间发送弹幕
|
||||||
static const String sendLiveMsg = '${HttpString.liveBaseUrl}/msg/send';
|
static const String sendLiveMsg = '${HttpString.liveBaseUrl}/msg/send';
|
||||||
|
|
||||||
|
/// 我的关注 - 正在直播
|
||||||
|
static const String getFollowingLive =
|
||||||
|
'${HttpString.liveBaseUrl}/xlive/web-ucenter/user/following';
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:pilipala/models/live/follow.dart';
|
||||||
|
|
||||||
import '../models/live/item.dart';
|
import '../models/live/item.dart';
|
||||||
import '../models/live/room_info.dart';
|
import '../models/live/room_info.dart';
|
||||||
import '../models/live/room_info_h5.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
126
lib/models/live/follow.dart
Normal 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'];
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/http/live.dart';
|
import 'package:pilipala/http/live.dart';
|
||||||
|
import 'package:pilipala/models/live/follow.dart';
|
||||||
import 'package:pilipala/models/live/item.dart';
|
import 'package:pilipala/models/live/item.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
@ -11,6 +12,8 @@ class LiveController extends GetxController {
|
|||||||
int _currentPage = 1;
|
int _currentPage = 1;
|
||||||
RxInt crossAxisCount = 2.obs;
|
RxInt crossAxisCount = 2.obs;
|
||||||
RxList<LiveItemModel> liveList = <LiveItemModel>[].obs;
|
RxList<LiveItemModel> liveList = <LiveItemModel>[].obs;
|
||||||
|
RxList<LiveFollowingItemModel> liveFollowingList =
|
||||||
|
<LiveFollowingItemModel>[].obs;
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
OverlayEntry? popupDialog;
|
OverlayEntry? popupDialog;
|
||||||
Box setting = GStrorage.setting;
|
Box setting = GStrorage.setting;
|
||||||
@ -44,6 +47,7 @@ class LiveController extends GetxController {
|
|||||||
// 下拉刷新
|
// 下拉刷新
|
||||||
Future onRefresh() async {
|
Future onRefresh() async {
|
||||||
queryLiveList('init');
|
queryLiveList('init');
|
||||||
|
fetchLiveFollowing();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上拉加载
|
// 上拉加载
|
||||||
@ -61,4 +65,17 @@ class LiveController extends GetxController {
|
|||||||
duration: const Duration(milliseconds: 500), curve: Curves.easeInOut);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import 'package:get/get.dart';
|
|||||||
import 'package:pilipala/common/constants.dart';
|
import 'package:pilipala/common/constants.dart';
|
||||||
import 'package:pilipala/common/skeleton/video_card_v.dart';
|
import 'package:pilipala/common/skeleton/video_card_v.dart';
|
||||||
import 'package:pilipala/common/widgets/http_error.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 'package:pilipala/utils/main_stream.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
@ -22,6 +24,7 @@ class _LivePageState extends State<LivePage>
|
|||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin {
|
||||||
final LiveController _liveController = Get.put(LiveController());
|
final LiveController _liveController = Get.put(LiveController());
|
||||||
late Future _futureBuilderFuture;
|
late Future _futureBuilderFuture;
|
||||||
|
late Future _futureBuilderFuture2;
|
||||||
late ScrollController scrollController;
|
late ScrollController scrollController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -31,6 +34,7 @@ class _LivePageState extends State<LivePage>
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_futureBuilderFuture = _liveController.queryLiveList('init');
|
_futureBuilderFuture = _liveController.queryLiveList('init');
|
||||||
|
_futureBuilderFuture2 = _liveController.fetchLiveFollowing();
|
||||||
scrollController = _liveController.scrollController;
|
scrollController = _liveController.scrollController;
|
||||||
scrollController.addListener(
|
scrollController.addListener(
|
||||||
() {
|
() {
|
||||||
@ -69,6 +73,7 @@ class _LivePageState extends State<LivePage>
|
|||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
controller: _liveController.scrollController,
|
controller: _liveController.scrollController,
|
||||||
slivers: [
|
slivers: [
|
||||||
|
buildFollowingList(),
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
// 单列布局 EdgeInsets.zero
|
// 单列布局 EdgeInsets.zero
|
||||||
padding:
|
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,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,11 +58,12 @@ class LiveRoomController extends GetxController {
|
|||||||
if (Get.arguments != null) {
|
if (Get.arguments != null) {
|
||||||
liveItem = Get.arguments['liveItem'];
|
liveItem = Get.arguments['liveItem'];
|
||||||
heroTag = Get.arguments['heroTag'] ?? '';
|
heroTag = Get.arguments['heroTag'] ?? '';
|
||||||
if (liveItem != null && liveItem.pic != null && liveItem.pic != '') {
|
if (liveItem != null) {
|
||||||
cover = liveItem.pic;
|
cover = (liveItem.pic != null && liveItem.pic != '')
|
||||||
}
|
? liveItem.pic
|
||||||
if (liveItem != null && liveItem.cover != null && liveItem.cover != '') {
|
: (liveItem.cover != null && liveItem.cover != '')
|
||||||
cover = liveItem.cover;
|
? liveItem.cover
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
Request.getBuvid().then((value) => buvid = value);
|
Request.getBuvid().then((value) => buvid = value);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user