mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
opt: reply2reply: highlight item
This commit is contained in:
@@ -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),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user