Popup comments

This commit is contained in:
LittleSheep 2024-04-16 20:36:47 +08:00
parent 0814c17407
commit bb5a10c4c4
5 changed files with 122 additions and 37 deletions

View File

@ -12,14 +12,14 @@ import 'package:solian/widgets/indent_wrapper.dart';
import 'package:solian/widgets/posts/attachment_editor.dart';
class CommentPostArguments {
final Post related;
final Post? related;
final Post? editing;
CommentPostArguments({required this.related, this.editing});
CommentPostArguments({this.related, this.editing});
}
class CommentEditorScreen extends StatefulWidget {
final Post related;
final Post? related;
final Post? editing;
const CommentEditorScreen({super.key, required this.related, this.editing});
@ -50,9 +50,10 @@ class _CommentEditorScreenState extends State<CommentEditorScreen> {
final auth = context.read<AuthProvider>();
if (!await auth.isAuthorized()) return;
final relatedDataset = '${widget.related.modelType}s';
final alias = widget.related?.alias ?? 'not-found';
final relatedDataset = '${widget.related?.modelType ?? 'comment'}s';
final uri = widget.editing == null
? getRequestUri('interactive', '/api/p/$relatedDataset/${widget.related.alias}/comments')
? getRequestUri('interactive', '/api/p/$relatedDataset/$alias/comments')
: getRequestUri('interactive', '/api/p/comments/${widget.editing!.id}');
final req = Request(widget.editing == null ? "POST" : "PUT", uri);

View File

@ -3,18 +3,29 @@ import 'package:solian/widgets/navigation_drawer.dart';
class LayoutWrapper extends StatelessWidget {
final Widget? child;
final Widget? floatingActionButton;
final List<Widget>? appBarActions;
final bool? noSafeArea;
final String title;
const LayoutWrapper({super.key, this.child, required this.title});
const LayoutWrapper({
super.key,
this.child,
required this.title,
this.floatingActionButton,
this.appBarActions,
this.noSafeArea,
});
@override
Widget build(BuildContext context) {
final content = child ?? Container();
return Scaffold(
appBar: AppBar(title: Text(title), actions: appBarActions),
floatingActionButton: floatingActionButton,
drawer: const SolianNavigationDrawer(),
appBar: AppBar(title: Text(title)),
body: SafeArea(
child: child ?? Container(),
),
body: (noSafeArea ?? false) ? content : SafeArea(child: content),
);
}
}

View File

@ -1,15 +1,19 @@
import 'package:flutter/material.dart';
import 'package:solian/widgets/common_wrapper.dart';
import 'package:solian/widgets/navigation_drawer.dart';
class IndentWrapper extends StatelessWidget {
final Widget? child;
final Widget? floatingActionButton;
final List<Widget>? appBarActions;
class IndentWrapper extends LayoutWrapper {
final bool? hideDrawer;
final bool? noSafeArea;
final String title;
const IndentWrapper({super.key, this.child, required this.title, this.floatingActionButton, this.appBarActions, this.hideDrawer, this.noSafeArea});
const IndentWrapper({
super.key,
super.child,
required super.title,
super.floatingActionButton,
super.appBarActions,
this.hideDrawer,
super.noSafeArea,
}) : super();
@override
Widget build(BuildContext context) {

View File

@ -1,5 +1,10 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/widgets.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:solian/models/post.dart';
import 'package:solian/widgets/posts/comment_list.dart';
import 'package:solian/widgets/posts/content/article.dart';
import 'package:solian/widgets/posts/content/attachment.dart';
import 'package:solian/widgets/posts/content/moment.dart';
@ -38,6 +43,36 @@ class _PostItemState extends State<PostItem> {
);
}
void viewComments(BuildContext context) {
final PagingController<int, Post> commentPaging =
PagingController(firstPageKey: 0);
showModalBottomSheet(
context: context,
builder: (context) {
return Column(
children: [
CommentListHeader(
related: widget.item,
paging: commentPaging,
),
Expanded(
child: CustomScrollView(
slivers: [
CommentList(
related: widget.item,
dataset: '${widget.item.modelType}s',
paging: commentPaging,
),
],
),
),
],
);
},
);
}
Widget renderContent() {
switch (widget.item.modelType) {
case 'article':
@ -62,20 +97,36 @@ class _PostItemState extends State<PostItem> {
}
Widget renderReactions() {
const density = VisualDensity(horizontal: -4, vertical: -2);
return Container(
height: 48,
padding: const EdgeInsets.only(top: 8, left: 4, right: 4),
child: ReactionList(
item: widget.item,
reactionList: reactionList,
onReact: (symbol, changes) {
setState(() {
if (!reactionList!.containsKey(symbol)) {
reactionList![symbol] = 0;
}
reactionList![symbol] += changes;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ActionChip(
avatar: const Icon(Icons.comment),
label: Text(widget.item.commentCount.toString()),
tooltip: 'Comment',
onPressed: () => viewComments(context),
),
const VerticalDivider(thickness: 0.3, indent: 8, endIndent: 8),
Expanded(
child: ReactionList(
item: widget.item,
reactionList: reactionList,
onReact: (symbol, changes) {
setState(() {
if (!reactionList!.containsKey(symbol)) {
reactionList![symbol] = 0;
}
reactionList![symbol] += changes;
});
},
),
),
],
),
);
}

View File

@ -4,6 +4,7 @@ import 'package:solian/models/post.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/router.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:solian/screens/posts/comment_editor.dart';
import 'package:solian/widgets/posts/item_deletion.dart';
class PostItemAction extends StatelessWidget {
@ -18,6 +19,31 @@ class PostItemAction extends StatelessWidget {
this.onDelete,
});
void viewEditor() async {
bool ok = false;
switch (item.modelType) {
case 'article':
ok = await router.pushNamed(
'posts.articles.editor',
extra: item,
) as bool;
case 'moment':
ok = await router.pushNamed(
'posts.moments.editor',
extra: item,
) as bool;
case 'comment':
ok = await router.pushNamed(
'posts.comments.editor',
extra: CommentPostArguments(editing: item),
) as bool;
}
if (ok == true && onUpdate != null) {
onUpdate!();
}
}
@override
Widget build(BuildContext context) {
final auth = context.read<AuthProvider>();
@ -43,15 +69,7 @@ class PostItemAction extends StatelessWidget {
ListTile(
leading: const Icon(Icons.edit),
title: Text(AppLocalizations.of(context)!.edit),
onTap: () {
router
.pushNamed('posts.moments.editor', extra: item)
.then((did) {
if (did == true && onUpdate != null) {
onUpdate!();
}
});
},
onTap: () => viewEditor(),
),
ListTile(
leading: const Icon(Icons.delete),