fixed delete and ad comment not updating properly in contact detailsnotes

This commit is contained in:
Vaibhav Surve 2025-10-10 10:10:46 +05:30
parent acb203848e
commit bb5fdb27b2
2 changed files with 52 additions and 31 deletions

View File

@ -1,13 +1,13 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:marco/helpers/services/api_service.dart'; import 'package:marco/helpers/services/api_service.dart';
import 'package:marco/helpers/services/app_logger.dart'; import 'package:marco/helpers/services/app_logger.dart';
import 'package:marco/helpers/widgets/my_snackbar.dart';
import 'package:marco/model/directory/contact_model.dart'; import 'package:marco/model/directory/contact_model.dart';
import 'package:marco/model/directory/contact_bucket_list_model.dart'; import 'package:marco/model/directory/contact_bucket_list_model.dart';
import 'package:marco/model/directory/directory_comment_model.dart'; import 'package:marco/model/directory/directory_comment_model.dart';
import 'package:marco/helpers/widgets/my_snackbar.dart';
class DirectoryController extends GetxController { class DirectoryController extends GetxController {
// Contacts // -------------------- CONTACTS --------------------
RxList<ContactModel> allContacts = <ContactModel>[].obs; RxList<ContactModel> allContacts = <ContactModel>[].obs;
RxList<ContactModel> filteredContacts = <ContactModel>[].obs; RxList<ContactModel> filteredContacts = <ContactModel>[].obs;
RxList<ContactCategory> contactCategories = <ContactCategory>[].obs; RxList<ContactCategory> contactCategories = <ContactCategory>[].obs;
@ -18,7 +18,7 @@ class DirectoryController extends GetxController {
RxList<ContactBucket> contactBuckets = <ContactBucket>[].obs; RxList<ContactBucket> contactBuckets = <ContactBucket>[].obs;
RxString searchQuery = ''.obs; RxString searchQuery = ''.obs;
// Notes / Comments // -------------------- COMMENTS --------------------
final Map<String, RxList<DirectoryComment>> activeCommentsMap = {}; final Map<String, RxList<DirectoryComment>> activeCommentsMap = {};
final Map<String, RxList<DirectoryComment>> inactiveCommentsMap = {}; final Map<String, RxList<DirectoryComment>> inactiveCommentsMap = {};
final editingCommentId = Rxn<String>(); final editingCommentId = Rxn<String>();
@ -30,7 +30,7 @@ class DirectoryController extends GetxController {
fetchBuckets(); fetchBuckets();
} }
// -------------------- COMMENTS -------------------- // -------------------- COMMENTS HANDLING --------------------
RxList<DirectoryComment> getCommentsForContact(String contactId, {bool active = true}) { RxList<DirectoryComment> getCommentsForContact(String contactId, {bool active = true}) {
return active return active
@ -41,7 +41,14 @@ class DirectoryController extends GetxController {
Future<void> fetchCommentsForContact(String contactId, {bool active = true}) async { Future<void> fetchCommentsForContact(String contactId, {bool active = true}) async {
try { try {
final data = await ApiService.getDirectoryComments(contactId, active: active); final data = await ApiService.getDirectoryComments(contactId, active: active);
final comments = data?.map((e) => DirectoryComment.fromJson(e)).toList() ?? []; var comments = data?.map((e) => DirectoryComment.fromJson(e)).toList() ?? [];
// Deduplicate by ID before storing
final Map<String, DirectoryComment> uniqueMap = {
for (var c in comments) c.id: c,
};
comments = uniqueMap.values.toList()
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
if (active) { if (active) {
activeCommentsMap[contactId] = <DirectoryComment>[].obs..assignAll(comments); activeCommentsMap[contactId] = <DirectoryComment>[].obs..assignAll(comments);
@ -60,22 +67,30 @@ class DirectoryController extends GetxController {
} }
} }
RxList<DirectoryComment> combinedComments(String contactId) { List<DirectoryComment> combinedComments(String contactId) {
final active = getCommentsForContact(contactId, active: true).toList(); final activeList = getCommentsForContact(contactId, active: true);
final inactive = getCommentsForContact(contactId, active: false).toList(); final inactiveList = getCommentsForContact(contactId, active: false);
final combined = [...active, ...inactive] // Deduplicate by ID (active wins)
final Map<String, DirectoryComment> byId = {};
for (final c in inactiveList) {
byId[c.id] = c;
}
for (final c in activeList) {
byId[c.id] = c;
}
final combined = byId.values.toList()
..sort((a, b) => b.createdAt.compareTo(a.createdAt)); ..sort((a, b) => b.createdAt.compareTo(a.createdAt));
return combined;
return combined.obs;
} }
Future<void> updateComment(DirectoryComment comment) async { Future<void> updateComment(DirectoryComment comment) async {
try { try {
final oldComment = final existing = getCommentsForContact(comment.contactId)
getCommentsForContact(comment.contactId).firstWhereOrNull((c) => c.id == comment.id); .firstWhereOrNull((c) => c.id == comment.id);
if (oldComment != null && oldComment.note.trim() == comment.note.trim()) { if (existing != null && existing.note.trim() == comment.note.trim()) {
showAppSnackbar( showAppSnackbar(
title: "No Changes", title: "No Changes",
message: "No changes were made to the comment.", message: "No changes were made to the comment.",
@ -84,12 +99,12 @@ class DirectoryController extends GetxController {
return; return;
} }
final success = await ApiService.updateContactComment(comment.id, comment.note, comment.contactId); final success =
await ApiService.updateContactComment(comment.id, comment.note, comment.contactId);
if (success) { if (success) {
await fetchCommentsForContact(comment.contactId, active: true); await fetchCommentsForContact(comment.contactId, active: true);
await fetchCommentsForContact(comment.contactId, active: false); await fetchCommentsForContact(comment.contactId, active: false);
showAppSnackbar( showAppSnackbar(
title: "Success", title: "Success",
message: "Comment updated successfully.", message: "Comment updated successfully.",
@ -103,9 +118,8 @@ class DirectoryController extends GetxController {
); );
} }
} catch (e, stack) { } catch (e, stack) {
logSafe("Update comment failed: ${e.toString()}", level: LogLevel.error); logSafe("Update comment failed: $e", level: LogLevel.error);
logSafe(stack.toString(), level: LogLevel.debug); logSafe(stack.toString(), level: LogLevel.debug);
showAppSnackbar( showAppSnackbar(
title: "Error", title: "Error",
message: "Failed to update comment.", message: "Failed to update comment.",
@ -120,10 +134,8 @@ class DirectoryController extends GetxController {
if (success) { if (success) {
if (editingCommentId.value == commentId) editingCommentId.value = null; if (editingCommentId.value == commentId) editingCommentId.value = null;
await fetchCommentsForContact(contactId, active: true); await fetchCommentsForContact(contactId, active: true);
await fetchCommentsForContact(contactId, active: false); await fetchCommentsForContact(contactId, active: false);
showAppSnackbar( showAppSnackbar(
title: "Deleted", title: "Deleted",
message: "Comment deleted successfully.", message: "Comment deleted successfully.",
@ -139,7 +151,6 @@ class DirectoryController extends GetxController {
} catch (e, stack) { } catch (e, stack) {
logSafe("Delete comment failed: $e", level: LogLevel.error); logSafe("Delete comment failed: $e", level: LogLevel.error);
logSafe(stack.toString(), level: LogLevel.debug); logSafe(stack.toString(), level: LogLevel.debug);
showAppSnackbar( showAppSnackbar(
title: "Error", title: "Error",
message: "Something went wrong while deleting comment.", message: "Something went wrong while deleting comment.",
@ -155,7 +166,6 @@ class DirectoryController extends GetxController {
if (success) { if (success) {
await fetchCommentsForContact(contactId, active: true); await fetchCommentsForContact(contactId, active: true);
await fetchCommentsForContact(contactId, active: false); await fetchCommentsForContact(contactId, active: false);
showAppSnackbar( showAppSnackbar(
title: "Restored", title: "Restored",
message: "Comment restored successfully.", message: "Comment restored successfully.",
@ -171,7 +181,6 @@ class DirectoryController extends GetxController {
} catch (e, stack) { } catch (e, stack) {
logSafe("Restore comment failed: $e", level: LogLevel.error); logSafe("Restore comment failed: $e", level: LogLevel.error);
logSafe(stack.toString(), level: LogLevel.debug); logSafe(stack.toString(), level: LogLevel.debug);
showAppSnackbar( showAppSnackbar(
title: "Error", title: "Error",
message: "Something went wrong while restoring comment.", message: "Something went wrong while restoring comment.",
@ -180,7 +189,7 @@ class DirectoryController extends GetxController {
} }
} }
// -------------------- CONTACTS -------------------- // -------------------- CONTACTS HANDLING --------------------
Future<void> fetchBuckets() async { Future<void> fetchBuckets() async {
try { try {
@ -201,8 +210,8 @@ class DirectoryController extends GetxController {
Future<void> fetchContacts({bool active = true}) async { Future<void> fetchContacts({bool active = true}) async {
try { try {
isLoading.value = true; isLoading.value = true;
final response = await ApiService.getDirectoryData(isActive: active); final response = await ApiService.getDirectoryData(isActive: active);
if (response != null) { if (response != null) {
final contacts = response.map((e) => ContactModel.fromJson(e)).toList(); final contacts = response.map((e) => ContactModel.fromJson(e)).toList();
allContacts.assignAll(contacts); allContacts.assignAll(contacts);
@ -223,8 +232,8 @@ class DirectoryController extends GetxController {
final uniqueCategories = <String, ContactCategory>{}; final uniqueCategories = <String, ContactCategory>{};
for (final contact in allContacts) { for (final contact in allContacts) {
final category = contact.contactCategory; final category = contact.contactCategory;
if (category != null && !uniqueCategories.containsKey(category.id)) { if (category != null) {
uniqueCategories[category.id] = category; uniqueCategories.putIfAbsent(category.id, () => category);
} }
} }
contactCategories.value = uniqueCategories.values.toList(); contactCategories.value = uniqueCategories.values.toList();
@ -251,9 +260,13 @@ class DirectoryController extends GetxController {
contact.tags.any((tag) => tag.name.toLowerCase().contains(query)); contact.tags.any((tag) => tag.name.toLowerCase().contains(query));
final categoryNameMatch = final categoryNameMatch =
contact.contactCategory?.name.toLowerCase().contains(query) ?? false; contact.contactCategory?.name.toLowerCase().contains(query) ?? false;
final bucketNameMatch = contact.bucketIds.any((id) { final bucketNameMatch = contact.bucketIds.any((id) {
final bucketName = final bucketName = contactBuckets
contactBuckets.firstWhereOrNull((b) => b.id == id)?.name.toLowerCase() ?? ''; .firstWhereOrNull((b) => b.id == id)
?.name
.toLowerCase() ??
'';
return bucketName.contains(query); return bucketName.contains(query);
}); });
@ -269,8 +282,7 @@ class DirectoryController extends GetxController {
return categoryMatch && bucketMatch && searchMatch; return categoryMatch && bucketMatch && searchMatch;
}).toList(); }).toList();
filteredContacts filteredContacts.sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
.sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
} }
void toggleCategory(String categoryId) { void toggleCategory(String categoryId) {

View File

@ -69,6 +69,15 @@ class DirectoryComment {
isActive: json['isActive'] ?? true, isActive: json['isActive'] ?? true,
); );
} }
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is DirectoryComment &&
runtimeType == other.runtimeType &&
id == other.id;
@override
int get hashCode => id.hashCode;
DirectoryComment copyWith({ DirectoryComment copyWith({
String? id, String? id,