mod: 动态评论、二级评论展示
This commit is contained in:
@ -27,7 +27,6 @@ class VideoReplyController extends GetxController {
|
||||
int currentPage = 0;
|
||||
bool isLoadingMore = false;
|
||||
RxString noMore = ''.obs;
|
||||
RxBool autoFocus = false.obs;
|
||||
// 当前回复的回复
|
||||
ReplyItemModel? currentReplyItem;
|
||||
// 回复来源
|
||||
@ -90,34 +89,4 @@ class VideoReplyController extends GetxController {
|
||||
Future onLoad() async {
|
||||
queryReplyList(type: 'onLoad');
|
||||
}
|
||||
|
||||
wakeUpReply() {
|
||||
autoFocus.value = true;
|
||||
}
|
||||
|
||||
// 发表评论
|
||||
Future submitReplyAdd() async {
|
||||
var result = await VideoHttp.replyAdd(
|
||||
type: ReplyType.video,
|
||||
oid: aid!,
|
||||
root: replyLevel == '0'
|
||||
? 0
|
||||
: replyLevel == '1'
|
||||
? currentReplyItem!.rpid
|
||||
: rPid,
|
||||
parent: replyLevel == '0'
|
||||
? 0
|
||||
: replyLevel == '1'
|
||||
? currentReplyItem!.rpid
|
||||
: currentReplyItem!.rpid,
|
||||
message: replyLevel == '2'
|
||||
? ' 回复 @${currentReplyItem!.member!.uname!} : 2楼31'
|
||||
: '2楼31',
|
||||
);
|
||||
if (result['status']) {
|
||||
SmartDialog.showToast(result['data']['success_toast']);
|
||||
} else {
|
||||
SmartDialog.showToast(result['message']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
late VideoReplyController _videoReplyController;
|
||||
late AnimationController fabAnimationCtr;
|
||||
|
||||
// List<ReplyItemModel>? replyList;
|
||||
Future? _futureBuilderFuture;
|
||||
bool _isFabVisible = true;
|
||||
String replyLevel = '1';
|
||||
@ -112,8 +111,8 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
_videoReplyController.replyLevel = '0';
|
||||
}
|
||||
|
||||
await Future.delayed(const Duration(microseconds: 100));
|
||||
_videoReplyController.wakeUpReply();
|
||||
// await Future.delayed(const Duration(microseconds: 100));
|
||||
// _videoReplyController.wakeUpReply();
|
||||
}
|
||||
|
||||
// 展示二级回复
|
||||
@ -231,7 +230,6 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
isScrollControlled: true,
|
||||
builder: (BuildContext context) {
|
||||
return VideoReplyNewDialog(
|
||||
replyLevel: '0',
|
||||
oid: IdUtils.bv2av(Get.parameters['bvid']!),
|
||||
root: 0,
|
||||
parent: 0,
|
||||
|
@ -185,7 +185,7 @@ class ReplyItem extends StatelessWidget {
|
||||
children: [
|
||||
if (replyItem!.isTop!)
|
||||
WidgetSpan(child: UpTag(tagText: 'TOP')),
|
||||
buildContent(context, replyItem!, replyReply, 1, null),
|
||||
buildContent(context, replyItem!, replyReply, null),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -194,7 +194,9 @@ class ReplyItem extends StatelessWidget {
|
||||
// 操作区域
|
||||
bottonAction(context, replyItem!.replyControl),
|
||||
// 一楼的评论
|
||||
if (replyItem!.replies!.isNotEmpty && showReplyRow!) ...[
|
||||
if ((replyItem!.replyControl!.isShow! ||
|
||||
replyItem!.replies!.isNotEmpty) &&
|
||||
showReplyRow!) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5, bottom: 12),
|
||||
child: ReplyItemRow(
|
||||
@ -262,16 +264,16 @@ class ReplyItem extends StatelessWidget {
|
||||
isScrollControlled: true,
|
||||
builder: (builder) {
|
||||
return VideoReplyNewDialog(
|
||||
replyLevel: replyLevel,
|
||||
oid: replyItem!.oid,
|
||||
root: replyItem!.rpid,
|
||||
parent: replyItem!.rpid,
|
||||
replyType: replyType,
|
||||
replyItem: replyItem,
|
||||
);
|
||||
},
|
||||
).then((value) => {
|
||||
// 完成评论,数据添加
|
||||
if (value['data'] != null)
|
||||
if (value != null && value['data'] != null)
|
||||
{
|
||||
addReply!(value['data'])
|
||||
// replyControl.replies.add(value['data']),
|
||||
@ -339,58 +341,57 @@ class ReplyItemRow extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
for (var i = 0; i < replies!.length; i++) ...[
|
||||
InkWell(
|
||||
// 一楼点击评论展开评论详情
|
||||
onTap: () => replyReply!(replyItem),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
8,
|
||||
i == 0 && (extraRow == 1 || replies!.length > 1) ? 8 : 5,
|
||||
8,
|
||||
i == 0 && (extraRow == 1 || replies!.length > 1) ? 5 : 6,
|
||||
),
|
||||
child: Text.rich(
|
||||
overflow: extraRow == 1
|
||||
? TextOverflow.ellipsis
|
||||
: TextOverflow.visible,
|
||||
maxLines: extraRow == 1 ? 2 : null,
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: replies![i].member.uname + ' ',
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.fontSize,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
if (replies!.isNotEmpty)
|
||||
for (var i = 0; i < replies!.length; i++) ...[
|
||||
InkWell(
|
||||
// 一楼点击评论展开评论详情
|
||||
onTap: () => replyReply!(replyItem),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
8,
|
||||
i == 0 && (extraRow == 1 || replies!.length > 1) ? 8 : 5,
|
||||
8,
|
||||
i == 0 && (extraRow == 1 || replies!.length > 1) ? 5 : 6,
|
||||
),
|
||||
child: Text.rich(
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: replies![i].member.uname + ' ',
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.fontSize,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
String heroTag =
|
||||
Utils.makeHeroTag(replies![i].member.mid);
|
||||
Get.toNamed(
|
||||
'/member?mid=${replies![i].member.mid}',
|
||||
arguments: {
|
||||
'face': replies![i].member.avatar,
|
||||
'heroTag': heroTag
|
||||
});
|
||||
},
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
String heroTag =
|
||||
Utils.makeHeroTag(replies![i].member.mid);
|
||||
Get.toNamed(
|
||||
'/member?mid=${replies![i].member.mid}',
|
||||
arguments: {
|
||||
'face': replies![i].member.avatar,
|
||||
'heroTag': heroTag
|
||||
});
|
||||
},
|
||||
),
|
||||
if (replies![i].isUp)
|
||||
WidgetSpan(
|
||||
child: UpTag(),
|
||||
),
|
||||
buildContent(
|
||||
context, replies![i], replyReply, 2, replyItem),
|
||||
],
|
||||
if (replies![i].isUp)
|
||||
WidgetSpan(
|
||||
child: UpTag(),
|
||||
),
|
||||
buildContent(
|
||||
context, replies![i], replyReply, replyItem),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
if (extraRow == 1)
|
||||
InkWell(
|
||||
// 一楼点击【共xx条回复】展开评论详情
|
||||
@ -426,21 +427,23 @@ class ReplyItemRow extends StatelessWidget {
|
||||
}
|
||||
|
||||
InlineSpan buildContent(
|
||||
BuildContext context, replyItem, replyReply, level, fReplyItem) {
|
||||
BuildContext context, replyItem, replyReply, fReplyItem) {
|
||||
// replyItem 当前回复内容
|
||||
// replyReply 查看二楼回复(回复详情)回调
|
||||
// fReplyItem 父级回复内容,用作二楼回复(回复详情)展示
|
||||
var content = replyItem.content;
|
||||
// if (content.emote.isEmpty &&
|
||||
// content.atNameToMid.isEmpty &&
|
||||
// content.jumpUrl.isEmpty &&
|
||||
// content.vote.isEmpty &&
|
||||
// content.pictures.isEmpty) {
|
||||
// return TextSpan(
|
||||
// text: content.message,
|
||||
// recognizer: TapGestureRecognizer()..onTap = () => replyReply(fReplyItem),
|
||||
// );
|
||||
// }
|
||||
if (content.emote.isEmpty &&
|
||||
content.atNameToMid.isEmpty &&
|
||||
content.jumpUrl.isEmpty &&
|
||||
content.vote.isEmpty &&
|
||||
content.pictures.isEmpty) {
|
||||
return TextSpan(
|
||||
text: content.message,
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap =
|
||||
() => replyReply(replyItem.root == 0 ? replyItem : fReplyItem),
|
||||
);
|
||||
}
|
||||
List<InlineSpan> spanChilds = [];
|
||||
bool hasMatchMember = true;
|
||||
|
||||
@ -501,15 +504,16 @@ InlineSpan buildContent(
|
||||
spanChilds.add(TextSpan(
|
||||
text: matchStr,
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap =
|
||||
() => replyReply(level == 1 ? replyItem : fReplyItem)));
|
||||
..onTap = () =>
|
||||
replyReply(replyItem.root == 0 ? replyItem : fReplyItem)));
|
||||
return matchStr;
|
||||
}
|
||||
} else {
|
||||
spanChilds.add(TextSpan(
|
||||
text: matchStr,
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => replyReply(level == 1 ? replyItem : fReplyItem)));
|
||||
..onTap = () =>
|
||||
replyReply(replyItem.root == 0 ? replyItem : fReplyItem)));
|
||||
return matchStr;
|
||||
}
|
||||
return '';
|
||||
@ -593,8 +597,8 @@ InlineSpan buildContent(
|
||||
spanChilds.add(TextSpan(
|
||||
text: str,
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap =
|
||||
() => replyReply(level == 1 ? replyItem : fReplyItem)));
|
||||
..onTap = () => replyReply(
|
||||
replyItem.root == 0 ? replyItem : fReplyItem)));
|
||||
return str;
|
||||
},
|
||||
);
|
||||
@ -630,7 +634,8 @@ InlineSpan buildContent(
|
||||
spanChilds.add(TextSpan(
|
||||
text: str,
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => replyReply(level == 1 ? replyItem : fReplyItem)));
|
||||
..onTap = () =>
|
||||
replyReply(replyItem.root == 0 ? replyItem : fReplyItem)));
|
||||
}
|
||||
return str;
|
||||
},
|
||||
|
@ -12,16 +12,16 @@ import 'package:pilipala/utils/storage.dart';
|
||||
class VideoReplyNewDialog extends StatefulWidget {
|
||||
int? oid;
|
||||
int? root;
|
||||
String? replyLevel;
|
||||
int? parent;
|
||||
ReplyType? replyType;
|
||||
ReplyItemModel? replyItem;
|
||||
|
||||
VideoReplyNewDialog({
|
||||
this.oid,
|
||||
this.root,
|
||||
this.replyLevel,
|
||||
this.parent,
|
||||
this.replyType,
|
||||
this.replyItem,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -36,14 +36,12 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
|
||||
double _keyboardHeight = 0.0; // 键盘高度
|
||||
final _debouncer = Debouncer(milliseconds: 100); // 设置延迟时间
|
||||
bool ableClean = false;
|
||||
bool autoFocus = false;
|
||||
Timer? timer;
|
||||
Box localCache = GStrorage.localCache;
|
||||
late double sheetHeight;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
// 监听输入框聚焦
|
||||
// replyContentFocusNode.addListener(_onFocus);
|
||||
@ -74,14 +72,18 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
|
||||
oid: widget.oid!,
|
||||
root: widget.root!,
|
||||
parent: widget.parent!,
|
||||
message: message,
|
||||
message: widget.replyItem != null && widget.replyItem!.root != 0
|
||||
? ' 回复 @${widget.replyItem!.member!.uname!} : $message'
|
||||
: message,
|
||||
);
|
||||
if (result['status']) {
|
||||
SmartDialog.showToast(result['data']['success_toast']);
|
||||
Get.back(result: {
|
||||
'data': ReplyItemModel.fromJson(result['data']['reply'], ''),
|
||||
});
|
||||
} else {}
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@ -103,6 +105,12 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_replyContentController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
|
@ -123,7 +123,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
|
||||
addReply: (replyItem) {
|
||||
_videoReplyReplyController.replyList.add(replyItem);
|
||||
},
|
||||
replyType: ReplyType.video,
|
||||
replyType: widget.replyType,
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
@ -167,16 +167,16 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Material(
|
||||
child: ReplyItem(
|
||||
replyItem: _videoReplyReplyController
|
||||
.replyList[index],
|
||||
replyLevel: '2',
|
||||
showReplyRow: false,
|
||||
addReply: (replyItem) {
|
||||
_videoReplyReplyController.replyList
|
||||
.add(replyItem);
|
||||
}),
|
||||
return ReplyItem(
|
||||
replyItem: _videoReplyReplyController
|
||||
.replyList[index],
|
||||
replyLevel: '2',
|
||||
showReplyRow: false,
|
||||
addReply: (replyItem) {
|
||||
_videoReplyReplyController.replyList
|
||||
.add(replyItem);
|
||||
},
|
||||
replyType: widget.replyType,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
Reference in New Issue
Block a user