Reverting RTE to use SDK markdown when in markdown mode (#2327)

This commit is contained in:
Mauro
2024-01-12 12:58:36 +01:00
committed by GitHub
parent 2d66e76b51
commit 1001b5dc33
13 changed files with 76 additions and 32 deletions
@@ -267,8 +267,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
return return
} }
let roomProxy = await userSession.clientProxy.roomForIdentifier(roomID) let roomProxy = await userSession.clientProxy.roomForIdentifier(roomID)
let messageContent = messageEventContentFromMarkdown(md: replyText) switch await roomProxy?.timeline.sendMessage(replyText,
switch await roomProxy?.timeline.sendMessageEventContent(messageContent) { html: nil,
intentionalMentions: .empty) {
case .success: case .success:
break break
default: default:
@@ -2487,12 +2487,12 @@ class TimelineProxyMock: TimelineProxyProtocol {
var editMessageHtmlOriginalIntentionalMentionsCalled: Bool { var editMessageHtmlOriginalIntentionalMentionsCalled: Bool {
return editMessageHtmlOriginalIntentionalMentionsCallsCount > 0 return editMessageHtmlOriginalIntentionalMentionsCallsCount > 0
} }
var editMessageHtmlOriginalIntentionalMentionsReceivedArguments: (message: String, html: String, eventID: String, intentionalMentions: IntentionalMentions)? var editMessageHtmlOriginalIntentionalMentionsReceivedArguments: (message: String, html: String?, eventID: String, intentionalMentions: IntentionalMentions)?
var editMessageHtmlOriginalIntentionalMentionsReceivedInvocations: [(message: String, html: String, eventID: String, intentionalMentions: IntentionalMentions)] = [] var editMessageHtmlOriginalIntentionalMentionsReceivedInvocations: [(message: String, html: String?, eventID: String, intentionalMentions: IntentionalMentions)] = []
var editMessageHtmlOriginalIntentionalMentionsReturnValue: Result<Void, TimelineProxyError>! var editMessageHtmlOriginalIntentionalMentionsReturnValue: Result<Void, TimelineProxyError>!
var editMessageHtmlOriginalIntentionalMentionsClosure: ((String, String, String, IntentionalMentions) async -> Result<Void, TimelineProxyError>)? var editMessageHtmlOriginalIntentionalMentionsClosure: ((String, String?, String, IntentionalMentions) async -> Result<Void, TimelineProxyError>)?
func editMessage(_ message: String, html: String, original eventID: String, intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> { func editMessage(_ message: String, html: String?, original eventID: String, intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
editMessageHtmlOriginalIntentionalMentionsCallsCount += 1 editMessageHtmlOriginalIntentionalMentionsCallsCount += 1
editMessageHtmlOriginalIntentionalMentionsReceivedArguments = (message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions) editMessageHtmlOriginalIntentionalMentionsReceivedArguments = (message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions)
editMessageHtmlOriginalIntentionalMentionsReceivedInvocations.append((message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions)) editMessageHtmlOriginalIntentionalMentionsReceivedInvocations.append((message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions))
@@ -2767,12 +2767,12 @@ class TimelineProxyMock: TimelineProxyProtocol {
var sendMessageHtmlInReplyToIntentionalMentionsCalled: Bool { var sendMessageHtmlInReplyToIntentionalMentionsCalled: Bool {
return sendMessageHtmlInReplyToIntentionalMentionsCallsCount > 0 return sendMessageHtmlInReplyToIntentionalMentionsCallsCount > 0
} }
var sendMessageHtmlInReplyToIntentionalMentionsReceivedArguments: (message: String, html: String, eventID: String?, intentionalMentions: IntentionalMentions)? var sendMessageHtmlInReplyToIntentionalMentionsReceivedArguments: (message: String, html: String?, eventID: String?, intentionalMentions: IntentionalMentions)?
var sendMessageHtmlInReplyToIntentionalMentionsReceivedInvocations: [(message: String, html: String, eventID: String?, intentionalMentions: IntentionalMentions)] = [] var sendMessageHtmlInReplyToIntentionalMentionsReceivedInvocations: [(message: String, html: String?, eventID: String?, intentionalMentions: IntentionalMentions)] = []
var sendMessageHtmlInReplyToIntentionalMentionsReturnValue: Result<Void, TimelineProxyError>! var sendMessageHtmlInReplyToIntentionalMentionsReturnValue: Result<Void, TimelineProxyError>!
var sendMessageHtmlInReplyToIntentionalMentionsClosure: ((String, String, String?, IntentionalMentions) async -> Result<Void, TimelineProxyError>)? var sendMessageHtmlInReplyToIntentionalMentionsClosure: ((String, String?, String?, IntentionalMentions) async -> Result<Void, TimelineProxyError>)?
func sendMessage(_ message: String, html: String, inReplyTo eventID: String?, intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> { func sendMessage(_ message: String, html: String?, inReplyTo eventID: String?, intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
sendMessageHtmlInReplyToIntentionalMentionsCallsCount += 1 sendMessageHtmlInReplyToIntentionalMentionsCallsCount += 1
sendMessageHtmlInReplyToIntentionalMentionsReceivedArguments = (message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions) sendMessageHtmlInReplyToIntentionalMentionsReceivedArguments = (message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions)
sendMessageHtmlInReplyToIntentionalMentionsReceivedInvocations.append((message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions)) sendMessageHtmlInReplyToIntentionalMentionsReceivedInvocations.append((message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions))
@@ -31,7 +31,7 @@ enum ComposerToolbarVoiceMessageAction {
} }
enum ComposerToolbarViewModelAction { enum ComposerToolbarViewModelAction {
case sendMessage(plain: String, html: String, mode: RoomScreenComposerMode, intentionalMentions: IntentionalMentions) case sendMessage(plain: String, html: String?, mode: RoomScreenComposerMode, intentionalMentions: IntentionalMentions)
case attach(ComposerAttachmentType) case attach(ComposerAttachmentType)
case handlePasteOrDrop(provider: NSItemProvider) case handlePasteOrDrop(provider: NSItemProvider)
@@ -87,11 +87,15 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
} }
.store(in: &cancellables) .store(in: &cancellables)
appSettings.$richTextEditorEnabled
.map { !$0 }
.assign(to: &wysiwygViewModel.$plainTextMode)
completionSuggestionService.suggestionsPublisher completionSuggestionService.suggestionsPublisher
.combineLatest(appSettings.$richTextEditorEnabled)
.map { suggestions, richTextEditorEnabled in
// We ignore user suggestions when RTE is disabled since mentions would not work
guard richTextEditorEnabled else {
return []
}
return suggestions
}
.weakAssign(to: \.state.suggestions, on: self) .weakAssign(to: \.state.suggestions, on: self)
.store(in: &cancellables) .store(in: &cancellables)
@@ -111,8 +115,9 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
case .previewVoiceMessage: case .previewVoiceMessage:
actionsSubject.send(.voiceMessage(.send)) actionsSubject.send(.voiceMessage(.send))
default: default:
let sendHTML = appSettings.richTextEditorEnabled
actionsSubject.send(.sendMessage(plain: wysiwygViewModel.content.markdown, actionsSubject.send(.sendMessage(plain: wysiwygViewModel.content.markdown,
html: wysiwygViewModel.content.html, html: sendHTML ? wysiwygViewModel.content.html : nil,
mode: state.composerMode, mode: state.composerMode,
intentionalMentions: wysiwygViewModel intentionalMentions: wysiwygViewModel
.getMentionsState() .getMentionsState()
@@ -461,7 +461,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
state.showLoading = false state.showLoading = false
} }
private func sendCurrentMessage(_ message: String, html: String, mode: RoomScreenComposerMode, intentionalMentions: IntentionalMentions) async { private func sendCurrentMessage(_ message: String, html: String?, mode: RoomScreenComposerMode, intentionalMentions: IntentionalMentions) async {
guard !message.isEmpty else { guard !message.isEmpty else {
fatalError("This message should never be empty") fatalError("This message should never be empty")
} }
@@ -25,6 +25,10 @@ struct IntentionalMentions: Equatable {
} }
extension IntentionalMentions { extension IntentionalMentions {
static var empty: Self {
IntentionalMentions(userIDs: .init(), atRoom: false)
}
func toRustMentions() -> Mentions { func toRustMentions() -> Mentions {
Mentions(userIds: Array(userIDs), room: atRoom) Mentions(userIds: Array(userIDs), room: atRoom)
} }
@@ -70,14 +70,14 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
func processItemDisappearance(_ itemID: TimelineItemIdentifier) async { } func processItemDisappearance(_ itemID: TimelineItemIdentifier) async { }
func sendMessage(_ message: String, func sendMessage(_ message: String,
html: String, html: String?,
inReplyTo itemID: TimelineItemIdentifier?, inReplyTo itemID: TimelineItemIdentifier?,
intentionalMentions: IntentionalMentions) async { } intentionalMentions: IntentionalMentions) async { }
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async { } func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async { }
func editMessage(_ newMessage: String, func editMessage(_ newMessage: String,
html: String, html: String?,
original itemID: TimelineItemIdentifier, original itemID: TimelineItemIdentifier,
intentionalMentions: IntentionalMentions) async { } intentionalMentions: IntentionalMentions) async { }
@@ -114,7 +114,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
func processItemDisappearance(_ itemID: TimelineItemIdentifier) { } func processItemDisappearance(_ itemID: TimelineItemIdentifier) { }
func sendMessage(_ message: String, func sendMessage(_ message: String,
html: String, html: String?,
inReplyTo itemID: TimelineItemIdentifier?, inReplyTo itemID: TimelineItemIdentifier?,
intentionalMentions: IntentionalMentions) async { intentionalMentions: IntentionalMentions) async {
var inReplyTo: String? var inReplyTo: String?
@@ -155,7 +155,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
} }
func editMessage(_ newMessage: String, func editMessage(_ newMessage: String,
html: String, html: String?,
original itemID: TimelineItemIdentifier, original itemID: TimelineItemIdentifier,
intentionalMentions: IntentionalMentions) async { intentionalMentions: IntentionalMentions) async {
MXLog.info("Edit message in \(roomID)") MXLog.info("Edit message in \(roomID)")
@@ -52,12 +52,12 @@ protocol RoomTimelineControllerProtocol {
func sendReadReceipt(for itemID: TimelineItemIdentifier) async -> Result<Void, RoomTimelineControllerError> func sendReadReceipt(for itemID: TimelineItemIdentifier) async -> Result<Void, RoomTimelineControllerError>
func sendMessage(_ message: String, func sendMessage(_ message: String,
html: String, html: String?,
inReplyTo itemID: TimelineItemIdentifier?, inReplyTo itemID: TimelineItemIdentifier?,
intentionalMentions: IntentionalMentions) async intentionalMentions: IntentionalMentions) async
func editMessage(_ newMessage: String, func editMessage(_ newMessage: String,
html: String, html: String?,
original itemID: TimelineItemIdentifier, original itemID: TimelineItemIdentifier,
intentionalMentions: IntentionalMentions) async intentionalMentions: IntentionalMentions) async
@@ -78,7 +78,7 @@ protocol RoomTimelineControllerProtocol {
extension RoomTimelineControllerProtocol { extension RoomTimelineControllerProtocol {
func sendMessage(_ message: String, func sendMessage(_ message: String,
html: String, html: String?,
intentionalMentions: IntentionalMentions) async { intentionalMentions: IntentionalMentions) async {
await sendMessage(message, await sendMessage(message,
html: html, html: html,
@@ -96,7 +96,7 @@ final class TimelineProxy: TimelineProxyProtocol {
} }
func editMessage(_ message: String, func editMessage(_ message: String,
html: String, html: String?,
original eventID: String, original eventID: String,
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> { intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
MXLog.info("Editing message with original event ID: \(eventID)") MXLog.info("Editing message with original event ID: \(eventID)")
@@ -390,7 +390,7 @@ final class TimelineProxy: TimelineProxyProtocol {
} }
func sendMessage(_ message: String, func sendMessage(_ message: String,
html: String, html: String?,
inReplyTo eventID: String? = nil, inReplyTo eventID: String? = nil,
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> { intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
if let eventID { if let eventID {
@@ -573,7 +573,7 @@ final class TimelineProxy: TimelineProxyProtocol {
// MARK: - Private // MARK: - Private
private func buildMessageContentFor(_ message: String, private func buildMessageContentFor(_ message: String,
html: String, html: String?,
intentionalMentions: Mentions) -> RoomMessageEventContentWithoutRelation { intentionalMentions: Mentions) -> RoomMessageEventContentWithoutRelation {
let emoteSlashCommand = "/me " let emoteSlashCommand = "/me "
let isEmote: Bool = message.starts(with: emoteSlashCommand) let isEmote: Bool = message.starts(with: emoteSlashCommand)
@@ -581,10 +581,18 @@ final class TimelineProxy: TimelineProxyProtocol {
let content: RoomMessageEventContentWithoutRelation let content: RoomMessageEventContentWithoutRelation
if isEmote { if isEmote {
let emoteMessage = String(message.dropFirst(emoteSlashCommand.count)) let emoteMessage = String(message.dropFirst(emoteSlashCommand.count))
let emoteHtml = String(html.dropFirst(emoteSlashCommand.count))
var emoteHtml: String?
if let html {
emoteHtml = String(html.dropFirst(emoteSlashCommand.count))
}
content = buildEmoteMessageContentFor(emoteMessage, html: emoteHtml) content = buildEmoteMessageContentFor(emoteMessage, html: emoteHtml)
} else { } else {
content = messageEventContentFromHtml(body: message, htmlBody: html) if let html {
content = messageEventContentFromHtml(body: message, htmlBody: html)
} else {
content = messageEventContentFromMarkdown(md: message)
}
} }
return content.withMentions(mentions: intentionalMentions) return content.withMentions(mentions: intentionalMentions)
} }
@@ -51,7 +51,7 @@ protocol TimelineProxyProtocol {
func cancelSend(transactionID: String) async func cancelSend(transactionID: String) async
func editMessage(_ message: String, func editMessage(_ message: String,
html: String, html: String?,
original eventID: String, original eventID: String,
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError>
@@ -107,7 +107,7 @@ protocol TimelineProxyProtocol {
func sendMessageEventContent(_ messageContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError> func sendMessageEventContent(_ messageContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError>
func sendMessage(_ message: String, func sendMessage(_ message: String,
html: String, html: String?,
inReplyTo eventID: String?, inReplyTo eventID: String?,
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError>
@@ -125,3 +125,14 @@ protocol TimelineProxyProtocol {
func sendPollResponse(pollStartID: String, answers: [String]) async -> Result<Void, TimelineProxyError> func sendPollResponse(pollStartID: String, answers: [String]) async -> Result<Void, TimelineProxyError>
} }
extension TimelineProxyProtocol {
func sendMessage(_ message: String,
html: String?,
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
await sendMessage(message,
html: html,
inReplyTo: nil,
intentionalMentions: intentionalMentions)
}
}
@@ -179,4 +179,18 @@ class ComposerToolbarViewModelTests: XCTestCase {
try await deferred.fulfill() try await deferred.fulfill()
} }
func testSuggestionsAreIgnoredWhenRTEDisabled() async throws {
appSettings.richTextEditorEnabled = false
let suggestions: [SuggestionItem] = [.user(item: MentionSuggestionItem(id: "@user_mention_1:matrix.org", displayName: "User 1", avatarURL: nil)),
.user(item: MentionSuggestionItem(id: "@user_mention_2:matrix.org", displayName: "User 2", avatarURL: URL.documentsDirectory))]
let mockCompletionSuggestionService = CompletionSuggestionServiceMock(configuration: .init(suggestions: suggestions))
viewModel = ComposerToolbarViewModel(wysiwygViewModel: wysiwygViewModel,
completionSuggestionService: mockCompletionSuggestionService,
mediaProvider: MockMediaProvider(),
appSettings: ServiceLocator.shared.settings,
mentionDisplayHelper: ComposerMentionDisplayHelper.mock)
XCTAssertEqual(viewModel.state.suggestions, [])
}
} }
+1
View File
@@ -0,0 +1 @@
Improved plain text mode stability.