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: conversation message timer update event - WPB-10171 #2098

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Foundation

/// An event where the message timer of a conversation was updated.

public struct ConversationMessageTimerUpdateEvent: Equatable, Codable {
public struct ConversationMessageTimerUpdateEvent: Equatable, Codable, Sendable {

/// The id of the conversation.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
C99322E72C986E3A0065E10F /* ConnectionsRepositoryError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C99322CD2C986E3A0065E10F /* ConnectionsRepositoryError.swift */; };
C99322E82C986E3A0065E10F /* ConversationLabelsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C99322CF2C986E3A0065E10F /* ConversationLabelsRepository.swift */; };
C99322E92C986E3A0065E10F /* ConversationLabelsRepositoryError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C99322D02C986E3A0065E10F /* ConversationLabelsRepositoryError.swift */; };
C9C758542CCFF089001D45D7 /* ConversationMessageTimerUpdateEventProcessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C758532CCFF089001D45D7 /* ConversationMessageTimerUpdateEventProcessorTests.swift */; };
C9C758582CD0DD17001D45D7 /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C758572CD0DD17001D45D7 /* Conversation.swift */; };
C9C8FDCE2C9DBE0E00702B91 /* FeatureConfigUpdateEventProcessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C8FDC32C9DBE0E00702B91 /* FeatureConfigUpdateEventProcessorTests.swift */; };
C9C8FDCF2C9DBE0E00702B91 /* TeamDeleteEventProcessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C8FDC52C9DBE0E00702B91 /* TeamDeleteEventProcessorTests.swift */; };
C9C8FDD02C9DBE0E00702B91 /* TeamMemberLeaveEventProcessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C8FDC62C9DBE0E00702B91 /* TeamMemberLeaveEventProcessorTests.swift */; };
Expand Down Expand Up @@ -204,6 +206,8 @@
C99322CD2C986E3A0065E10F /* ConnectionsRepositoryError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionsRepositoryError.swift; sourceTree = "<group>"; };
C99322CF2C986E3A0065E10F /* ConversationLabelsRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationLabelsRepository.swift; sourceTree = "<group>"; };
C99322D02C986E3A0065E10F /* ConversationLabelsRepositoryError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationLabelsRepositoryError.swift; sourceTree = "<group>"; };
C9C758532CCFF089001D45D7 /* ConversationMessageTimerUpdateEventProcessorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationMessageTimerUpdateEventProcessorTests.swift; sourceTree = "<group>"; };
C9C758572CD0DD17001D45D7 /* Conversation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conversation.swift; sourceTree = "<group>"; };
C9C8FDC32C9DBE0E00702B91 /* FeatureConfigUpdateEventProcessorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureConfigUpdateEventProcessorTests.swift; sourceTree = "<group>"; };
C9C8FDC52C9DBE0E00702B91 /* TeamDeleteEventProcessorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TeamDeleteEventProcessorTests.swift; sourceTree = "<group>"; };
C9C8FDC62C9DBE0E00702B91 /* TeamMemberLeaveEventProcessorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TeamMemberLeaveEventProcessorTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -465,6 +469,7 @@
C98433FA2CCFD9A2009723D4 /* ConversationReceiptModeUpdateEventProcessorTests.swift */,
C97C01B72CBD6D3C000683C5 /* ConversationCreateEventProcessorTests.swift */,
C98433EB2CCA97AC009723D4 /* ConversationMemberLeaveEventTests.swift */,
C9C758532CCFF089001D45D7 /* ConversationMessageTimerUpdateEventProcessorTests.swift */,
);
path = ConversationEventProcessor;
sourceTree = "<group>";
Expand All @@ -473,6 +478,7 @@
isa = PBXGroup;
children = (
C97C01D42CC138EC000683C5 /* SystemMessage.swift */,
C9C758572CD0DD17001D45D7 /* Conversation.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -1008,6 +1014,7 @@
C99322D82C986E3A0065E10F /* UpdateEventsRepository.swift in Sources */,
EE368CD12C2DAA87009DBAB0 /* TeamEventProcessor.swift in Sources */,
C99322D32C986E3A0065E10F /* TeamRepositoryError.swift in Sources */,
C9C758582CD0DD17001D45D7 /* Conversation.swift in Sources */,
EEAD0A222C46ABFB00CC8658 /* UserLegalholdDisableEventProcessor.swift in Sources */,
EEAD09F22C46604400CC8658 /* ConversationAccessUpdateEventProcessor.swift in Sources */,
EEAD0A082C46776400CC8658 /* ConversationProtocolUpdateEventProcessor.swift in Sources */,
Expand All @@ -1029,6 +1036,7 @@
C9F691292C9B164A008CC41F /* UserPushRemoveEventProcessorTests.swift in Sources */,
C93961932C91B15B00EA971A /* ConversationRepositoryTests.swift in Sources */,
C93961922C91B12800EA971A /* TestError.swift in Sources */,
C9C758542CCFF089001D45D7 /* ConversationMessageTimerUpdateEventProcessorTests.swift in Sources */,
EEC410262C60D48900E89394 /* SyncManagerTests.swift in Sources */,
C9C8FDD32C9DBE0E00702B91 /* UserLegalHoldDisableEventProcessorTests.swift in Sources */,
C98433F82CCFCFE5009723D4 /* ConversationProtocolUpdateEventProcessorTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct ConversationCreateEventProcessor: ConversationCreateEventProcessorProtoco
}

await repository.storeConversation(
conversation,
conversation.toDomainModel(),
timestamp: timestamp
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//

import WireAPI
import WireDataModel

/// Process conversation message timer update events.

Expand All @@ -26,15 +27,56 @@ protocol ConversationMessageTimerUpdateEventProcessorProtocol {
///
/// - Parameter event: A conversation message timer update event.

func processEvent(_ event: ConversationMessageTimerUpdateEvent) async throws
func processEvent(_ event: ConversationMessageTimerUpdateEvent) async

}

struct ConversationMessageTimerUpdateEventProcessor: ConversationMessageTimerUpdateEventProcessorProtocol {

func processEvent(_: ConversationMessageTimerUpdateEvent) async throws {
// TODO: [WPB-10171]
assertionFailure("not implemented yet")
let userRepository: any UserRepositoryProtocol
let conversationRepository: any ConversationRepositoryProtocol
let conversationLocalStore: any ConversationLocalStoreProtocol

func processEvent(_ event: ConversationMessageTimerUpdateEvent) async {
let userID = event.senderID
let conversationID = event.conversationID
let timer = Double(event.newTimer ?? 0)
let timestamp = event.timestamp

let sender = await userRepository.fetchOrCreateUser(
with: userID.uuid,
domain: userID.domain
)

let conversation = await conversationRepository.fetchOrCreateConversation(
with: conversationID.uuid,
domain: conversationID.domain
)

let timeoutValue = timer / 1_000
let timeout: MessageDestructionTimeoutValue = .init(rawValue: timeoutValue)
let currentTimeout = await conversationLocalStore.conversationMessageDestructionTimeout(conversation)

if currentTimeout != timeout {
let systemMessage = SystemMessage(
type: .messageTimerUpdate,
sender: sender,
users: [sender],
timestamp: timestamp,
messageTimer: timeoutValue
)

// TODO: [WPB-11839] Use MessageRepository
await conversationRepository.addSystemMessage(
systemMessage,
to: conversation
)
}

await conversationLocalStore.storeConversation(
timeoutValue: timeoutValue,
for: conversation
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ extension ConversationLocalStore {
// MARK: - User & Role

func fetchUserAndRole(
from remoteConversationMember: WireAPI.Conversation.Member,
from conversationMember: Conversation.Members.Member,
for localConversation: ZMConversation
) -> (user: ZMUser, role: Role?)? {
guard let userID = remoteConversationMember.id ?? remoteConversationMember.qualifiedID?.uuid else {
guard let userID = conversationMember.id ?? conversationMember.qualifiedID?.uuid else {
return nil
}

let user = ZMUser.fetchOrCreate(
with: userID,
domain: remoteConversationMember.qualifiedID?.domain,
domain: conversationMember.qualifiedID?.domain,
in: context
)

Expand All @@ -50,8 +50,11 @@ extension ConversationLocalStore {
)
}

let role = remoteConversationMember.conversationRole.map {
fetchOrCreateRoleForConversation(name: $0, conversation: localConversation)
let role = conversationMember.conversationRole.map {
fetchOrCreateRoleForConversation(
name: $0,
conversation: localConversation
)
}

return (user, role)
Expand All @@ -60,10 +63,10 @@ extension ConversationLocalStore {
// MARK: - Members

func updateMembers(
from remoteConversation: WireAPI.Conversation,
from conversation: Conversation,
for localConversation: ZMConversation
) {
guard let members = remoteConversation.members else {
guard let members = conversation.members else {
return
}

Expand All @@ -79,7 +82,10 @@ extension ConversationLocalStore {
for: localConversation
)?.role

localConversation.updateMembers(otherMembers, selfUserRole: selfUserRole)
localConversation.updateMembers(
otherMembers,
selfUserRole: selfUserRole
)
}

// MARK: - 1:1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,24 @@ extension ConversationLocalStore {
// MARK: - Message protocols

func assignMessageProtocol(
from remoteConversation: WireAPI.Conversation,
from conversation: Conversation,
for localConversation: ZMConversation
) {
guard let newMessageProtocol = remoteConversation.messageProtocol else {
guard let newMessageProtocol = conversation.messageProtocol else {
eventProcessingLogger.warn(
"message protocol is missing"
)
return
}

localConversation.messageProtocol = newMessageProtocol.toDomainModel()
localConversation.messageProtocol = newMessageProtocol
}

func updateMessageProtocol(
from remoteConversation: WireAPI.Conversation,
from conversation: Conversation,
for localConversation: ZMConversation
) {
guard let newMessageProtocol = remoteConversation.messageProtocol else {
guard let newMessageProtocol = conversation.messageProtocol else {
eventProcessingLogger.warn(
"message protocol is missing"
)
Expand All @@ -59,12 +59,16 @@ extension ConversationLocalStore {
break /// no update, ignore
case .mixed:
localConversation.appendMLSMigrationStartedSystemMessage(sender: sender, at: .now)
localConversation.messageProtocol = newMessageProtocol.toDomainModel()
localConversation.messageProtocol = newMessageProtocol

case .mls:
let date = localConversation.lastModifiedDate ?? .now
localConversation.appendMLSMigrationPotentialGapSystemMessage(sender: sender, at: date)
localConversation.messageProtocol = newMessageProtocol.toDomainModel()

localConversation.appendMLSMigrationPotentialGapSystemMessage(
sender: sender, at: date
)

localConversation.messageProtocol = newMessageProtocol
}

case .mixed:
Expand All @@ -78,7 +82,7 @@ extension ConversationLocalStore {
break /// no update, ignore
case .mls:
localConversation.appendMLSMigrationFinalizedSystemMessage(sender: sender, at: .now)
localConversation.messageProtocol = newMessageProtocol.toDomainModel()
localConversation.messageProtocol = newMessageProtocol
}

case .mls:
Expand Down Expand Up @@ -119,8 +123,14 @@ extension ConversationLocalStore {
)

if await context.perform({ localConversation.epoch <= 0 }) {
let ciphersuite = try await mlsService.createSelfGroup(for: groupID)
await context.perform { localConversation.ciphersuite = ciphersuite }
let ciphersuite = try await mlsService.createSelfGroup(
for: groupID
)

await context.perform {
localConversation.ciphersuite = ciphersuite
}

} else if try await !mlsService.conversationExists(groupID: groupID) {
try await mlsService.joinGroup(with: groupID)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,25 @@ extension ConversationLocalStore {
// MARK: - Metadata

func updateMetadata(
from remoteConversation: WireAPI.Conversation,
from conversation: Conversation,
for localConversation: ZMConversation
) {
if let teamID = remoteConversation.teamID {
if let teamID = conversation.teamID {
localConversation.updateTeam(identifier: teamID)
}

if let name = remoteConversation.name {
if let name = conversation.name {
localConversation.userDefinedName = name
}

guard let userID = remoteConversation.creator else {
guard let userID = conversation.creator else {
return
}

/// We assume that the creator always belongs to the same domain as the conversation
let creator = ZMUser.fetchOrCreate(
with: userID,
domain: remoteConversation.qualifiedID?.domain,
domain: conversation.qualifiedID?.domain,
in: context
)

Expand All @@ -54,28 +54,28 @@ extension ConversationLocalStore {
// MARK: - Attributes

func updateAttributes(
from remoteConversation: WireAPI.Conversation,
from conversation: Conversation,
for localConversation: ZMConversation,
isFederationEnabled: Bool
) {
localConversation.domain = isFederationEnabled ? remoteConversation.qualifiedID?.domain : nil
localConversation.domain = isFederationEnabled ? conversation.qualifiedID?.domain : nil
localConversation.needsToBeUpdatedFromBackend = false

if let epoch = remoteConversation.epoch {
if let epoch = conversation.epoch {
localConversation.epoch = UInt64(epoch)
}

let base64String = remoteConversation.mlsGroupID
let base64String = conversation.mlsGroupID

if let base64String, let mlsGroupID = MLSGroupID(base64Encoded: base64String) {
localConversation.mlsGroupID = mlsGroupID
}

let ciphersuite = remoteConversation.cipherSuite
let epoch = remoteConversation.epoch
let ciphersuite = conversation.cipherSuite
let epoch = conversation.epoch

if let ciphersuite, let epoch, epoch > 0 {
localConversation.ciphersuite = ciphersuite.toDomainModel()
localConversation.ciphersuite = ciphersuite
}
}

Expand Down
Loading
Loading