Implement single comment view
This commit is contained in:
parent
eecfa1498a
commit
ebc5dcedbe
|
@ -24,6 +24,20 @@ Future<EntryCommentListModel> fetchComments(
|
|||
jsonDecode(response.body) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<EntryCommentModel> fetchComment(
|
||||
http.Client client,
|
||||
String instanceHost,
|
||||
int commentId,
|
||||
) async {
|
||||
final response =
|
||||
await client.get(Uri.https(instanceHost, '/api/comments/$commentId'));
|
||||
|
||||
httpErrorHandler(response, message: 'Failed to load comment');
|
||||
|
||||
return EntryCommentModel.fromJson(
|
||||
jsonDecode(response.body) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<EntryCommentModel> putVote(
|
||||
http.Client client,
|
||||
String instanceHost,
|
||||
|
|
|
@ -24,6 +24,20 @@ Future<PostCommentListModel> fetchComments(
|
|||
jsonDecode(response.body) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<PostCommentModel> fetchComment(
|
||||
http.Client client,
|
||||
String instanceHost,
|
||||
int commentId,
|
||||
) async {
|
||||
final response = await client
|
||||
.get(Uri.https(instanceHost, '/api/post-comments/$commentId'));
|
||||
|
||||
httpErrorHandler(response, message: 'Failed to load comment');
|
||||
|
||||
return PostCommentModel.fromJson(
|
||||
jsonDecode(response.body) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<PostCommentModel> putVote(
|
||||
http.Client client,
|
||||
String instanceHost,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:interstellar/src/api/comments.dart' as api_comments;
|
||||
import 'package:interstellar/src/models/entry_comment.dart';
|
||||
import 'package:interstellar/src/screens/entries/entry_comment_screen.dart';
|
||||
import 'package:interstellar/src/screens/settings/settings_controller.dart';
|
||||
import 'package:interstellar/src/utils/utils.dart';
|
||||
import 'package:interstellar/src/widgets/content_item.dart';
|
||||
|
@ -72,6 +73,13 @@ class _EntryCommentState extends State<EntryComment> {
|
|||
children: widget.comment.children,
|
||||
));
|
||||
}),
|
||||
openContentLabel: 'Open comment',
|
||||
onOpenContent: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
EntryCommentScreen(widget.comment.commentId),
|
||||
),
|
||||
),
|
||||
onReply: whenLoggedIn(context, (body) async {
|
||||
var newSubComment = await api_comments.postComment(
|
||||
context.read<SettingsController>().httpClient,
|
||||
|
@ -125,6 +133,19 @@ class _EntryCommentState extends State<EntryComment> {
|
|||
: null,
|
||||
),
|
||||
),
|
||||
if (widget.comment.childCount > 0 &&
|
||||
!_isCollapsed &&
|
||||
(widget.comment.children?.isEmpty ?? false))
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
EntryCommentScreen(widget.comment.commentId),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'Open ${widget.comment.childCount} reply${widget.comment.childCount == 1 ? '' : 's'}'),
|
||||
),
|
||||
if (widget.comment.childCount > 0 && !_isCollapsed)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 1),
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:interstellar/src/api/comments.dart';
|
||||
import 'package:interstellar/src/models/entry_comment.dart';
|
||||
import 'package:interstellar/src/screens/entries/entry_comment.dart';
|
||||
import 'package:interstellar/src/screens/settings/settings_controller.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class EntryCommentScreen extends StatefulWidget {
|
||||
const EntryCommentScreen(
|
||||
this.commentId, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
final int commentId;
|
||||
|
||||
@override
|
||||
State<EntryCommentScreen> createState() => _EntryCommentScreenState();
|
||||
}
|
||||
|
||||
class _EntryCommentScreenState extends State<EntryCommentScreen> {
|
||||
EntryCommentModel? _comment;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
fetchComment(context.read<SettingsController>().httpClient,
|
||||
context.read<SettingsController>().instanceHost, widget.commentId)
|
||||
.then((value) => setState(() {
|
||||
_comment = value;
|
||||
}));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
'Comment${_comment != null ? ' by ${_comment!.user.username}' : ''}'),
|
||||
),
|
||||
body: _comment != null
|
||||
? ListView(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 4,
|
||||
),
|
||||
child: EntryComment(
|
||||
_comment!,
|
||||
(newComment) => setState(() {
|
||||
_comment = newComment;
|
||||
}),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
: const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:interstellar/src/api/post_comments.dart' as api_comments;
|
||||
import 'package:interstellar/src/models/post_comment.dart';
|
||||
import 'package:interstellar/src/screens/posts/post_comment_screen.dart';
|
||||
import 'package:interstellar/src/screens/settings/settings_controller.dart';
|
||||
import 'package:interstellar/src/utils/utils.dart';
|
||||
import 'package:interstellar/src/widgets/content_item.dart';
|
||||
|
@ -72,6 +73,13 @@ class _EntryCommentState extends State<PostComment> {
|
|||
children: widget.comment.children,
|
||||
));
|
||||
}),
|
||||
openContentLabel: 'Open comment',
|
||||
onOpenContent: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
PostCommentScreen(widget.comment.commentId),
|
||||
),
|
||||
),
|
||||
onReply: whenLoggedIn(context, (body) async {
|
||||
var newSubComment = await api_comments.postComment(
|
||||
context.read<SettingsController>().httpClient,
|
||||
|
@ -125,6 +133,19 @@ class _EntryCommentState extends State<PostComment> {
|
|||
: null,
|
||||
),
|
||||
),
|
||||
if (widget.comment.childCount > 0 &&
|
||||
!_isCollapsed &&
|
||||
(widget.comment.children?.isEmpty ?? false))
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
PostCommentScreen(widget.comment.commentId),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'Open ${widget.comment.childCount} reply${widget.comment.childCount == 1 ? '' : 's'}'),
|
||||
),
|
||||
if (widget.comment.childCount > 0 && !_isCollapsed)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 1),
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:interstellar/src/api/post_comments.dart';
|
||||
import 'package:interstellar/src/models/post_comment.dart';
|
||||
import 'package:interstellar/src/screens/posts/post_comment.dart';
|
||||
import 'package:interstellar/src/screens/settings/settings_controller.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class PostCommentScreen extends StatefulWidget {
|
||||
const PostCommentScreen(
|
||||
this.commentId, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
final int commentId;
|
||||
|
||||
@override
|
||||
State<PostCommentScreen> createState() => _PostCommentScreenState();
|
||||
}
|
||||
|
||||
class _PostCommentScreenState extends State<PostCommentScreen> {
|
||||
PostCommentModel? _comment;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
fetchComment(context.read<SettingsController>().httpClient,
|
||||
context.read<SettingsController>().instanceHost, widget.commentId)
|
||||
.then((value) => setState(() {
|
||||
_comment = value;
|
||||
}));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
'Comment${_comment != null ? ' by ${_comment!.user.username}' : ''}'),
|
||||
),
|
||||
body: _comment != null
|
||||
? ListView(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 4,
|
||||
),
|
||||
child: PostComment(
|
||||
_comment!,
|
||||
(newComment) => setState(() {
|
||||
_comment = newComment;
|
||||
}),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
: const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -46,6 +46,8 @@ class ContentItem extends StatefulWidget {
|
|||
|
||||
final int? numComments;
|
||||
final Future<void> Function(String)? onReply;
|
||||
final String? openContentLabel;
|
||||
final Future<void> Function()? onOpenContent;
|
||||
final Future<void> Function(String)? onEdit;
|
||||
final Future<void> Function()? onDelete;
|
||||
|
||||
|
@ -79,6 +81,8 @@ class ContentItem extends StatefulWidget {
|
|||
this.isDownVoted = false,
|
||||
this.onDownVote,
|
||||
this.numComments,
|
||||
this.openContentLabel,
|
||||
this.onOpenContent,
|
||||
this.onReply,
|
||||
this.onEdit,
|
||||
this.onDelete,
|
||||
|
@ -313,6 +317,13 @@ class _ContentItemState extends State<ContentItem> {
|
|||
},
|
||||
controller: _menuController,
|
||||
menuChildren: [
|
||||
if (widget.openContentLabel != null)
|
||||
MenuItemButton(
|
||||
onPressed: widget.onOpenContent,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Text(widget.openContentLabel!)),
|
||||
),
|
||||
MenuItemButton(
|
||||
onPressed: widget.onEdit != null
|
||||
? () => setState(() {
|
||||
|
|
|
@ -22,6 +22,7 @@ class TextEditor extends StatelessWidget {
|
|||
controller: controller,
|
||||
keyboardType:
|
||||
keyboardType ?? (isMarkdown ? TextInputType.multiline : null),
|
||||
minLines: isMarkdown ? 2 : null,
|
||||
maxLines: isMarkdown ? null : 1,
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
|
|
Loading…
Reference in New Issue