Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin
2020-11-27 13:01:19 +04:00
24 changed files with 2736 additions and 2375 deletions

View File

@@ -18,7 +18,9 @@ private extension PresentationGroupCallState {
static var initialValue: PresentationGroupCallState {
return PresentationGroupCallState(
networkState: .connecting,
isMuted: true
canManageCall: false,
adminIds: Set(),
muteState: GroupCallParticipantsContext.Participant.MuteState(canUnmute: true)
)
}
}
@@ -83,7 +85,6 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
init() {
}
func update(levels: [(PeerId, Float)]) {
@@ -123,7 +124,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
func get() -> Signal<Set<PeerId>, NoError> {
return self.speakingParticipantsPromise.get()
return self.speakingParticipantsPromise.get() |> distinctUntilChanged
}
}
@@ -156,10 +157,18 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
private var summaryStateDisposable: Disposable?
private let isMutedPromise = ValuePromise<Bool>(true)
private var isMutedValue = true
private var isMutedValue: PresentationGroupCallMuteAction = .muted(isPushToTalkActive: false)
private let isMutedPromise = ValuePromise<PresentationGroupCallMuteAction>(.muted(isPushToTalkActive: false))
public var isMuted: Signal<Bool, NoError> {
return self.isMutedPromise.get()
|> map { value -> Bool in
switch value {
case let .muted(isPushToTalkActive):
return isPushToTalkActive
case .unmuted:
return true
}
}
}
private let audioOutputStatePromise = Promise<([AudioSessionOutput], AudioSessionOutput?)>(([], nil))
@@ -446,8 +455,10 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
strongSelf.requestDisposable.set((joinGroupCall(
account: strongSelf.account,
peerId: strongSelf.peerId,
callId: callInfo.id,
accessHash: callInfo.accessHash,
preferMuted: true,
joinPayload: joinPayload
)
|> deliverOnMainQueue).start(next: { joinCallResult in
@@ -460,14 +471,6 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}))
}))
self.isMutedDisposable.set((callContext.isMuted
|> deliverOnMainQueue).start(next: { [weak self] isMuted in
guard let strongSelf = self else {
return
}
strongSelf.stateValue.isMuted = isMuted
}))
self.networkStateDisposable.set((callContext.networkState
|> deliverOnMainQueue).start(next: { [weak self] state in
guard let strongSelf = self else {
@@ -531,6 +534,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
if case let .estabilished(callInfo, clientParams, _, initialState) = internalState {
self.summaryInfoState.set(.single(SummaryInfoState(info: callInfo)))
self.stateValue.canManageCall = initialState.isCreator
self.ssrcMapping.removeAll()
var ssrcs: [UInt32] = []
for participant in initialState.participants {
@@ -566,9 +571,21 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
muteState: participant.muteState,
speaking: speakingParticipants.contains(participant.peer.id)
)
if participant.peer.id == strongSelf.accountContext.account.peerId {
if let muteState = participant.muteState {
strongSelf.stateValue.muteState = muteState
strongSelf.callContext?.setIsMuted(true)
} else if let currentMuteState = strongSelf.stateValue.muteState, !currentMuteState.canUnmute {
strongSelf.stateValue.muteState = GroupCallParticipantsContext.Participant.MuteState(canUnmute: true)
strongSelf.callContext?.setIsMuted(true)
}
}
}
strongSelf.membersValue = memberStates
strongSelf.stateValue.adminIds = state.adminIds
strongSelf.summaryParticipantsState.set(.single(SummaryParticipantsState(
participantCount: state.totalCount,
topParticipants: topParticipants
@@ -619,13 +636,20 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
}
public func leave() -> Signal<Bool, NoError> {
if case let .estabilished(callInfo, _, _, _) = self.internalState {
self.leaveDisposable.set((leaveGroupCall(account: self.account, callId: callInfo.id, accessHash: callInfo.accessHash)
|> deliverOnMainQueue).start(completed: { [weak self] in
self?._canBeRemoved.set(.single(true))
}))
} else if case .requesting = self.internalState {
public func leave(terminateIfPossible: Bool) -> Signal<Bool, NoError> {
if case let .estabilished(callInfo, _, localSsrc, _) = self.internalState {
if terminateIfPossible {
self.leaveDisposable.set((stopGroupCall(account: self.account, peerId: self.peerId, callId: callInfo.id, accessHash: callInfo.accessHash)
|> deliverOnMainQueue).start(completed: { [weak self] in
self?._canBeRemoved.set(.single(true))
}))
} else {
self.leaveDisposable.set((leaveGroupCall(account: self.account, callId: callInfo.id, accessHash: callInfo.accessHash, source: localSsrc)
|> deliverOnMainQueue).start(completed: { [weak self] in
self?._canBeRemoved.set(.single(true))
}))
}
} else if case .requesting = self.internalState {
self.callContext?.stop()
self.callContext = nil
self.requestDisposable.set(nil)
@@ -635,13 +659,39 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
public func toggleIsMuted() {
self.setIsMuted(!self.isMutedValue)
switch self.isMutedValue {
case .muted:
self.setIsMuted(action: .unmuted)
case .unmuted:
self.setIsMuted(action: .muted(isPushToTalkActive: false))
}
}
public func setIsMuted(_ value: Bool) {
self.isMutedValue = value
public func setIsMuted(action: PresentationGroupCallMuteAction) {
if self.isMutedValue == action {
return
}
if let muteState = self.stateValue.muteState, !muteState.canUnmute {
return
}
self.isMutedValue = action
self.isMutedPromise.set(self.isMutedValue)
self.callContext?.setIsMuted(self.isMutedValue)
let isEffectivelyMuted: Bool
switch self.isMutedValue {
case let .muted(isPushToTalkActive):
isEffectivelyMuted = !isPushToTalkActive
self.updateMuteState(peerId: self.accountContext.account.peerId, isMuted: true)
case .unmuted:
isEffectivelyMuted = false
self.updateMuteState(peerId: self.accountContext.account.peerId, isMuted: false)
}
self.callContext?.setIsMuted(isEffectivelyMuted)
if isEffectivelyMuted {
self.stateValue.muteState = GroupCallParticipantsContext.Participant.MuteState(canUnmute: true)
} else {
self.stateValue.muteState = nil
}
}
public func setCurrentAudioOutput(_ output: AudioSessionOutput) {
@@ -662,7 +712,29 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
public func updateMuteState(peerId: PeerId, isMuted: Bool) {
self.participantsContext?.updateMuteState(peerId: peerId, muteState: isMuted ? GroupCallParticipantsContext.Participant.MuteState(canUnmute: peerId == self.accountContext.account.peerId) : nil)
let canThenUnmute: Bool
if isMuted {
if peerId == self.accountContext.account.peerId {
canThenUnmute = true
} else if self.stateValue.canManageCall {
if self.stateValue.adminIds.contains(peerId) {
canThenUnmute = true
} else {
canThenUnmute = false
}
} else if self.stateValue.adminIds.contains(self.accountContext.account.peerId) {
canThenUnmute = true
} else {
canThenUnmute = true
}
self.participantsContext?.updateMuteState(peerId: peerId, muteState: isMuted ? GroupCallParticipantsContext.Participant.MuteState(canUnmute: canThenUnmute) : nil)
} else {
if peerId == self.accountContext.account.peerId {
self.participantsContext?.updateMuteState(peerId: peerId, muteState: nil)
} else {
self.participantsContext?.updateMuteState(peerId: peerId, muteState: GroupCallParticipantsContext.Participant.MuteState(canUnmute: true))
}
}
}
private func requestCall() {