Skip to content

Commit 36baffe

Browse files
delete a comment feature (#47)
* delete a comment feature * fix import
1 parent 3371c12 commit 36baffe

3 files changed

Lines changed: 154 additions & 51 deletions

File tree

lib/presentation/common/activity/view_model/activity_item_comments_view_model.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import 'package:flutter/material.dart';
22
import 'package:hooks_riverpod/hooks_riverpod.dart';
33

4+
import '../../../../core/utils/storage_utils.dart';
45
import '../../../../data/repositories/activity_repository_impl.dart';
56
import '../../../../domain/entities/activity.dart';
67
import '../../../../domain/entities/activity_comment.dart';
8+
import '../../../../domain/entities/user.dart';
79
import '../../core/enums/infinite_scroll_list.enum.dart';
810
import '../../core/utils/activity_utils.dart';
911
import '../../core/widgets/view_model/infinite_scroll_list_view_model.dart';
@@ -37,6 +39,7 @@ class ActivityItemCommentsViewModel
3739

3840
/// Comment the activity.
3941
Future<void> comment(Activity activity) async {
42+
state = state.copyWith(isLoading: true);
4043
ActivityComment? activityComment = await ref
4144
.read(activityRepositoryProvider)
4245
.createComment(activity.id, commentController.text);
@@ -59,5 +62,40 @@ class ActivityItemCommentsViewModel
5962
InfiniteScrollListEnum.community.toString(),
6063
).notifier)
6164
.replaceData(updatedActivities);
65+
state = state.copyWith(isLoading: false);
66+
}
67+
68+
/// Remove the comment
69+
Future<void> removeActivityComment(String id, Activity activity) async {
70+
state = state.copyWith(isLoading: true);
71+
72+
ref.read(activityRepositoryProvider).removeComment(id: id).then((value) {
73+
List<ActivityComment> updatedComments = List.from(state.comments);
74+
updatedComments.removeWhere((comment) => comment.id == id);
75+
76+
List<List<Activity>> activities = ref
77+
.read(infiniteScrollListViewModelProvider(
78+
InfiniteScrollListEnum.community.toString(),
79+
))
80+
.data as List<List<Activity>>;
81+
82+
var updatedActivities = ActivityUtils.replaceActivity(
83+
activities, activity.copy(comments: updatedComments));
84+
85+
ref
86+
.read(infiniteScrollListViewModelProvider(
87+
InfiniteScrollListEnum.community.toString(),
88+
).notifier)
89+
.replaceData(updatedActivities);
90+
91+
state = state.copyWith(comments: updatedComments, isLoading: false);
92+
}).catchError((error) {
93+
state = state.copyWith(isLoading: false);
94+
});
95+
}
96+
97+
//get current user
98+
Future<User?> getCurrentUser() async {
99+
return await StorageUtils.getUser();
62100
}
63101
}

lib/presentation/common/activity/view_model/state/activity_item_comments_state.dart

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,27 @@ import '../../../../../domain/entities/activity_comment.dart';
44
class ActivityItemCommentsState {
55
final bool displayPreviousComments;
66
final List<ActivityComment> comments;
7+
final bool isLoading;
78

89
const ActivityItemCommentsState(
9-
{required this.displayPreviousComments, required this.comments});
10+
{required this.displayPreviousComments,
11+
required this.comments,
12+
required this.isLoading});
1013

1114
/// Factory method to create the initial state.
1215
factory ActivityItemCommentsState.initial() {
1316
return const ActivityItemCommentsState(
14-
displayPreviousComments: false, comments: []);
17+
displayPreviousComments: false, comments: [], isLoading: false);
1518
}
1619

1720
ActivityItemCommentsState copyWith(
18-
{bool? displayPreviousComments, List<ActivityComment>? comments}) {
21+
{bool? displayPreviousComments,
22+
List<ActivityComment>? comments,
23+
bool? isLoading}) {
1924
return ActivityItemCommentsState(
2025
displayPreviousComments:
2126
displayPreviousComments ?? this.displayPreviousComments,
22-
comments: comments ?? this.comments);
27+
comments: comments ?? this.comments,
28+
isLoading: isLoading ?? this.isLoading);
2329
}
2430
}

lib/presentation/common/activity/widgets/activity_comments.dart

Lines changed: 106 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import 'package:comment_box/comment/comment.dart';
44
import 'package:flutter/material.dart';
55
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
66
import 'package:hooks_riverpod/hooks_riverpod.dart';
7+
import 'package:quickalert/quickalert.dart';
8+
import '../../core/utils/ui_utils.dart';
79

