-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
/
Copy pathCallLinkAdminManager.swift
111 lines (100 loc) · 4.37 KB
/
CallLinkAdminManager.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Combine
import SignalRingRTC
import SignalServiceKit
import SignalUI
@MainActor
class CallLinkAdminManager {
typealias CallLinkState = SignalServiceKit.CallLinkState
private let rootKey: CallLinkRootKey
private let adminPasskey: Data
let callNamePublisher: CurrentValueSubject<String?, Never>
private(set) var callLinkState: CallLinkState?
var didUpdateCallLinkState: (@MainActor (CallLinkState) -> Void)?
init(rootKey: CallLinkRootKey, adminPasskey: Data, callLinkState: CallLinkState?) {
self.rootKey = rootKey
self.adminPasskey = adminPasskey
self.callLinkState = callLinkState
self.callNamePublisher = .init(callLinkState?.name)
}
// MARK: Convenience properties
var editCallNameButtonTitle: String {
callLinkState?.name != nil ? CallStrings.editCallName : CallStrings.addCallName
}
// MARK: Actions
func updateName(_ name: String) async throws {
try await updateCallLink(
{ callLinkManager, authCredential in
return try await callLinkManager.updateCallLinkName(
name,
rootKey: self.rootKey,
adminPasskey: self.adminPasskey,
authCredential: authCredential
)
}
)
}
func toggleApproveAllMembersWithActivityIndicator(
_ sender: UISwitch,
from viewController: UIViewController
) {
let isOn = sender.isOn
ModalActivityIndicatorViewController.present(
fromViewController: viewController,
presentationDelay: 0.25,
asyncBlock: { modal in
let updateResult = await Result {
try await self.updateCallLink { callLinkManager, authCredential in
return try await callLinkManager.updateCallLinkRestrictions(
requiresAdminApproval: isOn,
rootKey: self.rootKey,
adminPasskey: self.adminPasskey,
authCredential: authCredential
)
}
}
modal.dismissIfNotCanceled {
do {
_ = try updateResult.get()
} catch {
if error.isNetworkFailureOrTimeout {
// [CallLink] TODO: Refresh switch UI, as we don't know whether the operation succeeded or failed.
} else {
Logger.warn("Call link approve members switch update failed with error \(error)")
// The operation definitely failed. Revert switch state.
sender.isOn = !isOn
OWSActionSheets.showActionSheet(
title: CallStrings.callLinkErrorSheetTitle,
message: CallStrings.callLinkUpdateErrorSheetDescription,
fromViewController: viewController
)
}
}
}
}
)
}
// MARK: Private
private func updateCallLink(
_ performUpdate: (CallLinkManager, SignalServiceKit.CallLinkAuthCredential) async throws -> CallLinkState
) async throws {
let callLinkManager = AppEnvironment.shared.callService.callLinkManager
let callLinkStateUpdater = AppEnvironment.shared.callService.callLinkStateUpdater
let databaseStorage = SSKEnvironment.shared.databaseStorageRef
_ = try await callLinkStateUpdater.updateExclusively(rootKey: rootKey) { authCredential in
let callLinkState = try await performUpdate(callLinkManager, authCredential)
await databaseStorage.awaitableWrite { [rootKey, adminPasskey] tx in
CallLinkUpdateMessageSender(
messageSenderJobQueue: SSKEnvironment.shared.messageSenderJobQueueRef
).sendCallLinkUpdateMessage(rootKey: rootKey, adminPasskey: adminPasskey, tx: tx)
}
self.callLinkState = callLinkState
self.didUpdateCallLinkState?(callLinkState)
self.callNamePublisher.send(callLinkState.name)
return callLinkState
}
}
}