feat(comment): improve comment submission feedback and validation messages
This commit is contained in:
parent
77e27ff98e
commit
a8c890a60d
@ -15,14 +15,15 @@ class AddCommentController extends GetxController {
|
|||||||
Future<void> submitComment() async {
|
Future<void> submitComment() async {
|
||||||
if (note.value.trim().isEmpty) {
|
if (note.value.trim().isEmpty) {
|
||||||
showAppSnackbar(
|
showAppSnackbar(
|
||||||
title: "Validation",
|
title: "Missing Comment",
|
||||||
message: "Comment cannot be empty.",
|
message: "Please enter a comment before submitting.",
|
||||||
type: SnackbarType.warning,
|
type: SnackbarType.warning,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
isSubmitting.value = true;
|
isSubmitting.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logSafe("Submitting comment for contactId: $contactId");
|
logSafe("Submitting comment for contactId: $contactId");
|
||||||
|
|
||||||
@ -34,32 +35,30 @@ class AddCommentController extends GetxController {
|
|||||||
if (success) {
|
if (success) {
|
||||||
logSafe("Comment added successfully.");
|
logSafe("Comment added successfully.");
|
||||||
|
|
||||||
// Get the directory controller
|
// Refresh UI
|
||||||
final directoryController = Get.find<DirectoryController>();
|
final directoryController = Get.find<DirectoryController>();
|
||||||
|
|
||||||
// Fetch latest comments for the contact to refresh UI
|
|
||||||
await directoryController.fetchCommentsForContact(contactId);
|
await directoryController.fetchCommentsForContact(contactId);
|
||||||
|
|
||||||
Get.back(result: true);
|
Get.back(result: true);
|
||||||
|
|
||||||
showAppSnackbar(
|
showAppSnackbar(
|
||||||
title: "Success",
|
title: "Comment Added",
|
||||||
message: "Comment added successfully.",
|
message: "Your comment has been successfully added.",
|
||||||
type: SnackbarType.success,
|
type: SnackbarType.success,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
logSafe("Comment submission failed", level: LogLevel.error);
|
logSafe("Comment submission failed", level: LogLevel.error);
|
||||||
showAppSnackbar(
|
showAppSnackbar(
|
||||||
title: "Error",
|
title: "Submission Failed",
|
||||||
message: "Failed to add comment.",
|
message: "Unable to add the comment. Please try again later.",
|
||||||
type: SnackbarType.error,
|
type: SnackbarType.error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logSafe("Error while submitting comment: $e", level: LogLevel.error);
|
logSafe("Error while submitting comment: $e", level: LogLevel.error);
|
||||||
showAppSnackbar(
|
showAppSnackbar(
|
||||||
title: "Error",
|
title: "Unexpected Error",
|
||||||
message: "Something went wrong.",
|
message: "Something went wrong while adding your comment.",
|
||||||
type: SnackbarType.error,
|
type: SnackbarType.error,
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -23,7 +23,6 @@ class _AddCommentBottomSheetState extends State<AddCommentBottomSheet> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
controller = Get.put(AddCommentController(contactId: widget.contactId));
|
controller = Get.put(AddCommentController(contactId: widget.contactId));
|
||||||
// Initialize empty editor for new comment
|
|
||||||
quillController = quill.QuillController.basic();
|
quillController = quill.QuillController.basic();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +42,11 @@ class _AddCommentBottomSheetState extends State<AddCommentBottomSheet> {
|
|||||||
color: Theme.of(context).cardColor,
|
color: Theme.of(context).cardColor,
|
||||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
|
borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
|
||||||
boxShadow: const [
|
boxShadow: const [
|
||||||
BoxShadow(color: Colors.black12, blurRadius: 12, offset: Offset(0, -2)),
|
BoxShadow(
|
||||||
|
color: Colors.black12,
|
||||||
|
blurRadius: 12,
|
||||||
|
offset: Offset(0, -2),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@ -67,12 +70,11 @@ class _AddCommentBottomSheetState extends State<AddCommentBottomSheet> {
|
|||||||
CommentEditorCard(
|
CommentEditorCard(
|
||||||
controller: quillController,
|
controller: quillController,
|
||||||
onCancel: () => Get.back(),
|
onCancel: () => Get.back(),
|
||||||
onSave: (controller) async {
|
onSave: (editorController) async {
|
||||||
final delta = controller.document.toDelta();
|
final delta = editorController.document.toDelta();
|
||||||
final htmlOutput = _convertDeltaToHtml(delta);
|
final htmlOutput = _convertDeltaToHtml(delta);
|
||||||
this.controller.updateNote(htmlOutput);
|
controller.updateNote(htmlOutput);
|
||||||
await this.controller.submitComment();
|
await controller.submitComment();
|
||||||
if (mounted) Get.back();
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -81,62 +83,54 @@ class _AddCommentBottomSheetState extends State<AddCommentBottomSheet> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
String _convertDeltaToHtml(dynamic delta) {
|
String _convertDeltaToHtml(dynamic delta) {
|
||||||
final buffer = StringBuffer();
|
final buffer = StringBuffer();
|
||||||
bool inList = false;
|
bool inList = false;
|
||||||
|
|
||||||
for (var op in delta.toList()) {
|
for (var op in delta.toList()) {
|
||||||
final data = op.data?.toString() ?? '';
|
final data = op.data?.toString() ?? '';
|
||||||
final attr = op.attributes ?? {};
|
final attr = op.attributes ?? {};
|
||||||
|
|
||||||
final isListItem = attr.containsKey('list');
|
final isListItem = attr.containsKey('list');
|
||||||
|
final trimmedData = data.trim();
|
||||||
|
|
||||||
// Start <ul> if list item starts
|
if (isListItem && !inList) {
|
||||||
if (isListItem && !inList) {
|
buffer.write('<ul>');
|
||||||
buffer.write('<ul>');
|
inList = true;
|
||||||
inList = true;
|
}
|
||||||
|
|
||||||
|
if (!isListItem && inList) {
|
||||||
|
buffer.write('</ul>');
|
||||||
|
inList = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isListItem && trimmedData.isEmpty) continue;
|
||||||
|
|
||||||
|
if (isListItem) buffer.write('<li>');
|
||||||
|
|
||||||
|
if (attr.containsKey('bold')) buffer.write('<strong>');
|
||||||
|
if (attr.containsKey('italic')) buffer.write('<em>');
|
||||||
|
if (attr.containsKey('underline')) buffer.write('<u>');
|
||||||
|
if (attr.containsKey('strike')) buffer.write('<s>');
|
||||||
|
if (attr.containsKey('link')) buffer.write('<a href="${attr['link']}">');
|
||||||
|
|
||||||
|
buffer.write(trimmedData.replaceAll('\n', ''));
|
||||||
|
|
||||||
|
if (attr.containsKey('link')) buffer.write('</a>');
|
||||||
|
if (attr.containsKey('strike')) buffer.write('</s>');
|
||||||
|
if (attr.containsKey('underline')) buffer.write('</u>');
|
||||||
|
if (attr.containsKey('italic')) buffer.write('</em>');
|
||||||
|
if (attr.containsKey('bold')) buffer.write('</strong>');
|
||||||
|
|
||||||
|
if (isListItem) {
|
||||||
|
buffer.write('</li>');
|
||||||
|
} else if (data.contains('\n')) {
|
||||||
|
buffer.write('<br>');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close <ul> if list ended
|
if (inList) buffer.write('</ul>');
|
||||||
if (!isListItem && inList) {
|
return buffer.toString();
|
||||||
buffer.write('</ul>');
|
|
||||||
inList = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip empty list items
|
|
||||||
final trimmedData = data.trim();
|
|
||||||
if (isListItem && trimmedData.isEmpty) {
|
|
||||||
// don't write empty <li>
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isListItem) buffer.write('<li>');
|
|
||||||
|
|
||||||
if (attr.containsKey('bold')) buffer.write('<strong>');
|
|
||||||
if (attr.containsKey('italic')) buffer.write('<em>');
|
|
||||||
if (attr.containsKey('underline')) buffer.write('<u>');
|
|
||||||
if (attr.containsKey('strike')) buffer.write('<s>');
|
|
||||||
if (attr.containsKey('link')) buffer.write('<a href="${attr['link']}">');
|
|
||||||
|
|
||||||
// Use trimmedData instead of raw data (removes trailing/leading spaces/newlines)
|
|
||||||
buffer.write(trimmedData.replaceAll('\n', ''));
|
|
||||||
|
|
||||||
if (attr.containsKey('link')) buffer.write('</a>');
|
|
||||||
if (attr.containsKey('strike')) buffer.write('</s>');
|
|
||||||
if (attr.containsKey('underline')) buffer.write('</u>');
|
|
||||||
if (attr.containsKey('italic')) buffer.write('</em>');
|
|
||||||
if (attr.containsKey('bold')) buffer.write('</strong>');
|
|
||||||
|
|
||||||
if (isListItem) {
|
|
||||||
buffer.write('</li>');
|
|
||||||
} else if (data.contains('\n')) {
|
|
||||||
buffer.write('<br>');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inList) buffer.write('</ul>');
|
|
||||||
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user