diff --git a/SignalServiceKit/Groups/GroupV2UpdatesImpl.swift b/SignalServiceKit/Groups/GroupV2UpdatesImpl.swift index 8853ce68bb..72f8286ca4 100644 --- a/SignalServiceKit/Groups/GroupV2UpdatesImpl.swift +++ b/SignalServiceKit/Groups/GroupV2UpdatesImpl.swift @@ -218,11 +218,13 @@ public class GroupV2UpdatesImpl: GroupV2Updates { return abs(lastSuccessfulRefreshDate.timeIntervalSinceNow) < refreshFrequency }() - let databaseStorage = SSKEnvironment.shared.databaseStorageRef - try databaseStorage.read { tx in - // - If we're blocked, it's an immediate error - if SSKEnvironment.shared.blockingManagerRef.isGroupIdBlocked(groupId, transaction: tx) { - throw GroupsV2Error.groupBlocked + if !options.contains(.leavingGroup) { + let databaseStorage = SSKEnvironment.shared.databaseStorageRef + try databaseStorage.read { tx in + // If we're blocked, it's an immediate error unless we're leaving the group. + if SSKEnvironment.shared.blockingManagerRef.isGroupIdBlocked(groupId, transaction: tx) { + throw GroupsV2Error.groupBlocked + } } } diff --git a/SignalServiceKit/Groups/GroupsV2Impl.swift b/SignalServiceKit/Groups/GroupsV2Impl.swift index 30e0e0e924..6257e85fc5 100644 --- a/SignalServiceKit/Groups/GroupsV2Impl.swift +++ b/SignalServiceKit/Groups/GroupsV2Impl.swift @@ -49,12 +49,15 @@ public class GroupsV2Impl: GroupsV2 { observeNotifications() } - private func refreshGroupWithTimeout(secretParams: GroupSecretParams) async throws { + private func refreshGroupWithTimeout(secretParams: GroupSecretParams, isLeavingGroup: Bool) async throws { do { // Ignore the result after the timeout. However, keep refreshing the group // in the background since the result is still useful/reusable. try await withUncooperativeTimeout(seconds: GroupManager.groupUpdateTimeoutDuration) { - try await SSKEnvironment.shared.groupV2UpdatesRef.refreshGroup(secretParams: secretParams) + try await SSKEnvironment.shared.groupV2UpdatesRef.refreshGroup( + secretParams: secretParams, + options: isLeavingGroup ? [.leavingGroup] : [], + ) } } catch is UncooperativeTimeoutError { throw GroupsV2Error.timeout @@ -227,7 +230,10 @@ public class GroupsV2Impl: GroupsV2 { // committed to the service, we should refresh our local state // for the group and try again to apply our changes. - try await refreshGroupWithTimeout(secretParams: groupV2Params.groupSecretParams) + try await refreshGroupWithTimeout( + secretParams: groupV2Params.groupSecretParams, + isLeavingGroup: changes.shouldLeaveGroupDeclineInvite, + ) groupUpdateResult = try await buildGroupChangeProtoAndTryToUpdateGroupOnService( groupV2Params: groupV2Params, @@ -1715,7 +1721,7 @@ public class GroupsV2Impl: GroupsV2 { // First try to fetch latest group state from service. // This will fail for users trying to join via group link // who are not yet in the group. - try await refreshGroupWithTimeout(secretParams: secretParams) + try await refreshGroupWithTimeout(secretParams: secretParams, isLeavingGroup: false) let groupThread = SSKEnvironment.shared.databaseStorageRef.read { tx in return TSGroupThread.fetch(forGroupId: groupId, tx: tx) diff --git a/SignalServiceKit/Groups/GroupsV2OutgoingChangesImpl.swift b/SignalServiceKit/Groups/GroupsV2OutgoingChangesImpl.swift index 2f1a9b6287..04eda6d68a 100644 --- a/SignalServiceKit/Groups/GroupsV2OutgoingChangesImpl.swift +++ b/SignalServiceKit/Groups/GroupsV2OutgoingChangesImpl.swift @@ -70,7 +70,7 @@ public class GroupsV2OutgoingChanges { private var inviteLinkPasswordMode: InviteLinkPasswordMode? private var shouldAcceptInvite = false - private var shouldLeaveGroupDeclineInvite = false + private(set) var shouldLeaveGroupDeclineInvite = false private var shouldRevokeInvalidInvites = false /// Non-nil if the value changed. diff --git a/SignalServiceKit/Groups/TSGroupModelBuilder.swift b/SignalServiceKit/Groups/TSGroupModelBuilder.swift index f6f47a864d..f1347e7ee6 100644 --- a/SignalServiceKit/Groups/TSGroupModelBuilder.swift +++ b/SignalServiceKit/Groups/TSGroupModelBuilder.swift @@ -169,6 +169,7 @@ public struct TSGroupModelOptions: OptionSet { public static let didJustAddSelfViaGroupLink = TSGroupModelOptions(rawValue: 1 << 0) public static let throttle = TSGroupModelOptions(rawValue: 1 << 1) + public static let leavingGroup = TSGroupModelOptions(rawValue: 1 << 2) public init(rawValue: Int) { self.rawValue = rawValue