Voice chat UI fixes

This commit is contained in:
Ali 2020-12-05 23:45:35 +00:00
parent 42834133f8
commit 1e10a74871
12 changed files with 74 additions and 16 deletions

View File

@ -5988,7 +5988,7 @@ Sorry for the inconvenience.";
"CHAT_VOICECHAT_START" = "%1$@ has started voice chat in the group %2$@";
"CHAT_VOICECHAT_INVITE" = "%1$@ has invited %3$@ in the group %2$@";
"CHAT_VOICECHAT_INVITE_YOU" = "%1$@ has invited you to voice chat in the group %1$@";
"CHAT_VOICECHAT_INVITE_YOU" = "%1$@ has invited you to voice chat in the group %2$@";
"Call.VoiceChatInProgressTitle" = "Voice Chat in Progress";
"Call.VoiceChatInProgressMessageCall" = "Leave voice chat in %1$@ and start a call with %2$@?";

View File

@ -1361,7 +1361,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
animateOnline = true
} else if let channel = renderedPeer.peer as? TelegramChannel {
onlineIsVoiceChat = true
if channel.flags.contains(.hasVoiceChat) && item.interaction.searchTextHighightState == nil {
if channel.flags.contains(.hasActiveVoiceChat) && item.interaction.searchTextHighightState == nil {
online = true
}
animateOnline = true

View File

@ -140,6 +140,7 @@ open class NavigationController: UINavigationController, ContainableController,
var inCallNavigate: (() -> Void)?
private var inCallStatusBar: StatusBar?
private var updateInCallStatusBarState: CallStatusBarNode?
private var globalScrollToTopNode: ScrollToTopNode?
private var rootContainer: RootContainer?
private var rootModalFrame: NavigationModalFrame?
@ -406,6 +407,11 @@ open class NavigationController: UINavigationController, ContainableController,
inCallStatusBar.callStatusBarNode?.frame = inCallStatusBarFrame
layout.statusBarHeight = inCallStatusBarFrame.height
inCallStatusBar.frame = inCallStatusBarFrame
if let forceInCallStatusBar = self.updateInCallStatusBarState {
self.updateInCallStatusBarState = nil
inCallStatusBar.updateState(statusBar: nil, withSafeInsets: !layout.safeInsets.top.isZero, inCallNode: forceInCallStatusBar, animated: false)
}
}
if let globalOverlayContainerParent = self.globalOverlayContainerParent {
@ -1409,6 +1415,8 @@ open class NavigationController: UINavigationController, ContainableController,
if let layout = self.validLayout {
inCallStatusBar.updateState(statusBar: nil, withSafeInsets: !layout.safeInsets.top.isZero, inCallNode: forceInCallStatusBar, animated: false)
self.containerLayoutUpdated(layout, transition: transition)
} else {
self.updateInCallStatusBarState = forceInCallStatusBar
}
} else if let inCallStatusBar = self.inCallStatusBar {
self.inCallStatusBar = nil

View File

@ -333,8 +333,7 @@ final class NavigationModalContainer: ASDisplayNode, UIScrollViewDelegate, UIGes
let containerLayout: ContainerViewLayout
let containerFrame: CGRect
let containerScale: CGFloat
switch layout.metrics.widthClass {
case .compact:
if layout.metrics.widthClass == .compact || self.isFlat {
self.panRecognizer?.isEnabled = true
self.container.clipsToBounds = true
if self.isFlat {
@ -387,7 +386,7 @@ final class NavigationModalContainer: ASDisplayNode, UIScrollViewDelegate, UIGes
let scaledTopInset: CGFloat = topInset * (1.0 - coveredByModalTransition) + maxScaledTopInset * coveredByModalTransition
containerFrame = unscaledFrame.offsetBy(dx: 0.0, dy: scaledTopInset - (unscaledFrame.midY - containerScale * unscaledFrame.height / 2.0))
}
case .regular:
} else {
self.panRecognizer?.isEnabled = false
if self.isFlat {
self.dim.backgroundColor = .clear

View File

@ -142,6 +142,7 @@ public struct TelegramChannelFlags: OptionSet {
public static let isScam = TelegramChannelFlags(rawValue: 1 << 2)
public static let hasGeo = TelegramChannelFlags(rawValue: 1 << 3)
public static let hasVoiceChat = TelegramChannelFlags(rawValue: 1 << 4)
public static let hasActiveVoiceChat = TelegramChannelFlags(rawValue: 1 << 5)
}
public final class TelegramChannel: Peer {
@ -298,4 +299,8 @@ public final class TelegramChannel: Peer {
public func withUpdatedDefaultBannedRights(_ defaultBannedRights: TelegramChatBannedRights?) -> TelegramChannel {
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: defaultBannedRights)
}
public func withUpdatedFlags(_ flags: TelegramChannelFlags) -> TelegramChannel {
return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights)
}
}

View File

@ -38,6 +38,7 @@ swift_library(
"//submodules/AlertUI:AlertUI",
"//submodules/DirectionalPanGesture:DirectionalPanGesture",
"//submodules/PeerInfoUI:PeerInfoUI",
"//submodules/DeviceProximity:DeviceProximity",
],
visibility = [
"//visibility:public",

View File

@ -404,7 +404,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
}
if let (size, leftInset, rightInset) = self.validLayout {
self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset, transition: .immediate)
self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset, transition: .animated(duration: 0.2, curve: .easeInOut))
}
if updateAudioLevels {
@ -448,6 +448,8 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
public func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) {
self.validLayout = (size, leftInset, rightInset)
let staticTransition: ContainedViewLayoutTransition = .immediate
let panelHeight = size.height
transition.updateFrame(node: self.contentNode, frame: CGRect(origin: CGPoint(), size: size))
@ -462,17 +464,17 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
let joinButtonTitleSize = self.joinButtonTitleNode.updateLayout(CGSize(width: 150.0, height: .greatestFiniteMagnitude))
let joinButtonSize = CGSize(width: joinButtonTitleSize.width + 20.0, height: 28.0)
let joinButtonFrame = CGRect(origin: CGPoint(x: size.width - rightInset - 7.0 - joinButtonSize.width, y: floor((panelHeight - joinButtonSize.height) / 2.0)), size: joinButtonSize)
transition.updateFrame(node: self.joinButton, frame: joinButtonFrame)
transition.updateFrame(node: self.joinButtonBackgroundNode, frame: CGRect(origin: CGPoint(), size: joinButtonFrame.size))
transition.updateFrame(node: self.joinButtonTitleNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((joinButtonFrame.width - joinButtonTitleSize.width) / 2.0), y: floorToScreenPixels((joinButtonFrame.height - joinButtonTitleSize.height) / 2.0)), size: joinButtonTitleSize))
staticTransition.updateFrame(node: self.joinButton, frame: joinButtonFrame)
staticTransition.updateFrame(node: self.joinButtonBackgroundNode, frame: CGRect(origin: CGPoint(), size: joinButtonFrame.size))
staticTransition.updateFrame(node: self.joinButtonTitleNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((joinButtonFrame.width - joinButtonTitleSize.width) / 2.0), y: floorToScreenPixels((joinButtonFrame.height - joinButtonTitleSize.height) / 2.0)), size: joinButtonTitleSize))
let micButtonSize = CGSize(width: 36.0, height: 36.0)
let micButtonFrame = CGRect(origin: CGPoint(x: size.width - rightInset - 7.0 - micButtonSize.width, y: floor((panelHeight - micButtonSize.height) / 2.0)), size: micButtonSize)
transition.updateFrame(node: self.micButton, frame: micButtonFrame)
transition.updateFrame(node: self.micButtonBackgroundNode, frame: CGRect(origin: CGPoint(), size: micButtonFrame.size))
staticTransition.updateFrame(node: self.micButton, frame: micButtonFrame)
staticTransition.updateFrame(node: self.micButtonBackgroundNode, frame: CGRect(origin: CGPoint(), size: micButtonFrame.size))
let animationSize = CGSize(width: 36.0, height: 36.0)
transition.updateFrame(node: self.micButtonForegroundNode, frame: CGRect(origin: CGPoint(x: floor((micButtonFrame.width - animationSize.width) / 2.0), y: floor((micButtonFrame.height - animationSize.height) / 2.0)), size: animationSize))
staticTransition.updateFrame(node: self.micButtonForegroundNode, frame: CGRect(origin: CGPoint(x: floor((micButtonFrame.width - animationSize.width) / 2.0), y: floor((micButtonFrame.height - animationSize.height) / 2.0)), size: animationSize))
var isMuted = true
if let _ = self.callState?.muteState {
@ -498,11 +500,11 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
let textSize = self.textNode.updateLayout(CGSize(width: size.width, height: .greatestFiniteMagnitude))
let titleFrame = CGRect(origin: CGPoint(x: leftInset + 16.0, y: 9.0), size: titleSize)
transition.updateFrame(node: self.titleNode, frame: titleFrame)
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: leftInset + 16.0, y: titleFrame.maxY + 1.0), size: textSize))
staticTransition.updateFrame(node: self.titleNode, frame: titleFrame)
staticTransition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: leftInset + 16.0, y: titleFrame.maxY + 1.0), size: textSize))
if let image = self.muteIconNode.image {
transition.updateFrame(node: self.muteIconNode, frame: CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: titleFrame.minY + 5.0), size: image.size))
staticTransition.updateFrame(node: self.muteIconNode, frame: CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: titleFrame.minY + 5.0), size: image.size))
}
self.muteIconNode.isHidden = self.currentData?.groupCall != nil
self.joinButton.isHidden = self.currentData?.groupCall != nil