810
import '../../../../core/utils/storage_utils.dart';
911
import '../../../../domain/entities/activity.dart';
@@ -43,32 +45,86 @@ class ActivityComments extends HookConsumerWidget {
4345

4446
Widget buildCommentList(
4547
WidgetRef ref,
48+
ActivityItemCommentsViewModel provider,
4649
List<ActivityComment> comments,
4750
) {
4851
return Expanded(
4952
child: ListView.builder(
5053
itemCount: comments.length,
51-
itemBuilder: (context, index) => buildCommentItem(ref, comments[index]),
54+
itemBuilder: (context, index) =>
55+
buildCommentItem(ref, provider, comments[index]),
5256
),
5357
);
5458
}
5559

56-
Widget buildCommentItem(WidgetRef ref, ActivityComment comment) {
57-
final profilePicture = ref
58-
.watch(profilePictureViewModelProvider(comment.user.id))
59-
.profilePicture;
60-
return Padding(
61-
padding: const EdgeInsets.fromLTRB(2.0, 8.0, 2.0, 0.0),
62-
child: ListTile(
63-
leading: buildUserAvatar(ref, comment.user, profilePicture),
64-
title: GestureDetector(
65-
child: Text(
66-
UserUtils.getNameOrUsername(comment.user),
67-
style: const TextStyle(),
68-
),
69-
),
70-
subtitle: Text(comment.content),
71-
),
60+
Widget buildCommentItem(WidgetRef ref, ActivityItemCommentsViewModel provider,
61+
ActivityComment comment) {
62+
return FutureBuilder<User?>(
63+
future: provider.getCurrentUser(),
64+
builder: (context, snapshot) {
65+
if (snapshot.connectionState == ConnectionState.waiting) {
66+
return Center(child: UIUtils.loader);
67+
} else if (snapshot.hasError) {
68+
return Text('Error: ${snapshot.error}');
69+
} else {
70+
final currentUser = snapshot.data!;
71+
final profilePicture = ref
72+
.watch(profilePictureViewModelProvider(comment.user.id))
73+
.profilePicture;
74+
75+
return Padding(
76+
padding: const EdgeInsets.fromLTRB(2.0, 8.0, 2.0, 0.0),
77+
child: ListTile(
78+
leading: buildUserAvatar(ref, comment.user, profilePicture),
79+
title: GestureDetector(
80+
child: Text(
81+
UserUtils.getNameOrUsername(comment.user),
82+
style: const TextStyle(),
83+
),
84+
),
85+
subtitle: Row(
86+
children: [
87+
Expanded(
88+
child: Text(
89+
comment.content,
90+
overflow: TextOverflow.visible,
91+
),
92+
),
93+
const Spacer(),
94+
if (currentUser.id == comment.user.id)
95+
IconButton(
96+
color: ColorUtils.black,
97+
tooltip: 'Remove',
98+
onPressed: () {
99+
QuickAlert.show(
100+
context: ref.context,
101+
type: QuickAlertType.confirm,
102+
title: AppLocalizations.of(ref.context)!
103+
.ask_activity_removal,
104+
confirmBtnText:
105+
AppLocalizations.of(ref.context)!.delete,
106+
cancelBtnText:
107+
AppLocalizations.of(ref.context)!.cancel,
108+
confirmBtnColor: ColorUtils.red,
109+
onCancelBtnTap: () => Navigator.of(ref.context).pop(),
110+
onConfirmBtnTap: () {
111+
Navigator.of(ref.context).pop();
112+
provider.removeActivityComment(
113+
comment.id, currentActivity);
114+
},
115+
);
116+
},
117+
icon: Icon(
118+
Icons.delete,
119+
color: ColorUtils.red,
120+
),
121+
)
122+
],
123+
),
124+
),
125+
);
126+
}
127+
},
72128
);
73129
}
74130

@@ -102,8 +158,8 @@ class ActivityComments extends HookConsumerWidget {
102158
if (comments.length > 1 && !displayPreviousComments)
103159
buildViewPreviousComments(provider, appLocalizations, comments),
104160
if (lastComment != null && !displayPreviousComments)
105-
buildCommentItem(ref, lastComment),
106-
if (displayPreviousComments) buildCommentList(ref, comments),
161+
buildCommentItem(ref, provider, lastComment),
162+
if (displayPreviousComments) buildCommentList(ref, provider, comments),
107163
],
108164
);
109165
}
@@ -139,33 +195,36 @@ class ActivityComments extends HookConsumerWidget {
139195
ref.watch(activityItemCommentsViewModelProvider(currentActivity.id));
140196
final appLocalizations = AppLocalizations.of(context)!;
141197

142-
return SizedBox(
143-
height: state.comments.isNotEmpty ? 210 : 80,
144-
child: CommentBox(
145-
userImage: currentUserPictureProvider.when(
146-
data: (userId) {
147-
if (userId != null) {
148-
final profilePicture = ref
149-
.watch(profilePictureViewModelProvider(userId))
150-
.profilePicture;
151-
return profilePicture != null
152-
? MemoryImage(profilePicture)
153-
: null;
154-
}
155-
return null;
156-
},
157-
loading: () => null,
158-
error: (_, __) => null,
159-
),
160-
sendButtonMethod: () => commentsProvider.comment(currentActivity),
161-
formKey: formKey,
162-
commentController: commentsProvider.commentController,
163-
backgroundColor: ColorUtils.white,
164-
textColor: ColorUtils.mainMedium,
165-
sendWidget: Icon(Icons.send_sharp, size: 30, color: ColorUtils.main),
166-
child: buildCommentChild(ref, appLocalizations, commentsProvider,
167-
state.comments, state.displayPreviousComments),
168-
),
169-
);
198+
return state.isLoading
199+
? Center(child: UIUtils.loader)
200+
: SizedBox(
201+
height: state.comments.isNotEmpty ? 210 : 80,
202+
child: CommentBox(
203+
userImage: currentUserPictureProvider.when(
204+
data: (userId) {
205+
if (userId != null) {
206+
final profilePicture = ref
207+
.watch(profilePictureViewModelProvider(userId))
208+
.profilePicture;
209+
return profilePicture != null
210+
? MemoryImage(profilePicture)
211+
: null;
212+
}
213+
return null;
214+
},
215+
loading: () => null,
216+
error: (_, __) => null,
217+
),
218+
sendButtonMethod: () => commentsProvider.comment(currentActivity),
219+
formKey: formKey,
220+
commentController: commentsProvider.commentController,
221+
backgroundColor: ColorUtils.white,
222+
textColor: ColorUtils.mainMedium,
223+
sendWidget:
224+
Icon(Icons.send_sharp, size: 30, color: ColorUtils.main),
225+
child: buildCommentChild(ref, appLocalizations, commentsProvider,
226+
state.comments, state.displayPreviousComments),
227+
),
228+
);
170229
}
171230
}

0 commit comments

Comments
 (0)