Conference updates

This commit is contained in:
Isaac 2025-04-11 14:41:49 +04:00
parent a1631b421a
commit 22b4c30774
11 changed files with 80 additions and 13 deletions

View File

@ -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";
"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.";

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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<JoinGroupCallResult, InternalJoinError> 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
}
}
}

View File

@ -336,6 +336,8 @@ public enum PresentationResourceKey: Int32 {
case peerStatusLockedImage
case expandDownArrowImage
case expandSmallDownArrowImage
case callListCallIcon
}
public enum ChatExpiredStoryIndicatorType: Hashable {

View File

@ -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)
})
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "newcall_30.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}