Voice Chat fixes

This commit is contained in:
Ali 2020-11-29 22:01:17 +04:00
parent 2889bae353
commit e6c91a905d
15 changed files with 4569 additions and 4678 deletions

View File

@ -5933,8 +5933,23 @@ Sorry for the inconvenience.";
"VoiceChat.RemovePeerConfirmation" = "Are you sure you want to remove %@ from the group chat?"; "VoiceChat.RemovePeerConfirmation" = "Are you sure you want to remove %@ from the group chat?";
"VoiceChat.RemovePeerRemove" = "Remove"; "VoiceChat.RemovePeerRemove" = "Remove";
"VoiceChat.PanelJoin" = "Join";
"VoiceChat.Title" = "Voice Chat";
"Message.VoiceChat.Started" = "Voice chat started";
"Message.VoiceChat.Ended" = "Voice chat ended";
"VoiceChat.StatusMembersSpeaking_0" = "%@ members speaking";
"VoiceChat.StatusMembersSpeaking_1" = "1 member speaking";
"VoiceChat.StatusMembersSpeaking_2" = "2 members speaking";
"VoiceChat.StatusMembersSpeaking_3_10" = "%@ members speaking";
"VoiceChat.StatusMembersSpeaking_many" = "%@ members speaking";
"VoiceChat.StatusMembersSpeaking_any" = "%@ members speaking";
"VoiceChat.UserInvited" = "You invited **%@** to the voice chat"; "VoiceChat.UserInvited" = "You invited **%@** to the voice chat";
"PeerInfo.CreateVoiceChat" = "Create Voice Chat";
"Notification.VoiceChatInvitation" = "%1$@ invited %2$@ to the voice chat"; "Notification.VoiceChatInvitation" = "%1$@ invited %2$@ to the voice chat";
"Notification.VoiceChatInvitationByYou" = "You invited %1$@ to the voice chat"; "Notification.VoiceChatInvitationByYou" = "You invited %1$@ to the voice chat";
"Notification.VoiceChatInvitationForYou" = "%1$@ invited you to the voice chat"; "Notification.VoiceChatInvitationForYou" = "%1$@ invited you to the voice chat";

View File

@ -390,6 +390,8 @@ open class NavigationController: UINavigationController, ContainableController,
globalScrollToTopNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -1.0), size: CGSize(width: layout.size.width, height: 1.0)) globalScrollToTopNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -1.0), size: CGSize(width: layout.size.width, height: 1.0))
} }
var overlayContainerLayout = layout
if let inCallStatusBar = self.inCallStatusBar { if let inCallStatusBar = self.inCallStatusBar {
var inCallStatusBarFrame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: max(layout.statusBarHeight ?? 0.0, max(40.0, layout.safeInsets.top)))) var inCallStatusBarFrame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: max(layout.statusBarHeight ?? 0.0, max(40.0, layout.safeInsets.top))))
if layout.deviceMetrics.hasTopNotch { if layout.deviceMetrics.hasTopNotch {
@ -541,8 +543,8 @@ open class NavigationController: UINavigationController, ContainableController,
containerTransition = transition containerTransition = transition
} }
containerTransition.updateFrame(node: overlayContainer, frame: CGRect(origin: CGPoint(), size: layout.size)) containerTransition.updateFrame(node: overlayContainer, frame: CGRect(origin: CGPoint(), size: overlayContainerLayout.size))
overlayContainer.update(layout: layout, transition: containerTransition) overlayContainer.update(layout: overlayContainerLayout, transition: containerTransition)
modalStyleOverlayTransitionFactor = max(modalStyleOverlayTransitionFactor, overlayContainer.controller.modalStyleOverlayTransitionFactor) modalStyleOverlayTransitionFactor = max(modalStyleOverlayTransitionFactor, overlayContainer.controller.modalStyleOverlayTransitionFactor)
@ -586,7 +588,7 @@ open class NavigationController: UINavigationController, ContainableController,
var previousModalContainer: NavigationModalContainer? var previousModalContainer: NavigationModalContainer?
var visibleModalCount = 0 var visibleModalCount = 0
var topModalIsFlat = false var topModalIsFlat = false
var isLandscape = layout.orientation == .landscape let isLandscape = layout.orientation == .landscape
var hasVisibleStandaloneModal = false var hasVisibleStandaloneModal = false
var topModalDismissProgress: CGFloat = 0.0 var topModalDismissProgress: CGFloat = 0.0

