mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
1d0bc9ab6f
@ -5946,6 +5946,9 @@ Sorry for the inconvenience.";
|
||||
"VoiceChat.RemovePeerConfirmation" = "Are you sure you want to remove %@ from the group chat?";
|
||||
"VoiceChat.RemovePeerRemove" = "Remove";
|
||||
|
||||
"VoiceChat.PanelJoin" = "Join";
|
||||
"VoiceChat.Title" = "Voice Chat";
|
||||
|
||||
"VoiceChat.UserInvited" = "You invited **%@** to the voice chat";
|
||||
|
||||
"Notification.VoiceChatInvitation" = "%1$@ invited %2$@ to the voice chat";
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
var overlayContainerLayout = layout
|
||||
|
||||
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))))
|
||||
if layout.deviceMetrics.hasTopNotch {
|
||||
@ -541,8 +543,8 @@ open class NavigationController: UINavigationController, ContainableController,
|
||||
containerTransition = transition
|
||||
}
|
||||
|
||||
containerTransition.updateFrame(node: overlayContainer, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||
overlayContainer.update(layout: layout, transition: containerTransition)
|
||||
containerTransition.updateFrame(node: overlayContainer, frame: CGRect(origin: CGPoint(), size: overlayContainerLayout.size))
|
||||
overlayContainer.update(layout: overlayContainerLayout, transition: containerTransition)
|
||||
|
||||
modalStyleOverlayTransitionFactor = max(modalStyleOverlayTransitionFactor, overlayContainer.controller.modalStyleOverlayTransitionFactor)
|
||||
|
||||
@ -586,7 +588,7 @@ open class NavigationController: UINavigationController, ContainableController,
|
||||
var previousModalContainer: NavigationModalContainer?
|
||||
var visibleModalCount = 0
|
||||
var topModalIsFlat = false
|
||||
var isLandscape = layout.orientation == .landscape
|
||||
let isLandscape = layout.orientation == .landscape
|
||||
var hasVisibleStandaloneModal = false
|
||||
var topModalDismissProgress: CGFloat = 0.0
|
||||
|
||||
|
@ -263,7 +263,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-309990731] = { return Api.Update.parse_updatePinnedMessages($0) }
|
||||
dict[-2054649973] = { return Api.Update.parse_updatePinnedChannelMessages($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[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
|
||||
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
|
||||
|
@ -6346,7 +6346,7 @@ public extension Api {
|
||||
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 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) {
|
||||
switch self {
|
||||
@ -7094,10 +7094,11 @@ public extension Api {
|
||||
}
|
||||
serializeInt32(version, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .updateGroupCall(let call):
|
||||
case .updateGroupCall(let channelId, let call):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2046916883)
|
||||
buffer.appendInt32(1462009966)
|
||||
}
|
||||
serializeInt32(channelId, buffer: buffer, boxed: false)
|
||||
call.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
@ -7277,8 +7278,8 @@ public extension Api {
|
||||
return ("updatePinnedChannelMessages", [("flags", flags), ("channelId", channelId), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)])
|
||||
case .updateGroupCallParticipants(let call, let participants, let version):
|
||||
return ("updateGroupCallParticipants", [("call", call), ("participants", participants), ("version", version)])
|
||||
case .updateGroupCall(let call):
|
||||
return ("updateGroupCall", [("call", call)])
|
||||
case .updateGroupCall(let channelId, let call):
|
||||
return ("updateGroupCall", [("channelId", channelId), ("call", call)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -8773,13 +8774,16 @@ public extension Api {
|
||||
}
|
||||
}
|
||||
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() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.GroupCall
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.GroupCall
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.Update.updateGroupCall(call: _1!)
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.Update.updateGroupCall(channelId: _1!, call: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
@ -32,6 +32,15 @@ private class CallStatusBarBackgroundNode: ASDisplayNode {
|
||||
var presentationAudioLevel: CGFloat = 0.0
|
||||
var phase: CGFloat = 0.0
|
||||
|
||||
var transitionArguments: (Double, Double)?
|
||||
var speaking = false {
|
||||
didSet {
|
||||
if self.speaking != oldValue {
|
||||
self.transitionArguments = (CACurrentMediaTime(), 0.3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var animator: ConstantDisplayLinkAnimator?
|
||||
|
||||
override init() {
|
||||
@ -61,7 +70,7 @@ private class CallStatusBarBackgroundNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
override public func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
|
||||
return CallStatusBarBackgroundNodeDrawingState(timestamp: CACurrentMediaTime(), amplitude: self.presentationAudioLevel, phase: self.phase, speaking: false, transitionArguments: nil)
|
||||
return CallStatusBarBackgroundNodeDrawingState(timestamp: CACurrentMediaTime(), amplitude: self.presentationAudioLevel, phase: self.phase, speaking: self.speaking, transitionArguments: self.transitionArguments)
|
||||
}
|
||||
|
||||
@objc override public class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) {
|
||||
@ -96,7 +105,7 @@ private class CallStatusBarBackgroundNode: ASDisplayNode {
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||
|
||||
let position: CGFloat = bounds.height - 6.0
|
||||
let maxAmplitude: CGFloat = 8.0
|
||||
let maxAmplitude: CGFloat = 12.0
|
||||
|
||||
let amplitude = max(0.35, parameters.amplitude)
|
||||
|
||||
@ -126,7 +135,7 @@ private class CallStatusBarBackgroundNode: ASDisplayNode {
|
||||
context.clip()
|
||||
}
|
||||
|
||||
for i in (0 ..< 2).reversed() {
|
||||
for i in (0 ..< 3).reversed() {
|
||||
let progress = 1.0 - CGFloat(i) / 3.0
|
||||
var normalizedAmplitude = (1.5 * progress - 0.8) * amplitude
|
||||
if i == 1 {
|
||||
@ -255,7 +264,7 @@ public class CallStatusBarNodeImpl: CallStatusBarNode {
|
||||
if !strongSelf.currentIsMuted {
|
||||
effectiveLevel = level
|
||||
}
|
||||
strongSelf.backgroundNode.audioLevel = effectiveLevel
|
||||
strongSelf.backgroundNode.audioLevel = max(0.0, min(1.0, effectiveLevel / 8.0))
|
||||
}))
|
||||
}
|
||||
self.didSetupData = true
|
||||
@ -297,6 +306,7 @@ public class CallStatusBarNodeImpl: CallStatusBarNode {
|
||||
self.titleNode.frame = CGRect(origin: CGPoint(x: horizontalOrigin + animationSize + iconSpacing, y: verticalOrigin + floor((contentHeight - titleSize.height) / 2.0)), size: titleSize)
|
||||
self.subtitleNode.frame = CGRect(origin: CGPoint(x: horizontalOrigin + animationSize + iconSpacing + titleSize.width + spacing, y: verticalOrigin + floor((contentHeight - subtitleSize.height) / 2.0)), size: subtitleSize)
|
||||
|
||||
self.backgroundNode.speaking = !self.currentIsMuted
|
||||
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: size.height + 7.0))
|
||||
}
|
||||
}
|
||||
|
@ -211,14 +211,13 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
|
||||
|
||||
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)
|
||||
|
||||
//TODO:localize
|
||||
self.micButtonBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 36.0, color: UIColor(rgb: 0x30b251))
|
||||
|
||||
//TODO:localize
|
||||
self.titleNode.attributedText = NSAttributedString(string: "Voice Chat", font: Font.semibold(15.0), textColor: presentationData.theme.chat.inputPanel.primaryTextColor)
|
||||
self.titleNode.attributedText = NSAttributedString(string: presentationData.strings.VoiceChat_Title, 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.muteIconNode.image = PresentationResourcesChat.chatTitleMuteIcon(presentationData.theme)
|
||||
|
@ -168,9 +168,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
|> map { value -> Bool in
|
||||
switch value {
|
||||
case let .muted(isPushToTalkActive):
|
||||
return isPushToTalkActive
|
||||
return !isPushToTalkActive
|
||||
case .unmuted:
|
||||
return true
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -488,10 +488,9 @@ public final class VoiceChatController: ViewController {
|
||||
strongSelf.currentCallMembers = callMembers.participants
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let subtitle = strongSelf.presentationData.strings.Conversation_StatusMembers(Int32(max(1, callMembers.totalCount)))
|
||||
let subtitle = strongSelf.presentationData.strings.VoiceChat_Panel_Members(Int32(max(1, callMembers.totalCount)))
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
@ -760,13 +759,12 @@ public final class VoiceChatController: ViewController {
|
||||
|
||||
@objc private func actionButtonPressed() {
|
||||
if let callState = self.callState, case .connected = callState.networkState, let muteState = callState.muteState, !muteState.canUnmute {
|
||||
|
||||
self.hapticFeedback.error()
|
||||
self.actionButton.layer.addShakeAnimation()
|
||||
return
|
||||
}
|
||||
|
||||
self.hapticFeedback.error()
|
||||
self.actionButton.layer.addShakeAnimation()
|
||||
// self.call.toggleIsMuted()
|
||||
|
||||
self.call.toggleIsMuted()
|
||||
}
|
||||
|
||||
@objc private func audioOutputPressed() {
|
||||
|
@ -111,7 +111,7 @@ enum AccountStateMutationOperation {
|
||||
case UpdateChatListFilter(id: Int32, filter: Api.DialogFilter?)
|
||||
case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?)
|
||||
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 {
|
||||
@ -282,8 +282,8 @@ struct AccountMutableState {
|
||||
self.addOperation(.UpdateGroupCallParticipants(id: id, accessHash: accessHash, participants: participants, version: version))
|
||||
}
|
||||
|
||||
mutating func updateGroupCall(call: Api.GroupCall) {
|
||||
self.addOperation(.UpdateGroupCall(call: call))
|
||||
mutating func updateGroupCall(peerId: PeerId, call: Api.GroupCall) {
|
||||
self.addOperation(.UpdateGroupCall(peerId: peerId, call: call))
|
||||
}
|
||||
|
||||
mutating func readGroupFeedInbox(groupId: PeerGroupId, index: MessageIndex) {
|
||||
|
@ -1332,8 +1332,8 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
||||
case let .inputGroupCall(id, accessHash):
|
||||
updatedState.updateGroupCallParticipants(id: id, accessHash: accessHash, participants: participants, version: version)
|
||||
}
|
||||
case let .updateGroupCall(call):
|
||||
updatedState.updateGroupCall(call: call)
|
||||
case let .updateGroupCall(channelId, call):
|
||||
updatedState.updateGroupCall(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), call: call)
|
||||
case let .updateLangPackTooLong(langCode):
|
||||
updatedState.updateLangPack(langCode: langCode, difference: nil)
|
||||
case let .updateLangPack(difference):
|
||||
@ -2959,15 +2959,35 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
||||
callId,
|
||||
.state(update: GroupCallParticipantsContext.Update.StateUpdate(participants: participants, version: version))
|
||||
))
|
||||
case let .UpdateGroupCall(call):
|
||||
case let .UpdateGroupCall(peerId, call):
|
||||
switch call {
|
||||
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, _, _):
|
||||
updatedGroupCallParticipants.append((
|
||||
callId,
|
||||
.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):
|
||||
if let difference = difference {
|
||||
|
@ -28,7 +28,7 @@ public struct GroupCallSummary: Equatable {
|
||||
public var topParticipants: [GroupCallParticipantsContext.Participant]
|
||||
}
|
||||
|
||||
private extension GroupCallInfo {
|
||||
extension GroupCallInfo {
|
||||
init?(_ call: Api.GroupCall) {
|
||||
switch call {
|
||||
case let .groupCall(_, id, accessHash, participantCount, params, _):
|
||||
@ -142,7 +142,7 @@ public func createGroupCall(account: Account, peerId: PeerId) -> Signal<GroupCal
|
||||
var parsedCall: GroupCallInfo?
|
||||
loop: for update in result.allUpdates {
|
||||
switch update {
|
||||
case let .updateGroupCall(call):
|
||||
case let .updateGroupCall(_, call):
|
||||
parsedCall = GroupCallInfo(call)
|
||||
break loop
|
||||
default:
|
||||
@ -316,7 +316,7 @@ public func joinGroupCall(account: Account, peerId: PeerId, callId: Int64, acces
|
||||
var maybeParsedCall: GroupCallInfo?
|
||||
loop: for update in updates.allUpdates {
|
||||
switch update {
|
||||
case let .updateGroupCall(call):
|
||||
case let .updateGroupCall(_, call):
|
||||
maybeParsedCall = GroupCallInfo(call)
|
||||
break loop
|
||||
default:
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -133,9 +133,16 @@ public final class SharedWakeupManager {
|
||||
return call?.account.id == account.id
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
let isPlayingBackgroundActiveCall = combineLatest(queue: .mainQueue(), hasActiveCalls, hasActiveAudioSession)
|
||||
|> map { hasActiveCalls, hasActiveAudioSession -> Bool in
|
||||
return hasActiveCalls && hasActiveAudioSession
|
||||
|
||||
let hasActiveGroupCalls = (callManager?.currentGroupCallSignal ?? .single(nil))
|
||||
|> 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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user