Video call UI improvements

This commit is contained in:
Ilya Laktyushin
2020-08-07 18:47:32 +03:00
parent a784720d3a
commit 3515fee9af
73 changed files with 4787 additions and 3835 deletions

View File

@@ -6,12 +6,18 @@ import SwiftSignalKit
import MediaPlayer
import TelegramPresentationData
enum CallControllerButtonsSpeakerMode {
enum CallControllerButtonsSpeakerMode: Equatable {
enum BluetoothType: Equatable {
case generic
case airpods
case airpodsPro
}
case none
case builtin
case speaker
case headphones
case bluetooth
case bluetooth(BluetoothType)
}
enum CallControllerButtonsMode: Equatable {
@@ -23,9 +29,9 @@ enum CallControllerButtonsMode: Equatable {
case active
}
case active(speakerMode: CallControllerButtonsSpeakerMode, videoState: VideoState)
case incoming(speakerMode: CallControllerButtonsSpeakerMode, videoState: VideoState)
case outgoingRinging(speakerMode: CallControllerButtonsSpeakerMode, videoState: VideoState)
case active(speakerMode: CallControllerButtonsSpeakerMode, hasAudioRouteMenu: Bool, videoState: VideoState)
case incoming(speakerMode: CallControllerButtonsSpeakerMode, hasAudioRouteMenu: Bool, videoState: VideoState)
case outgoingRinging(speakerMode: CallControllerButtonsSpeakerMode, hasAudioRouteMenu: Bool, videoState: VideoState)
}
private enum ButtonDescription: Equatable {
@@ -43,6 +49,8 @@ private enum ButtonDescription: Equatable {
case builtin
case speaker
case bluetooth
case airpods
case airpodsPro
}
enum EndType {
@@ -54,7 +62,7 @@ private enum ButtonDescription: Equatable {
case accept
case end(EndType)
case enableCamera(Bool, Bool, Bool)
case switchCamera
case switchCamera(Bool)
case soundOutput(SoundOutput)
case mute(Bool)
@@ -160,10 +168,12 @@ final class CallControllerButtonsNode: ASDisplayNode {
let speakerMode: CallControllerButtonsSpeakerMode
var videoState: CallControllerButtonsMode.VideoState
let hasAudioRouteMenu: Bool
switch mode {
case .incoming(let speakerModeValue, let videoStateValue), .outgoingRinging(let speakerModeValue, let videoStateValue), .active(let speakerModeValue, let videoStateValue):
case .incoming(let speakerModeValue, let hasAudioRouteMenuValue, let videoStateValue), .outgoingRinging(let speakerModeValue, let hasAudioRouteMenuValue, let videoStateValue), .active(let speakerModeValue, let hasAudioRouteMenuValue, let videoStateValue):
speakerMode = speakerModeValue
videoState = videoStateValue
hasAudioRouteMenu = hasAudioRouteMenuValue
}
enum MappedState {
@@ -178,7 +188,7 @@ final class CallControllerButtonsNode: ASDisplayNode {
mappedState = .incomingRinging
case .outgoingRinging:
mappedState = .outgoingRinging
case let .active(_, videoStateValue):
case let .active(_, _, videoStateValue):
switch videoStateValue {
case let .incomingRequested(sendsVideo):
mappedState = .active
@@ -199,14 +209,21 @@ final class CallControllerButtonsNode: ASDisplayNode {
let soundOutput: ButtonDescription.SoundOutput
switch speakerMode {
case .none, .builtin:
soundOutput = .builtin
case .speaker:
soundOutput = .speaker
case .headphones:
soundOutput = .bluetooth
case .bluetooth:
soundOutput = .bluetooth
case .none, .builtin:
soundOutput = .builtin
case .speaker:
soundOutput = .speaker
case .headphones:
soundOutput = .bluetooth
case let .bluetooth(type):
switch type {
case .generic:
soundOutput = .bluetooth
case .airpods:
soundOutput = .airpods
case .airpodsPro:
soundOutput = .airpodsPro
}
}
switch videoState {
@@ -223,12 +240,17 @@ final class CallControllerButtonsNode: ASDisplayNode {
isCameraEnabled = true
isCameraInitializing = false
}
topButtons.append(.enableCamera(isCameraActive, isCameraEnabled, isCameraInitializing))
topButtons.append(.mute(self.isMuted))
topButtons.append(.enableCamera(isCameraActive, false, isCameraInitializing))
if case .possible = videoState {
topButtons.append(.mute(self.isMuted))
topButtons.append(.soundOutput(soundOutput))
} else {
topButtons.append(.switchCamera)
if hasAudioRouteMenu {
topButtons.append(.soundOutput(soundOutput))
} else {
topButtons.append(.mute(self.isMuted))
}
topButtons.append(.switchCamera(isCameraActive && !isCameraInitializing))
}
case .notAvailable:
topButtons.append(.mute(self.isMuted))
@@ -287,14 +309,21 @@ final class CallControllerButtonsNode: ASDisplayNode {
let soundOutput: ButtonDescription.SoundOutput
switch speakerMode {
case .none, .builtin:
soundOutput = .builtin
case .speaker:
soundOutput = .speaker
case .headphones:
soundOutput = .builtin
case .bluetooth:
soundOutput = .bluetooth
case .none, .builtin:
soundOutput = .builtin
case .speaker:
soundOutput = .speaker
case .headphones:
soundOutput = .builtin
case let .bluetooth(type):
switch type {
case .generic:
soundOutput = .bluetooth
case .airpods:
soundOutput = .airpods
case .airpodsPro:
soundOutput = .airpodsPro
}
}
if case let .outgoingRequested(isInitializing) = videoState {
@@ -302,8 +331,12 @@ final class CallControllerButtonsNode: ASDisplayNode {
}
topButtons.append(.enableCamera(isCameraActive, isCameraEnabled, isCameraInitializing))
topButtons.append(.mute(isMuted))
topButtons.append(.switchCamera)
if hasAudioRouteMenu {
topButtons.append(.soundOutput(soundOutput))
} else {
topButtons.append(.mute(isMuted))
}
topButtons.append(.switchCamera(isCameraActive && !isCameraInitializing))
topButtons.append(.end(.end))
let topButtonsContentWidth = CGFloat(topButtons.count) * smallButtonSize
@@ -336,14 +369,21 @@ final class CallControllerButtonsNode: ASDisplayNode {
let soundOutput: ButtonDescription.SoundOutput
switch speakerMode {
case .none, .builtin:
soundOutput = .builtin
case .speaker:
soundOutput = .speaker
case .headphones:
soundOutput = .bluetooth
case .bluetooth:
soundOutput = .bluetooth
case .none, .builtin:
soundOutput = .builtin
case .speaker:
soundOutput = .speaker
case .headphones:
soundOutput = .bluetooth
case let .bluetooth(type):
switch type {
case .generic:
soundOutput = .bluetooth
case .airpods:
soundOutput = .airpods
case .airpodsPro:
soundOutput = .airpodsPro
}
}
topButtons.append(.enableCamera(isCameraActive, isCameraEnabled, isCameraInitializing))
@@ -423,15 +463,17 @@ final class CallControllerButtonsNode: ASDisplayNode {
hasProgress: isInitializing
)
buttonText = strings.Call_Camera
case .switchCamera:
case let .switchCamera(isEnabled):
buttonContent = CallControllerButtonItemNode.Content(
appearance: .blurred(isFilled: false),
image: .flipCamera
image: .flipCamera,
isEnabled: isEnabled
)
buttonText = strings.Call_Flip
case let .soundOutput(value):
let image: CallControllerButtonItemNode.Content.Image
var isFilled = false
var title: String = strings.Call_Speaker
switch value {
case .builtin:
image = .speaker
@@ -440,12 +482,19 @@ final class CallControllerButtonsNode: ASDisplayNode {
isFilled = true
case .bluetooth:
image = .bluetooth
title = strings.Call_Audio
case .airpods:
image = .airpods
title = strings.Call_Audio
case .airpodsPro:
image = .airpodsPro
title = strings.Call_Audio
}
buttonContent = CallControllerButtonItemNode.Content(
appearance: .blurred(isFilled: isFilled),
image: image
)
buttonText = strings.Call_Speaker
buttonText = title
case let .mute(isMuted):
buttonContent = CallControllerButtonItemNode.Content(
appearance: .blurred(isFilled: isMuted),