View File

@ -14,6 +14,7 @@ import TelegramPresentationData
import DeviceAccess
import UniversalMediaPlayer
import AccountContext
import DeviceProximity
public final class AccountGroupCallContextImpl: AccountGroupCallContext {
public final class Proxy {
@ -427,6 +428,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
public weak var sourcePanel: ASDisplayNode?
private var proximityManagerIndex: Int?
init(
accountContext: AccountContext,
audioSession: ManagedAudioSession,
@ -651,6 +654,10 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
self.myAudioLevelTimer?.invalidate()
self.typingDisposable.dispose()
if let proximityManagerIndex = self.proximityManagerIndex {
DeviceProximityManager.shared().remove(proximityManagerIndex)
}
}
private func updateSessionState(internalState: InternalState, audioSessionControl: ManagedAudioSessionControl?) {
@ -663,6 +670,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
if let audioSessionControl = audioSessionControl, previousControl == nil {
audioSessionControl.setOutputMode(.custom(self.currentAudioOutputValue))
audioSessionControl.setup(synchronous: true)
self.setCurrentAudioOutput(.speaker)
}
self.audioSessionShouldBeActive.set(true)
@ -1033,6 +1042,26 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
self.currentAudioOutputValue = output
var shouldMonitorProximity = false
switch output {
case .builtin:
shouldMonitorProximity = true
default:
break
}
if shouldMonitorProximity {
if self.proximityManagerIndex == nil {
self.proximityManagerIndex = DeviceProximityManager.shared().add { _ in
}
}
} else {
if let proximityManagerIndex = self.proximityManagerIndex {
self.proximityManagerIndex = nil
DeviceProximityManager.shared().remove(proximityManagerIndex)
}
}
self.audioOutputStatePromise.set(.single((self.audioOutputStateValue.0, output))
|> then(
.single(self.audioOutputStateValue)

View File

@ -100,6 +100,9 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
if (flags & Int32(1 << 23)) != 0 {
channelFlags.insert(.hasVoiceChat)
}
if (flags & Int32(1 << 24)) != 0 {
channelFlags.insert(.hasActiveVoiceChat)
}
let restrictionInfo: PeerAccessRestrictionInfo?
if let restrictionReason = restrictionReason {

View File

@ -440,6 +440,15 @@ public func stopGroupCall(account: Account, peerId: PeerId, callId: Int64, acces
return cachedData
}
})
if var peer = transaction.getPeer(peerId) as? TelegramChannel {
var flags = peer.flags
flags.remove(.hasVoiceChat)
flags.remove(.hasActiveVoiceChat)
peer = peer.withUpdatedFlags(flags)
updatePeers(transaction: transaction, peers: [peer], update: { _, updated in
return updated
})
}
account.stateManager.addUpdates(result)
}

View File

@ -729,6 +729,8 @@ final class AuthorizedApplicationContext {
}
}))
})
self.rootController.setForceInCallStatusBar((self.context.sharedContext as! SharedAccountContextImpl).currentCallStatusBarNode)
}
deinit {

View File

@ -94,7 +94,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
private var callDisposable: Disposable?
private var callStateDisposable: Disposable?
private var currentCallStatusBarNode: CallStatusBarNodeImpl?
private(set) var currentCallStatusBarNode: CallStatusBarNodeImpl?
private var groupCallDisposable: Disposable?