Commit e26f8b9d authored by Quentin Muret's avatar Quentin Muret Committed by Kateryna Kostiuk

UI / UX: refactor call view

- replace the registered name display by the display name if exist
- bigger hang up button
- change the switch camera button image
- hide the switch audio button for iPad

Audio calls:
- change the background color to white during connecting, ringing and current call state
- change buttons, texts, and status bar color to gray
- change the pulse animation color to ring color
- add a fade-in animation for the duration label and buttons container appearance
- hide the switch camera and mute video buttons
- remove the info and buttons containers backgrounds

Video calls:
- change the background to captured video with white blur effect during connecting,
ringing and pause call state
- change buttons, texts, and status bar color to white
- change the background of the info and buttons containers to transparent blur effect
- add an activity indicator view when loading the video of the interlocutor
- add a fade-in animation for the info and buttons container appearance
- change the time of disappearance of the info and buttons containers to 7 seconds
- add animation for the captured video vignette appearance
- add rounded corners to the captured video vignette

Change-Id: I37b634782e3ea5f5eb2afd1f8f1809924435e445
Reviewed-by: Kateryna Kostiuk<kateryna.kostiuk@savoirfairelinux.com>
parent 1ee99939
github "AliSoftware/Reusable" "4.0.3"
github "ReactiveX/RxSwift" "4.3.0"
github "AliSoftware/Reusable" "4.0.4"
github "ReactiveX/RxSwift" "4.4.0"
github "RxSwiftCommunity/RxDataSources" "3.1.0"
github "RxSwiftCommunity/RxRealm" "0.7.5"
github "RxSwiftCommunity/RxRealm" "0.7.6"
github "SwiftyBeaver/SwiftyBeaver" "1.6.1"
github "ViccAlexander/Chameleon" "2.2.0"
github "andreamazz/AMPopTip" "3.4.0"
github "ashleymills/Reachability.swift" "v4.2.1"
github "andreamazz/AMPopTip" "3.5.0"
github "ashleymills/Reachability.swift" "v4.3.0"
github "gskbyte/GSKStretchyHeaderView" "1.0.4"
github "optonaut/ActiveLabel.swift" "0.9.0"
github "pkluz/PKHUD" "5.1.0"
github "realm/realm-cocoa" "v3.9.0"
github "optonaut/ActiveLabel.swift" "1.0.1"
github "pkluz/PKHUD" "5.2.0"
github "realm/realm-cocoa" "v3.11.1"
github "stephencelis/SQLite.swift" "0.11.5"
......@@ -25,14 +25,19 @@ class ButtonsContainerView: UIView, NibLoadable {
@IBOutlet var containerView: UIView!
@IBOutlet weak var container: UIView!
@IBOutlet weak var stackView: UIStackView!
@IBOutlet weak var backgroundBlurEffect: UIVisualEffectView!
@IBOutlet weak var muteAudioButton: UIButton!
@IBOutlet weak var muteVideoButton: UIButton!
@IBOutlet weak var pauseCallButton: UIButton!
@IBOutlet weak var switchCameraButton: UIButton!
@IBOutlet weak var switchSpeakerButton: UIButton!
@IBOutlet weak var cancelButton: UIButton!
@IBOutlet weak var cancelButtonHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var containerHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var bottomSpaceConstraint: NSLayoutConstraint!
@IBOutlet weak var stackViewWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var stackViewBottomConstraint: NSLayoutConstraint!
let disposeBag = DisposeBag()
var viewModel: ButtonsContainerViewModel? {
......@@ -79,9 +84,8 @@ class ButtonsContainerView: UIView, NibLoadable {
}
func withoutOptions() {
containerHeightConstraint.priority = UILayoutPriority(rawValue: 250.00)
bottomSpaceConstraint.priority = UILayoutPriority(rawValue: 999.00)
self.container.backgroundColor = UIColor.clear
self.backgroundBlurEffect.isHidden = true
muteAudioButton.isHidden = true
muteVideoButton.isHidden = true
pauseCallButton.isHidden = true
......@@ -91,13 +95,17 @@ class ButtonsContainerView: UIView, NibLoadable {
}
func optionsWithSpeaker() {
containerHeightConstraint.priority = UILayoutPriority(rawValue: 999.00)
bottomSpaceConstraint.priority = UILayoutPriority(rawValue: 250.00)
self.container.backgroundColor = UIColor.black.withAlphaComponent(0.3)
self.backgroundBlurEffect.isHidden = false
muteAudioButton.isHidden = false
muteVideoButton.isHidden = false
if self.viewModel?.isAudioOnly ?? false {
self.stackViewWidthConstraint.constant = 200
muteVideoButton.isHidden = true
switchCameraButton.isHidden = true
} else {
muteVideoButton.isHidden = false
switchCameraButton.isHidden = false
}
pauseCallButton.isHidden = false
switchCameraButton.isHidden = false
switchSpeakerButton.isHidden = false
switchSpeakerButton.alpha = 1.00
switchSpeakerButton.isEnabled = true
......@@ -105,16 +113,18 @@ class ButtonsContainerView: UIView, NibLoadable {
}
func optionsWithoutSpeaker() {
containerHeightConstraint.priority = UILayoutPriority(rawValue: 250.00)
bottomSpaceConstraint.priority = UILayoutPriority(rawValue: 999.00)
self.container.backgroundColor = UIColor.black.withAlphaComponent(0.3)
if self.viewModel?.isAudioOnly ?? false {
self.stackViewWidthConstraint.constant = 150
muteVideoButton.isHidden = true
switchCameraButton.isHidden = true
} else {
muteVideoButton.isHidden = false
switchCameraButton.isHidden = false
}
self.backgroundBlurEffect.isHidden = false
muteAudioButton.isHidden = false
muteVideoButton.isHidden = false
pauseCallButton.isHidden = false
switchCameraButton.isHidden = false
switchSpeakerButton.isHidden = false
switchSpeakerButton.alpha = 0.00
switchSpeakerButton.isEnabled = false
switchSpeakerButton.isHidden = true
cancelButton.isHidden = false
}
}
This diff is collapsed.
......@@ -31,16 +31,18 @@ class ButtonsContainerViewModel {
let audioService: AudioService
let callID: String
let disposeBag = DisposeBag()
var isAudioOnly: Bool
let avalaibleCallOptions = BehaviorSubject<CallOptions>(value: .none)
lazy var observableCallOptions: Observable<CallOptions> = {
return self.avalaibleCallOptions.asObservable()
}()
init(with callService: CallsService, audioService: AudioService, callID: String) {
init(isAudioOnly: Bool, with callService: CallsService, audioService: AudioService, callID: String) {
self.callService = callService
self.audioService = audioService
self.callID = callID
self.isAudioOnly = isAudioOnly
checkCallOptions()
}
......
This diff is collapsed.
......@@ -53,7 +53,7 @@ class CallViewModel: Stateable, ViewModel {
isHeadsetConnected = self.audioService.isHeadsetConnected.value
isAudioOnly = call.isAudioOnly
containerViewModel = ButtonsContainerViewModel(with: self.callService, audioService: self.audioService, callID: call.callId)
containerViewModel = ButtonsContainerViewModel(isAudioOnly: self.isAudioOnly, with: self.callService, audioService: self.audioService, callID: call.callId)
}
}
......@@ -82,6 +82,7 @@ class CallViewModel: Stateable, ViewModel {
})
}()
lazy var capturedFrame: Observable<UIImage?> = {
videoService.startVideoCaptureBeforeCall()
return videoService.capturedVideoFrame.asObservable().map({ frame in
return frame
})
......@@ -181,6 +182,16 @@ class CallViewModel: Stateable, ViewModel {
})
}()
lazy var showCapturedFrame: Observable<Bool> = {
return self.callService.currentCall
.filter({ [weak self] call in
return call.callId == self?.call?.callId &&
(call.state == .connecting || call.state == .ringing || call.state == .current)
}).map({ call in
call.state == .current
})
}()
var screenTapped = BehaviorSubject(value: false)
lazy var videoButtonState: Observable<UIImage?> = {
......
......@@ -100,11 +100,11 @@ internal enum L10n {
internal static let callFinished = L10n.tr("Localizable", "calls.callFinished")
/// Call
internal static let callItemTitle = L10n.tr("Localizable", "calls.callItemTitle")
/// Connecting
/// Connecting
internal static let connecting = L10n.tr("Localizable", "calls.connecting")
/// wants to talk to you
internal static let incomingCallInfo = L10n.tr("Localizable", "calls.incomingCallInfo")
/// Ringing
/// Ringing
internal static let ringing = L10n.tr("Localizable", "calls.ringing")
/// Unknown
internal static let unknown = L10n.tr("Localizable", "calls.unknown")
......
......@@ -48,6 +48,8 @@ extension UIColor {
static let ringMsgTextFieldBorder = UIColor(red: 220, green: 220, blue: 220, alpha: 1.0)
static let ringUITableViewCellSelection = UIColor(red: 209, green: 210, blue: 210, alpha: 1.0)
static let ringNavigationBar = UIColor(red: 235, green: 235, blue: 235, alpha: 1.0)
static let ringCallInfos = UIColor(hex: 0x626262, alpha: 1.0)
static let ringCallPulse = UIColor(red: 99, green: 191, blue: 208, alpha: 1.0)
static let ringSuccess = UIColor(hex: 0x00b20b, alpha: 1.0)
static let ringFailure = UIColor(hex: 0xf00000, alpha: 1.0)
static let ringWarning = UIColor.orange
......
......@@ -357,7 +357,7 @@ class ConversationViewModel: Stateable, ViewModel {
if self.conversation.value.messages.isEmpty {
self.sendContactRequest()
}
self.stateSubject.onNext(ConversationState.startAudioCall(contactRingId: self.conversation.value.recipientRingId, userName: self.userName.value))
self.stateSubject.onNext(ConversationState.startAudioCall(contactRingId: self.conversation.value.recipientRingId, userName: self.displayName.value ?? self.userName.value))
}
func showContactInfo() {
......
......@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -2,22 +2,23 @@
"images" : [
{
"idiom" : "universal",
"filename" : "rotate_camera.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "rotate_camera2.png",
"filename" : "img_530061.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "rotate_camera3.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
\ No newline at end of file
......@@ -104,8 +104,8 @@
"calls.callItemTitle" = "Call";
"calls.unknown" = "Unknown";
"calls.incomingCallInfo" = "wants to talk to you";
"calls.ringing" = "Ringing";
"calls.connecting" = "Connecting";
"calls.ringing" = "Ringing";
"calls.connecting" = "Connecting";
"calls.callFinished" = "Call finished";
//Account Page
......
 /*
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
......@@ -104,8 +104,8 @@
"calls.callItemTitle" = "Appeler";
"calls.unknown" = "Inconnu";
"calls.incomingCallInfo" = "wants to talk to you";
"calls.ringing" = "Sonnerie en cours";
"calls.connecting" = "Connexion en cours";
"calls.ringing" = "Sonnerie en cours";
"calls.connecting" = "Connexion en cours";
"calls.callFinished" = "Call finished";
//Account Page
......
......@@ -387,6 +387,10 @@ extension VideoService: VideoAdapterDelegate {
self.blockOutgoingFrame = false
}
func startVideoCaptureBeforeCall() {
self.camera.startCapturing()
}
func stopCapture() {
self.log.debug("Capture stopped...")
self.camera.stopCapturing()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment