mirror of
https://github.com/Iconica-Development/flutter_timeline.git
synced 2025-05-19 10:33:44 +02:00
feat: option to delete reactions
This commit is contained in:
parent
e523f52118
commit
7e89ba9c85
5 changed files with 115 additions and 51 deletions
|
@ -28,7 +28,11 @@ class TimelineUserStoryConfiguration {
|
||||||
final Widget Function(BuildContext context, Widget filterBar, Widget child)?
|
final Widget Function(BuildContext context, Widget filterBar, Widget child)?
|
||||||
mainPageBuilder;
|
mainPageBuilder;
|
||||||
|
|
||||||
final Widget Function(BuildContext context, Widget child, TimelineCategory category)? postScreenBuilder;
|
final Widget Function(
|
||||||
|
BuildContext context,
|
||||||
|
Widget child,
|
||||||
|
TimelineCategory category,
|
||||||
|
)? postScreenBuilder;
|
||||||
|
|
||||||
final Widget Function(BuildContext context, Widget child)?
|
final Widget Function(BuildContext context, Widget child)?
|
||||||
postCreationScreenBuilder;
|
postCreationScreenBuilder;
|
||||||
|
|
|
@ -60,6 +60,30 @@ class FirebaseTimelineService with ChangeNotifier implements TimelineService {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TimelinePost> deletePostReaction(
|
||||||
|
TimelinePost post,
|
||||||
|
String reactionId,
|
||||||
|
) async {
|
||||||
|
var updatedPost = post.copyWith(
|
||||||
|
reaction: post.reaction - 1,
|
||||||
|
reactions: (post.reactions ?? [])
|
||||||
|
..removeWhere((element) => element.id == reactionId),
|
||||||
|
);
|
||||||
|
_posts = _posts
|
||||||
|
.map(
|
||||||
|
(p) => p.id == post.id ? updatedPost : p,
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
var postRef = _db.collection(_options.timelineCollectionName).doc(post.id);
|
||||||
|
await postRef.update({
|
||||||
|
'reaction': FieldValue.increment(-1),
|
||||||
|
'reactions': FieldValue.arrayRemove([reactionId]),
|
||||||
|
});
|
||||||
|
notifyListeners();
|
||||||
|
return updatedPost;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<TimelinePost> fetchPostDetails(TimelinePost post) async {
|
Future<TimelinePost> fetchPostDetails(TimelinePost post) async {
|
||||||
var reactions = post.reactions ?? [];
|
var reactions = post.reactions ?? [];
|
||||||
|
|
|
@ -10,6 +10,7 @@ import 'package:flutter_timeline_interface/src/model/timeline_reaction.dart';
|
||||||
|
|
||||||
abstract class TimelineService with ChangeNotifier {
|
abstract class TimelineService with ChangeNotifier {
|
||||||
Future<void> deletePost(TimelinePost post);
|
Future<void> deletePost(TimelinePost post);
|
||||||
|
Future<TimelinePost> deletePostReaction(TimelinePost post, String reactionId);
|
||||||
Future<TimelinePost> createPost(TimelinePost post);
|
Future<TimelinePost> createPost(TimelinePost post);
|
||||||
Future<List<TimelinePost>> fetchPosts(String? category);
|
Future<List<TimelinePost>> fetchPosts(String? category);
|
||||||
Future<TimelinePost> fetchPost(TimelinePost post);
|
Future<TimelinePost> fetchPost(TimelinePost post);
|
||||||
|
|
|
@ -20,6 +20,7 @@ class TimelineTranslations {
|
||||||
'Indicate whether people are allowed to respond',
|
'Indicate whether people are allowed to respond',
|
||||||
this.checkPost = 'Check post overview',
|
this.checkPost = 'Check post overview',
|
||||||
this.deletePost = 'Delete post',
|
this.deletePost = 'Delete post',
|
||||||
|
this.deleteReaction = 'Delete Reaction',
|
||||||
this.viewPost = 'View post',
|
this.viewPost = 'View post',
|
||||||
this.likesTitle = 'Likes',
|
this.likesTitle = 'Likes',
|
||||||
this.commentsTitle = 'Comments',
|
this.commentsTitle = 'Comments',
|
||||||
|
@ -45,6 +46,7 @@ class TimelineTranslations {
|
||||||
final String postAt;
|
final String postAt;
|
||||||
|
|
||||||
final String deletePost;
|
final String deletePost;
|
||||||
|
final String deleteReaction;
|
||||||
final String viewPost;
|
final String viewPost;
|
||||||
final String likesTitle;
|
final String likesTitle;
|
||||||
final String commentsTitle;
|
final String commentsTitle;
|
||||||
|
|
|
@ -312,66 +312,99 @@ class _TimelinePostScreenState extends State<TimelinePostScreen> {
|
||||||
for (var reaction
|
for (var reaction
|
||||||
in post.reactions ?? <TimelinePostReaction>[]) ...[
|
in post.reactions ?? <TimelinePostReaction>[]) ...[
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Row(
|
GestureDetector(
|
||||||
crossAxisAlignment: reaction.imageUrl != null
|
onLongPress: () async {
|
||||||
? CrossAxisAlignment.start
|
if (reaction.creatorId == widget.userId ||
|
||||||
: CrossAxisAlignment.center,
|
widget.options.allowAllDeletion) {
|
||||||
children: [
|
// Show popup menu for deletion
|
||||||
if (reaction.creator?.imageUrl != null &&
|
var value = await showMenu<String>(
|
||||||
reaction.creator!.imageUrl!.isNotEmpty) ...[
|
context: context,
|
||||||
widget.options.userAvatarBuilder?.call(
|
position: const RelativeRect.fromLTRB(
|
||||||
reaction.creator!,
|
100.0,
|
||||||
25,
|
200.0,
|
||||||
) ??
|
100.0,
|
||||||
CircleAvatar(
|
100.0,
|
||||||
radius: 20,
|
),
|
||||||
backgroundImage: CachedNetworkImageProvider(
|
items: [
|
||||||
reaction.creator!.imageUrl!,
|
PopupMenuItem<String>(
|
||||||
|
value: 'delete',
|
||||||
|
child: Text(
|
||||||
|
widget.options.translations.deleteReaction,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(width: 10),
|
);
|
||||||
if (reaction.imageUrl != null) ...[
|
if (value == 'delete') {
|
||||||
Expanded(
|
// Call service to delete reaction
|
||||||
child: Column(
|
updatePost(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
await widget.service
|
||||||
children: [
|
.deletePostReaction(post, reaction.id),
|
||||||
Text(
|
);
|
||||||
reaction.creator?.fullName ??
|
}
|
||||||
widget
|
}
|
||||||
.options.translations.anonymousUser,
|
},
|
||||||
style: theme.textTheme.titleSmall,
|
child: Row(
|
||||||
),
|
crossAxisAlignment: reaction.imageUrl != null
|
||||||
Padding(
|
? CrossAxisAlignment.start
|
||||||
padding: const EdgeInsets.all(8.0),
|
: CrossAxisAlignment.center,
|
||||||
child: CachedNetworkImage(
|
children: [
|
||||||
imageUrl: reaction.imageUrl!,
|
if (reaction.creator?.imageUrl != null &&
|
||||||
fit: BoxFit.fitWidth,
|
reaction.creator!.imageUrl!.isNotEmpty) ...[
|
||||||
|
widget.options.userAvatarBuilder?.call(
|
||||||
|
reaction.creator!,
|
||||||
|
25,
|
||||||
|
) ??
|
||||||
|
CircleAvatar(
|
||||||
|
radius: 20,
|
||||||
|
backgroundImage: CachedNetworkImageProvider(
|
||||||
|
reaction.creator!.imageUrl!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
const SizedBox(width: 10),
|
||||||
),
|
if (reaction.imageUrl != null) ...[
|
||||||
] else ...[
|
Expanded(
|
||||||
Expanded(
|
child: Column(
|
||||||
child: Text.rich(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
TextSpan(
|
|
||||||
text: reaction.creator?.fullName ??
|
|
||||||
widget.options.translations.anonymousUser,
|
|
||||||
style: theme.textTheme.titleSmall,
|
|
||||||
children: [
|
children: [
|
||||||
const TextSpan(text: ' '),
|
Text(
|
||||||
TextSpan(
|
reaction.creator?.fullName ??
|
||||||
text: reaction.reaction ?? '',
|
widget.options.translations
|
||||||
style: theme.textTheme.bodyMedium,
|
.anonymousUser,
|
||||||
|
style: theme.textTheme.titleSmall,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl: reaction.imageUrl!,
|
||||||
|
fit: BoxFit.fitWidth,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// text should go to new line
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
] else ...[
|
||||||
|
Expanded(
|
||||||
|
child: Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
text: reaction.creator?.fullName ??
|
||||||
|
widget
|
||||||
|
.options.translations.anonymousUser,
|
||||||
|
style: theme.textTheme.titleSmall,
|
||||||
|
children: [
|
||||||
|
const TextSpan(text: ' '),
|
||||||
|
TextSpan(
|
||||||
|
text: reaction.reaction ?? '',
|
||||||
|
style: theme.textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
// text should go to new line
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
if (post.reactions?.isEmpty ?? true) ...[
|
if (post.reactions?.isEmpty ?? true) ...[
|
||||||
|
|
Loading…
Reference in a new issue