Voice Chat UI improvements

This commit is contained in:
Ilya Laktyushin
2020-11-28 00:47:16 +04:00
parent 2d890dd1e2
commit 2368dc4917
24 changed files with 520 additions and 346 deletions

View File

@@ -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)
}