Skip to content

Edit-message (7/n): Implement edit-message methods on MessageStore #1484

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

chrisbobbe
Copy link
Collaborator

This PR, toward the edit-message feature #126, implements three new methods on MessageStore:

editMessage, to be called when the user taps the "Edit message" button in the message action sheet:

getEditMessageErrorStatus, to be called when rendering the message list; showing a loading state when we haven't gotten the update-message event yet, and an error state for a failed edit request:

image image

(The UI text isn't final; see updates on CZO: #mobile-design > edit message @ 💬)

takeFailedMessageEdit, to be called when you tap the error message pictured above, so we can put you back in the edit box, starting with the text you'd tried to edit to. This part is from CZO discussion: #mobile-design > edit message @ 💬

Related: #126

@chrisbobbe chrisbobbe added the maintainer review PR ready for review by Zulip maintainers label Apr 24, 2025
@chrisbobbe chrisbobbe requested a review from PIG208 April 24, 2025 03:12
@chrisbobbe
Copy link
Collaborator Author

chrisbobbe commented Apr 24, 2025

Marking as a draft because I still have a TODO for some tests about delete-message events. Done; ready for review!

@chrisbobbe chrisbobbe changed the title Edit-message (6/n): Implement edit-message methods on MessageStore Edit-message (7/n): Implement edit-message methods on MessageStore Apr 24, 2025
@chrisbobbe chrisbobbe marked this pull request as ready for review April 25, 2025 21:29
@chrisbobbe
Copy link
Collaborator Author

Revision pushed, this time putting the tests in test/model/message_test.dart instead of test/model/store_test.dart (but still testing against the whole PerAccountStore API, not the MessageStoreImpl substore, following the reasoning in ec9aa35).

Copy link
Member

@PIG208 PIG208 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Left some comments.

String? takeFailedMessageEdit(int messageId) {
final status = _editMessageRequests.remove(messageId);
if (status == null) {
throw StateError('called takeFailedEdit, but no edit');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this doesn't match the name of the method: takeFailedMessageEdit

Comment on lines +161 to +162
// Request has succeeded; event hasn't arrived
check(store.getEditMessageErrorStatus(message.id)).isNotNull().isFalse();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that we can be a bit more certain that the request has complete by awaiting its future. But I guess editMessage doesn't return it because the UI code doesn't need the future.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there's nothing user-facing to do when the future succeeds (we take the event as signaling edit-message success), so editMessage doesn't return it.

await updateMessage(connection, messageId: messageId, content: content);
// On success, we'll clear `status` from editMessageRequests
// when we get the event.
} catch (e) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see why an error dialog isn't needed. The error text is shown immediately when the edit request fails. I wonder if the e is something more interesting/unexpected, do we want to log it?

check(store.getEditMessageErrorStatus(message.id)).isNull();
}));

test('request failure before event arrival; take failed edit in between', () => awaitFakeAsync((async) async {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the format "request fails, then message deleted" seems preferable to me to help understand the sequence of events

check(store.getEditMessageErrorStatus(message.id)).isNull();
}));

test('takeFailedMessageEdit throws StateError when nothing to take', () => awaitFakeAsync((async) async {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a similarly useful test would be repeated editMessage calls that operate on the same message.

store = eg.store();
connection = store.connection as FakeApiConnection;
message = eg.streamMessage();
await store.addMessage(message);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can also test if the listeners are notified whenever an update is expected.

/// See also:
/// * [getEditMessageErrorStatus]
/// * [takeFailedMessageEdit]
void editMessage({required int messageId, required String content});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should document the condition when you should not call editMessage (like we do for takeFailedMessageEdit), i.e., when there is a current edit message request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintainer review PR ready for review by Zulip maintainers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants