feat: live following
This commit is contained in:
50
lib/pages/live_follow/controller.dart
Normal file
50
lib/pages/live_follow/controller.dart
Normal file
@ -0,0 +1,50 @@
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.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/utils/storage.dart';
|
||||
|
||||
class LiveFollowController extends GetxController {
|
||||
RxInt crossAxisCount = 2.obs;
|
||||
Box setting = GStrorage.setting;
|
||||
int _currentPage = 1;
|
||||
RxInt liveFollowingCount = 0.obs;
|
||||
RxList<LiveFollowingItemModel> liveFollowingList =
|
||||
<LiveFollowingItemModel>[].obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
crossAxisCount.value =
|
||||
setting.get(SettingBoxKey.customRows, defaultValue: 2);
|
||||
}
|
||||
|
||||
Future queryLiveFollowList(type) async {
|
||||
var res = await LiveHttp.liveFollowing(
|
||||
pn: _currentPage,
|
||||
ps: 20,
|
||||
);
|
||||
if (res['status']) {
|
||||
if (type == 'init') {
|
||||
liveFollowingList.value = res['data'].list;
|
||||
liveFollowingCount.value = res['data'].liveCount;
|
||||
} else if (type == 'onLoad') {
|
||||
liveFollowingList.addAll(res['data'].list);
|
||||
}
|
||||
_currentPage += 1;
|
||||
} else {
|
||||
SmartDialog.showToast(res['msg']);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Future onRefresh() async {
|
||||
_currentPage = 1;
|
||||
await queryLiveFollowList('init');
|
||||
}
|
||||
|
||||
void onLoad() async {
|
||||
queryLiveFollowList('onLoad');
|
||||
}
|
||||
}
|
||||
4
lib/pages/live_follow/index.dart
Normal file
4
lib/pages/live_follow/index.dart
Normal file
@ -0,0 +1,4 @@
|
||||
library live_follow;
|
||||
|
||||
export 'view.dart';
|
||||
export 'controller.dart';
|
||||
136
lib/pages/live_follow/view.dart
Normal file
136
lib/pages/live_follow/view.dart
Normal file
@ -0,0 +1,136 @@
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
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/pages/live/widgets/live_item.dart';
|
||||
|
||||
import 'controller.dart';
|
||||
|
||||
class LiveFollowPage extends StatefulWidget {
|
||||
const LiveFollowPage({super.key});
|
||||
|
||||
@override
|
||||
State<LiveFollowPage> createState() => _LiveFollowPageState();
|
||||
}
|
||||
|
||||
class _LiveFollowPageState extends State<LiveFollowPage> {
|
||||
late Future _futureBuilderFuture;
|
||||
final ScrollController scrollController = ScrollController();
|
||||
final LiveFollowController _liveFollowController =
|
||||
Get.put(LiveFollowController());
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_futureBuilderFuture = _liveFollowController.queryLiveFollowList('init');
|
||||
scrollController.addListener(
|
||||
() {
|
||||
if (scrollController.position.pixels >=
|
||||
scrollController.position.maxScrollExtent - 200) {
|
||||
EasyThrottle.throttle(
|
||||
'liveFollowList', const Duration(milliseconds: 200), () {
|
||||
_liveFollowController.onLoad();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
titleSpacing: 0,
|
||||
centerTitle: false,
|
||||
title: Obx(() => Text(
|
||||
'${_liveFollowController.liveFollowingCount}人正在直播中',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
)),
|
||||
),
|
||||
body: Container(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
margin: const EdgeInsets.only(
|
||||
left: StyleString.safeSpace, right: StyleString.safeSpace),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(StyleString.imgRadius),
|
||||
),
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
return await _liveFollowController.onRefresh();
|
||||
},
|
||||
child: CustomScrollView(
|
||||
controller: scrollController,
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
padding:
|
||||
const EdgeInsets.fromLTRB(0, StyleString.safeSpace, 0, 0),
|
||||
sliver: FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.data == null) {
|
||||
return const SliverToBoxAdapter(child: SizedBox());
|
||||
}
|
||||
Map data = snapshot.data as Map;
|
||||
if (data['status']) {
|
||||
return SliverLayoutBuilder(
|
||||
builder: (context, boxConstraints) {
|
||||
return Obx(
|
||||
() => contentGrid(_liveFollowController,
|
||||
_liveFollowController.liveFollowingList),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return HttpError(
|
||||
errMsg: data['msg'],
|
||||
fn: () {
|
||||
setState(() {
|
||||
_futureBuilderFuture = _liveFollowController
|
||||
.queryLiveFollowList('init');
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return contentGrid(_liveFollowController, []);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Widget contentGrid(ctr, liveList) {
|
||||
int crossAxisCount = ctr.crossAxisCount.value;
|
||||
return SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
mainAxisSpacing: StyleString.safeSpace,
|
||||
crossAxisSpacing: StyleString.safeSpace,
|
||||
crossAxisCount: crossAxisCount,
|
||||
mainAxisExtent:
|
||||
Get.size.width / crossAxisCount / StyleString.aspectRatio +
|
||||
MediaQuery.textScalerOf(context).scale(
|
||||
(crossAxisCount == 1 ? 48 : 68),
|
||||
),
|
||||
),
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(BuildContext context, int index) {
|
||||
return liveList!.isNotEmpty
|
||||
? LiveCardV(
|
||||
liveItem: liveList[index],
|
||||
crossAxisCount: crossAxisCount,
|
||||
)
|
||||
: const VideoCardVSkeleton();
|
||||
},
|
||||
childCount: liveList!.isNotEmpty ? liveList!.length : 10,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user