-
-
Notifications
You must be signed in to change notification settings - Fork 120
Implement message actions and message status in the new ChatView #1471
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
Conversation
|
Continuing the discussion from this comment thread #1465 (comment):
I agree that we want the newly sent message in the DB the moment it's shown on screen. But, we can delay displaying the new message until after the DB write is finished. In fact, that is the case already for message sending. So, by running the DB write on a separate thread, we avoid blocking the UI: the user can scroll up and down; and they know their message wasn't sent yet, as it still didn't show up in a chat bubble (and it probably is still visible in the input view) I think this same reasoning applies to other message actions like correction, retraction and local deletion, so I adhered to it in this PR: run the DB write on a separate thread, and only update the UI after the write is finished. |
f5af703 to
5c59276
Compare
5c59276 to
245e7c2
Compare
|
I ended up choosing an empty icon for |
Monal/Classes/ChatView.swift
Outdated
| case .copy: | ||
| defaultActionClosure(message, .copy) | ||
| case .edit: | ||
| defaultActionClosure(message, .edit { editedText in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This .edit closure is defined as Sendable in ExyteChat.
This results in the following warning on the sendMessage call a couple of lines below :
Capture of 'mlMessage' with non-sendable type 'MLMessage' in a `@Sendable` closure; this is an error in the Swift 6 language mode
Class 'MLMessage' does not conform to the 'Sendable' protocol (monalxmpp.MLMessage)
We can't make the MLMessage class Sendable (that would require it to contain only stored properties that are immutable and sendable), so I silenced the warning by declaring it @unchecked Sendable in this source file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the reasons why I din't like the direction Swift is currently moving to, it makes easy things much much harder or even impossible, even if the programmer knows what they are doing :(
Same goes for the stupid actor stuff that should ensure that ui things run on the main thread, but not detecting that we are already on the main thread.
That said, I'm not sure why the closure was defined as Sendable in the first place. @matthewrfennell do you have any insights here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matthewrfennell Do you know why this closure was defined as sendable?
Would it be possible to remove that sendable requirement upstream? That would spare us this dirty MLMessage as Sendable hack
|
Note that for messages with On the other hand, the "Resend" message action I added resends the same message (it reuses the same IDs) This means we have two, slightly different ways to resend a failed message. |
245e7c2 to
1d75594
Compare
Oh yes, good idea!
Yes, great! :) |
Why did you add a "resend" action in the first place? I think removing the old message having the error when resending using the status icon would be better, if that's easily achievable. |
Sounds sensible :) |
I did so because I thought the error status icon was too small, and that it's not obvious that it's a clickable button. (Note however that some of the area neighboring the icon to the top, right, and top-right is also clickable) |
That may be easily achievable on the ExyteChat side, but the message won't be removed from the DB, meaning it'll be shown the next time the ChatView is entered. A proper solution is to modify ExyteChat, allowing library users to provide a custom closure that is triggered when the error status icon is clicked. If you prefer clicking the error status icon over using the message actions, I can try to contribute this change to ExyteChat. (A custom make it possible to also remove the "Show Error" message action.) |
1d75594 to
cccf314
Compare
4ce6b4e to
0679810
Compare
cccf314 to
8753f19
Compare
5b3d3b0 to
0e6bc5d
Compare
yes please :) |
f92692c to
6d1997e
Compare
518a17d to
eaba046
Compare
8753f19 to
4ee957b
Compare
|
Here's how the UI for resending messages is currently implemented: Simulator_resending_failed_message.mp4Also, note that I tested the localization extraction script, and the following string is extracted successfully: |
|
Sure, I've updated the extraction script a few months ago to really build the project, so everything taking a |
tmolitor-stud-tu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only small comments
Monal/Classes/ChatView.swift
Outdated
| case .copy: | ||
| defaultActionClosure(message, .copy) | ||
| case .edit: | ||
| defaultActionClosure(message, .edit { editedText in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matthewrfennell Do you know why this closure was defined as sendable?
Would it be possible to remove that sendable requirement upstream? That would spare us this dirty MLMessage as Sendable hack
Monal/Classes/ChatView.swift
Outdated
| } | ||
| })) | ||
| } | ||
| .alert("Moderating message", isPresented: $showModeratingMessageAlert, actions: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe richAlert would be a better fit than alert? I don't know how both would look and what would look better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't try the richAlert yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is how it looks like with alert:

Though I admit it might look a bit ugly on macOS:


I didn't try richAlert because it will require a bit of refactoring to use .optionalMappedToBool() with it:
richAlert expects isPresented to be a Binding<T?> but optionalMappedToBool returns a Binding<Bool>, and the Swift compiler can't convert automatically.
The error is:
Cannot convert value of type 'Binding<Bool>' to expected argument type 'Binding<()?>'
Arguments to generic parameter 'Value' ('Bool' and '()?') are expected to be equal
You can check the invite creation view to get a feel for richAlert: its background is blurred, it has a small shadow (try it in dark mode!), and it would look the same on iOS and macOS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you don't need the optionalMappedToBool at all. The rich alert will do this internally already :) You can just use the value directly and the alert will pop up if it is not nil.
4ee957b to
0f0e9a3
Compare
by updating the DB and posting the deletion notification inside xmpp retractMessage: and by doing so asynchronously on the receiveQueue, in the same block where the retraction is sent
Support for replies or quotes will come later
0f0e9a3 to
04f101b
Compare
| to: self.contact.obj, | ||
| isEncrypted: isEncrypted, | ||
| isUpload: isUpload, | ||
| andMessageId: mlMessage.messageId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is how Xcode automatically indents multiline function arguments:
self.account.sendMessage(mlMessage.messageText,
to: self.contact.obj,
isEncrypted: isEncrypted,
isUpload: isUpload,
andMessageId: mlMessage.messageId)But if you prefer we could use 4-space indentation for the argument list instead:
self.account.sendMessage(editedText,
to: self.contact.obj,
isEncrypted: self.contact.isEncrypted || mlMessage.encrypted,
isUpload: false,
andMessageId: UUID().uuidString,
withLMCId: mlMessage.messageId
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I somewhat lean to the 4-space version. But we for sure have the XCode version in our codebase, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nearly all code written by me uses the 4-space version, though.
bc01177 to
6e8eeac
Compare

Support for replies or quotes will come later in the future, as part of another PR.