Release 2.0.0

This commit is contained in:
Frank Rotermund
2022-11-27 13:18:53 +00:00
parent bf57719009
commit 0dc8ec0982
570 changed files with 20366 additions and 4410 deletions
@@ -21,7 +21,7 @@ extension RoomDataSource {
private enum Constants {
static let emoteMessageSlashCommandPrefix = String(format: "%@ ", kMXKSlashCmdEmote)
}
// MARK: - NSAttributedString Sending
/// Send a text message to the room.
/// While sending, a fake event will be echoed in the messages list.
@@ -33,7 +33,7 @@ extension RoomDataSource {
func sendAttributedTextMessage(_ attributedText: NSAttributedString,
completion: @escaping (MXResponse<String?>) -> Void) {
var localEcho: MXEvent?
let isEmote = isAttributedTextMessageAnEmote(attributedText)
let sanitized = sanitizedAttributedMessageText(attributedText)
let rawText: String
@@ -43,7 +43,7 @@ extension RoomDataSource {
} else {
rawText = sanitized.string
}
if isEmote {
room.sendEmote(rawText,
formattedText: html,
@@ -57,13 +57,38 @@ extension RoomDataSource {
localEcho: &localEcho,
completion: completion)
}
if localEcho != nil {
self.queueEvent(forProcessing: localEcho, with: self.roomState, direction: .forwards)
self.processQueuedEvents(nil)
}
}
// MARK: - NSAttributedString Sending
/// Send a text message to the room.
/// While sending, a fake event will be echoed in the messages list.
/// Once complete, this local echo will be replaced by the event saved by the homeserver.
///
/// - Parameters:
/// - rawText: the raw text to send
/// - html: the formatted html to send
/// - completion: http operation completion block
func sendFormattedTextMessage(_ rawText: String,
html: String,
completion: @escaping (MXResponse<String?>) -> Void) {
var localEcho: MXEvent?
room.sendTextMessage(rawText,
formattedText: html,
threadId: self.threadId,
localEcho: &localEcho,
completion: completion)
if localEcho != nil {
self.queueEvent(forProcessing: localEcho, with: self.roomState, direction: .forwards)
self.processQueuedEvents(nil)
}
}
/// Send a reply to an event with text message to the room.
///
/// While sending, a fake event will be echoed in the messages list.
@@ -76,8 +101,6 @@ extension RoomDataSource {
func sendReply(to eventToReply: MXEvent,
withAttributedTextMessage attributedText: NSAttributedString,
completion: @escaping (MXResponse<String?>) -> Void) {
var localEcho: MXEvent?
let sanitized = sanitizedAttributedMessageText(attributedText)
let rawText: String
let html: String? = htmlMessageFromSanitizedAttributedText(sanitized)
@@ -86,23 +109,29 @@ extension RoomDataSource {
} else {
rawText = sanitized.string
}
let stringLocalizer: MXSendReplyEventStringLocalizerProtocol = MXKSendReplyEventStringLocalizer()
room.sendReply(to: eventToReply,
textMessage: rawText,
formattedTextMessage: html,
stringLocalizer: stringLocalizer,
threadId: self.threadId,
localEcho: &localEcho,
completion: completion)
if localEcho != nil {
self.queueEvent(forProcessing: localEcho, with: self.roomState, direction: .forwards)
self.processQueuedEvents(nil)
}
handleFormattedSendReply(to: eventToReply, rawText: rawText, html: html, completion: completion)
}
/// Send a reply to an event with a html formatted text message to the room.
///
/// While sending, a fake event will be echoed in the messages list.
/// Once complete, this local echo will be replaced by the event saved by the homeserver.
///
/// - Parameters:
/// - eventToReply: the event to reply
/// - rawText: the raw text to send
/// - htmlText: the html text to send
/// - completion: http operation completion block
func sendReply(to eventToReply: MXEvent,
rawText: String,
htmlText: String,
completion: @escaping (MXResponse<String?>) -> Void) {
handleFormattedSendReply(to: eventToReply, rawText: rawText, html: htmlText, completion: completion)
}
/// Replace a text in an event.
///
/// - Parameters:
@@ -122,29 +151,24 @@ extension RoomDataSource {
} else {
rawText = sanitized.string
}
let eventBody = event.content[kMXMessageBodyKey] as? String
let eventFormattedBody = event.content["formatted_body"] as? String
if rawText != eventBody && (eventFormattedBody == nil || html != eventFormattedBody) {
self.mxSession.aggregations.replaceTextMessageEvent(
event,
withTextMessage: rawText,
formattedText: html,
localEcho: { localEcho in
// Apply the local echo to the timeline
self.updateEvent(withReplace: localEcho)
// Integrate the replace local event into the timeline like when sending a message
// This also allows to manage read receipt on this replace event
self.queueEvent(forProcessing: localEcho, with: self.roomState, direction: .forwards)
self.processQueuedEvents(nil)
},
success: success,
failure: failure)
} else {
failure(nil)
}
handleReplaceFormattedMessage(for: event, rawText: rawText, html: html, success: success, failure: failure)
}
/// Replace a formatted html text in an event
///
/// - Parameters:
/// - event: The event to replace
/// - rawText: The new rawText
/// - html: The new html text
/// - success: A block object called when the operation succeeds. It returns the event id of the event generated on the homeserver
/// - failure: A block object called when the operation fails
func replaceFormattedTextMessage( for event: MXEvent,
rawText: String,
html: String,
success: @escaping ((String?) -> Void),
failure: @escaping ((Error?) -> Void)) {
handleReplaceFormattedMessage(for: event, rawText: rawText, html: html, success: success, failure: failure)
}
/// Retrieve editable attributed text message from an event.
@@ -197,8 +221,10 @@ extension RoomDataSource {
return editableTextMessage
}
@objc func editableHtmlTextMessage(for event: MXEvent) -> String {
event.content["formatted_body"] as? String ?? event.content["body"] as? String ?? ""
}
}
// MARK: - Private Helpers
@@ -232,4 +258,54 @@ private extension RoomDataSource {
func isAttributedTextMessageAnEmote(_ attributedText: NSAttributedString) -> Bool {
return attributedText.string.starts(with: Constants.emoteMessageSlashCommandPrefix)
}
func handleReplaceFormattedMessage(for event: MXEvent,
rawText: String,
html: String?,
success: @escaping ((String?) -> Void),
failure: @escaping ((Error?) -> Void)) {
let eventBody = event.content[kMXMessageBodyKey] as? String
let eventFormattedBody = event.content["formatted_body"] as? String
if rawText != eventBody && (eventFormattedBody == nil || html != eventFormattedBody) {
self.mxSession.aggregations.replaceTextMessageEvent(
event,
withTextMessage: rawText,
formattedText: html,
localEcho: { localEcho in
// Apply the local echo to the timeline
self.updateEvent(withReplace: localEcho)
// Integrate the replace local event into the timeline like when sending a message
// This also allows to manage read receipt on this replace event
self.queueEvent(forProcessing: localEcho, with: self.roomState, direction: .forwards)
self.processQueuedEvents(nil)
},
success: success,
failure: failure)
} else {
failure(nil)
}
}
func handleFormattedSendReply(to eventToReply: MXEvent,
rawText: String,
html: String?,
completion: @escaping (MXResponse<String?>) -> Void) {
var localEcho: MXEvent?
let stringLocalizer: MXSendReplyEventStringLocalizerProtocol = MXKSendReplyEventStringLocalizer()
room.sendReply(to: eventToReply,
textMessage: rawText,
formattedTextMessage: html,
stringLocalizer: stringLocalizer,
threadId: self.threadId,
localEcho: &localEcho,
completion: completion)
if localEcho != nil {
self.queueEvent(forProcessing: localEcho, with: self.roomState, direction: .forwards)
self.processQueuedEvents(nil)
}
}
}