feat: 按排序查看评论
This commit is contained in:
@ -5,6 +5,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/http/reply.dart';
|
||||
import 'package:pilipala/http/video.dart';
|
||||
import 'package:pilipala/models/common/reply_sort_type.dart';
|
||||
import 'package:pilipala/models/common/reply_type.dart';
|
||||
import 'package:pilipala/models/video/reply/data.dart';
|
||||
import 'package:pilipala/models/video/reply/item.dart';
|
||||
@ -36,11 +37,19 @@ class VideoReplyController extends GetxController {
|
||||
// 默认回复主楼
|
||||
String replyLevel = '0';
|
||||
|
||||
ReplySortType sortType = ReplySortType.time;
|
||||
RxString sortTypeTitle = ReplySortType.time.titles.obs;
|
||||
RxString sortTypeLabel = ReplySortType.time.labels.obs;
|
||||
|
||||
Future queryReplyList({type = 'init'}) async {
|
||||
isLoadingMore = true;
|
||||
var res = level == '1'
|
||||
? await ReplyHttp.replyList(
|
||||
oid: aid!, pageNum: currentPage + 1, type: 1)
|
||||
oid: aid!,
|
||||
pageNum: currentPage + 1,
|
||||
type: ReplyType.video.index,
|
||||
sort: sortType.index,
|
||||
)
|
||||
: await ReplyHttp.replyReplyList(
|
||||
oid: aid!, root: rpid!, pageNum: currentPage + 1, type: 1);
|
||||
if (res['status']) {
|
||||
@ -89,4 +98,25 @@ class VideoReplyController extends GetxController {
|
||||
Future onLoad() async {
|
||||
queryReplyList(type: 'onLoad');
|
||||
}
|
||||
|
||||
// 排序搜索评论
|
||||
queryBySort() {
|
||||
switch (sortType) {
|
||||
case ReplySortType.time:
|
||||
sortType = ReplySortType.like;
|
||||
break;
|
||||
case ReplySortType.like:
|
||||
sortType = ReplySortType.reply;
|
||||
break;
|
||||
case ReplySortType.reply:
|
||||
sortType = ReplySortType.time;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
sortTypeTitle.value = sortType.titles;
|
||||
sortTypeLabel.value = sortType.labels;
|
||||
currentPage = 0;
|
||||
replyList.clear();
|
||||
queryReplyList(type: 'init');
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,46 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
controller: _videoReplyController.scrollController,
|
||||
key: const PageStorageKey<String>('评论'),
|
||||
slivers: <Widget>[
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 12)),
|
||||
SliverPersistentHeader(
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: _MySliverPersistentHeaderDelegate(
|
||||
child: Container(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
padding: const EdgeInsets.fromLTRB(12, 6, 10, 6),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() => AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 400),
|
||||
transitionBuilder:
|
||||
(Widget child, Animation<double> animation) {
|
||||
return ScaleTransition(
|
||||
scale: animation, child: child);
|
||||
},
|
||||
child: Text(
|
||||
_videoReplyController.sortTypeTitle.value,
|
||||
key: ValueKey<String>(
|
||||
_videoReplyController.sortTypeTitle.value),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
child: TextButton.icon(
|
||||
onPressed: () =>
|
||||
_videoReplyController.queryBySort(),
|
||||
icon: const Icon(Icons.sort, size: 17),
|
||||
label: Obx(() => Text(
|
||||
_videoReplyController.sortTypeLabel.value)),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (context, snapshot) {
|
||||
@ -155,40 +194,51 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
if (data['status']) {
|
||||
// 请求成功
|
||||
return Obx(
|
||||
() => SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
if (index ==
|
||||
_videoReplyController.replyList.length) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context)
|
||||
.padding
|
||||
.bottom),
|
||||
height:
|
||||
MediaQuery.of(context).padding.bottom +
|
||||
100,
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
_videoReplyController.noMore.value)),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return ReplyItem(
|
||||
replyItem:
|
||||
_videoReplyController.replyList[index],
|
||||
showReplyRow: true,
|
||||
replyLevel: replyLevel,
|
||||
replyReply: (replyItem) =>
|
||||
replyReply(replyItem),
|
||||
replyType: ReplyType.video,
|
||||
);
|
||||
}
|
||||
},
|
||||
childCount:
|
||||
_videoReplyController.replyList.length + 1,
|
||||
),
|
||||
),
|
||||
() => _videoReplyController.replyList.isEmpty
|
||||
? SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
return const VideoReplySkeleton();
|
||||
}, childCount: 5),
|
||||
)
|
||||
: SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
if (index ==
|
||||
_videoReplyController
|
||||
.replyList.length) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context)
|
||||
.padding
|
||||
.bottom),
|
||||
height: MediaQuery.of(context)
|
||||
.padding
|
||||
.bottom +
|
||||
100,
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
_videoReplyController
|
||||
.noMore.value)),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return ReplyItem(
|
||||
replyItem: _videoReplyController
|
||||
.replyList[index],
|
||||
showReplyRow: true,
|
||||
replyLevel: replyLevel,
|
||||
replyReply: (replyItem) =>
|
||||
replyReply(replyItem),
|
||||
replyType: ReplyType.video,
|
||||
);
|
||||
}
|
||||
},
|
||||
childCount:
|
||||
_videoReplyController.replyList.length +
|
||||
1,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// 请求错误
|
||||
@ -254,3 +304,33 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||
final double _minExtent = 45;
|
||||
final double _maxExtent = 45;
|
||||
final Widget child;
|
||||
|
||||
_MySliverPersistentHeaderDelegate({required this.child});
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||
//创建child子组件
|
||||
//shrinkOffset:child偏移值minExtent~maxExtent
|
||||
//overlapsContent:SliverPersistentHeader覆盖其他子组件返回true,否则返回false
|
||||
return child;
|
||||
}
|
||||
|
||||
//SliverPersistentHeader最大高度
|
||||
@override
|
||||
double get maxExtent => _maxExtent;
|
||||
|
||||
//SliverPersistentHeader最小高度
|
||||
@override
|
||||
double get minExtent => _minExtent;
|
||||
|
||||
@override
|
||||
bool shouldRebuild(covariant _MySliverPersistentHeaderDelegate oldDelegate) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ class ReplyItem extends StatelessWidget {
|
||||
replyItem!.member!.uname!,
|
||||
style: TextStyle(
|
||||
color: replyItem!.isUp! ||
|
||||
replyItem!.member!.vip!['vipType'] > 0
|
||||
replyItem!.member!.vip!['vipStatus'] > 0
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).colorScheme.outline,
|
||||
fontSize:
|
||||
@ -177,7 +177,7 @@ class ReplyItem extends StatelessWidget {
|
||||
focusNode: FocusNode(),
|
||||
selectionControls: MaterialTextSelectionControls(),
|
||||
child: Text.rich(
|
||||
style: const TextStyle(height: 1.65),
|
||||
style: const TextStyle(height: 1.75),
|
||||
maxLines:
|
||||
replyItem!.content!.isText! && replyLevel == '1' ? 3 : 999,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
Reference in New Issue
Block a user