diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index f6e9611518..ab0406233a 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -14179,4 +14179,6 @@ Sorry for the inconvenience."; "Call.IncomingGroupCallTitle.Single" = "%@"; "Call.IncomingGroupCallTitle.Multiple_1" = "{} and 1 other"; -"Call.IncomingGroupCallTitle.Multiple_any" = "{} and %d others"; \ No newline at end of file +"Call.IncomingGroupCallTitle.Multiple_any" = "{} and %d others"; + +"GroupCall.RevokeLinkText" = "Are you sure you want to revoke this link? Once you do, no one will be able to join the call using it."; diff --git a/submodules/CallListUI/Sources/CallListControllerNode.swift b/submodules/CallListUI/Sources/CallListControllerNode.swift index 204dffbf3f..dfb1a324e2 100644 --- a/submodules/CallListUI/Sources/CallListControllerNode.swift +++ b/submodules/CallListUI/Sources/CallListControllerNode.swift @@ -126,7 +126,7 @@ private func mappedInsertEntries(context: AccountContext, presentationData: Item case let .displayTabInfo(_, text): return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint) case .openNewCall: - let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: PresentationResourcesRootController.navigationCallIcon(presentationData.theme), title: presentationData.strings.CallList_NewCall, hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: { + let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: PresentationResourcesRootController.callListCallIcon(presentationData.theme), title: presentationData.strings.CallList_NewCall, hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: { nodeInteraction.openNewCall() }) return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) @@ -150,7 +150,7 @@ private func mappedUpdateEntries(context: AccountContext, presentationData: Item case let .displayTabInfo(_, text): return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint) case .openNewCall: - let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: PresentationResourcesRootController.navigationCallIcon(presentationData.theme), title: presentationData.strings.CallList_NewCall, hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: { + let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: PresentationResourcesRootController.callListCallIcon(presentationData.theme), title: presentationData.strings.CallList_NewCall, hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: { nodeInteraction.openNewCall() }) return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) diff --git a/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift b/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift index 153bcc6d57..34a52902e2 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift @@ -494,7 +494,7 @@ public final class InviteLinkInviteController: ViewController { } controller.setItemGroups([ ActionSheetItemGroup(items: [ - ActionSheetTextItem(title: presentationData.strings.VideoChat_RevokeLink), + ActionSheetTextItem(title: presentationData.strings.GroupCall_RevokeLinkText), ActionSheetButtonItem(title: presentationData.strings.GroupInfo_InviteLink_RevokeLink, color: .destructive, action: { [weak self] in dismissAction() diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index bb7957c770..3b8178798e 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -2003,7 +2003,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.updateSessionState(internalState: .established(info: joinCallResult.callInfo, connectionMode: joinCallResult.connectionMode, clientParams: clientParams, localSsrc: ssrc, initialState: joinCallResult.state), audioSessionControl: self.audioSessionControl) - self.e2eContext?.begin() + if let e2eState = joinCallResult.e2eState { + self.e2eContext?.begin(initialState: e2eState) + } else { + self.e2eContext?.begin(initialState: nil) + } }, error: { [weak self] error in guard let self else { return diff --git a/submodules/TelegramCallsUI/Sources/VideoChatEncryptionKeyComponent.swift b/submodules/TelegramCallsUI/Sources/VideoChatEncryptionKeyComponent.swift index 02cfbd82ca..83abd095f9 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatEncryptionKeyComponent.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatEncryptionKeyComponent.swift @@ -550,7 +550,7 @@ final class VideoChatEncryptionKeyComponent: Component { self.isUpdating = false } - #if DEBUG && true +#if DEBUG && false if self.component == nil { self.mockStateTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 4.0, repeats: true, block: { [weak self] _ in guard let self else { diff --git a/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift b/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift index 07471dfedb..5914833d9b 100644 --- a/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift +++ b/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift @@ -79,7 +79,7 @@ public final class ConferenceCallE2EContext { self.synchronizeRemovedParticipantsTimer?.invalidate() } - func begin() { + func begin(initialState: JoinGroupCallResult.E2EState?) { self.scheduledSynchronizeRemovedParticipantsAfterPoll = true self.synchronizeRemovedParticipantsTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 10.0, repeats: true, block: { [weak self] _ in guard let self else { @@ -88,6 +88,13 @@ public final class ConferenceCallE2EContext { self.synchronizeRemovedParticipants() }) + if let initialState { + self.e2ePoll0Offset = initialState.subChain0.offset + self.e2ePoll1Offset = initialState.subChain1.offset + self.addE2EBlocks(blocks: initialState.subChain0.blocks, subChainId: 0) + self.addE2EBlocks(blocks: initialState.subChain1.blocks, subChainId: 1) + } + self.e2ePoll(subChainId: 0) self.e2ePoll(subChainId: 1) } @@ -424,9 +431,9 @@ public final class ConferenceCallE2EContext { }) } - public func begin() { + public func begin(initialState: JoinGroupCallResult.E2EState?) { self.impl.with { impl in - impl.begin() + impl.begin(initialState: initialState) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift index 46b0773315..755d84711b 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift @@ -587,11 +587,22 @@ public struct JoinGroupCallResult { case rtc case broadcast(isExternalStream: Bool) } + + public struct E2EState { + public let subChain0: (offset: Int, blocks: [Data]) + public let subChain1: (offset: Int, blocks: [Data]) + + public init(subChain0: (offset: Int, blocks: [Data]), subChain1: (offset: Int, blocks: [Data])) { + self.subChain0 = subChain0 + self.subChain1 = subChain1 + } + } public var callInfo: GroupCallInfo public var state: GroupCallParticipantsContext.State public var connectionMode: ConnectionMode public var jsonParams: String + public var e2eState: E2EState? } public class JoinGroupCallE2E { @@ -791,7 +802,7 @@ func _internal_joinGroupCall(account: Account, peerId: PeerId?, joinAs: PeerId?, connectionMode = .broadcast(isExternalStream: false) } - return account.postbox.transaction { transaction -> JoinGroupCallResult in + return account.postbox.transaction { transaction -> Signal in if let peerId { transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { @@ -806,6 +817,9 @@ func _internal_joinGroupCall(account: Account, peerId: PeerId?, joinAs: PeerId?, var state = state + var e2eSubChain1State: (offset: Int, blocks: [Data])? + var e2eSubChain0State: (offset: Int, blocks: [Data])? + for update in updates.allUpdates { switch update { case let .updateGroupCallParticipants(_, participants, _): @@ -852,21 +866,41 @@ func _internal_joinGroupCall(account: Account, peerId: PeerId?, joinAs: PeerId?, } } } + case let .updateGroupCallChainBlocks(_, subChainId, blocks, nextOffset): + if subChainId == 0 { + e2eSubChain0State = (offset: Int(nextOffset), blocks: blocks.map { $0.makeData() }) + } else { + e2eSubChain1State = (offset: Int(nextOffset), blocks: blocks.map { $0.makeData() }) + } default: break } } + + var e2eState: JoinGroupCallResult.E2EState? + if let e2eSubChain0State, let e2eSubChain1State { + e2eState = JoinGroupCallResult.E2EState( + subChain0: e2eSubChain0State, + subChain1: e2eSubChain1State + ) + } + + if generateE2E != nil && e2eState == nil { + return .fail(.error(.generic)) + } state.participants.sort(by: { GroupCallParticipantsContext.Participant.compare(lhs: $0, rhs: $1, sortAscending: state.sortAscending) }) - return JoinGroupCallResult( + return .single(JoinGroupCallResult( callInfo: parsedCall, state: state, connectionMode: connectionMode, - jsonParams: parsedClientParams - ) + jsonParams: parsedClientParams, + e2eState: e2eState + )) } |> castError(InternalJoinError.self) + |> switchToLatest } } } diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift index 6afe54e1d7..2dea72f9a3 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift @@ -336,6 +336,8 @@ public enum PresentationResourceKey: Int32 { case peerStatusLockedImage case expandDownArrowImage case expandSmallDownArrowImage + + case callListCallIcon } public enum ChatExpiredStoryIndicatorType: Hashable { diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift index 0e4915686b..d486af773d 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift @@ -199,4 +199,10 @@ public struct PresentationResourcesRootController { return generateTintedImage(image: UIImage(bundleImageName: "Peer Info/SortIcon"), color: .white) }) } + + public static func callListCallIcon(_ theme: PresentationTheme) -> UIImage? { + return theme.image(PresentationResourceKey.callListCallIcon.rawValue, { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Call List/NewCallListIcon"), color: theme.rootController.navigationBar.accentTextColor) + }) + } } diff --git a/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/Contents.json new file mode 100644 index 0000000000..91489efbe6 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "newcall_30.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/newcall_30.pdf b/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/newcall_30.pdf new file mode 100644 index 0000000000..4a915649db Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/newcall_30.pdf differ