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,8 +47,7 @@ class ReplyItemGrpc extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Material( return InkWell(
child: InkWell(
// 点击整个评论区 评论详情/回复 // 点击整个评论区 评论详情/回复
onTap: () { onTap: () {
feedBack(); feedBack();
@@ -99,7 +98,6 @@ class ReplyItemGrpc extends StatelessWidget {
) )
], ],
), ),
),
); );
} }

View File

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

View File

@@ -57,6 +57,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
@override @override
void dispose() { void dispose() {
_videoReplyReplyController.controller?.dispose();
Get.delete<VideoReplyReplyController>(tag: widget.rpid.toString()); Get.delete<VideoReplyReplyController>(tag: widget.rpid.toString());
super.dispose(); super.dispose();
} }
@@ -256,24 +257,18 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
), ),
); );
} else { } else {
return ReplyItemGrpc( return _videoReplyReplyController.index == index
replyItem: loadingState.response[index], ? AnimatedBuilder(
replyLevel: '2', animation: _videoReplyReplyController.colorAnimation!,
showReplyRow: false, builder: (context, child) {
replyType: widget.replyType, return ColoredBox(
onReply: () { color: _videoReplyReplyController.colorAnimation?.value ??
_onReply(loadingState.response[index]); Theme.of(Get.context!).colorScheme.onInverseSurface,
}, child: _replyItem(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,
); );
},
)
: _replyItem(loadingState.response[index]);
} }
} else if (loadingState is Error) { } else if (loadingState is Error) {
return CustomScrollView( 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(LoadingState loadingState) {
int itemCount = 0; int itemCount = 0;
if (widget.firstFloor != null) { if (widget.firstFloor != null) {