Replies

This commit is contained in:
2024-05-25 17:21:27 +08:00
parent daee3e8074
commit 9eae49128e
9 changed files with 191 additions and 41 deletions

View File

@ -16,6 +16,7 @@ class PostItem extends StatefulWidget {
final bool isCompact;
final bool isReactable;
final bool isShowReply;
final bool isShowEmbed;
const PostItem({
super.key,
@ -24,6 +25,7 @@ class PostItem extends StatefulWidget {
this.isCompact = false,
this.isReactable = true,
this.isShowReply = true,
this.isShowEmbed = true,
});
@override
@ -162,7 +164,7 @@ class _PostItemState extends State<PostItem> {
data: item.content,
padding: const EdgeInsets.all(0),
).paddingOnly(left: 12, right: 8),
if (widget.item.replyTo != null)
if (widget.item.replyTo != null && widget.isShowEmbed)
GestureDetector(
child: buildReply(context).paddingOnly(top: 4),
onTap: () {
@ -175,7 +177,7 @@ class _PostItemState extends State<PostItem> {
);
},
),
if (widget.item.repostTo != null)
if (widget.item.repostTo != null && widget.isShowEmbed)
GestureDetector(
child: buildRepost(context).paddingOnly(top: 4),
onTap: () {

View File

@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:solian/models/post.dart';
import 'package:solian/router.dart';
import 'package:solian/widgets/posts/post_action.dart';
import 'package:solian/widgets/posts/post_item.dart';
class PostListWidget extends StatelessWidget {
final bool shrinkWrap;
final bool isShowEmbed;
final bool isClickable;
final bool isNestedClickable;
final PagingController<int, Post> controller;
const PostListWidget({
super.key,
required this.controller,
this.shrinkWrap = false,
this.isShowEmbed = true,
this.isClickable = true,
this.isNestedClickable = true,
});
@override
Widget build(BuildContext context) {
return PagedListView<int, Post>.separated(
shrinkWrap: shrinkWrap,
pagingController: controller,
builderDelegate: PagedChildBuilderDelegate<Post>(
itemBuilder: (context, item, index) {
return GestureDetector(
child: PostItem(
key: Key('p${item.alias}'),
item: item,
isShowEmbed: isShowEmbed,
isClickable: isNestedClickable,
).paddingSymmetric(
vertical: (item.attachments?.isEmpty ?? false) ? 8 : 0,
),
onTap: () {
if (!isClickable) return;
AppRouter.instance.pushNamed(
'postDetail',
pathParameters: {'alias': item.alias},
);
},
onLongPress: () {
showModalBottomSheet(
useRootNavigator: true,
context: context,
builder: (context) => PostAction(item: item),
).then((value) {
if (value == true) controller.refresh();
});
},
);
},
),
separatorBuilder: (_, __) => const Divider(thickness: 0.3, height: 0.3),
);
}
}

View File

@ -6,6 +6,7 @@ import 'package:solian/models/reaction.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/services.dart';
import 'package:solian/widgets/posts/post_reaction.dart';
import 'package:solian/widgets/posts/post_replies.dart';
class PostQuickAction extends StatefulWidget {
final Post item;
@ -100,7 +101,15 @@ class _PostQuickActionState extends State<PostQuickAction> {
avatar: const Icon(Icons.comment),
label: Text(widget.item.replyCount.toString()),
visualDensity: density,
onPressed: () {},
onPressed: () {
showModalBottomSheet(
useRootNavigator: true,
context: context,
builder: (context) {
return PostReplyListPopup(item: widget.item);
},
);
},
),
if (widget.isReactable && widget.isShowReply)
const VerticalDivider(

View File

@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:solian/models/pagination.dart';
import 'package:solian/models/post.dart';
import 'package:solian/providers/content/post_explore.dart';
import 'package:solian/widgets/posts/post_list.dart';
class PostReplyList extends StatefulWidget {
final Post item;
final bool shrinkWrap;
const PostReplyList({
super.key,
required this.item,
this.shrinkWrap = false,
});
@override
State<PostReplyList> createState() => _PostReplyListState();
}
class _PostReplyListState extends State<PostReplyList> {
final PagingController<int, Post> _pagingController =
PagingController(firstPageKey: 0);
Future<void> getReplies(int pageKey) async {
final PostProvider provider = Get.find();
Response resp;
try {
resp = await provider.listPostReplies(widget.item.alias, pageKey);
} catch (e) {
_pagingController.error = e;
return;
}
final PaginationResult result = PaginationResult.fromJson(resp.body);
final parsed = result.data?.map((e) => Post.fromJson(e)).toList();
if (parsed != null && parsed.length >= 10) {
_pagingController.appendPage(parsed, pageKey + parsed.length);
} else if (parsed != null) {
_pagingController.appendLastPage(parsed);
}
}
@override
void initState() {
super.initState();
_pagingController.addPageRequestListener(getReplies);
}
@override
Widget build(BuildContext context) {
return PostListWidget(
isShowEmbed: false,
shrinkWrap: widget.shrinkWrap,
controller: _pagingController,
);
}
}
class PostReplyListPopup extends StatelessWidget {
final Post item;
const PostReplyListPopup({super.key, required this.item});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'postReplies'.tr,
style: Theme.of(context).textTheme.headlineSmall,
).paddingOnly(left: 24, right: 24, top: 32, bottom: 16),
Expanded(
child: PostReplyList(
item: item,
),
),
],
);
}
}