mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-05 14:02:48 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
a7d322999a
BIN
Telegram/Telegram-iOS/Resources/VoiceCancelReminder.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/VoiceCancelReminder.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/VoiceCancelReminderToMute.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/VoiceCancelReminderToMute.tgs
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/VoiceMuteToRaiseHand.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/VoiceMuteToRaiseHand.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/VoiceRaiseHandToMute.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/VoiceRaiseHandToMute.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/VoiceSetReminder.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/VoiceSetReminder.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/VoiceSetReminderToMute.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/VoiceSetReminderToMute.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/VoiceSetReminderToRaiseHand.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/VoiceSetReminderToRaiseHand.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/VoiceUnmuteToRaiseHand.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/VoiceUnmuteToRaiseHand.tgs
Normal file
Binary file not shown.
@ -187,6 +187,7 @@ public struct PresentationGroupCallState: Equatable {
|
|||||||
public var title: String?
|
public var title: String?
|
||||||
public var raisedHand: Bool
|
public var raisedHand: Bool
|
||||||
public var scheduleTimestamp: Int32?
|
public var scheduleTimestamp: Int32?
|
||||||
|
public var subscribedToScheduled: Bool
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
myPeerId: PeerId,
|
myPeerId: PeerId,
|
||||||
@ -198,7 +199,8 @@ public struct PresentationGroupCallState: Equatable {
|
|||||||
recordingStartTimestamp: Int32?,
|
recordingStartTimestamp: Int32?,
|
||||||
title: String?,
|
title: String?,
|
||||||
raisedHand: Bool,
|
raisedHand: Bool,
|
||||||
scheduleTimestamp: Int32?
|
scheduleTimestamp: Int32?,
|
||||||
|
subscribedToScheduled: Bool
|
||||||
) {
|
) {
|
||||||
self.myPeerId = myPeerId
|
self.myPeerId = myPeerId
|
||||||
self.networkState = networkState
|
self.networkState = networkState
|
||||||
@ -210,6 +212,7 @@ public struct PresentationGroupCallState: Equatable {
|
|||||||
self.title = title
|
self.title = title
|
||||||
self.raisedHand = raisedHand
|
self.raisedHand = raisedHand
|
||||||
self.scheduleTimestamp = scheduleTimestamp
|
self.scheduleTimestamp = scheduleTimestamp
|
||||||
|
self.subscribedToScheduled = subscribedToScheduled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,6 +326,7 @@ public protocol PresentationGroupCall: class {
|
|||||||
var memberEvents: Signal<PresentationGroupCallMemberEvent, NoError> { get }
|
var memberEvents: Signal<PresentationGroupCallMemberEvent, NoError> { get }
|
||||||
var reconnectedAsEvents: Signal<Peer, NoError> { get }
|
var reconnectedAsEvents: Signal<Peer, NoError> { get }
|
||||||
|
|
||||||
|
func toggleScheduledSubscription(_ subscribe: Bool)
|
||||||
func schedule(timestamp: Int32)
|
func schedule(timestamp: Int32)
|
||||||
func startScheduled()
|
func startScheduled()
|
||||||
|
|
||||||
|
|||||||
@ -160,20 +160,20 @@ public final class CachedChannelData: CachedPeerData {
|
|||||||
public var accessHash: Int64
|
public var accessHash: Int64
|
||||||
public var title: String?
|
public var title: String?
|
||||||
public var scheduleTimestamp: Int32?
|
public var scheduleTimestamp: Int32?
|
||||||
public var subscribed: Bool
|
public var subscribedToScheduled: Bool
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
id: Int64,
|
id: Int64,
|
||||||
accessHash: Int64,
|
accessHash: Int64,
|
||||||
title: String?,
|
title: String?,
|
||||||
scheduleTimestamp: Int32?,
|
scheduleTimestamp: Int32?,
|
||||||
subscribed: Bool
|
subscribedToScheduled: Bool
|
||||||
) {
|
) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.accessHash = accessHash
|
self.accessHash = accessHash
|
||||||
self.title = title
|
self.title = title
|
||||||
self.scheduleTimestamp = scheduleTimestamp
|
self.scheduleTimestamp = scheduleTimestamp
|
||||||
self.subscribed = subscribed
|
self.subscribedToScheduled = subscribedToScheduled
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
@ -181,7 +181,7 @@ public final class CachedChannelData: CachedPeerData {
|
|||||||
self.accessHash = decoder.decodeInt64ForKey("accessHash", orElse: 0)
|
self.accessHash = decoder.decodeInt64ForKey("accessHash", orElse: 0)
|
||||||
self.title = decoder.decodeOptionalStringForKey("title")
|
self.title = decoder.decodeOptionalStringForKey("title")
|
||||||
self.scheduleTimestamp = decoder.decodeOptionalInt32ForKey("scheduleTimestamp")
|
self.scheduleTimestamp = decoder.decodeOptionalInt32ForKey("scheduleTimestamp")
|
||||||
self.subscribed = decoder.decodeBoolForKey("subscribed", orElse: false)
|
self.subscribedToScheduled = decoder.decodeBoolForKey("subscribed", orElse: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -197,7 +197,7 @@ public final class CachedChannelData: CachedPeerData {
|
|||||||
} else {
|
} else {
|
||||||
encoder.encodeNil(forKey: "scheduleTimestamp")
|
encoder.encodeNil(forKey: "scheduleTimestamp")
|
||||||
}
|
}
|
||||||
encoder.encodeBool(self.subscribed, forKey: "subscribed")
|
encoder.encodeBool(self.subscribedToScheduled, forKey: "subscribed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -406,7 +406,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
|||||||
strongSelf.joinGroupCall(
|
strongSelf.joinGroupCall(
|
||||||
peerId: groupCallPanelData.peerId,
|
peerId: groupCallPanelData.peerId,
|
||||||
invite: nil,
|
invite: nil,
|
||||||
activeCall: CachedChannelData.ActiveCall(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash, title: groupCallPanelData.info.title, scheduleTimestamp: groupCallPanelData.info.scheduleTimestamp, subscribed: false)
|
activeCall: CachedChannelData.ActiveCall(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash, title: groupCallPanelData.info.title, scheduleTimestamp: groupCallPanelData.info.scheduleTimestamp, subscribedToScheduled: groupCallPanelData.info.subscribedToScheduled)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
if let navigationBar = self.navigationBar {
|
if let navigationBar = self.navigationBar {
|
||||||
|
|||||||
@ -505,7 +505,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
|
|||||||
transition.updateFrame(node: self.avatarsNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - avatarsSize.width) / 2.0), y: floor((size.height - avatarsSize.height) / 2.0)), size: avatarsSize))
|
transition.updateFrame(node: self.avatarsNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - avatarsSize.width) / 2.0), y: floor((size.height - avatarsSize.height) / 2.0)), size: avatarsSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
var joinText = self.strings.VoiceChat_PanelJoin.uppercased()
|
var joinText = self.strings.VoiceChat_PanelJoin
|
||||||
var title = self.strings.VoiceChat_Title
|
var title = self.strings.VoiceChat_Title
|
||||||
var text = self.currentText
|
var text = self.currentText
|
||||||
var isScheduled = false
|
var isScheduled = false
|
||||||
@ -554,7 +554,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
|
|||||||
self.updateJoinButton()
|
self.updateJoinButton()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.joinButtonTitleNode.attributedText = NSAttributedString(string: joinText, font: Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.theme.chat.inputPanel.actionControlForegroundColor)
|
self.joinButtonTitleNode.attributedText = NSAttributedString(string: joinText.uppercased(), font: Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.theme.chat.inputPanel.actionControlForegroundColor)
|
||||||
|
|
||||||
let joinButtonTitleSize = self.joinButtonTitleNode.updateLayout(CGSize(width: 150.0, height: .greatestFiniteMagnitude))
|
let joinButtonTitleSize = self.joinButtonTitleNode.updateLayout(CGSize(width: 150.0, height: .greatestFiniteMagnitude))
|
||||||
let joinButtonSize = CGSize(width: joinButtonTitleSize.width + 20.0, height: 28.0)
|
let joinButtonSize = CGSize(width: joinButtonTitleSize.width + 20.0, height: 28.0)
|
||||||
|
|||||||
@ -78,6 +78,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext {
|
|||||||
streamDcId: nil,
|
streamDcId: nil,
|
||||||
title: call.title,
|
title: call.title,
|
||||||
scheduleTimestamp: call.scheduleTimestamp,
|
scheduleTimestamp: call.scheduleTimestamp,
|
||||||
|
subscribedToScheduled: call.subscribedToScheduled,
|
||||||
recordingStartTimestamp: nil,
|
recordingStartTimestamp: nil,
|
||||||
sortAscending: true
|
sortAscending: true
|
||||||
),
|
),
|
||||||
@ -121,7 +122,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext {
|
|||||||
}
|
}
|
||||||
return GroupCallPanelData(
|
return GroupCallPanelData(
|
||||||
peerId: peerId,
|
peerId: peerId,
|
||||||
info: GroupCallInfo(id: call.id, accessHash: call.accessHash, participantCount: state.totalCount, clientParams: nil, streamDcId: nil, title: state.title, scheduleTimestamp: state.scheduleTimestamp, recordingStartTimestamp: nil, sortAscending: state.sortAscending),
|
info: GroupCallInfo(id: call.id, accessHash: call.accessHash, participantCount: state.totalCount, clientParams: nil, streamDcId: nil, title: state.title, scheduleTimestamp: state.scheduleTimestamp, subscribedToScheduled: state.subscribedToScheduled, recordingStartTimestamp: nil, sortAscending: state.sortAscending),
|
||||||
topParticipants: topParticipants,
|
topParticipants: topParticipants,
|
||||||
participantCount: state.totalCount,
|
participantCount: state.totalCount,
|
||||||
activeSpeakers: activeSpeakers,
|
activeSpeakers: activeSpeakers,
|
||||||
@ -206,7 +207,7 @@ public final class AccountGroupCallContextCacheImpl: AccountGroupCallContextCach
|
|||||||
}
|
}
|
||||||
|
|
||||||
private extension PresentationGroupCallState {
|
private extension PresentationGroupCallState {
|
||||||
static func initialValue(myPeerId: PeerId, title: String?, scheduleTimestamp: Int32?) -> PresentationGroupCallState {
|
static func initialValue(myPeerId: PeerId, title: String?, scheduleTimestamp: Int32?, subscribedToScheduled: Bool) -> PresentationGroupCallState {
|
||||||
return PresentationGroupCallState(
|
return PresentationGroupCallState(
|
||||||
myPeerId: myPeerId,
|
myPeerId: myPeerId,
|
||||||
networkState: .connecting,
|
networkState: .connecting,
|
||||||
@ -217,7 +218,8 @@ private extension PresentationGroupCallState {
|
|||||||
recordingStartTimestamp: nil,
|
recordingStartTimestamp: nil,
|
||||||
title: title,
|
title: title,
|
||||||
raisedHand: false,
|
raisedHand: false,
|
||||||
scheduleTimestamp: scheduleTimestamp
|
scheduleTimestamp: scheduleTimestamp,
|
||||||
|
subscribedToScheduled: subscribedToScheduled
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,6 +513,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
private let joinDisposable = MetaDisposable()
|
private let joinDisposable = MetaDisposable()
|
||||||
private let requestDisposable = MetaDisposable()
|
private let requestDisposable = MetaDisposable()
|
||||||
private let startDisposable = MetaDisposable()
|
private let startDisposable = MetaDisposable()
|
||||||
|
private let subscribeDisposable = MetaDisposable()
|
||||||
private var groupCallParticipantUpdatesDisposable: Disposable?
|
private var groupCallParticipantUpdatesDisposable: Disposable?
|
||||||
|
|
||||||
private let networkStateDisposable = MetaDisposable()
|
private let networkStateDisposable = MetaDisposable()
|
||||||
@ -579,7 +582,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
self.joinAsPeerId = joinAsPeerId ?? accountContext.account.peerId
|
self.joinAsPeerId = joinAsPeerId ?? accountContext.account.peerId
|
||||||
self.schedulePending = initialCall == nil
|
self.schedulePending = initialCall == nil
|
||||||
|
|
||||||
self.stateValue = PresentationGroupCallState.initialValue(myPeerId: self.joinAsPeerId, title: initialCall?.title, scheduleTimestamp: initialCall?.scheduleTimestamp)
|
self.stateValue = PresentationGroupCallState.initialValue(myPeerId: self.joinAsPeerId, title: initialCall?.title, scheduleTimestamp: initialCall?.scheduleTimestamp, subscribedToScheduled: initialCall?.subscribedToScheduled ?? false)
|
||||||
self.statePromise = ValuePromise(self.stateValue)
|
self.statePromise = ValuePromise(self.stateValue)
|
||||||
|
|
||||||
self.temporaryJoinTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
self.temporaryJoinTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||||
@ -734,7 +737,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
addedParticipants.append((ssrc, participantUpdate.jsonParams))
|
addedParticipants.append((ssrc, participantUpdate.jsonParams))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .call(isTerminated, _, _, _):
|
case let .call(isTerminated, _, _, _, _):
|
||||||
if isTerminated {
|
if isTerminated {
|
||||||
strongSelf.markAsCanBeRemoved()
|
strongSelf.markAsCanBeRemoved()
|
||||||
}
|
}
|
||||||
@ -767,7 +770,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if let initialCall = initialCall, let temporaryParticipantsContext = (self.accountContext.cachedGroupCallContexts as? AccountGroupCallContextCacheImpl)?.impl.syncWith({ impl in
|
if let initialCall = initialCall, let temporaryParticipantsContext = (self.accountContext.cachedGroupCallContexts as? AccountGroupCallContextCacheImpl)?.impl.syncWith({ impl in
|
||||||
impl.get(account: accountContext.account, peerId: peerId, call: CachedChannelData.ActiveCall(id: initialCall.id, accessHash: initialCall.accessHash, title: initialCall.title, scheduleTimestamp: initialCall.scheduleTimestamp, subscribed: initialCall.subscribed))
|
impl.get(account: accountContext.account, peerId: peerId, call: CachedChannelData.ActiveCall(id: initialCall.id, accessHash: initialCall.accessHash, title: initialCall.title, scheduleTimestamp: initialCall.scheduleTimestamp, subscribedToScheduled: initialCall.subscribedToScheduled))
|
||||||
}) {
|
}) {
|
||||||
self.switchToTemporaryParticipantsContext(sourceContext: temporaryParticipantsContext.context.participantsContext, oldMyPeerId: self.joinAsPeerId)
|
self.switchToTemporaryParticipantsContext(sourceContext: temporaryParticipantsContext.context.participantsContext, oldMyPeerId: self.joinAsPeerId)
|
||||||
} else {
|
} else {
|
||||||
@ -824,6 +827,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
self.joinDisposable.dispose()
|
self.joinDisposable.dispose()
|
||||||
self.requestDisposable.dispose()
|
self.requestDisposable.dispose()
|
||||||
self.startDisposable.dispose()
|
self.startDisposable.dispose()
|
||||||
|
self.subscribeDisposable.dispose()
|
||||||
self.groupCallParticipantUpdatesDisposable?.dispose()
|
self.groupCallParticipantUpdatesDisposable?.dispose()
|
||||||
self.leaveDisposable.dispose()
|
self.leaveDisposable.dispose()
|
||||||
self.isMutedDisposable.dispose()
|
self.isMutedDisposable.dispose()
|
||||||
@ -1666,6 +1670,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
streamDcId: nil,
|
streamDcId: nil,
|
||||||
title: state.title,
|
title: state.title,
|
||||||
scheduleTimestamp: state.scheduleTimestamp,
|
scheduleTimestamp: state.scheduleTimestamp,
|
||||||
|
subscribedToScheduled: false,
|
||||||
recordingStartTimestamp: state.recordingStartTimestamp,
|
recordingStartTimestamp: state.recordingStartTimestamp,
|
||||||
sortAscending: state.sortAscending
|
sortAscending: state.sortAscending
|
||||||
))))
|
))))
|
||||||
@ -1987,6 +1992,17 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
self.callContext?.setIsNoiseSuppressionEnabled(isNoiseSuppressionEnabled)
|
self.callContext?.setIsNoiseSuppressionEnabled(isNoiseSuppressionEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func toggleScheduledSubscription(_ subscribe: Bool) {
|
||||||
|
guard case let .active(callInfo) = self.internalState, callInfo.scheduleTimestamp != nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.stateValue.subscribedToScheduled = subscribe
|
||||||
|
|
||||||
|
self.subscribeDisposable.set((toggleScheduledGroupCallSubscription(account: self.account, peerId: self.peerId, callId: callInfo.id, accessHash: callInfo.accessHash, subscribe: subscribe)
|
||||||
|
|> deliverOnMainQueue).start())
|
||||||
|
}
|
||||||
|
|
||||||
public func schedule(timestamp: Int32) {
|
public func schedule(timestamp: Int32) {
|
||||||
guard self.schedulePending else {
|
guard self.schedulePending else {
|
||||||
return
|
return
|
||||||
@ -2270,7 +2286,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let value = value {
|
if let value = value {
|
||||||
strongSelf.initialCall = CachedChannelData.ActiveCall(id: value.id, accessHash: value.accessHash, title: value.title, scheduleTimestamp: nil, subscribed: false)
|
strongSelf.initialCall = CachedChannelData.ActiveCall(id: value.id, accessHash: value.accessHash, title: value.title, scheduleTimestamp: nil, subscribedToScheduled: false)
|
||||||
|
|
||||||
strongSelf.updateSessionState(internalState: .active(value), audioSessionControl: strongSelf.audioSessionControl)
|
strongSelf.updateSessionState(internalState: .active(value), audioSessionControl: strongSelf.audioSessionControl)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -607,11 +607,11 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
self.maskProgressLayer.lineCap = .round
|
self.maskProgressLayer.lineCap = .round
|
||||||
self.maskProgressLayer.path = path
|
self.maskProgressLayer.path = path
|
||||||
|
|
||||||
let circleFrame = CGRect(origin: CGPoint(x: (358 - buttonSize.width) / 2.0, y: (358 - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0)
|
let circleFrame = CGRect(origin: CGPoint(x: (areaSize.width - buttonSize.width) / 2.0, y: (areaSize.height - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0)
|
||||||
let largerCirclePath = UIBezierPath(roundedRect: CGRect(x: circleFrame.minX, y: circleFrame.minY, width: circleFrame.width, height: circleFrame.height), cornerRadius: circleFrame.width / 2.0).cgPath
|
let largerCirclePath = UIBezierPath(roundedRect: CGRect(x: circleFrame.minX, y: circleFrame.minY, width: circleFrame.width, height: circleFrame.height), cornerRadius: circleFrame.width / 2.0).cgPath
|
||||||
|
|
||||||
self.maskCircleLayer.fillColor = white.cgColor
|
|
||||||
self.maskCircleLayer.path = largerCirclePath
|
self.maskCircleLayer.path = largerCirclePath
|
||||||
|
self.maskCircleLayer.fillColor = white.cgColor
|
||||||
self.maskCircleLayer.isHidden = true
|
self.maskCircleLayer.isHidden = true
|
||||||
|
|
||||||
updateInHierarchy = { [weak self] value in
|
updateInHierarchy = { [weak self] value in
|
||||||
@ -971,6 +971,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
CATransaction.commit()
|
CATransaction.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var maskIsCircle = true
|
||||||
private func setupButtonAnimation() {
|
private func setupButtonAnimation() {
|
||||||
CATransaction.begin()
|
CATransaction.begin()
|
||||||
CATransaction.setDisableActions(true)
|
CATransaction.setDisableActions(true)
|
||||||
@ -982,6 +983,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
let path = UIBezierPath(roundedRect: CGRect(x: 0.0, y: floor((self.bounds.height - buttonHeight) / 2.0), width: self.bounds.width, height: buttonHeight), cornerRadius: 10.0).cgPath
|
let path = UIBezierPath(roundedRect: CGRect(x: 0.0, y: floor((self.bounds.height - buttonHeight) / 2.0), width: self.bounds.width, height: buttonHeight), cornerRadius: 10.0).cgPath
|
||||||
self.maskCircleLayer.path = path
|
self.maskCircleLayer.path = path
|
||||||
|
self.maskIsCircle = false
|
||||||
|
|
||||||
CATransaction.commit()
|
CATransaction.commit()
|
||||||
|
|
||||||
@ -1001,6 +1003,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
let previousPath = self.maskCircleLayer.path
|
let previousPath = self.maskCircleLayer.path
|
||||||
self.maskCircleLayer.path = largerCirclePath
|
self.maskCircleLayer.path = largerCirclePath
|
||||||
|
self.maskIsCircle = true
|
||||||
|
|
||||||
self.maskCircleLayer.animateSpring(from: previousPath as AnyObject, to: largerCirclePath as AnyObject, keyPath: "path", duration: 0.42, initialVelocity: 0.0, damping: 104.0)
|
self.maskCircleLayer.animateSpring(from: previousPath as AnyObject, to: largerCirclePath as AnyObject, keyPath: "path", duration: 0.42, initialVelocity: 0.0, damping: 104.0)
|
||||||
|
|
||||||
@ -1144,9 +1147,13 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
self.updateAnimations()
|
self.updateAnimations()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var previousSize: CGSize?
|
||||||
override func layout() {
|
override func layout() {
|
||||||
super.layout()
|
super.layout()
|
||||||
|
|
||||||
|
let sizeUpdated = self.previousSize != self.bounds.size
|
||||||
|
self.previousSize = self.bounds.size
|
||||||
|
|
||||||
let bounds = CGRect(x: (self.bounds.width - areaSize.width) / 2.0, y: (self.bounds.height - areaSize.height) / 2.0, width: areaSize.width, height: areaSize.height)
|
let bounds = CGRect(x: (self.bounds.width - areaSize.width) / 2.0, y: (self.bounds.height - areaSize.height) / 2.0, width: areaSize.width, height: areaSize.height)
|
||||||
let center = bounds.center
|
let center = bounds.center
|
||||||
|
|
||||||
@ -1159,7 +1166,17 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
self.growingForegroundCircleLayer.position = center
|
self.growingForegroundCircleLayer.position = center
|
||||||
self.growingForegroundCircleLayer.bounds = self.foregroundCircleLayer.bounds
|
self.growingForegroundCircleLayer.bounds = self.foregroundCircleLayer.bounds
|
||||||
self.maskCircleLayer.frame = self.bounds
|
self.maskCircleLayer.frame = self.bounds
|
||||||
// circleFrame.insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0)
|
|
||||||
|
if sizeUpdated && self.maskIsCircle {
|
||||||
|
CATransaction.begin()
|
||||||
|
CATransaction.setDisableActions(true)
|
||||||
|
let circleFrame = CGRect(origin: CGPoint(x: (self.bounds.width - buttonSize.width) / 2.0, y: (self.bounds.height - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0)
|
||||||
|
let largerCirclePath = UIBezierPath(roundedRect: CGRect(x: circleFrame.minX, y: circleFrame.minY, width: circleFrame.width, height: circleFrame.height), cornerRadius: circleFrame.width / 2.0).cgPath
|
||||||
|
|
||||||
|
self.maskCircleLayer.path = largerCirclePath
|
||||||
|
CATransaction.commit()
|
||||||
|
}
|
||||||
|
|
||||||
self.maskProgressLayer.frame = circleFrame.insetBy(dx: -3.0, dy: -3.0)
|
self.maskProgressLayer.frame = circleFrame.insetBy(dx: -3.0, dy: -3.0)
|
||||||
self.foregroundView.frame = self.bounds
|
self.foregroundView.frame = self.bounds
|
||||||
self.foregroundGradientLayer.frame = self.bounds
|
self.foregroundGradientLayer.frame = self.bounds
|
||||||
@ -1543,22 +1560,22 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode {
|
|||||||
case .subscribe:
|
case .subscribe:
|
||||||
switch state {
|
switch state {
|
||||||
case .unsubscribe:
|
case .unsubscribe:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminder")))
|
||||||
case .mute:
|
case .mute:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToMute")))
|
||||||
case .hand:
|
case .hand:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToRaiseHand")))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case .unsubscribe:
|
case .unsubscribe:
|
||||||
switch state {
|
switch state {
|
||||||
case .subscribe:
|
case .subscribe:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminder")))
|
||||||
case .mute:
|
case .mute:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToMute")))
|
||||||
case .hand:
|
case .hand:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToRaiseHand")))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -1574,7 +1591,7 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode {
|
|||||||
case .mute:
|
case .mute:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceMute")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceMute")))
|
||||||
case .hand:
|
case .hand:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOff2")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmuteToRaiseHand")))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -1585,7 +1602,11 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode {
|
|||||||
case .unmute:
|
case .unmute:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmute")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmute")))
|
||||||
case .hand:
|
case .hand:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOff")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceMuteToRaiseHand")))
|
||||||
|
case .subscribe:
|
||||||
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToRaiseHand"), frames: .range(startFrame: 0, endFrame: 0), duration: 0.001))
|
||||||
|
case .unsubscribe:
|
||||||
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToRaiseHand"), frames: .range(startFrame: 0, endFrame: 0), duration: 0.001))
|
||||||
case .empty:
|
case .empty:
|
||||||
self.alpha = 0.0
|
self.alpha = 0.0
|
||||||
default:
|
default:
|
||||||
@ -1594,7 +1615,7 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode {
|
|||||||
case .hand:
|
case .hand:
|
||||||
switch state {
|
switch state {
|
||||||
case .mute, .unmute:
|
case .mute, .unmute:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOn")))
|
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceRaiseHandToMute")))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2438,8 +2438,12 @@ public final class VoiceChatController: ViewController {
|
|||||||
|
|
||||||
@objc func dimTapGesture(_ recognizer: UITapGestureRecognizer) {
|
@objc func dimTapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||||
if case .ended = recognizer.state {
|
if case .ended = recognizer.state {
|
||||||
self.controller?.dismiss(closing: false)
|
if self.isScheduling {
|
||||||
self.controller?.dismissAllTooltips()
|
self.dismissScheduled()
|
||||||
|
} else {
|
||||||
|
self.controller?.dismiss(closing: false)
|
||||||
|
self.controller?.dismissAllTooltips()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2594,7 +2598,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
self.call.startScheduled()
|
self.call.startScheduled()
|
||||||
self.transitionToCall()
|
self.transitionToCall()
|
||||||
} else {
|
} else {
|
||||||
|
self.call.toggleScheduledSubscription(!callState.subscribedToScheduled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -2670,8 +2674,6 @@ public final class VoiceChatController: ViewController {
|
|||||||
|> deliverOnMainQueue).start(next: { [weak self] inviteLinks in
|
|> deliverOnMainQueue).start(next: { [weak self] inviteLinks in
|
||||||
if let inviteLinks = inviteLinks {
|
if let inviteLinks = inviteLinks {
|
||||||
self?.presentShare(inviteLinks)
|
self?.presentShare(inviteLinks)
|
||||||
} else {
|
|
||||||
self?.presentShare(GroupCallInviteLinks(listenerLink: "a", speakerLink: nil))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@ -3199,16 +3201,20 @@ public final class VoiceChatController: ViewController {
|
|||||||
let actionButtonSubtitle: String
|
let actionButtonSubtitle: String
|
||||||
var actionButtonEnabled = true
|
var actionButtonEnabled = true
|
||||||
if let callState = self.callState, !self.isScheduling {
|
if let callState = self.callState, !self.isScheduling {
|
||||||
var isScheduled = callState.scheduleTimestamp != nil
|
if callState.scheduleTimestamp != nil {
|
||||||
if isScheduled {
|
|
||||||
self.ignoreNextConnecting = true
|
self.ignoreNextConnecting = true
|
||||||
if callState.canManageCall {
|
if callState.canManageCall {
|
||||||
actionButtonState = .scheduled(state: .start)
|
actionButtonState = .scheduled(state: .start)
|
||||||
actionButtonTitle = self.presentationData.strings.VoiceChat_StartNow
|
actionButtonTitle = self.presentationData.strings.VoiceChat_StartNow
|
||||||
actionButtonSubtitle = ""
|
actionButtonSubtitle = ""
|
||||||
} else {
|
} else {
|
||||||
actionButtonState = .scheduled(state: .subscribe)
|
if callState.subscribedToScheduled {
|
||||||
actionButtonTitle = self.presentationData.strings.VoiceChat_SetReminder
|
actionButtonState = .scheduled(state: .unsubscribe)
|
||||||
|
actionButtonTitle = self.presentationData.strings.VoiceChat_CancelReminder
|
||||||
|
} else {
|
||||||
|
actionButtonState = .scheduled(state: .subscribe)
|
||||||
|
actionButtonTitle = self.presentationData.strings.VoiceChat_SetReminder
|
||||||
|
}
|
||||||
actionButtonSubtitle = ""
|
actionButtonSubtitle = ""
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3681,6 +3687,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
|
|
||||||
@objc func panGesture(_ recognizer: UIPanGestureRecognizer) {
|
@objc func panGesture(_ recognizer: UIPanGestureRecognizer) {
|
||||||
let contentOffset = self.listNode.visibleContentOffset()
|
let contentOffset = self.listNode.visibleContentOffset()
|
||||||
|
let isScheduling = self.isScheduling || self.callState?.scheduleTimestamp != nil
|
||||||
switch recognizer.state {
|
switch recognizer.state {
|
||||||
case .began:
|
case .began:
|
||||||
let topInset: CGFloat
|
let topInset: CGFloat
|
||||||
@ -3696,7 +3703,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
self.controller?.dismissAllTooltips()
|
self.controller?.dismissAllTooltips()
|
||||||
case .changed:
|
case .changed:
|
||||||
var translation = recognizer.translation(in: self.contentContainer.view).y
|
var translation = recognizer.translation(in: self.contentContainer.view).y
|
||||||
if (self.isScheduling || self.callState?.scheduleTimestamp != nil) && translation < 0.0 {
|
if isScheduling && translation < 0.0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var topInset: CGFloat = 0.0
|
var topInset: CGFloat = 0.0
|
||||||
@ -3802,7 +3809,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
self.controller?.dismiss(closing: false, manual: true)
|
self.controller?.dismiss(closing: false, manual: true)
|
||||||
}
|
}
|
||||||
dismissing = true
|
dismissing = true
|
||||||
} else if !self.isScheduling && (velocity.y < -300.0 || offset < topInset / 2.0) {
|
} else if !isScheduling && (velocity.y < -300.0 || offset < topInset / 2.0) {
|
||||||
if velocity.y > -1500.0 && !self.isFullscreen {
|
if velocity.y > -1500.0 && !self.isFullscreen {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||||
@ -3819,7 +3826,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
self.updateFloatingHeaderOffset(offset: self.currentContentOffset ?? 0.0, transition: .animated(duration: 0.3, curve: .easeInOut), completion: {
|
self.updateFloatingHeaderOffset(offset: self.currentContentOffset ?? 0.0, transition: .animated(duration: 0.3, curve: .easeInOut), completion: {
|
||||||
self.animatingExpansion = false
|
self.animatingExpansion = false
|
||||||
})
|
})
|
||||||
} else if !self.isScheduling {
|
} else if !isScheduling {
|
||||||
self.updateIsFullscreen(false)
|
self.updateIsFullscreen(false)
|
||||||
self.animatingExpansion = true
|
self.animatingExpansion = true
|
||||||
self.listNode.scroller.setContentOffset(CGPoint(), animated: false)
|
self.listNode.scroller.setContentOffset(CGPoint(), animated: false)
|
||||||
|
|||||||
@ -144,8 +144,8 @@ public final class VoiceChatJoinScreen: ViewController {
|
|||||||
} else if let cachedData = cachedData as? CachedGroupData {
|
} else if let cachedData = cachedData as? CachedGroupData {
|
||||||
defaultJoinAsPeerId = cachedData.callJoinPeerId
|
defaultJoinAsPeerId = cachedData.callJoinPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
let activeCall = CachedChannelData.ActiveCall(id: call.info.id, accessHash: call.info.accessHash, title: call.info.title, scheduleTimestamp: call.info.scheduleTimestamp, subscribed: false)
|
let activeCall = CachedChannelData.ActiveCall(id: call.info.id, accessHash: call.info.accessHash, title: call.info.title, scheduleTimestamp: call.info.scheduleTimestamp, subscribedToScheduled: call.info.subscribedToScheduled)
|
||||||
if availablePeers.count > 0 && defaultJoinAsPeerId == nil {
|
if availablePeers.count > 0 && defaultJoinAsPeerId == nil {
|
||||||
strongSelf.dismiss()
|
strongSelf.dismiss()
|
||||||
strongSelf.join(activeCall)
|
strongSelf.join(activeCall)
|
||||||
|
|||||||
@ -136,7 +136,7 @@ final class VoiceChatTimerNode: ASDisplayNode {
|
|||||||
|
|
||||||
self.subtitleNode.attributedText = NSAttributedString(string: subtitle, font: Font.with(size: 21.0, design: .round, weight: .semibold, traits: []), textColor: .white)
|
self.subtitleNode.attributedText = NSAttributedString(string: subtitle, font: Font.with(size: 21.0, design: .round, weight: .semibold, traits: []), textColor: .white)
|
||||||
let subtitleSize = self.subtitleNode.updateLayout(size)
|
let subtitleSize = self.subtitleNode.updateLayout(size)
|
||||||
self.subtitleNode.frame = CGRect(x: floor((size.width - subtitleSize.width) / 2.0), y: 164.0, width: timerSize.width, height: subtitleSize.height)
|
self.subtitleNode.frame = CGRect(x: floor((size.width - subtitleSize.width) / 2.0), y: 164.0, width: subtitleSize.width, height: subtitleSize.height)
|
||||||
|
|
||||||
self.foregroundView.frame = CGRect(origin: CGPoint(), size: size)
|
self.foregroundView.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ public struct GroupCallInfo: Equatable {
|
|||||||
public var streamDcId: Int32?
|
public var streamDcId: Int32?
|
||||||
public var title: String?
|
public var title: String?
|
||||||
public var scheduleTimestamp: Int32?
|
public var scheduleTimestamp: Int32?
|
||||||
|
public var subscribedToScheduled: Bool
|
||||||
public var recordingStartTimestamp: Int32?
|
public var recordingStartTimestamp: Int32?
|
||||||
public var sortAscending: Bool
|
public var sortAscending: Bool
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ public struct GroupCallInfo: Equatable {
|
|||||||
streamDcId: Int32?,
|
streamDcId: Int32?,
|
||||||
title: String?,
|
title: String?,
|
||||||
scheduleTimestamp: Int32?,
|
scheduleTimestamp: Int32?,
|
||||||
|
subscribedToScheduled: Bool,
|
||||||
recordingStartTimestamp: Int32?,
|
recordingStartTimestamp: Int32?,
|
||||||
sortAscending: Bool
|
sortAscending: Bool
|
||||||
) {
|
) {
|
||||||
@ -33,6 +35,7 @@ public struct GroupCallInfo: Equatable {
|
|||||||
self.streamDcId = streamDcId
|
self.streamDcId = streamDcId
|
||||||
self.title = title
|
self.title = title
|
||||||
self.scheduleTimestamp = scheduleTimestamp
|
self.scheduleTimestamp = scheduleTimestamp
|
||||||
|
self.subscribedToScheduled = subscribedToScheduled
|
||||||
self.recordingStartTimestamp = recordingStartTimestamp
|
self.recordingStartTimestamp = recordingStartTimestamp
|
||||||
self.sortAscending = sortAscending
|
self.sortAscending = sortAscending
|
||||||
}
|
}
|
||||||
@ -62,6 +65,7 @@ extension GroupCallInfo {
|
|||||||
streamDcId: streamDcId,
|
streamDcId: streamDcId,
|
||||||
title: title,
|
title: title,
|
||||||
scheduleTimestamp: scheduleDate,
|
scheduleTimestamp: scheduleDate,
|
||||||
|
subscribedToScheduled: (flags & (1 << 8)) != 0,
|
||||||
recordingStartTimestamp: recordStartDate,
|
recordingStartTimestamp: recordStartDate,
|
||||||
sortAscending: (flags & (1 << 6)) != 0
|
sortAscending: (flags & (1 << 6)) != 0
|
||||||
)
|
)
|
||||||
@ -226,9 +230,9 @@ public func createGroupCall(account: Account, peerId: PeerId, title: String?, sc
|
|||||||
return account.postbox.transaction { transaction -> GroupCallInfo in
|
return account.postbox.transaction { transaction -> GroupCallInfo in
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
||||||
if let cachedData = cachedData as? CachedChannelData {
|
if let cachedData = cachedData as? CachedChannelData {
|
||||||
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: false))
|
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled))
|
||||||
} else if let cachedData = cachedData as? CachedGroupData {
|
} else if let cachedData = cachedData as? CachedGroupData {
|
||||||
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: false))
|
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled))
|
||||||
} else {
|
} else {
|
||||||
return cachedData
|
return cachedData
|
||||||
}
|
}
|
||||||
@ -271,9 +275,9 @@ public func startScheduledGroupCall(account: Account, peerId: PeerId, callId: In
|
|||||||
return account.postbox.transaction { transaction -> GroupCallInfo in
|
return account.postbox.transaction { transaction -> GroupCallInfo in
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
||||||
if let cachedData = cachedData as? CachedChannelData {
|
if let cachedData = cachedData as? CachedChannelData {
|
||||||
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribed: false))
|
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribedToScheduled: false))
|
||||||
} else if let cachedData = cachedData as? CachedGroupData {
|
} else if let cachedData = cachedData as? CachedGroupData {
|
||||||
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribed: false))
|
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribedToScheduled: false))
|
||||||
} else {
|
} else {
|
||||||
return cachedData
|
return cachedData
|
||||||
}
|
}
|
||||||
@ -315,9 +319,9 @@ public func toggleScheduledGroupCallSubscription(account: Account, peerId: PeerI
|
|||||||
return account.postbox.transaction { transaction in
|
return account.postbox.transaction { transaction in
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
||||||
if let cachedData = cachedData as? CachedChannelData {
|
if let cachedData = cachedData as? CachedChannelData {
|
||||||
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: subscribe))
|
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled))
|
||||||
} else if let cachedData = cachedData as? CachedGroupData {
|
} else if let cachedData = cachedData as? CachedGroupData {
|
||||||
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: subscribe))
|
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled))
|
||||||
} else {
|
} else {
|
||||||
return cachedData
|
return cachedData
|
||||||
}
|
}
|
||||||
@ -373,19 +377,19 @@ public enum GetGroupCallParticipantsError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func getGroupCallParticipants(account: Account, callId: Int64, accessHash: Int64, offset: String, ssrcs: [UInt32], limit: Int32, sortAscending: Bool?) -> Signal<GroupCallParticipantsContext.State, GetGroupCallParticipantsError> {
|
public func getGroupCallParticipants(account: Account, callId: Int64, accessHash: Int64, offset: String, ssrcs: [UInt32], limit: Int32, sortAscending: Bool?) -> Signal<GroupCallParticipantsContext.State, GetGroupCallParticipantsError> {
|
||||||
let sortAscendingValue: Signal<(Bool, Int32?), GetGroupCallParticipantsError>
|
let sortAscendingValue: Signal<(Bool, Int32?, Bool), GetGroupCallParticipantsError>
|
||||||
if let sortAscending = sortAscending {
|
if let sortAscending = sortAscending {
|
||||||
sortAscendingValue = .single((sortAscending, nil))
|
sortAscendingValue = .single((sortAscending, nil, false))
|
||||||
} else {
|
} else {
|
||||||
sortAscendingValue = getCurrentGroupCall(account: account, callId: callId, accessHash: accessHash)
|
sortAscendingValue = getCurrentGroupCall(account: account, callId: callId, accessHash: accessHash)
|
||||||
|> mapError { _ -> GetGroupCallParticipantsError in
|
|> mapError { _ -> GetGroupCallParticipantsError in
|
||||||
return .generic
|
return .generic
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<(Bool, Int32?), GetGroupCallParticipantsError> in
|
|> mapToSignal { result -> Signal<(Bool, Int32?, Bool), GetGroupCallParticipantsError> in
|
||||||
guard let result = result else {
|
guard let result = result else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
return .single((result.info.sortAscending, result.info.scheduleTimestamp))
|
return .single((result.info.sortAscending, result.info.scheduleTimestamp, result.info.subscribedToScheduled))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +407,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
|
|||||||
let version: Int32
|
let version: Int32
|
||||||
let nextParticipantsFetchOffset: String?
|
let nextParticipantsFetchOffset: String?
|
||||||
|
|
||||||
let (sortAscendingValue, scheduleTimestamp) = sortAscendingAndScheduleTimestamp
|
let (sortAscendingValue, scheduleTimestamp, subscribedToScheduled) = sortAscendingAndScheduleTimestamp
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case let .groupParticipants(count, participants, nextOffset, chats, users, apiVersion):
|
case let .groupParticipants(count, participants, nextOffset, chats, users, apiVersion):
|
||||||
@ -492,6 +496,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
|
|||||||
recordingStartTimestamp: nil,
|
recordingStartTimestamp: nil,
|
||||||
title: nil,
|
title: nil,
|
||||||
scheduleTimestamp: scheduleTimestamp,
|
scheduleTimestamp: scheduleTimestamp,
|
||||||
|
subscribedToScheduled: subscribedToScheduled,
|
||||||
totalCount: totalCount,
|
totalCount: totalCount,
|
||||||
version: version
|
version: version
|
||||||
)
|
)
|
||||||
@ -668,9 +673,9 @@ public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, cal
|
|||||||
return account.postbox.transaction { transaction -> JoinGroupCallResult in
|
return account.postbox.transaction { transaction -> JoinGroupCallResult in
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
||||||
if let cachedData = cachedData as? CachedChannelData {
|
if let cachedData = cachedData as? CachedChannelData {
|
||||||
return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribed: false))
|
return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribedToScheduled: false))
|
||||||
} else if let cachedData = cachedData as? CachedGroupData {
|
} else if let cachedData = cachedData as? CachedGroupData {
|
||||||
return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribed: false))
|
return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribedToScheduled: false))
|
||||||
} else {
|
} else {
|
||||||
return cachedData
|
return cachedData
|
||||||
}
|
}
|
||||||
@ -1011,6 +1016,7 @@ public final class GroupCallParticipantsContext {
|
|||||||
public var recordingStartTimestamp: Int32?
|
public var recordingStartTimestamp: Int32?
|
||||||
public var title: String?
|
public var title: String?
|
||||||
public var scheduleTimestamp: Int32?
|
public var scheduleTimestamp: Int32?
|
||||||
|
public var subscribedToScheduled: Bool
|
||||||
public var totalCount: Int
|
public var totalCount: Int
|
||||||
public var version: Int32
|
public var version: Int32
|
||||||
|
|
||||||
@ -1123,7 +1129,7 @@ public final class GroupCallParticipantsContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case state(update: StateUpdate)
|
case state(update: StateUpdate)
|
||||||
case call(isTerminated: Bool, defaultParticipantsAreMuted: State.DefaultParticipantsAreMuted, title: String?, recordingStartTimestamp: Int32?)
|
case call(isTerminated: Bool, defaultParticipantsAreMuted: State.DefaultParticipantsAreMuted, title: String?, recordingStartTimestamp: Int32?, scheduleTimestamp: Int32?)
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class MemberEvent {
|
public final class MemberEvent {
|
||||||
@ -1313,6 +1319,7 @@ public final class GroupCallParticipantsContext {
|
|||||||
recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp,
|
recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp,
|
||||||
title: strongSelf.stateValue.state.title,
|
title: strongSelf.stateValue.state.title,
|
||||||
scheduleTimestamp: strongSelf.stateValue.state.scheduleTimestamp,
|
scheduleTimestamp: strongSelf.stateValue.state.scheduleTimestamp,
|
||||||
|
subscribedToScheduled: strongSelf.stateValue.state.subscribedToScheduled,
|
||||||
totalCount: strongSelf.stateValue.state.totalCount,
|
totalCount: strongSelf.stateValue.state.totalCount,
|
||||||
version: strongSelf.stateValue.state.version
|
version: strongSelf.stateValue.state.version
|
||||||
),
|
),
|
||||||
@ -1368,11 +1375,12 @@ public final class GroupCallParticipantsContext {
|
|||||||
for update in updates {
|
for update in updates {
|
||||||
if case let .state(update) = update {
|
if case let .state(update) = update {
|
||||||
stateUpdates.append(update)
|
stateUpdates.append(update)
|
||||||
} else if case let .call(_, defaultParticipantsAreMuted, title, recordingStartTimestamp) = update {
|
} else if case let .call(_, defaultParticipantsAreMuted, title, recordingStartTimestamp, scheduleTimestamp) = update {
|
||||||
var state = self.stateValue.state
|
var state = self.stateValue.state
|
||||||
state.defaultParticipantsAreMuted = defaultParticipantsAreMuted
|
state.defaultParticipantsAreMuted = defaultParticipantsAreMuted
|
||||||
state.recordingStartTimestamp = recordingStartTimestamp
|
state.recordingStartTimestamp = recordingStartTimestamp
|
||||||
state.title = title
|
state.title = title
|
||||||
|
state.scheduleTimestamp = scheduleTimestamp
|
||||||
|
|
||||||
self.stateValue.state = state
|
self.stateValue.state = state
|
||||||
}
|
}
|
||||||
@ -1446,6 +1454,7 @@ public final class GroupCallParticipantsContext {
|
|||||||
recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp,
|
recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp,
|
||||||
title: strongSelf.stateValue.state.title,
|
title: strongSelf.stateValue.state.title,
|
||||||
scheduleTimestamp: strongSelf.stateValue.state.scheduleTimestamp,
|
scheduleTimestamp: strongSelf.stateValue.state.scheduleTimestamp,
|
||||||
|
subscribedToScheduled: strongSelf.stateValue.state.subscribedToScheduled,
|
||||||
totalCount: strongSelf.stateValue.state.totalCount,
|
totalCount: strongSelf.stateValue.state.totalCount,
|
||||||
version: strongSelf.stateValue.state.version
|
version: strongSelf.stateValue.state.version
|
||||||
),
|
),
|
||||||
@ -1662,6 +1671,7 @@ public final class GroupCallParticipantsContext {
|
|||||||
let recordingStartTimestamp = strongSelf.stateValue.state.recordingStartTimestamp
|
let recordingStartTimestamp = strongSelf.stateValue.state.recordingStartTimestamp
|
||||||
let title = strongSelf.stateValue.state.title
|
let title = strongSelf.stateValue.state.title
|
||||||
let scheduleTimestamp = strongSelf.stateValue.state.scheduleTimestamp
|
let scheduleTimestamp = strongSelf.stateValue.state.scheduleTimestamp
|
||||||
|
let subscribedToScheduled = strongSelf.stateValue.state.subscribedToScheduled
|
||||||
|
|
||||||
updatedParticipants.sort(by: { GroupCallParticipantsContext.Participant.compare(lhs: $0, rhs: $1, sortAscending: strongSelf.stateValue.state.sortAscending) })
|
updatedParticipants.sort(by: { GroupCallParticipantsContext.Participant.compare(lhs: $0, rhs: $1, sortAscending: strongSelf.stateValue.state.sortAscending) })
|
||||||
|
|
||||||
@ -1676,6 +1686,7 @@ public final class GroupCallParticipantsContext {
|
|||||||
recordingStartTimestamp: recordingStartTimestamp,
|
recordingStartTimestamp: recordingStartTimestamp,
|
||||||
title: title,
|
title: title,
|
||||||
scheduleTimestamp: scheduleTimestamp,
|
scheduleTimestamp: scheduleTimestamp,
|
||||||
|
subscribedToScheduled: subscribedToScheduled,
|
||||||
totalCount: updatedTotalCount,
|
totalCount: updatedTotalCount,
|
||||||
version: update.version
|
version: update.version
|
||||||
),
|
),
|
||||||
|
|||||||
@ -2982,9 +2982,9 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
if let info = GroupCallInfo(call) {
|
if let info = GroupCallInfo(call) {
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||||
if let current = current as? CachedChannelData {
|
if let current = current as? CachedChannelData {
|
||||||
return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false))
|
return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled))
|
||||||
} else if let current = current as? CachedGroupData {
|
} else if let current = current as? CachedGroupData {
|
||||||
return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false))
|
return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled))
|
||||||
} else {
|
} else {
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
@ -2997,7 +2997,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
let defaultParticipantsAreMuted = GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: isMuted, canChange: canChange)
|
let defaultParticipantsAreMuted = GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: isMuted, canChange: canChange)
|
||||||
updatedGroupCallParticipants.append((
|
updatedGroupCallParticipants.append((
|
||||||
info.id,
|
info.id,
|
||||||
.call(isTerminated: false, defaultParticipantsAreMuted: defaultParticipantsAreMuted, title: title, recordingStartTimestamp: recordStartDate)
|
.call(isTerminated: false, defaultParticipantsAreMuted: defaultParticipantsAreMuted, title: title, recordingStartTimestamp: recordStartDate, scheduleTimestamp: scheduleDate)
|
||||||
))
|
))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@ -3006,7 +3006,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
case let .groupCallDiscarded(callId, _, _):
|
case let .groupCallDiscarded(callId, _, _):
|
||||||
updatedGroupCallParticipants.append((
|
updatedGroupCallParticipants.append((
|
||||||
callId,
|
callId,
|
||||||
.call(isTerminated: true, defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: false, canChange: false), title: nil, recordingStartTimestamp: nil)
|
.call(isTerminated: true, defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: false, canChange: false), title: nil, recordingStartTimestamp: nil, scheduleTimestamp: nil)
|
||||||
))
|
))
|
||||||
|
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||||
|
|||||||
@ -306,7 +306,7 @@ public func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId
|
|||||||
if let inputCall = chatFull.call {
|
if let inputCall = chatFull.call {
|
||||||
switch inputCall {
|
switch inputCall {
|
||||||
case let .inputGroupCall(id, accessHash):
|
case let .inputGroupCall(id, accessHash):
|
||||||
updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribed: previous.activeCall?.subscribed ?? false)
|
updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribedToScheduled: previous.activeCall?.subscribedToScheduled ?? false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +516,7 @@ public func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId
|
|||||||
if let inputCall = inputCall {
|
if let inputCall = inputCall {
|
||||||
switch inputCall {
|
switch inputCall {
|
||||||
case let .inputGroupCall(id, accessHash):
|
case let .inputGroupCall(id, accessHash):
|
||||||
updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribed: previous.activeCall?.subscribed ?? false)
|
updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribedToScheduled: previous.activeCall?.subscribedToScheduled ?? false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -535,7 +535,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
case .groupPhoneCall, .inviteToGroupPhoneCall:
|
case .groupPhoneCall, .inviteToGroupPhoneCall:
|
||||||
if let activeCall = strongSelf.presentationInterfaceState.activeGroupCallInfo?.activeCall {
|
if let activeCall = strongSelf.presentationInterfaceState.activeGroupCallInfo?.activeCall {
|
||||||
strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: activeCall.id, accessHash: activeCall.accessHash, title: activeCall.title, scheduleTimestamp: activeCall.scheduleTimestamp, subscribed: activeCall.subscribed))
|
strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: activeCall.id, accessHash: activeCall.accessHash, title: activeCall.title, scheduleTimestamp: activeCall.scheduleTimestamp, subscribedToScheduled: activeCall.subscribedToScheduled))
|
||||||
} else {
|
} else {
|
||||||
var canManageGroupCalls = false
|
var canManageGroupCalls = false
|
||||||
if let channel = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramChannel {
|
if let channel = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramChannel {
|
||||||
@ -569,7 +569,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false))
|
strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled))
|
||||||
}, error: { [weak self] error in
|
}, error: { [weak self] error in
|
||||||
dismissStatus?()
|
dismissStatus?()
|
||||||
|
|
||||||
|
|||||||
@ -4020,7 +4020,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
}
|
}
|
||||||
strongSelf.context.joinGroupCall(peerId: peerId, invite: nil, requestJoinAsPeerId: { result in
|
strongSelf.context.joinGroupCall(peerId: peerId, invite: nil, requestJoinAsPeerId: { result in
|
||||||
result(joinAsPeerId)
|
result(joinAsPeerId)
|
||||||
}, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: nil, subscribed: false))
|
}, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: nil, subscribedToScheduled: false))
|
||||||
}, error: { [weak self] error in
|
}, error: { [weak self] error in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
@ -4199,7 +4199,9 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||||
if let strongSelf = self, let peer = strongSelf.data?.peer {
|
if let strongSelf = self, let peer = strongSelf.data?.peer {
|
||||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .info(text: presentationData.strings.Conversation_DeletedFromContacts(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
let controller = UndoOverlayController(presentationData: presentationData, content: .info(text: presentationData.strings.Conversation_DeletedFromContacts(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false })
|
||||||
|
controller.keepOnParentDismissal = true
|
||||||
|
strongSelf.controller?.present(controller, in: .window(.root))
|
||||||
|
|
||||||
strongSelf.controller?.dismiss()
|
strongSelf.controller?.dismiss()
|
||||||
}
|
}
|
||||||
@ -6642,12 +6644,12 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
|
|||||||
|
|
||||||
private func dismissAllTooltips() {
|
private func dismissAllTooltips() {
|
||||||
self.window?.forEachController({ controller in
|
self.window?.forEachController({ controller in
|
||||||
if let controller = controller as? UndoOverlayController {
|
if let controller = controller as? UndoOverlayController, !controller.keepOnParentDismissal {
|
||||||
controller.dismissWithCommitAction()
|
controller.dismissWithCommitAction()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
self.forEachController({ controller in
|
self.forEachController({ controller in
|
||||||
if let controller = controller as? UndoOverlayController {
|
if let controller = controller as? UndoOverlayController, !controller.keepOnParentDismissal {
|
||||||
controller.dismissWithCommitAction()
|
controller.dismissWithCommitAction()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -56,6 +56,8 @@ public final class UndoOverlayController: ViewController {
|
|||||||
private var didPlayPresentationAnimation = false
|
private var didPlayPresentationAnimation = false
|
||||||
private var dismissed = false
|
private var dismissed = false
|
||||||
|
|
||||||
|
public var keepOnParentDismissal = false
|
||||||
|
|
||||||
public init(presentationData: PresentationData, content: UndoOverlayContent, elevatedLayout: Bool, animateInAsReplacement: Bool = false, action: @escaping (UndoOverlayAction) -> Bool) {
|
public init(presentationData: PresentationData, content: UndoOverlayContent, elevatedLayout: Bool, animateInAsReplacement: Bool = false, action: @escaping (UndoOverlayAction) -> Bool) {
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
self.content = content
|
self.content = content
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user