mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Voice Chat UI improvements
This commit is contained in:
@@ -28,11 +28,6 @@ import AlertUI
|
||||
import PresentationDataUtils
|
||||
import LocationUI
|
||||
|
||||
private enum CallStatusText: Equatable {
|
||||
case none
|
||||
case inProgress(Double?)
|
||||
}
|
||||
|
||||
private final class AccountUserInterfaceInUseContext {
|
||||
let subscribers = Bag<(Bool) -> Void>()
|
||||
let tokens = Bag<Void>()
|
||||
@@ -98,8 +93,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
|
||||
private var callDisposable: Disposable?
|
||||
private var callStateDisposable: Disposable?
|
||||
private var currentCallStatusText: CallStatusText = .none
|
||||
private var currentCallStatusTextTimer: SwiftSignalKit.Timer?
|
||||
|
||||
private var currentCallStatusBarNode: CallStatusBarNodeImpl?
|
||||
|
||||
private var groupCallDisposable: Disposable?
|
||||
|
||||
@@ -645,6 +640,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
if let call = call {
|
||||
mainWindow.hostView.containerView.endEditing(true)
|
||||
let groupCallController = VoiceChatController(sharedContext: strongSelf, accountContext: call.accountContext, call: call)
|
||||
groupCallController.sourcePanel = call.sourcePanel
|
||||
call.sourcePanel = nil
|
||||
strongSelf.groupCallController = groupCallController
|
||||
strongSelf.mainWindow?.present(groupCallController, on: .calls)
|
||||
strongSelf.hasOngoingCall.set(true)
|
||||
@@ -655,54 +652,56 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
}
|
||||
})
|
||||
|
||||
self.callStateDisposable = combineLatest(queue: .mainQueue(),
|
||||
self.callState.get(),
|
||||
callManager.currentGroupCallSignal
|
||||
|> map { call -> Bool in
|
||||
return call != nil
|
||||
}
|
||||
).start(next: { [weak self] state, hasGroupCall in
|
||||
if let strongSelf = self {
|
||||
let resolvedText: CallStatusText
|
||||
if let state = state {
|
||||
switch state.state {
|
||||
case .connecting, .requesting, .terminating, .ringing, .waiting:
|
||||
resolvedText = .inProgress(nil)
|
||||
case .terminated:
|
||||
resolvedText = .none
|
||||
case .active(let timestamp, _, _), .reconnecting(let timestamp, _, _):
|
||||
resolvedText = .inProgress(timestamp)
|
||||
let callAndStateSignal: Signal<(PresentationCall, PresentationCallState)?, NoError> = .single(nil)
|
||||
|> then(
|
||||
callManager.currentCallSignal
|
||||
|> mapToSignal { call in
|
||||
if let call = call {
|
||||
return call.state
|
||||
|> map { state in
|
||||
return (call, state)
|
||||
}
|
||||
} else if hasGroupCall {
|
||||
resolvedText = .inProgress(nil)
|
||||
} else {
|
||||
resolvedText = .none
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
)
|
||||
let groupCallAndStateSignal: Signal<PresentationGroupCall?, NoError> = .single(nil)
|
||||
|> then(
|
||||
callManager.currentGroupCallSignal
|
||||
)
|
||||
|
||||
self.callStateDisposable = combineLatest(queue: .mainQueue(),
|
||||
callAndStateSignal,
|
||||
groupCallAndStateSignal
|
||||
).start(next: { [weak self] callAndState, groupCall in
|
||||
if let strongSelf = self {
|
||||
let statusBarContent: CallStatusBarNodeImpl.Content?
|
||||
|
||||
if let (call, state) = callAndState {
|
||||
statusBarContent = .call(call)
|
||||
} else if let groupCall = groupCall {
|
||||
statusBarContent = .groupCall(groupCall)
|
||||
} else {
|
||||
statusBarContent = nil
|
||||
}
|
||||
|
||||
if strongSelf.currentCallStatusText != resolvedText {
|
||||
strongSelf.currentCallStatusText = resolvedText
|
||||
|
||||
var referenceTimestamp: Double?
|
||||
if case let .inProgress(timestamp) = resolvedText, let concreteTimestamp = timestamp {
|
||||
referenceTimestamp = concreteTimestamp
|
||||
}
|
||||
|
||||
if let _ = referenceTimestamp {
|
||||
if strongSelf.currentCallStatusTextTimer == nil {
|
||||
let timer = SwiftSignalKit.Timer(timeout: 0.5, repeat: true, completion: {
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateStatusBarText()
|
||||
}
|
||||
}, queue: Queue.mainQueue())
|
||||
strongSelf.currentCallStatusTextTimer = timer
|
||||
timer.start()
|
||||
}
|
||||
var resolvedCallStatusBarNode: CallStatusBarNodeImpl?
|
||||
|
||||
if let statusBarContent = statusBarContent {
|
||||
if let current = strongSelf.currentCallStatusBarNode {
|
||||
resolvedCallStatusBarNode = current
|
||||
} else {
|
||||
strongSelf.currentCallStatusTextTimer?.invalidate()
|
||||
strongSelf.currentCallStatusTextTimer = nil
|
||||
resolvedCallStatusBarNode = CallStatusBarNodeImpl()
|
||||
strongSelf.currentCallStatusBarNode = resolvedCallStatusBarNode
|
||||
}
|
||||
|
||||
strongSelf.updateStatusBarText()
|
||||
resolvedCallStatusBarNode?.update(content: statusBarContent)
|
||||
} else {
|
||||
strongSelf.currentCallStatusBarNode = nil
|
||||
}
|
||||
|
||||
if let navigationController = strongSelf.mainWindow?.viewController as? NavigationController {
|
||||
navigationController.setForceInCallStatusBar(resolvedCallStatusBarNode)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -780,7 +779,6 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
self.callDisposable?.dispose()
|
||||
self.groupCallDisposable?.dispose()
|
||||
self.callStateDisposable?.dispose()
|
||||
self.currentCallStatusTextTimer?.invalidate()
|
||||
}
|
||||
|
||||
private func updateAccountBackupData(account: Account) -> Signal<Never, NoError> {
|
||||
@@ -988,34 +986,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
return openChatMessageImpl(params)
|
||||
}
|
||||
|
||||
private func updateStatusBarText() {
|
||||
if case let .inProgress(timestamp) = self.currentCallStatusText {
|
||||
let text: String
|
||||
let presentationData = self.currentPresentationData.with { $0 }
|
||||
if let timestamp = timestamp {
|
||||
let duration = Int32(CFAbsoluteTimeGetCurrent() - timestamp)
|
||||
let durationString: String
|
||||
if duration > 60 * 60 {
|
||||
durationString = String(format: "%02d:%02d:%02d", arguments: [duration / 3600, (duration / 60) % 60, duration % 60])
|
||||
} else {
|
||||
durationString = String(format: "%02d:%02d", arguments: [(duration / 60) % 60, duration % 60])
|
||||
}
|
||||
|
||||
text = presentationData.strings.Call_StatusBar(durationString).0
|
||||
} else {
|
||||
text = presentationData.strings.Call_StatusBar("").0
|
||||
}
|
||||
if let navigationController = self.mainWindow?.viewController as? NavigationController {
|
||||
navigationController.setForceInCallStatusBar(text)
|
||||
}
|
||||
} else {
|
||||
if let navigationController = self.mainWindow?.viewController as? NavigationController {
|
||||
navigationController.setForceInCallStatusBar(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func navigateToCurrentCall() {
|
||||
public func navigateToCurrentCall(sourcePanel: ASDisplayNode? = nil) {
|
||||
guard let mainWindow = self.mainWindow else {
|
||||
return
|
||||
}
|
||||
@@ -1026,6 +997,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
}
|
||||
} else if let groupCallController = self.groupCallController {
|
||||
if groupCallController.isNodeLoaded && groupCallController.view.superview == nil {
|
||||
groupCallController.sourcePanel = sourcePanel
|
||||
mainWindow.hostView.containerView.endEditing(true)
|
||||
mainWindow.present(groupCallController, on: .calls)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user