opt: reply2reply: highlight item

This commit is contained in:
bggRGjQaUbCoE
2024-10-12 15:22:39 +08:00
parent 17f0277be9
commit e8207cba5d
3 changed files with 105 additions and 74 deletions

View File

@@ -47,58 +47,56 @@ class ReplyItemGrpc extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
child: InkWell(
// 点击整个评论区 评论详情/回复
onTap: () {
feedBack();
if (replyReply != null) {
replyReply!(replyItem, null);
}
},
onLongPress: () {
feedBack();
// showDialog(
// context: Get.context!,
// builder: (_) => AlertDialog(
// content: SelectableText(
// jsonEncode(replyItem.replyControl.toProto3Json())),
// ),
// );
showModalBottomSheet(
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (context) {
return MorePanel(
item: replyItem,
onDelete: (rpid) {
if (onDelete != null) {
onDelete!(rpid, null);
}
},
);
},
);
},
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(12, 14, 8, 5),
child: content(context),
),
if (needDivider)
Divider(
indent: 55,
endIndent: 15,
height: 0.3,
color: Theme.of(context)
.colorScheme
.onInverseSurface
.withOpacity(0.5),
)
],
),
return InkWell(
// 点击整个评论区 评论详情/回复
onTap: () {
feedBack();
if (replyReply != null) {
replyReply!(replyItem, null);
}
},
onLongPress: () {
feedBack();
// showDialog(
// context: Get.context!,
// builder: (_) => AlertDialog(
// content: SelectableText(
// jsonEncode(replyItem.replyControl.toProto3Json())),
// ),
// );
showModalBottomSheet(
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (context) {
return MorePanel(
item: replyItem,
onDelete: (rpid) {
if (onDelete != null) {
onDelete!(rpid, null);
}
},
);
},
);
},
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(12, 14, 8, 5),
child: content(context),
),
if (needDivider)
Divider(
indent: 55,
endIndent: 15,
height: 0.3,
color: Theme.of(context)
.colorScheme
.onInverseSurface
.withOpacity(0.5),
)
],
),
);
}

View File

@@ -1,12 +1,14 @@
import 'package:PiliPalaX/grpc/app/main/community/reply/v1/reply.pb.dart';
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/pages/common/common_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:PiliPalaX/http/reply.dart';
import 'package:PiliPalaX/models/common/reply_type.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class VideoReplyReplyController extends CommonController {
class VideoReplyReplyController extends CommonController
with GetTickerProviderStateMixin {
VideoReplyReplyController(
this.hasRoot,
this.id,
@@ -32,6 +34,10 @@ class VideoReplyReplyController extends CommonController {
RxInt count = (-1).obs;
int? upMid;
int? index;
AnimationController? controller;
Animation<Color?>? colorAnimation;
@override
void onInit() {
super.onInit();
@@ -92,17 +98,29 @@ class VideoReplyReplyController extends CommonController {
if (cursor == null) {
count.value = replies.root.count.toInt();
if (id != null) {
int index = replies.root.replies
index = replies.root.replies
.map((item) => item.id.toInt())
.toList()
.indexOf(id);
if (index != -1) {
controller = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
colorAnimation = ColorTween(
begin: Theme.of(Get.context!).colorScheme.onInverseSurface,
end: Theme.of(Get.context!).colorScheme.surface,
).animate(controller!);
() async {
await Future.delayed(const Duration(milliseconds: 200));
itemScrollCtr.scrollTo(
index: hasRoot ? index + 3 : index + 1,
await itemScrollCtr.scrollTo(
index: hasRoot ? index! + 3 : index! + 1,
duration: const Duration(milliseconds: 200),
);
await Future.delayed(const Duration(milliseconds: 800));
controller?.forward().whenComplete(() {
index = null;
});
}();
}
id = null;

View File

@@ -57,6 +57,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
@override
void dispose() {
_videoReplyReplyController.controller?.dispose();
Get.delete<VideoReplyReplyController>(tag: widget.rpid.toString());
super.dispose();
}
@@ -256,24 +257,18 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
),
);
} else {
return ReplyItemGrpc(
replyItem: loadingState.response[index],
replyLevel: '2',
showReplyRow: false,
replyType: widget.replyType,
onReply: () {
_onReply(loadingState.response[index]);
},
onDelete: (rpid, frpid) {
List list =
(_videoReplyReplyController.loadingState.value as Success)
.response;
list = list.where((item) => item.id != rpid).toList();
_videoReplyReplyController.loadingState.value =
LoadingState.success(list);
},
upMid: _videoReplyReplyController.upMid,
);
return _videoReplyReplyController.index == index
? AnimatedBuilder(
animation: _videoReplyReplyController.colorAnimation!,
builder: (context, child) {
return ColoredBox(
color: _videoReplyReplyController.colorAnimation?.value ??
Theme.of(Get.context!).colorScheme.onInverseSurface,
child: _replyItem(loadingState.response[index]),
);
},
)
: _replyItem(loadingState.response[index]);
}
} else if (loadingState is Error) {
return CustomScrollView(
@@ -304,6 +299,26 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
}
}
Widget _replyItem(replyItem) {
return ReplyItemGrpc(
replyItem: replyItem,
replyLevel: '2',
showReplyRow: false,
replyType: widget.replyType,
onReply: () {
_onReply(replyItem);
},
onDelete: (rpid, frpid) {
List list =
(_videoReplyReplyController.loadingState.value as Success).response;
list = list.where((item) => item.id != rpid).toList();
_videoReplyReplyController.loadingState.value =
LoadingState.success(list);
},
upMid: _videoReplyReplyController.upMid,
);
}
int _itemCount(LoadingState loadingState) {
int itemCount = 0;
if (widget.firstFloor != null) {