Skip to content
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

Refactor theTimelineItemIdentifier handling #3418

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ElementX.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@
86F9D3028A1F4AE819D75560 /* RoomChangePermissionsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D879FC4E881E748BB9B34DC /* RoomChangePermissionsScreenCoordinator.swift */; };
872A6457DF573AF8CEAE927A /* LoginHomeserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9349F590E35CE514A71E6764 /* LoginHomeserver.swift */; };
874FEFB9D4A4AF447E0E086E /* AuthenticationStartScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F7CCC4A9D1927223F559D5 /* AuthenticationStartScreenViewModelProtocol.swift */; };
877D3CE8680536DB430DE6A2 /* TimelineItemIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = E48C91C8BE55CAE1A3DBC3BC /* TimelineItemIdentifier.swift */; };
878070573C7BF19E735707B4 /* RoomTimelineItemProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DE8D25D6A91030175D52A20 /* RoomTimelineItemProperties.swift */; };
87B4E59A4467F8EC75F82372 /* VoiceMessageRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70A50C41C5871B4DB905E7E /* VoiceMessageRoomTimelineView.swift */; };
87CEA3E07B602705BC2D2A20 /* ClientBuilderHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC0CD1CAFD3F8B057F9AEA5 /* ClientBuilderHook.swift */; };
Expand Down Expand Up @@ -2189,6 +2190,7 @@
E44E35AA87F49503E7B3BF6E /* AudioConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioConverter.swift; sourceTree = "<group>"; };
E45EBAFF1A83538D54ABDF92 /* ServerSelectionScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenViewModelTests.swift; sourceTree = "<group>"; };
E461B3C8BBBFCA400B268D14 /* AppRouteURLParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouteURLParserTests.swift; sourceTree = "<group>"; };
E48C91C8BE55CAE1A3DBC3BC /* TimelineItemIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemIdentifier.swift; sourceTree = "<group>"; };
E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
E53BFB7E4F329621C844E8C3 /* AnalyticsPromptScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptScreen.swift; sourceTree = "<group>"; };
E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsProxyProtocol.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5473,6 +5475,7 @@
0DF5CBAF69BDF5DF31C661E1 /* IntentionalMentions.swift */,
66F2402D738694F98729A441 /* RoomTimelineProvider.swift */,
095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */,
E48C91C8BE55CAE1A3DBC3BC /* TimelineItemIdentifier.swift */,
2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */,
55AEEF8142DF1B59DB40FB93 /* TimelineItemSender.swift */,
F9E543072DE58E751F028998 /* TimelineProxy.swift */,
Expand Down Expand Up @@ -6931,6 +6934,7 @@
E6FA87F773424B27614B23E9 /* TimelineItemAccessibilityModifier.swift in Sources */,
79959F8E45C3749997482A7F /* TimelineItemBubbledStylerView.swift in Sources */,
A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */,
877D3CE8680536DB430DE6A2 /* TimelineItemIdentifier.swift in Sources */,
C0B97FFEC0083F3A36609E61 /* TimelineItemMacContextMenu.swift in Sources */,
6C98153D60FF9B648C166C27 /* TimelineItemMenu.swift in Sources */,
AE07F215EBC2B9CBF17AA54B /* TimelineItemMenuAction.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions ElementX/Sources/Application/AppCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg

switch await roomProxy.timeline.sendMessage(replyText,
html: nil,
inReplyToEventID: nil,
intentionalMentions: .empty) {
case .success:
break
Expand Down
62 changes: 31 additions & 31 deletions ElementX/Sources/Mocks/Generated/GeneratedMocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13987,8 +13987,8 @@ class TimelineProxyMock: TimelineProxyProtocol {
var editNewContentCalled: Bool {
return editNewContentCallsCount > 0
}
var editNewContentReceivedArguments: (timelineItem: EventTimelineItem, newContent: RoomMessageEventContentWithoutRelation)?
var editNewContentReceivedInvocations: [(timelineItem: EventTimelineItem, newContent: RoomMessageEventContentWithoutRelation)] = []
var editNewContentReceivedArguments: (eventOrTransactionID: EventOrTransactionId, newContent: RoomMessageEventContentWithoutRelation)?
var editNewContentReceivedInvocations: [(eventOrTransactionID: EventOrTransactionId, newContent: RoomMessageEventContentWithoutRelation)] = []

var editNewContentUnderlyingReturnValue: Result<Void, TimelineProxyError>!
var editNewContentReturnValue: Result<Void, TimelineProxyError>! {
Expand All @@ -14014,16 +14014,16 @@ class TimelineProxyMock: TimelineProxyProtocol {
}
}
}
var editNewContentClosure: ((EventTimelineItem, RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError>)?
var editNewContentClosure: ((EventOrTransactionId, RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError>)?

func edit(_ timelineItem: EventTimelineItem, newContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError> {
func edit(_ eventOrTransactionID: EventOrTransactionId, newContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError> {
editNewContentCallsCount += 1
editNewContentReceivedArguments = (timelineItem: timelineItem, newContent: newContent)
editNewContentReceivedArguments = (eventOrTransactionID: eventOrTransactionID, newContent: newContent)
DispatchQueue.main.async {
self.editNewContentReceivedInvocations.append((timelineItem: timelineItem, newContent: newContent))
self.editNewContentReceivedInvocations.append((eventOrTransactionID: eventOrTransactionID, newContent: newContent))
}
if let editNewContentClosure = editNewContentClosure {
return await editNewContentClosure(timelineItem, newContent)
return await editNewContentClosure(eventOrTransactionID, newContent)
} else {
return editNewContentReturnValue
}
Expand Down Expand Up @@ -14770,72 +14770,72 @@ class TimelineProxyMock: TimelineProxyProtocol {
}
//MARK: - sendMessage

var sendMessageHtmlInReplyToIntentionalMentionsUnderlyingCallsCount = 0
var sendMessageHtmlInReplyToIntentionalMentionsCallsCount: Int {
var sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingCallsCount = 0
var sendMessageHtmlInReplyToEventIDIntentionalMentionsCallsCount: Int {
get {
if Thread.isMainThread {
return sendMessageHtmlInReplyToIntentionalMentionsUnderlyingCallsCount
return sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = sendMessageHtmlInReplyToIntentionalMentionsUnderlyingCallsCount
returnValue = sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingCallsCount
}

return returnValue!
}
}
set {
if Thread.isMainThread {
sendMessageHtmlInReplyToIntentionalMentionsUnderlyingCallsCount = newValue
sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
sendMessageHtmlInReplyToIntentionalMentionsUnderlyingCallsCount = newValue
sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingCallsCount = newValue
}
}
}
}
var sendMessageHtmlInReplyToIntentionalMentionsCalled: Bool {
return sendMessageHtmlInReplyToIntentionalMentionsCallsCount > 0
var sendMessageHtmlInReplyToEventIDIntentionalMentionsCalled: Bool {
return sendMessageHtmlInReplyToEventIDIntentionalMentionsCallsCount > 0
}
var sendMessageHtmlInReplyToIntentionalMentionsReceivedArguments: (message: String, html: String?, eventID: String?, intentionalMentions: IntentionalMentions)?
var sendMessageHtmlInReplyToIntentionalMentionsReceivedInvocations: [(message: String, html: String?, eventID: String?, intentionalMentions: IntentionalMentions)] = []
var sendMessageHtmlInReplyToEventIDIntentionalMentionsReceivedArguments: (message: String, html: String?, inReplyToEventID: String?, intentionalMentions: IntentionalMentions)?
var sendMessageHtmlInReplyToEventIDIntentionalMentionsReceivedInvocations: [(message: String, html: String?, inReplyToEventID: String?, intentionalMentions: IntentionalMentions)] = []

var sendMessageHtmlInReplyToIntentionalMentionsUnderlyingReturnValue: Result<Void, TimelineProxyError>!
var sendMessageHtmlInReplyToIntentionalMentionsReturnValue: Result<Void, TimelineProxyError>! {
var sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingReturnValue: Result<Void, TimelineProxyError>!
var sendMessageHtmlInReplyToEventIDIntentionalMentionsReturnValue: Result<Void, TimelineProxyError>! {
get {
if Thread.isMainThread {
return sendMessageHtmlInReplyToIntentionalMentionsUnderlyingReturnValue
return sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingReturnValue
} else {
var returnValue: Result<Void, TimelineProxyError>? = nil
DispatchQueue.main.sync {
returnValue = sendMessageHtmlInReplyToIntentionalMentionsUnderlyingReturnValue
returnValue = sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingReturnValue
}

return returnValue!
}
}
set {
if Thread.isMainThread {
sendMessageHtmlInReplyToIntentionalMentionsUnderlyingReturnValue = newValue
sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
sendMessageHtmlInReplyToIntentionalMentionsUnderlyingReturnValue = newValue
sendMessageHtmlInReplyToEventIDIntentionalMentionsUnderlyingReturnValue = newValue
}
}
}
}
var sendMessageHtmlInReplyToIntentionalMentionsClosure: ((String, String?, String?, IntentionalMentions) async -> Result<Void, TimelineProxyError>)?
var sendMessageHtmlInReplyToEventIDIntentionalMentionsClosure: ((String, String?, String?, IntentionalMentions) async -> Result<Void, TimelineProxyError>)?

func sendMessage(_ message: String, html: String?, inReplyTo eventID: String?, intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
sendMessageHtmlInReplyToIntentionalMentionsCallsCount += 1
sendMessageHtmlInReplyToIntentionalMentionsReceivedArguments = (message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions)
func sendMessage(_ message: String, html: String?, inReplyToEventID: String?, intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
sendMessageHtmlInReplyToEventIDIntentionalMentionsCallsCount += 1
sendMessageHtmlInReplyToEventIDIntentionalMentionsReceivedArguments = (message: message, html: html, inReplyToEventID: inReplyToEventID, intentionalMentions: intentionalMentions)
DispatchQueue.main.async {
self.sendMessageHtmlInReplyToIntentionalMentionsReceivedInvocations.append((message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions))
self.sendMessageHtmlInReplyToEventIDIntentionalMentionsReceivedInvocations.append((message: message, html: html, inReplyToEventID: inReplyToEventID, intentionalMentions: intentionalMentions))
}
if let sendMessageHtmlInReplyToIntentionalMentionsClosure = sendMessageHtmlInReplyToIntentionalMentionsClosure {
return await sendMessageHtmlInReplyToIntentionalMentionsClosure(message, html, eventID, intentionalMentions)
if let sendMessageHtmlInReplyToEventIDIntentionalMentionsClosure = sendMessageHtmlInReplyToEventIDIntentionalMentionsClosure {
return await sendMessageHtmlInReplyToEventIDIntentionalMentionsClosure(message, html, inReplyToEventID, intentionalMentions)
} else {
return sendMessageHtmlInReplyToIntentionalMentionsReturnValue
return sendMessageHtmlInReplyToEventIDIntentionalMentionsReturnValue
}
}
//MARK: - toggleReaction
Expand Down
2 changes: 1 addition & 1 deletion ElementX/Sources/Mocks/PollMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ extension Poll.Option {

extension PollRoomTimelineItem {
static func mock(poll: Poll, isOutgoing: Bool = true, isEditable: Bool = false) -> Self {
.init(id: .random,
.init(id: .randomEvent,
poll: poll,
body: "poll",
timestamp: "Now",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private struct MessageForwardingListRow: View {
struct MessageForwardingScreen_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
let summaryProvider = RoomSummaryProviderMock(.init(state: .loaded(.mockRooms)))
let viewModel = MessageForwardingScreenViewModel(forwardingItem: .init(id: .init(uniqueID: ""),
let viewModel = MessageForwardingScreenViewModel(forwardingItem: .init(id: .randomEvent,
roomID: "",
content: .init(noPointer: .init())),
clientProxy: ClientProxyMock(.init()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ struct ResolveVerifiedUserSendFailureScreen_Previews: PreviewProvider, TestableP

static func makeViewModel(failure: TimelineItemSendFailure.VerifiedUser) -> ResolveVerifiedUserSendFailureScreenViewModel {
ResolveVerifiedUserSendFailureScreenViewModel(failure: failure,
itemID: .random,
itemID: .randomEvent,
roomProxy: JoinedRoomProxyMock(.init()),
userIndicatorController: UserIndicatorControllerMock())
}
}

struct ResolveVerifiedUserSendFailureScreenSheet_Previews: PreviewProvider {
static let viewModel = ResolveVerifiedUserSendFailureScreenViewModel(failure: .changedIdentity(users: ["@alice:matrix.org"]),
itemID: .random,
itemID: .randomEvent,
roomProxy: JoinedRoomProxyMock(.init()),
userIndicatorController: UserIndicatorControllerMock())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import Compound
import MatrixRustSDK
import SwiftUI
import WysiwygComposer

Expand Down Expand Up @@ -283,9 +284,14 @@ extension FormatType {
}

enum ComposerMode: Equatable {
enum EditSource {
Copy link
Member

Choose a reason for hiding this comment

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

Could call this EditActionSource if you think it makes the timeline case clearer.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think ComposerMode.EditActionSource is clear enough

case timeline
case draftService
}

case `default`
case reply(itemID: TimelineItemIdentifier, replyDetails: TimelineItemReplyDetails, isThread: Bool)
case edit(originalItemId: TimelineItemIdentifier)
case reply(eventID: String, replyDetails: TimelineItemReplyDetails, isThread: Bool)
case edit(originalEventOrTransactionID: EventOrTransactionId, source: EditSource)
case recordVoiceMessage(state: AudioRecorderState)
case previewVoiceMessage(state: AudioPlayerState, waveform: WaveformSource, isUploading: Bool)

Expand Down Expand Up @@ -323,8 +329,8 @@ enum ComposerMode: Equatable {

var replyEventID: String? {
switch self {
case .reply(let itemID, _, _):
return itemID.eventID
case .reply(let eventID, _, _):
return eventID
default:
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
case .newMessage:
set(mode: .default)
case .edit(let eventID):
set(mode: .edit(originalItemId: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: eventID))))
set(mode: .edit(originalEventOrTransactionID: .eventId(eventId: eventID), source: .draftService))
case .reply(let eventID):
set(mode: .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: eventID)), replyDetails: .loading(eventID: eventID), isThread: false))
set(mode: .reply(eventID: eventID, replyDetails: .loading(eventID: eventID), isThread: false))
replyLoadingTask = Task {
let reply = switch await draftService.getReply(eventID: eventID) {
case .success(let reply):
Expand All @@ -273,7 +273,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
return
}

set(mode: .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: eventID)), replyDetails: reply.details, isThread: reply.isThreaded))
set(mode: .reply(eventID: eventID, replyDetails: reply.details, isThread: reply.isThreaded))
}
}
}
Expand Down Expand Up @@ -314,17 +314,9 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
switch state.composerMode {
case .default:
type = .newMessage
case .edit(let itemID):
guard let eventID = itemID.eventID else {
MXLog.error("The event id for this message is missing")
return
}
type = .edit(eventID: eventID)
case .reply(let itemID, _, _):
guard let eventID = itemID.eventID else {
MXLog.error("The event id for this message is missing")
return
}
case .edit(.eventId(let originalEventID), _):
type = .edit(eventID: originalEventID)
case .reply(let eventID, _, _):
type = .reply(eventID: eventID)
default:
if isVolatile {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,10 @@ extension ComposerToolbar {
mentionDisplayHelper: ComposerMentionDisplayHelper.mock,
analyticsService: ServiceLocator.shared.analytics,
composerDraftService: ComposerDraftServiceMock())
model.state.composerMode = isLoading ? .reply(itemID: .init(uniqueID: ""),
model.state.composerMode = isLoading ? .reply(eventID: UUID().uuidString,
replyDetails: .loading(eventID: ""),
isThread: false) :
.reply(itemID: .init(uniqueID: ""),
.reply(eventID: UUID().uuidString,
replyDetails: .loaded(sender: .init(id: "",
displayName: "Test"),
eventID: "", eventContent: .message(.text(.init(body: "Hello World!")))), isThread: false)
Expand Down
Loading
Loading