mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
WIP
This commit is contained in:
@@ -25,6 +25,34 @@ public enum LocationBroadcastPanelSource {
|
||||
case peer(PeerId)
|
||||
}
|
||||
|
||||
public enum GroupCallPanelSource {
|
||||
case none
|
||||
case all
|
||||
case peer(PeerId)
|
||||
}
|
||||
|
||||
final class GroupCallPanelData {
|
||||
let peerId: PeerId
|
||||
let info: GroupCallInfo
|
||||
let topParticipants: [GroupCallParticipantsContext.Participant]
|
||||
let participantCount: Int
|
||||
let groupCall: PresentationGroupCall?
|
||||
|
||||
init(
|
||||
peerId: PeerId,
|
||||
info: GroupCallInfo,
|
||||
topParticipants: [GroupCallParticipantsContext.Participant],
|
||||
participantCount: Int,
|
||||
groupCall: PresentationGroupCall?
|
||||
) {
|
||||
self.peerId = peerId
|
||||
self.info = info
|
||||
self.topParticipants = topParticipants
|
||||
self.participantCount = participantCount
|
||||
self.groupCall = groupCall
|
||||
}
|
||||
}
|
||||
|
||||
private func presentLiveLocationController(context: AccountContext, peerId: PeerId, controller: ViewController) {
|
||||
let presentImpl: (Message?) -> Void = { [weak controller] message in
|
||||
if let message = message, let strongController = controller {
|
||||
@@ -64,9 +92,11 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
|
||||
public let mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility
|
||||
public let locationBroadcastPanelSource: LocationBroadcastPanelSource
|
||||
public let groupCallPanelSource: GroupCallPanelSource
|
||||
|
||||
private var mediaStatusDisposable: Disposable?
|
||||
private var locationBroadcastDisposable: Disposable?
|
||||
private var currentGroupCallDisposable: Disposable?
|
||||
|
||||
public private(set) var playlistStateAndType: (SharedMediaPlaylistItem, SharedMediaPlaylistItem?, SharedMediaPlaylistItem?, MusicPlaybackSettingsOrder, MediaManagerPlayerType, Account)?
|
||||
private var playlistLocation: SharedMediaPlaylistLocation?
|
||||
@@ -81,6 +111,9 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
private var locationBroadcastMessages: [MessageId: Message]?
|
||||
private var locationBroadcastAccessoryPanel: LocationBroadcastNavigationAccessoryPanel?
|
||||
|
||||
private var groupCallPanelData: GroupCallPanelData?
|
||||
private var groupCallAccessoryPanel: GroupCallNavigationAccessoryPanel?
|
||||
|
||||
private var dismissingPanel: ASDisplayNode?
|
||||
|
||||
private var presentationData: PresentationData
|
||||
@@ -101,6 +134,9 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
|
||||
public var additionalHeight: CGFloat {
|
||||
var height: CGFloat = 0.0
|
||||
if let _ = self.groupCallAccessoryPanel {
|
||||
height += 50.0
|
||||
}
|
||||
if let _ = self.mediaAccessoryPanel {
|
||||
height += MediaNavigationAccessoryHeaderNode.minimizedHeight
|
||||
}
|
||||
@@ -114,11 +150,12 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
return super.navigationHeight
|
||||
}
|
||||
|
||||
public init(context: AccountContext, navigationBarPresentationData: NavigationBarPresentationData?, mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility, locationBroadcastPanelSource: LocationBroadcastPanelSource) {
|
||||
public init(context: AccountContext, navigationBarPresentationData: NavigationBarPresentationData?, mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility, locationBroadcastPanelSource: LocationBroadcastPanelSource, groupCallPanelSource: GroupCallPanelSource) {
|
||||
self.context = context
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.mediaAccessoryPanelVisibility = mediaAccessoryPanelVisibility
|
||||
self.locationBroadcastPanelSource = locationBroadcastPanelSource
|
||||
self.groupCallPanelSource = groupCallPanelSource
|
||||
|
||||
super.init(navigationBarPresentationData: navigationBarPresentationData)
|
||||
|
||||
@@ -250,6 +287,93 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
}
|
||||
}
|
||||
|
||||
if let callManager = context.sharedContext.callManager {
|
||||
switch groupCallPanelSource {
|
||||
case .none:
|
||||
break
|
||||
default:
|
||||
let currentGroupCall: Signal<GroupCallPanelData?, NoError> = callManager.currentGroupCallSignal
|
||||
|> distinctUntilChanged(isEqual: { lhs, rhs in
|
||||
return lhs?.internalId == rhs?.internalId
|
||||
})
|
||||
|> mapToSignal { call -> Signal<GroupCallPanelData?, NoError> in
|
||||
guard let call = call else {
|
||||
return .single(nil)
|
||||
}
|
||||
return call.summaryState
|
||||
|> filter { $0 != nil }
|
||||
|> take(1)
|
||||
|> map { summary -> GroupCallPanelData? in
|
||||
guard let summary = summary else {
|
||||
return nil
|
||||
}
|
||||
return GroupCallPanelData(
|
||||
peerId: call.peerId,
|
||||
info: summary.info,
|
||||
topParticipants: summary.topParticipants,
|
||||
participantCount: summary.participantCount,
|
||||
groupCall: call
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let availableGroupCall: Signal<GroupCallPanelData?, NoError>
|
||||
if case let .peer(peerId) = groupCallPanelSource {
|
||||
availableGroupCall = context.account.viewTracker.peerView(peerId)
|
||||
|> map { peerView -> CachedChannelData.ActiveCall? in
|
||||
guard let cachedData = peerView.cachedData as? CachedChannelData else {
|
||||
return nil
|
||||
}
|
||||
return cachedData.activeCall
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|> mapToSignal { activeCall -> Signal<GroupCallPanelData?, NoError> in
|
||||
guard let activeCall = activeCall else {
|
||||
return .single(nil)
|
||||
}
|
||||
return getCurrentGroupCall(account: context.account, callId: activeCall.id, accessHash: activeCall.accessHash)
|
||||
|> `catch` { _ -> Signal<GroupCallSummary?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> map { summary -> GroupCallPanelData? in
|
||||
guard let summary = summary else {
|
||||
return nil
|
||||
}
|
||||
return GroupCallPanelData(
|
||||
peerId: peerId,
|
||||
info: summary.info,
|
||||
topParticipants: summary.topParticipants,
|
||||
participantCount: summary.info.participantCount,
|
||||
groupCall: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
availableGroupCall = .single(nil)
|
||||
}
|
||||
|
||||
self.currentGroupCallDisposable = combineLatest(queue: .mainQueue(),
|
||||
currentGroupCall,
|
||||
availableGroupCall
|
||||
).start(next: { [weak self] currentState, availableState in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
let panelData = currentState ?? availableState
|
||||
|
||||
let wasEmpty = strongSelf.groupCallPanelData == nil
|
||||
strongSelf.groupCallPanelData = panelData
|
||||
let isEmpty = strongSelf.groupCallPanelData == nil
|
||||
if wasEmpty != isEmpty {
|
||||
strongSelf.requestLayout(transition: .animated(duration: 0.4, curve: .spring))
|
||||
} else if let groupCallPanelData = strongSelf.groupCallPanelData {
|
||||
strongSelf.groupCallAccessoryPanel?.update(data: groupCallPanelData)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
@@ -269,6 +393,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
deinit {
|
||||
self.mediaStatusDisposable?.dispose()
|
||||
self.locationBroadcastDisposable?.dispose()
|
||||
self.currentGroupCallDisposable?.dispose()
|
||||
self.presentationDataDisposable?.dispose()
|
||||
self.playlistPreloadDisposable?.dispose()
|
||||
}
|
||||
@@ -287,6 +412,52 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
|
||||
var additionalHeight: CGFloat = 0.0
|
||||
|
||||
if let groupCallPanelData = self.groupCallPanelData {
|
||||
let panelHeight: CGFloat = 50.0
|
||||
let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: navigationHeight.isZero ? -panelHeight : (navigationHeight + additionalHeight + UIScreenPixel)), size: CGSize(width: layout.size.width, height: panelHeight))
|
||||
additionalHeight += panelHeight
|
||||
|
||||
let groupCallAccessoryPanel: GroupCallNavigationAccessoryPanel
|
||||
if let current = self.groupCallAccessoryPanel {
|
||||
groupCallAccessoryPanel = current
|
||||
transition.updateFrame(node: groupCallAccessoryPanel, frame: panelFrame)
|
||||
groupCallAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: transition)
|
||||
} else {
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
groupCallAccessoryPanel = GroupCallNavigationAccessoryPanel(context: self.context, presentationData: presentationData, tapAction: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.joinGroupCall(
|
||||
peerId: groupCallPanelData.peerId,
|
||||
info: groupCallPanelData.info
|
||||
)
|
||||
})
|
||||
if let navigationBar = self.navigationBar {
|
||||
self.displayNode.insertSubnode(groupCallAccessoryPanel, aboveSubnode: navigationBar)
|
||||
} else {
|
||||
self.displayNode.addSubnode(groupCallAccessoryPanel)
|
||||
}
|
||||
self.groupCallAccessoryPanel = groupCallAccessoryPanel
|
||||
groupCallAccessoryPanel.frame = panelFrame
|
||||
|
||||
groupCallAccessoryPanel.update(data: groupCallPanelData)
|
||||
groupCallAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: .immediate)
|
||||
if transition.isAnimated {
|
||||
groupCallAccessoryPanel.animateIn(transition)
|
||||
}
|
||||
}
|
||||
} else if let groupCallAccessoryPanel = self.groupCallAccessoryPanel {
|
||||
self.groupCallAccessoryPanel = nil
|
||||
if transition.isAnimated {
|
||||
groupCallAccessoryPanel.animateOut(transition, completion: { [weak groupCallAccessoryPanel] in
|
||||
groupCallAccessoryPanel?.removeFromSupernode()
|
||||
})
|
||||
} else {
|
||||
groupCallAccessoryPanel.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
|
||||
if let locationBroadcastPeers = self.locationBroadcastPeers, let locationBroadcastMode = self.locationBroadcastMode {
|
||||
let panelHeight = MediaNavigationAccessoryHeaderNode.minimizedHeight
|
||||
let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: navigationHeight.isZero ? -panelHeight : (navigationHeight + additionalHeight + UIScreenPixel)), size: CGSize(width: layout.size.width, height: panelHeight))
|
||||
@@ -675,4 +846,36 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
}
|
||||
})]
|
||||
}
|
||||
|
||||
private func joinGroupCall(peerId: PeerId, info: GroupCallInfo) {
|
||||
let callResult = self.context.sharedContext.callManager?.requestOrJoinGroupCall(context: self.context, peerId: peerId, initialCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash), endCurrentIfAny: false)
|
||||
if let callResult = callResult, case let .alreadyInProgress(currentPeerId) = callResult {
|
||||
if currentPeerId == peerId {
|
||||
self.context.sharedContext.navigateToCurrentCall()
|
||||
} else {
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> (Peer?, Peer?) in
|
||||
return (transaction.getPeer(peerId), currentPeerId.flatMap(transaction.getPeer))
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, current in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
guard let peer = peer else {
|
||||
return
|
||||
}
|
||||
if let current = current {
|
||||
strongSelf.present(textAlertController(context: strongSelf.context, title: presentationData.strings.Call_CallInProgressTitle, text: presentationData.strings.Call_CallInProgressMessage(current.compactDisplayTitle, peer.compactDisplayTitle).0, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
|
||||
if let strongSelf = self {
|
||||
let _ = strongSelf.context.sharedContext.callManager?.requestOrJoinGroupCall(context: strongSelf.context, peerId: peerId, initialCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash), endCurrentIfAny: true)
|
||||
}
|
||||
})]), in: .window(.root))
|
||||
} else {
|
||||
strongSelf.present(textAlertController(context: strongSelf.context, title: presentationData.strings.Call_CallInProgressTitle, text: presentationData.strings.Call_ExternalCallInProgressMessage, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
|
||||
})]), in: .window(.root))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user