Screen sharing in 1-to-1 calls

This commit is contained in:
Ali
2021-07-23 18:02:47 +02:00
parent 37c6de33ff
commit ee7116ff15
25 changed files with 395 additions and 275 deletions

View File

@@ -42,12 +42,12 @@ private struct AccountAttributes: Equatable {
private enum AddedAccountResult {
case upgrading(Float)
case ready(AccountRecordId, Account?, Int32)
case ready(AccountRecordId, Account?, Int32, LimitsConfiguration?, ContentSettings?, AppConfiguration?)
}
private enum AddedAccountsResult {
case upgrading(Float)
case ready([(AccountRecordId, Account?, Int32)])
case ready([(AccountRecordId, Account?, Int32, LimitsConfiguration?, ContentSettings?, AppConfiguration?)])
}
private var testHasInstance = false
@@ -65,9 +65,9 @@ public final class SharedAccountContextImpl: SharedAccountContext {
private let apsNotificationToken: Signal<Data?, NoError>
private let voipNotificationToken: Signal<Data?, NoError>
private var activeAccountsValue: (primary: Account?, accounts: [(AccountRecordId, Account, Int32)], currentAuth: UnauthorizedAccount?)?
private let activeAccountsPromise = Promise<(primary: Account?, accounts: [(AccountRecordId, Account, Int32)], currentAuth: UnauthorizedAccount?)>()
public var activeAccounts: Signal<(primary: Account?, accounts: [(AccountRecordId, Account, Int32)], currentAuth: UnauthorizedAccount?), NoError> {
private var activeAccountsValue: (primary: AccountContext?, accounts: [(AccountRecordId, AccountContext, Int32)], currentAuth: UnauthorizedAccount?)?
private let activeAccountsPromise = Promise<(primary: AccountContext?, accounts: [(AccountRecordId, AccountContext, Int32)], currentAuth: UnauthorizedAccount?)>()
public var activeAccountContexts: Signal<(primary: AccountContext?, accounts: [(AccountRecordId, AccountContext, Int32)], currentAuth: UnauthorizedAccount?), NoError> {
return self.activeAccountsPromise.get()
}
private let managedAccountDisposables = DisposableDict<AccountRecordId>()
@@ -401,17 +401,22 @@ public final class SharedAccountContextImpl: SharedAccountContext {
for (id, attributes) in records {
if self.activeAccountsValue?.accounts.firstIndex(where: { $0.0 == id}) == nil {
addedSignals.append(accountWithId(accountManager: accountManager, networkArguments: networkArguments, id: id, encryptionParameters: encryptionParameters, supplementary: !applicationBindings.isMainApp, rootPath: rootPath, beginWithTestingEnvironment: attributes.isTestingEnvironment, backupData: attributes.backupData, auxiliaryMethods: telegramAccountAuxiliaryMethods)
|> map { result -> AddedAccountResult in
|> mapToSignal { result -> Signal<AddedAccountResult, NoError> in
switch result {
case let .authorized(account):
setupAccount(account, fetchCachedResourceRepresentation: fetchCachedResourceRepresentation, transformOutgoingMessageMedia: transformOutgoingMessageMedia, preFetchedResourcePath: { resource in
return nil
})
return .ready(id, account, attributes.sortIndex)
return account.postbox.transaction { transaction -> AddedAccountResult in
let limitsConfiguration = transaction.getPreferencesEntry(key: PreferencesKeys.limitsConfiguration) as? LimitsConfiguration ?? LimitsConfiguration.defaultValue
let contentSettings = getContentSettings(transaction: transaction)
let appConfiguration = getAppConfiguration(transaction: transaction)
return .ready(id, account, attributes.sortIndex, limitsConfiguration, contentSettings, appConfiguration)
}
case let .upgrading(progress):
return .upgrading(progress)
return .single(.upgrading(progress))
default:
return .ready(id, nil, attributes.sortIndex)
return .single(.ready(id, nil, attributes.sortIndex, nil, nil, nil))
}
})
}
@@ -432,13 +437,13 @@ public final class SharedAccountContextImpl: SharedAccountContext {
let mappedAddedAccounts = combineLatest(queue: .mainQueue(), addedSignals)
|> map { results -> AddedAccountsResult in
var readyAccounts: [(AccountRecordId, Account?, Int32)] = []
var readyAccounts: [(AccountRecordId, Account?, Int32, LimitsConfiguration?, ContentSettings?, AppConfiguration?)] = []
var totalProgress: Float = 0.0
var hasItemsWithProgress = false
for result in results {
switch result {
case let .ready(id, account, sortIndex):
readyAccounts.append((id, account, sortIndex))
case let .ready(id, account, sortIndex, limitsConfiguration, contentSettings, appConfiguration):
readyAccounts.append((id, account, sortIndex, limitsConfiguration, contentSettings, appConfiguration))
totalProgress += 1.0
case let .upgrading(progress):
hasItemsWithProgress = true
@@ -456,7 +461,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|> deliverOnMainQueue).start(next: { mappedAddedAccounts, authAccount in
print("SharedAccountContextImpl: accounts processed in \(CFAbsoluteTimeGetCurrent() - startTime)")
var addedAccounts: [(AccountRecordId, Account?, Int32)] = []
var addedAccounts: [(AccountRecordId, Account?, Int32, LimitsConfiguration?, ContentSettings?, AppConfiguration?)] = []
switch mappedAddedAccounts {
case let .upgrading(progress):
self.displayUpgradeProgress(progress)
@@ -494,7 +499,11 @@ public final class SharedAccountContextImpl: SharedAccountContext {
self.managedAccountDisposables.set(nil, forKey: account.id)
assertionFailure()
}
self.activeAccountsValue!.accounts.append((account.id, account, accountRecord.2))
let context = AccountContextImpl(sharedContext: self, account: account, limitsConfiguration: accountRecord.3 ?? .defaultValue, contentSettings: accountRecord.4 ?? .default, appConfiguration: accountRecord.5 ?? .defaultValue)
self.activeAccountsValue!.accounts.append((account.id, context, accountRecord.2))
self.managedAccountDisposables.set(self.updateAccountBackupData(account: account).start(), forKey: account.id)
account.resetStateManagement()
hadUpdates = true
@@ -520,7 +529,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
self.managedAccountDisposables.set(nil, forKey: id)
}
}
var primary: Account?
var primary: AccountContext?
if let primaryId = primaryId {
if let index = self.activeAccountsValue?.accounts.firstIndex(where: { $0.0 == primaryId }) {
primary = self.activeAccountsValue?.accounts[index].1
@@ -531,8 +540,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
}
if primary !== self.activeAccountsValue!.primary {
hadUpdates = true
self.activeAccountsValue!.primary?.postbox.clearCaches()
self.activeAccountsValue!.primary?.resetCachedData()
self.activeAccountsValue!.primary?.account.postbox.clearCaches()
self.activeAccountsValue!.primary?.account.resetCachedData()
self.activeAccountsValue!.primary = primary
}
if self.activeAccountsValue!.currentAuth?.id != authRecord?.0 {
@@ -555,16 +564,16 @@ public final class SharedAccountContextImpl: SharedAccountContext {
}))
})
self.activeAccountsWithInfoPromise.set(self.activeAccounts
self.activeAccountsWithInfoPromise.set(self.activeAccountContexts
|> mapToSignal { primary, accounts, _ -> Signal<(primary: AccountRecordId?, accounts: [AccountWithInfo]), NoError> in
return combineLatest(accounts.map { _, account, _ -> Signal<AccountWithInfo?, NoError> in
let peerViewKey: PostboxViewKey = .peer(peerId: account.peerId, components: [])
return account.postbox.combinedView(keys: [peerViewKey])
return combineLatest(accounts.map { _, context, _ -> Signal<AccountWithInfo?, NoError> in
let peerViewKey: PostboxViewKey = .peer(peerId: context.account.peerId, components: [])
return context.account.postbox.combinedView(keys: [peerViewKey])
|> map { view -> AccountWithInfo? in
guard let peerView = view.views[peerViewKey] as? PeerView, let peer = peerView.peers[peerView.peerId] else {
return nil
}
return AccountWithInfo(account: account, peer: peer)
return AccountWithInfo(account: context.account, peer: peer)
}
|> distinctUntilChanged
})
@@ -575,7 +584,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
accountsWithInfoResult.append(info)
}
}
return (primary?.id, accountsWithInfoResult)
return (primary?.account.id, accountsWithInfoResult)
}
})
@@ -604,7 +613,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return
}
strongSelf.mediaManager.playlistControl(.playback(.play), type: nil)
}, audioSession: self.mediaManager.audioSession, activeAccounts: self.activeAccounts |> map { _, accounts, _ in
}, audioSession: self.mediaManager.audioSession, activeAccounts: self.activeAccountContexts |> map { _, accounts, _ in
return Array(accounts.map({ $0.1 }))
})
self.callManager = callManager
@@ -619,7 +628,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
if let call = call {
mainWindow.hostView.containerView.endEditing(true)
let callController = CallController(sharedContext: strongSelf, account: call.account, call: call, easyDebugAccess: !GlobalExperimentalSettings.isAppStoreBuild)
let callController = CallController(sharedContext: strongSelf, account: call.context.account, call: call, easyDebugAccess: !GlobalExperimentalSettings.isAppStoreBuild)
strongSelf.callController = callController
strongSelf.mainWindow?.present(callController, on: .calls)
strongSelf.callState.set(call.state
@@ -686,7 +695,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
if let strongSelf = self {
let statusBarContent: CallStatusBarNodeImpl.Content?
if let call = call {
statusBarContent = .call(strongSelf, call.account, call)
statusBarContent = .call(strongSelf, call.context.account, call)
} else if let groupCall = groupCall, !hasGroupCallOnScreen {
statusBarContent = .groupCall(strongSelf, groupCall.account, groupCall)
} else {
@@ -748,9 +757,9 @@ public final class SharedAccountContextImpl: SharedAccountContext {
self.updateNotificationTokensRegistration()
if applicationBindings.isMainApp {
self.widgetDataContext = WidgetDataContext(basePath: self.basePath, inForeground: self.applicationBindings.applicationInForeground, activeAccounts: self.activeAccounts
self.widgetDataContext = WidgetDataContext(basePath: self.basePath, inForeground: self.applicationBindings.applicationInForeground, activeAccounts: self.activeAccountContexts
|> map { _, accounts, _ in
return accounts.map { $0.1 }
return accounts.map { $0.1.account }
}, presentationData: self.presentationData, appLockContext: self.appLockContext as! AppLockContextImpl)
let enableSpotlight = accountManager.sharedData(keys: Set([ApplicationSpecificSharedDataKeys.intentsSettings]))
@@ -759,10 +768,10 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return intentsSettings.contacts
}
|> distinctUntilChanged
self.spotlightDataContext = SpotlightDataContext(appBasePath: applicationBindings.containerPath, accountManager: accountManager, accounts: combineLatest(enableSpotlight, self.activeAccounts
self.spotlightDataContext = SpotlightDataContext(appBasePath: applicationBindings.containerPath, accountManager: accountManager, accounts: combineLatest(enableSpotlight, self.activeAccountContexts
|> map { _, accounts, _ in
return accounts.map { _, account, _ in
return account
return account.account
}
}) |> map { enableSpotlight, accounts in
if enableSpotlight {
@@ -830,24 +839,24 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return true
})
self.registeredNotificationTokensDisposable.set((combineLatest(queue: .mainQueue(), settings, self.activeAccounts)
self.registeredNotificationTokensDisposable.set((combineLatest(queue: .mainQueue(), settings, self.activeAccountContexts)
|> mapToSignal { settings, activeAccountsAndInfo -> Signal<Never, NoError> in
let (primary, activeAccounts, _) = activeAccountsAndInfo
var applied: [Signal<Never, NoError>] = []
var activeProductionUserIds = activeAccounts.map({ $0.1 }).filter({ !$0.testingEnvironment }).map({ $0.peerId.id })
var activeTestingUserIds = activeAccounts.map({ $0.1 }).filter({ $0.testingEnvironment }).map({ $0.peerId.id })
var activeProductionUserIds = activeAccounts.map({ $0.1 }).filter({ !$0.account.testingEnvironment }).map({ $0.account.peerId.id })
var activeTestingUserIds = activeAccounts.map({ $0.1 }).filter({ $0.account.testingEnvironment }).map({ $0.account.peerId.id })
let allProductionUserIds = activeProductionUserIds
let allTestingUserIds = activeTestingUserIds
if !settings.allAccounts {
if let primary = primary {
if !primary.testingEnvironment {
activeProductionUserIds = [primary.peerId.id]
if !primary.account.testingEnvironment {
activeProductionUserIds = [primary.account.peerId.id]
activeTestingUserIds = []
} else {
activeProductionUserIds = []
activeTestingUserIds = [primary.peerId.id]
activeTestingUserIds = [primary.account.peerId.id]
}
} else {
activeProductionUserIds = []
@@ -859,14 +868,14 @@ public final class SharedAccountContextImpl: SharedAccountContext {
let appliedAps: Signal<Never, NoError>
let appliedVoip: Signal<Never, NoError>
if !activeProductionUserIds.contains(account.peerId.id) && !activeTestingUserIds.contains(account.peerId.id) {
if !activeProductionUserIds.contains(account.account.peerId.id) && !activeTestingUserIds.contains(account.account.peerId.id) {
appliedAps = self.apsNotificationToken
|> distinctUntilChanged(isEqual: { $0 == $1 })
|> mapToSignal { token -> Signal<Never, NoError> in
guard let token = token else {
return .complete()
}
return TelegramEngine(account: account).accountData.unregisterNotificationToken(token: token, type: .aps(encrypt: false), otherAccountUserIds: (account.testingEnvironment ? allTestingUserIds : allProductionUserIds).filter({ $0 != account.peerId.id }))
return account.engine.accountData.unregisterNotificationToken(token: token, type: .aps(encrypt: false), otherAccountUserIds: (account.account.testingEnvironment ? allTestingUserIds : allProductionUserIds).filter({ $0 != account.account.peerId.id }))
}
appliedVoip = self.voipNotificationToken
|> distinctUntilChanged(isEqual: { $0 == $1 })
@@ -874,7 +883,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
guard let token = token else {
return .complete()
}
return TelegramEngine(account: account).accountData.unregisterNotificationToken(token: token, type: .voip, otherAccountUserIds: (account.testingEnvironment ? allTestingUserIds : allProductionUserIds).filter({ $0 != account.peerId.id }))
return account.engine.accountData.unregisterNotificationToken(token: token, type: .voip, otherAccountUserIds: (account.account.testingEnvironment ? allTestingUserIds : allProductionUserIds).filter({ $0 != account.account.peerId.id }))
}
} else {
appliedAps = self.apsNotificationToken
@@ -889,7 +898,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
} else {
encrypt = false
}
return TelegramEngine(account: account).accountData.registerNotificationToken(token: token, type: .aps(encrypt: encrypt), sandbox: sandbox, otherAccountUserIds: (account.testingEnvironment ? activeTestingUserIds : activeProductionUserIds).filter({ $0 != account.peerId.id }), excludeMutedChats: !settings.includeMuted)
return account.engine.accountData.registerNotificationToken(token: token, type: .aps(encrypt: encrypt), sandbox: sandbox, otherAccountUserIds: (account.account.testingEnvironment ? activeTestingUserIds : activeProductionUserIds).filter({ $0 != account.account.peerId.id }), excludeMutedChats: !settings.includeMuted)
}
appliedVoip = self.voipNotificationToken
|> distinctUntilChanged(isEqual: { $0 == $1 })
@@ -897,7 +906,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
guard let token = token else {
return .complete()
}
return TelegramEngine(account: account).accountData.registerNotificationToken(token: token, type: .voip, sandbox: sandbox, otherAccountUserIds: (account.testingEnvironment ? activeTestingUserIds : activeProductionUserIds).filter({ $0 != account.peerId.id }), excludeMutedChats: !settings.includeMuted)
return account.engine.accountData.registerNotificationToken(token: token, type: .voip, sandbox: sandbox, otherAccountUserIds: (account.account.testingEnvironment ? activeTestingUserIds : activeProductionUserIds).filter({ $0 != account.account.peerId.id }), excludeMutedChats: !settings.includeMuted)
}
}
@@ -916,7 +925,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
}
public func switchToAccount(id: AccountRecordId, fromSettingsController settingsController: ViewController? = nil, withChatListController chatListController: ViewController? = nil) {
if self.activeAccountsValue?.primary?.id == id {
if self.activeAccountsValue?.primary?.account.id == id {
return
}