✨ Popup comments
This commit is contained in:
parent
0814c17407
commit
bb5a10c4c4
@ -12,14 +12,14 @@ import 'package:solian/widgets/indent_wrapper.dart';
|
|||||||
import 'package:solian/widgets/posts/attachment_editor.dart';
|
import 'package:solian/widgets/posts/attachment_editor.dart';
|
||||||
|
|
||||||
class CommentPostArguments {
|
class CommentPostArguments {
|
||||||
final Post related;
|
final Post? related;
|
||||||
final Post? editing;
|
final Post? editing;
|
||||||
|
|
||||||
CommentPostArguments({required this.related, this.editing});
|
CommentPostArguments({this.related, this.editing});
|
||||||
}
|
}
|
||||||
|
|
||||||
class CommentEditorScreen extends StatefulWidget {
|
class CommentEditorScreen extends StatefulWidget {
|
||||||
final Post related;
|
final Post? related;
|
||||||
final Post? editing;
|
final Post? editing;
|
||||||
|
|
||||||
const CommentEditorScreen({super.key, required this.related, this.editing});
|
const CommentEditorScreen({super.key, required this.related, this.editing});
|
||||||
@ -50,9 +50,10 @@ class _CommentEditorScreenState extends State<CommentEditorScreen> {
|
|||||||
final auth = context.read<AuthProvider>();
|
final auth = context.read<AuthProvider>();
|
||||||
if (!await auth.isAuthorized()) return;
|
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
|
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}');
|
: getRequestUri('interactive', '/api/p/comments/${widget.editing!.id}');
|
||||||
|
|
||||||
final req = Request(widget.editing == null ? "POST" : "PUT", uri);
|
final req = Request(widget.editing == null ? "POST" : "PUT", uri);
|
||||||
|
@ -3,18 +3,29 @@ import 'package:solian/widgets/navigation_drawer.dart';
|
|||||||
|
|
||||||
class LayoutWrapper extends StatelessWidget {
|
class LayoutWrapper extends StatelessWidget {
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
|
final Widget? floatingActionButton;
|
||||||
|
final List<Widget>? appBarActions;
|
||||||
|
final bool? noSafeArea;
|
||||||
final String title;
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final content = child ?? Container();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: Text(title), actions: appBarActions),
|
||||||
|
floatingActionButton: floatingActionButton,
|
||||||
drawer: const SolianNavigationDrawer(),
|
drawer: const SolianNavigationDrawer(),
|
||||||
appBar: AppBar(title: Text(title)),
|
body: (noSafeArea ?? false) ? content : SafeArea(child: content),
|
||||||
body: SafeArea(
|
|
||||||
child: child ?? Container(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:solian/widgets/common_wrapper.dart';
|
||||||
import 'package:solian/widgets/navigation_drawer.dart';
|
import 'package:solian/widgets/navigation_drawer.dart';
|
||||||
|
|
||||||
class IndentWrapper extends StatelessWidget {
|
class IndentWrapper extends LayoutWrapper {
|
||||||
final Widget? child;
|
|
||||||
final Widget? floatingActionButton;
|
|
||||||
final List<Widget>? appBarActions;
|
|
||||||
final bool? hideDrawer;
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.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/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/article.dart';
|
||||||
import 'package:solian/widgets/posts/content/attachment.dart';
|
import 'package:solian/widgets/posts/content/attachment.dart';
|
||||||
import 'package:solian/widgets/posts/content/moment.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() {
|
Widget renderContent() {
|
||||||
switch (widget.item.modelType) {
|
switch (widget.item.modelType) {
|
||||||
case 'article':
|
case 'article':
|
||||||
@ -62,20 +97,36 @@ class _PostItemState extends State<PostItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget renderReactions() {
|
Widget renderReactions() {
|
||||||
|
const density = VisualDensity(horizontal: -4, vertical: -2);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
height: 48,
|
height: 48,
|
||||||
padding: const EdgeInsets.only(top: 8, left: 4, right: 4),
|
padding: const EdgeInsets.only(top: 8, left: 4, right: 4),
|
||||||
child: ReactionList(
|
child: Row(
|
||||||
item: widget.item,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
reactionList: reactionList,
|
children: [
|
||||||
onReact: (symbol, changes) {
|
ActionChip(
|
||||||
setState(() {
|
avatar: const Icon(Icons.comment),
|
||||||
if (!reactionList!.containsKey(symbol)) {
|
label: Text(widget.item.commentCount.toString()),
|
||||||
reactionList![symbol] = 0;
|
tooltip: 'Comment',
|
||||||
}
|
onPressed: () => viewComments(context),
|
||||||
reactionList![symbol] += changes;
|
),
|
||||||
});
|
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;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import 'package:solian/models/post.dart';
|
|||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.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';
|
import 'package:solian/widgets/posts/item_deletion.dart';
|
||||||
|
|
||||||
class PostItemAction extends StatelessWidget {
|
class PostItemAction extends StatelessWidget {
|
||||||
@ -18,6 +19,31 @@ class PostItemAction extends StatelessWidget {
|
|||||||
this.onDelete,
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final auth = context.read<AuthProvider>();
|
final auth = context.read<AuthProvider>();
|
||||||
@ -43,15 +69,7 @@ class PostItemAction extends StatelessWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.edit),
|
leading: const Icon(Icons.edit),
|
||||||
title: Text(AppLocalizations.of(context)!.edit),
|
title: Text(AppLocalizations.of(context)!.edit),
|
||||||
onTap: () {
|
onTap: () => viewEditor(),
|
||||||
router
|
|
||||||
.pushNamed('posts.moments.editor', extra: item)
|
|
||||||
.then((did) {
|
|
||||||
if (did == true && onUpdate != null) {
|
|
||||||
onUpdate!();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.delete),
|
leading: const Icon(Icons.delete),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user