View File

@ -263,7 +263,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-309990731] = { return Api.Update.parse_updatePinnedMessages($0) } dict[-309990731] = { return Api.Update.parse_updatePinnedMessages($0) }
dict[-2054649973] = { return Api.Update.parse_updatePinnedChannelMessages($0) } dict[-2054649973] = { return Api.Update.parse_updatePinnedChannelMessages($0) }
dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) } dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
dict[-2046916883] = { return Api.Update.parse_updateGroupCall($0) } dict[1462009966] = { return Api.Update.parse_updateGroupCall($0) }
dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) } dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) } dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) } dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }

View File

@ -6346,7 +6346,7 @@ public extension Api {
case updatePinnedMessages(flags: Int32, peer: Api.Peer, messages: [Int32], pts: Int32, ptsCount: Int32) case updatePinnedMessages(flags: Int32, peer: Api.Peer, messages: [Int32], pts: Int32, ptsCount: Int32)
case updatePinnedChannelMessages(flags: Int32, channelId: Int32, messages: [Int32], pts: Int32, ptsCount: Int32) case updatePinnedChannelMessages(flags: Int32, channelId: Int32, messages: [Int32], pts: Int32, ptsCount: Int32)
case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32) case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
case updateGroupCall(call: Api.GroupCall) case updateGroupCall(channelId: Int32, call: Api.GroupCall)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -7094,10 +7094,11 @@ public extension Api {
} }
serializeInt32(version, buffer: buffer, boxed: false) serializeInt32(version, buffer: buffer, boxed: false)
break break
case .updateGroupCall(let call): case .updateGroupCall(let channelId, let call):
if boxed { if boxed {
buffer.appendInt32(-2046916883) buffer.appendInt32(1462009966)
} }
serializeInt32(channelId, buffer: buffer, boxed: false)
call.serialize(buffer, true) call.serialize(buffer, true)
break break
} }
@ -7277,8 +7278,8 @@ public extension Api {
return ("updatePinnedChannelMessages", [("flags", flags), ("channelId", channelId), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)]) return ("updatePinnedChannelMessages", [("flags", flags), ("channelId", channelId), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)])
case .updateGroupCallParticipants(let call, let participants, let version): case .updateGroupCallParticipants(let call, let participants, let version):
return ("updateGroupCallParticipants", [("call", call), ("participants", participants), ("version", version)]) return ("updateGroupCallParticipants", [("call", call), ("participants", participants), ("version", version)])
case .updateGroupCall(let call): case .updateGroupCall(let channelId, let call):
return ("updateGroupCall", [("call", call)]) return ("updateGroupCall", [("channelId", channelId), ("call", call)])
} }
} }
@ -8773,13 +8774,16 @@ public extension Api {
} }
} }
public static func parse_updateGroupCall(_ reader: BufferReader) -> Update? { public static func parse_updateGroupCall(_ reader: BufferReader) -> Update? {
var _1: Api.GroupCall? var _1: Int32?
_1 = reader.readInt32()
var _2: Api.GroupCall?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.GroupCall _2 = Api.parse(reader, signature: signature) as? Api.GroupCall
} }
let _c1 = _1 != nil let _c1 = _1 != nil
if _c1 { let _c2 = _2 != nil
return Api.Update.updateGroupCall(call: _1!) if _c1 && _c2 {
return Api.Update.updateGroupCall(channelId: _1!, call: _2!)
} }
else { else {
return nil return nil

View File

@ -211,14 +211,13 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
self.separatorNode.backgroundColor = presentationData.theme.chat.historyNavigation.strokeColor self.separatorNode.backgroundColor = presentationData.theme.chat.historyNavigation.strokeColor
self.joinButtonTitleNode.attributedText = NSAttributedString(string: presentationData.strings.Channel_JoinChannel.uppercased(), font: Font.semibold(15.0), textColor: presentationData.theme.chat.inputPanel.actionControlForegroundColor) self.joinButtonTitleNode.attributedText = NSAttributedString(string: presentationData.strings.VoiceChat_PanelJoin.uppercased(), font: Font.semibold(15.0), textColor: presentationData.theme.chat.inputPanel.actionControlForegroundColor)
self.joinButtonBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 28.0, color: presentationData.theme.chat.inputPanel.actionControlFillColor) self.joinButtonBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 28.0, color: presentationData.theme.chat.inputPanel.actionControlFillColor)
//TODO:localize //TODO:localize
self.micButtonBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 36.0, color: UIColor(rgb: 0x30b251)) self.micButtonBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 36.0, color: UIColor(rgb: 0x30b251))
//TODO:localize self.titleNode.attributedText = NSAttributedString(string: presentationData.strings.VoiceChat_Title, font: Font.semibold(15.0), textColor: presentationData.theme.chat.inputPanel.primaryTextColor)
self.titleNode.attributedText = NSAttributedString(string: "Voice Chat", font: Font.semibold(15.0), textColor: presentationData.theme.chat.inputPanel.primaryTextColor)
self.textNode.attributedText = NSAttributedString(string: self.textNode.attributedText?.string ?? "", font: Font.regular(13.0), textColor: presentationData.theme.chat.inputPanel.secondaryTextColor) self.textNode.attributedText = NSAttributedString(string: self.textNode.attributedText?.string ?? "", font: Font.regular(13.0), textColor: presentationData.theme.chat.inputPanel.secondaryTextColor)
self.muteIconNode.image = PresentationResourcesChat.chatTitleMuteIcon(presentationData.theme) self.muteIconNode.image = PresentationResourcesChat.chatTitleMuteIcon(presentationData.theme)
@ -253,12 +252,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
let membersText: String let membersText: String
let membersTextIsActive: Bool let membersTextIsActive: Bool
if summaryState.numberOfActiveSpeakers != 0 { if summaryState.numberOfActiveSpeakers != 0 {
//TODO:localize membersText = strongSelf.strings.VoiceChat_StatusMembersSpeaking(Int32(summaryState.numberOfActiveSpeakers))
if summaryState.numberOfActiveSpeakers == 1 {
membersText = "1 member speaking"
} else {
membersText = "\(summaryState.numberOfActiveSpeakers) members speaking"
}
membersTextIsActive = true membersTextIsActive = true
} else { } else {
if summaryState.participantCount == 0 { if summaryState.participantCount == 0 {
@ -290,12 +284,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
let membersText: String let membersText: String
let membersTextIsActive: Bool let membersTextIsActive: Bool
if data.numberOfActiveSpeakers != 0 { if data.numberOfActiveSpeakers != 0 {
//TODO:localize membersText = self.strings.VoiceChat_StatusMembersSpeaking(Int32(data.numberOfActiveSpeakers))
if data.numberOfActiveSpeakers == 1 {
membersText = "1 member speaking"
} else {
membersText = "\(data.numberOfActiveSpeakers) members speaking"
}
membersTextIsActive = true membersTextIsActive = true
} else { } else {
if data.participantCount == 0 { if data.participantCount == 0 {

View File

@ -487,10 +487,9 @@ public final class VoiceChatController: ViewController {
strongSelf.currentCallMembers = callMembers.participants strongSelf.currentCallMembers = callMembers.participants
} }
//TODO:localize
let subtitle = strongSelf.presentationData.strings.Conversation_StatusMembers(Int32(callMembers.totalCount)) let subtitle = strongSelf.presentationData.strings.Conversation_StatusMembers(Int32(callMembers.totalCount))
if let titleView = strongSelf.controller?.navigationItem.titleView as? VoiceChatControllerTitleView { if let titleView = strongSelf.controller?.navigationItem.titleView as? VoiceChatControllerTitleView {
titleView.set(title: "Voice Chat", subtitle: subtitle) titleView.set(title: strongSelf.presentationData.strings.VoiceChat_Title, subtitle: subtitle)
} }
}) })

View File

@ -111,7 +111,7 @@ enum AccountStateMutationOperation {
case UpdateChatListFilter(id: Int32, filter: Api.DialogFilter?) case UpdateChatListFilter(id: Int32, filter: Api.DialogFilter?)
case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?) case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?)
case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32) case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32)
case UpdateGroupCall(call: Api.GroupCall) case UpdateGroupCall(peerId: PeerId, call: Api.GroupCall)
} }
struct HoleFromPreviousState { struct HoleFromPreviousState {
@ -282,8 +282,8 @@ struct AccountMutableState {
self.addOperation(.UpdateGroupCallParticipants(id: id, accessHash: accessHash, participants: participants, version: version)) self.addOperation(.UpdateGroupCallParticipants(id: id, accessHash: accessHash, participants: participants, version: version))
} }
mutating func updateGroupCall(call: Api.GroupCall) { mutating func updateGroupCall(peerId: PeerId, call: Api.GroupCall) {
self.addOperation(.UpdateGroupCall(call: call)) self.addOperation(.UpdateGroupCall(peerId: peerId, call: call))
} }
mutating func readGroupFeedInbox(groupId: PeerGroupId, index: MessageIndex) { mutating func readGroupFeedInbox(groupId: PeerGroupId, index: MessageIndex) {

View File

@ -1332,8 +1332,8 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
case let .inputGroupCall(id, accessHash): case let .inputGroupCall(id, accessHash):
updatedState.updateGroupCallParticipants(id: id, accessHash: accessHash, participants: participants, version: version) updatedState.updateGroupCallParticipants(id: id, accessHash: accessHash, participants: participants, version: version)
} }
case let .updateGroupCall(call): case let .updateGroupCall(channelId, call):
updatedState.updateGroupCall(call: call) updatedState.updateGroupCall(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), call: call)
case let .updateLangPackTooLong(langCode): case let .updateLangPackTooLong(langCode):
updatedState.updateLangPack(langCode: langCode, difference: nil) updatedState.updateLangPack(langCode: langCode, difference: nil)
case let .updateLangPack(difference): case let .updateLangPack(difference):
@ -2959,15 +2959,35 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
callId, callId,
.state(update: GroupCallParticipantsContext.Update.StateUpdate(participants: participants, version: version)) .state(update: GroupCallParticipantsContext.Update.StateUpdate(participants: participants, version: version))
)) ))
case let .UpdateGroupCall(call): case let .UpdateGroupCall(peerId, call):
switch call { switch call {
case .groupCall: case .groupCall:
break if let info = GroupCallInfo(call) {
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
if let current = current as? CachedChannelData {
return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash))
} else {
return current
}
})
}
case let .groupCallDiscarded(callId, _, _): case let .groupCallDiscarded(callId, _, _):
updatedGroupCallParticipants.append(( updatedGroupCallParticipants.append((
callId, callId,
.call(isTerminated: true) .call(isTerminated: true)
)) ))
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
if let current = current as? CachedChannelData {
if let activeCall = current.activeCall, activeCall.id == callId {
return current.withUpdatedActiveCall(nil)
} else {
return current
}
} else {
return current
}
})
} }
case let .UpdateLangPack(langCode, difference): case let .UpdateLangPack(langCode, difference):
if let difference = difference { if let difference = difference {

View File

@ -28,7 +28,7 @@ public struct GroupCallSummary: Equatable {
public var topParticipants: [GroupCallParticipantsContext.Participant] public var topParticipants: [GroupCallParticipantsContext.Participant]
} }
private extension GroupCallInfo { extension GroupCallInfo {
init?(_ call: Api.GroupCall) { init?(_ call: Api.GroupCall) {
switch call { switch call {
case let .groupCall(_, id, accessHash, participantCount, params, _): case let .groupCall(_, id, accessHash, participantCount, params, _):
@ -142,7 +142,7 @@ public func createGroupCall(account: Account, peerId: PeerId) -> Signal<GroupCal
var parsedCall: GroupCallInfo? var parsedCall: GroupCallInfo?
loop: for update in result.allUpdates { loop: for update in result.allUpdates {
switch update { switch update {
case let .updateGroupCall(call): case let .updateGroupCall(_, call):
parsedCall = GroupCallInfo(call) parsedCall = GroupCallInfo(call)
break loop break loop
default: default:
@ -316,7 +316,7 @@ public func joinGroupCall(account: Account, peerId: PeerId, callId: Int64, acces
var maybeParsedCall: GroupCallInfo? var maybeParsedCall: GroupCallInfo?
loop: for update in updates.allUpdates { loop: for update in updates.allUpdates {
switch update { switch update {
case let .updateGroupCall(call): case let .updateGroupCall(_, call):
maybeParsedCall = GroupCallInfo(call) maybeParsedCall = GroupCallInfo(call)
break loop break loop
default: default:

View File

@ -405,12 +405,11 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
} }
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor)
case let .groupPhoneCall(_, _, duration): case let .groupPhoneCall(_, _, duration):
//TODO:localize
let titleString: String let titleString: String
if let duration = duration { if let duration = duration {
titleString = "Voice chat ended (\(duration)s)" titleString = strings.Message_VoiceChat_Ended
} else { } else {
titleString = "Voice chat started" titleString = strings.Message_VoiceChat_Started
} }
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor)
case let .customText(text, entities): case let .customText(text, entities):

View File

@ -1,153 +0,0 @@
import Foundation
import UIKit
import Display
import AsyncDisplayKit
import Postbox
import TelegramCore
import SyncCore
import SwiftSignalKit
import TelegramPresentationData
import TelegramUIPreferences
import AccountContext
import StickerResources
import PhotoResources
import TelegramStringFormatting
import AnimatedCountLabelNode
import AnimatedNavigationStripeNode
import ContextUI
import RadialStatusNode
import AnimatedAvatarSetNode
final class ChatCallTitlePanelNode: ChatTitleAccessoryPanelNode {
private let context: AccountContext
private let tapButton: HighlightTrackingButtonNode
private let joinButton: HighlightableButtonNode
private let joinButtonTitleNode: ImmediateTextNode
private let joinButtonBackgroundNode: ASImageNode
private let titleNode: ImmediateTextNode
private let textNode: ImmediateTextNode
private let muteIconNode: ASImageNode
private let separatorNode: ASDisplayNode
private var theme: PresentationTheme?
private var currentLayout: (CGFloat, CGFloat, CGFloat)?
private var activeGroupCallInfo: ChatActiveGroupCallInfo?
private let queue = Queue()
init(context: AccountContext) {
self.context = context
self.tapButton = HighlightTrackingButtonNode()
self.joinButton = HighlightableButtonNode()
self.joinButtonTitleNode = ImmediateTextNode()
self.joinButtonBackgroundNode = ASImageNode()
self.titleNode = ImmediateTextNode()
self.textNode = ImmediateTextNode()
self.muteIconNode = ASImageNode()
self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true
super.init()
self.tapButton.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self {
if highlighted {
strongSelf.titleNode.layer.removeAnimation(forKey: "opacity")
strongSelf.titleNode.alpha = 0.4
strongSelf.textNode.layer.removeAnimation(forKey: "opacity")
strongSelf.textNode.alpha = 0.4
} else {
strongSelf.titleNode.alpha = 1.0
strongSelf.titleNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
strongSelf.textNode.alpha = 1.0
strongSelf.textNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
}
}
}
self.addSubnode(self.titleNode)
self.addSubnode(self.textNode)
self.addSubnode(self.muteIconNode)
self.tapButton.addTarget(self, action: #selector(self.tapped), forControlEvents: [.touchUpInside])
self.addSubnode(self.tapButton)
self.joinButton.addSubnode(self.joinButtonBackgroundNode)
self.joinButton.addSubnode(self.joinButtonTitleNode)
self.addSubnode(self.joinButton)
self.joinButton.addTarget(self, action: #selector(self.tapped), forControlEvents: [.touchUpInside])
self.addSubnode(self.separatorNode)
}
deinit {
}
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat {
let panelHeight: CGFloat = 50.0
self.tapButton.frame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: panelHeight))
self.activeGroupCallInfo = interfaceState.activeGroupCallInfo
if self.theme !== interfaceState.theme {
self.theme = interfaceState.theme
self.backgroundColor = interfaceState.theme.chat.historyNavigation.fillColor
self.separatorNode.backgroundColor = interfaceState.theme.chat.historyNavigation.strokeColor
self.joinButtonTitleNode.attributedText = NSAttributedString(string: interfaceState.strings.Channel_JoinChannel.uppercased(), font: Font.semibold(15.0), textColor: interfaceState.theme.chat.inputPanel.actionControlForegroundColor)
self.joinButtonBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 28.0, color: interfaceState.theme.chat.inputPanel.actionControlFillColor)
//TODO:localize
self.titleNode.attributedText = NSAttributedString(string: "Voice Chat", font: Font.semibold(15.0), textColor: interfaceState.theme.chat.inputPanel.primaryTextColor)
self.textNode.attributedText = NSAttributedString(string: "4 members", font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
self.muteIconNode.image = PresentationResourcesChat.chatTitleMuteIcon(interfaceState.theme)
}
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: 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))
let titleSize = self.titleNode.updateLayout(CGSize(width: width, height: .greatestFiniteMagnitude))
let textSize = self.textNode.updateLayout(CGSize(width: width, height: .greatestFiniteMagnitude))
let titleFrame = CGRect(origin: CGPoint(x: floor((width - titleSize.width) / 2.0), y: 10.0), size: titleSize)
transition.updateFrame(node: self.titleNode, frame: titleFrame)
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floor((width - textSize.width) / 2.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))
}
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: panelHeight - UIScreenPixel), size: CGSize(width: width, height: UIScreenPixel)))
return panelHeight
}
@objc private func tapped() {
guard let interfaceInteraction = self.interfaceInteraction else {
return
}
guard let activeGroupCallInfo = self.activeGroupCallInfo else {
return
}
interfaceInteraction.joinGroupCall(activeGroupCallInfo.activeCall)
}
}

View File

@ -2968,8 +2968,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
} else if let channel = peer as? TelegramChannel { } else if let channel = peer as? TelegramChannel {
if case .group = channel.info, !channel.flags.contains(.hasVoiceChat) { if case .group = channel.info, !channel.flags.contains(.hasVoiceChat) {
if channel.flags.contains(.isCreator) || channel.hasPermission(.manageCalls) { if channel.flags.contains(.isCreator) || channel.hasPermission(.manageCalls) {
//TODO:localize items.append(ActionSheetButtonItem(title: presentationData.strings.PeerInfo_CreateVoiceChat, color: .accent, action: { [weak self] in
items.append(ActionSheetButtonItem(title: "Create Voice Chat", color: .accent, action: { [weak self] in
dismissAction() dismissAction()
self?.requestCall(isVideo: false) self?.requestCall(isVideo: false)
})) }))

View File

@ -133,9 +133,16 @@ public final class SharedWakeupManager {
return call?.account.id == account.id return call?.account.id == account.id
} }
|> distinctUntilChanged |> distinctUntilChanged
let isPlayingBackgroundActiveCall = combineLatest(queue: .mainQueue(), hasActiveCalls, hasActiveAudioSession)
|> map { hasActiveCalls, hasActiveAudioSession -> Bool in let hasActiveGroupCalls = (callManager?.currentGroupCallSignal ?? .single(nil))
return hasActiveCalls && hasActiveAudioSession |> map { call in
return call?.accountContext.account.id == account.id
}
|> distinctUntilChanged
let isPlayingBackgroundActiveCall = combineLatest(queue: .mainQueue(), hasActiveCalls, hasActiveGroupCalls, hasActiveAudioSession)
|> map { hasActiveCalls, hasActiveGroupCalls, hasActiveAudioSession -> Bool in
return (hasActiveCalls || hasActiveGroupCalls) && hasActiveAudioSession
} }
|> distinctUntilChanged |> distinctUntilChanged