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

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; : _replyItem(loadingState.response[index]);
list = list.where((item) => item.id != rpid).toList();
_videoReplyReplyController.loadingState.value =
LoadingState.success(list);
},
upMid: _videoReplyReplyController.upMid,
);
} }
} 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) {