feat: live following
This commit is contained in:
@ -14,6 +14,7 @@ class LiveController extends GetxController {
|
||||
RxList<LiveItemModel> liveList = <LiveItemModel>[].obs;
|
||||
RxList<LiveFollowingItemModel> liveFollowingList =
|
||||
<LiveFollowingItemModel>[].obs;
|
||||
RxInt liveFollowingCount = 0.obs;
|
||||
bool flag = false;
|
||||
OverlayEntry? popupDialog;
|
||||
Box setting = GStrorage.setting;
|
||||
@ -27,9 +28,6 @@ class LiveController extends GetxController {
|
||||
|
||||
// 获取推荐
|
||||
Future queryLiveList(type) async {
|
||||
// if (type == 'init') {
|
||||
// _currentPage = 1;
|
||||
// }
|
||||
var res = await LiveHttp.liveList(
|
||||
pn: _currentPage,
|
||||
);
|
||||
@ -68,13 +66,14 @@ class LiveController extends GetxController {
|
||||
|
||||
//
|
||||
Future fetchLiveFollowing() async {
|
||||
var res = await LiveHttp.liveFollowing(pn: 1, ps: 20);
|
||||
var res = await LiveHttp.liveFollowing(pn: 1, ps: 10);
|
||||
if (res['status']) {
|
||||
liveFollowingList.value =
|
||||
(res['data'].list as List<LiveFollowingItemModel>)
|
||||
.where((LiveFollowingItemModel item) =>
|
||||
item.liveStatus == 1 && item.recordLiveTime == 0) // 根据条件过滤
|
||||
.toList();
|
||||
liveFollowingCount.value = res['data'].liveCount;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -162,34 +162,61 @@ class _LivePageState extends State<LivePage>
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Obx(
|
||||
() => Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
const TextSpan(
|
||||
text: ' 我的关注 ',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() => Text.rich(
|
||||
TextSpan(
|
||||
text: ' ${_liveController.liveFollowingList.length}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
children: [
|
||||
const TextSpan(
|
||||
text: ' 我的关注 ',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: ' ${_liveController.liveFollowingCount}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: '人正在直播',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TextSpan(
|
||||
text: '人正在直播',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Get.toNamed('/liveFollowing');
|
||||
},
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'查看更多',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
FutureBuilder(
|
||||
future: _futureBuilderFuture2,
|
||||
@ -201,8 +228,7 @@ class _LivePageState extends State<LivePage>
|
||||
Map? data = snapshot.data;
|
||||
if (data?['status']) {
|
||||
RxList list = _liveController.liveFollowingList;
|
||||
// ignore: invalid_use_of_protected_member
|
||||
return Obx(() => LiveFollowingListView(list: list.value));
|
||||
return LiveFollowingListView(list: list);
|
||||
} else {
|
||||
return SizedBox(
|
||||
height: 80,
|
||||
@ -230,69 +256,71 @@ class _LivePageState extends State<LivePage>
|
||||
}
|
||||
|
||||
class LiveFollowingListView extends StatelessWidget {
|
||||
final List list;
|
||||
final RxList 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,
|
||||
return Obx(
|
||||
() => 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,
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: list.length,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/common/constants.dart';
|
||||
import 'package:pilipala/common/widgets/badge.dart';
|
||||
import 'package:pilipala/models/live/follow.dart';
|
||||
import 'package:pilipala/models/live/item.dart';
|
||||
import 'package:pilipala/utils/image_save.dart';
|
||||
import 'package:pilipala/utils/utils.dart';
|
||||
@ -9,7 +11,7 @@ import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||
|
||||
// 视频卡片 - 垂直布局
|
||||
class LiveCardV extends StatelessWidget {
|
||||
final LiveItemModel liveItem;
|
||||
final dynamic liveItem;
|
||||
final int crossAxisCount;
|
||||
|
||||
const LiveCardV({
|
||||
@ -64,6 +66,9 @@ class LiveCardV extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (liveItem is LiveFollowingItemModel &&
|
||||
liveItem.liveStatus == 1)
|
||||
const PBadge(top: 8, right: 8, text: '直播中'),
|
||||
],
|
||||
);
|
||||
}),
|
||||
@ -148,7 +153,7 @@ class LiveContent extends StatelessWidget {
|
||||
}
|
||||
|
||||
class VideoStat extends StatelessWidget {
|
||||
final LiveItemModel? liveItem;
|
||||
final dynamic liveItem;
|
||||
|
||||
const VideoStat({
|
||||
Key? key,
|
||||
@ -178,25 +183,20 @@ class VideoStat extends StatelessWidget {
|
||||
liveItem!.areaName!,
|
||||
style: const TextStyle(fontSize: 11, color: Colors.white),
|
||||
),
|
||||
Text(
|
||||
liveItem!.watchedShow!['text_small'],
|
||||
style: const TextStyle(fontSize: 11, color: Colors.white),
|
||||
),
|
||||
if (liveItem is LiveItemModel) ...[
|
||||
Text(
|
||||
liveItem!.watchedShow?['text_small'],
|
||||
style: const TextStyle(fontSize: 11, color: Colors.white),
|
||||
),
|
||||
],
|
||||
if (liveItem is LiveFollowingItemModel) ...[
|
||||
Text(
|
||||
'${liveItem.textSmall}',
|
||||
style: const TextStyle(fontSize: 11, color: Colors.white),
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
|
||||
// child: RichText(
|
||||
// maxLines: 1,
|
||||
// textAlign: TextAlign.justify,
|
||||
// softWrap: false,
|
||||
// text: TextSpan(
|
||||
// style: const TextStyle(fontSize: 11, color: Colors.white),
|
||||
// children: [
|
||||
// TextSpan(text: liveItem!.areaName!),
|
||||
// TextSpan(text: liveItem!.watchedShow!['text_small']),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user