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

call view: improve UI / UX

- improve UI / UX: the view has been refactored
- add UIDevice extension allowing to know if the device has a notch or not
- doesn't show hours of the duration label when the call is under 1 hour
- management of the screen orientation for both audio and video calls
- the Name Label is showing bigger and the Duration label is showing smaller
- the UI has been adapted to the size of the iPhone 5
- fix the bug concerning the disappearance of the info and buttons containers
- show the Ring ID when the display name doesn't exist

Change-Id: I78203660603e451a2b088a3fcad1e64bbbe4f8e0
Reviewed-by: Kateryna Kostiuk<kateryna.kostiuk@savoirfairelinux.com>
parent d752c4eb
......@@ -133,10 +133,12 @@ struct AccountModelHelper {
let accountUsernameKey = ConfigKeyModel(withKey: ConfigKey.accountUsername)
let accountUsername = self.account.details?.get(withConfigKeyModel: accountUsernameKey)
if accountUsername!.contains(AccountModelHelper.ringIdPrefix) {
let index = accountUsername?.range(of: AccountModelHelper.ringIdPrefix)?.upperBound
return accountUsername?.substring(from: index!)
guard let userName = accountUsername else {
return nil
}
if userName.contains(AccountModelHelper.ringIdPrefix) {
let index = userName.range(of: AccountModelHelper.ringIdPrefix)?.upperBound
return userName.substring(from: index!)
} else {
return nil
}
......
......@@ -23,6 +23,7 @@ import RxSwift
class ButtonsContainerView: UIView, NibLoadable {
//Outlets
@IBOutlet var containerView: UIView!
@IBOutlet weak var container: UIView!
@IBOutlet weak var stackView: UIStackView!
......@@ -33,12 +34,17 @@ class ButtonsContainerView: UIView, NibLoadable {
@IBOutlet weak var switchCameraButton: UIButton!
@IBOutlet weak var switchSpeakerButton: UIButton!
@IBOutlet weak var cancelButton: UIButton!
//Constraints
@IBOutlet weak var cancelButtonWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var cancelButtonBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var cancelButtonHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var containerHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var stackViewYConstraint: NSLayoutConstraint!
@IBOutlet weak var stackViewWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var stackViewBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var containerHeightConstraint: NSLayoutConstraint!
let disposeBag = DisposeBag()
var isCallStarted: Bool = false
var viewModel: ButtonsContainerViewModel? {
didSet {
......@@ -73,7 +79,6 @@ class ButtonsContainerView: UIView, NibLoadable {
guard let window = self.window else {
return
}
self.container.bottomAnchor.constraint(equalTo: window.bottomAnchor).isActive = true
}
}
......@@ -84,47 +89,52 @@ class ButtonsContainerView: UIView, NibLoadable {
}
func withoutOptions() {
self.container.backgroundColor = UIColor.clear
self.backgroundBlurEffect.isHidden = true
muteAudioButton.isHidden = true
muteVideoButton.isHidden = true
pauseCallButton.isHidden = true
switchCameraButton.isHidden = true
switchSpeakerButton.isHidden = true
cancelButton.isHidden = false
self.container.backgroundColor = UIColor.clear
self.backgroundBlurEffect.isHidden = true
muteAudioButton.isHidden = true
muteVideoButton.isHidden = true
pauseCallButton.isHidden = true
switchCameraButton.isHidden = true
switchSpeakerButton.isHidden = true
cancelButton.isHidden = false
}
func optionsWithSpeaker() {
self.backgroundBlurEffect.isHidden = false
muteAudioButton.isHidden = false
if self.viewModel?.isAudioOnly ?? false {
self.stackViewWidthConstraint.constant = 200
muteVideoButton.isHidden = true
switchCameraButton.isHidden = true
} else {
muteVideoButton.isHidden = false
switchCameraButton.isHidden = false
if !self.isCallStarted {
self.isCallStarted = true
self.backgroundBlurEffect.isHidden = false
muteAudioButton.isHidden = false
if self.viewModel?.isAudioOnly ?? false {
muteVideoButton.isHidden = true
switchCameraButton.isHidden = true
} else {
muteVideoButton.isHidden = false
switchCameraButton.isHidden = false
}
pauseCallButton.isHidden = false
switchSpeakerButton.isHidden = false
switchSpeakerButton.alpha = 1.00
switchSpeakerButton.isEnabled = true
cancelButton.isHidden = false
}
pauseCallButton.isHidden = false
switchSpeakerButton.isHidden = false
switchSpeakerButton.alpha = 1.00
switchSpeakerButton.isEnabled = true
cancelButton.isHidden = false
}
func optionsWithoutSpeaker() {
if self.viewModel?.isAudioOnly ?? false {
self.stackViewWidthConstraint.constant = 150
muteVideoButton.isHidden = true
switchCameraButton.isHidden = true
} else {
muteVideoButton.isHidden = false
switchCameraButton.isHidden = false
if !self.isCallStarted {
self.isCallStarted = true
if self.viewModel?.isAudioOnly ?? false {
muteVideoButton.isHidden = true
switchCameraButton.isHidden = true
switchSpeakerButton.isHidden = true
} else {
muteVideoButton.isHidden = false
switchCameraButton.isHidden = false
switchSpeakerButton.isHidden = false
}
self.muteAudioButton.isHidden = false
self.backgroundBlurEffect.isHidden = false
pauseCallButton.isHidden = false
cancelButton.isHidden = false
}
self.backgroundBlurEffect.isHidden = false
muteAudioButton.isHidden = false
pauseCallButton.isHidden = false
switchSpeakerButton.isHidden = true
cancelButton.isHidden = false
}
}
......@@ -14,39 +14,46 @@
<connections>
<outlet property="backgroundBlurEffect" destination="w5l-pw-1ET" id="YYh-qB-WIL"/>
<outlet property="cancelButton" destination="ZxT-mA-1xU" id="68q-sF-gBC"/>
<outlet property="cancelButtonHeightConstraint" destination="XhM-wC-j2L" id="xcg-V6-2BW"/>
<outlet property="cancelButtonBottomConstraint" destination="Ilu-Zu-JqW" id="Yeg-Ca-8pf"/>
<outlet property="cancelButtonHeightConstraint" destination="kls-aA-2zS" id="CzE-vC-V5Z"/>
<outlet property="cancelButtonWidthConstraint" destination="0vV-4C-odp" id="beL-yR-ehA"/>
<outlet property="container" destination="a9g-pf-bHy" id="6bw-CB-5qN"/>
<outlet property="containerHeightConstraint" destination="W6T-0D-HwX" id="Pdz-5B-x5j"/>
<outlet property="containerHeightConstraint" destination="Gjk-7U-rEe" id="G5G-Uh-zRV"/>
<outlet property="containerView" destination="iN0-l3-epB" id="mcP-kY-dVO"/>
<outlet property="muteAudioButton" destination="tXL-FB-O0X" id="6Bh-x3-veQ"/>
<outlet property="muteVideoButton" destination="W7F-nH-kda" id="MWK-JU-544"/>
<outlet property="pauseCallButton" destination="MPk-dB-dhR" id="W4G-AB-WFw"/>
<outlet property="stackView" destination="RHx-cL-CV5" id="Iz9-B0-2Rd"/>
<outlet property="stackViewBottomConstraint" destination="deA-Gc-8FZ" id="etU-MD-0Ig"/>
<outlet property="stackViewWidthConstraint" destination="mIk-2g-tbX" id="Wcy-wd-Quy"/>
<outlet property="stackViewWidthConstraint" destination="ZuV-LV-CYZ" id="ita-8Y-fAb"/>
<outlet property="stackViewYConstraint" destination="z8B-uv-Vcb" id="Gaj-8x-yif"/>
<outlet property="switchCameraButton" destination="gfb-nb-FyB" id="FTM-2Z-u3u"/>
<outlet property="switchSpeakerButton" destination="0VH-mO-vFE" id="1Gy-a9-FAW"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="205"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="108"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a9g-pf-bHy">
<rect key="frame" x="0.0" y="0.0" width="375" height="205"/>
<rect key="frame" x="0.0" y="-2" width="375" height="110"/>
<subviews>
<visualEffectView opaque="NO" alpha="0.84999999999999998" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="w5l-pw-1ET" userLabel="Background Blur Effect">
<rect key="frame" x="0.0" y="0.0" width="375" height="205"/>
<visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="w5l-pw-1ET" userLabel="Background Blur Effect">
<rect key="frame" x="0.0" y="0.0" width="375" height="110"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="JSn-50-Cd9">
<rect key="frame" x="0.0" y="0.0" width="375" height="205"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="110"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</view>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
<blurEffect style="light"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<real key="value" value="35"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</visualEffectView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="RHx-cL-CV5">
<rect key="frame" x="12.5" y="5" width="350" height="50"/>
<rect key="frame" x="15" y="30" width="345" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tXL-FB-O0X">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
......@@ -70,7 +77,7 @@
</userDefinedRuntimeAttributes>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="W7F-nH-kda">
<rect key="frame" x="75" y="0.0" width="50" height="50"/>
<rect key="frame" x="74" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="Pn1-SS-vPN"/>
<constraint firstAttribute="width" constant="50" id="jCp-ib-ySo"/>
......@@ -91,7 +98,7 @@
</userDefinedRuntimeAttributes>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0VH-mO-vFE">
<rect key="frame" x="150" y="0.0" width="50" height="50"/>
<rect key="frame" x="147.5" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="oso-jU-2U3"/>
<constraint firstAttribute="height" constant="50" id="qmE-To-ipl"/>
......@@ -112,7 +119,7 @@
</userDefinedRuntimeAttributes>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MPk-dB-dhR">
<rect key="frame" x="225" y="0.0" width="50" height="50"/>
<rect key="frame" x="221.5" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="984-Na-56G"/>
<constraint firstAttribute="height" constant="50" id="kIF-vP-ZJP"/>
......@@ -133,7 +140,7 @@
</userDefinedRuntimeAttributes>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gfb-nb-FyB">
<rect key="frame" x="300" y="0.0" width="50" height="50"/>
<rect key="frame" x="295" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="DYV-x7-KoO"/>
<constraint firstAttribute="width" constant="50" id="XYg-b8-pt8"/>
......@@ -156,12 +163,12 @@
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="width" priority="250" constant="200" id="ZuV-LV-CYZ"/>
<constraint firstAttribute="height" constant="50" id="gaC-GZ-ftw"/>
<constraint firstAttribute="width" constant="350" id="mIk-2g-tbX"/>
</constraints>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZxT-mA-1xU">
<rect key="frame" x="152.5" y="75" width="70" height="70"/>
<rect key="frame" x="152.5" y="20" width="70" height="70"/>
<constraints>
<constraint firstAttribute="width" constant="70" id="0vV-4C-odp"/>
<constraint firstAttribute="height" constant="70" id="kls-aA-2zS"/>
......@@ -184,28 +191,29 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="w5l-pw-1ET" firstAttribute="height" secondItem="a9g-pf-bHy" secondAttribute="height" id="3vF-Mr-YlI"/>
<constraint firstItem="RHx-cL-CV5" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="a9g-pf-bHy" secondAttribute="leading" constant="12.5" id="FwG-sE-gpJ"/>
<constraint firstAttribute="height" constant="110" id="Gjk-7U-rEe"/>
<constraint firstAttribute="bottom" secondItem="ZxT-mA-1xU" secondAttribute="bottom" constant="20" id="Ilu-Zu-JqW"/>
<constraint firstItem="w5l-pw-1ET" firstAttribute="centerY" secondItem="a9g-pf-bHy" secondAttribute="centerY" id="Key-mX-9mY"/>
<constraint firstAttribute="height" priority="999" constant="212" id="W6T-0D-HwX"/>
<constraint firstAttribute="bottom" secondItem="ZxT-mA-1xU" secondAttribute="bottom" priority="250" constant="60" id="XhM-wC-j2L"/>
<constraint firstAttribute="trailing" secondItem="w5l-pw-1ET" secondAttribute="trailing" id="TnQ-lp-9B9"/>
<constraint firstItem="RHx-cL-CV5" firstAttribute="leading" secondItem="a9g-pf-bHy" secondAttribute="leading" constant="15" id="Y9c-4n-eid"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="450" id="ZfR-cx-MUB"/>
<constraint firstItem="w5l-pw-1ET" firstAttribute="leading" secondItem="a9g-pf-bHy" secondAttribute="leading" id="bbd-5D-5So"/>
<constraint firstItem="RHx-cL-CV5" firstAttribute="centerX" secondItem="a9g-pf-bHy" secondAttribute="centerX" id="bmE-qo-8aJ"/>
<constraint firstAttribute="bottom" secondItem="RHx-cL-CV5" secondAttribute="bottom" constant="150" id="deA-Gc-8FZ"/>
<constraint firstItem="w5l-pw-1ET" firstAttribute="centerX" secondItem="a9g-pf-bHy" secondAttribute="centerX" id="eH5-i0-6bS"/>
<constraint firstItem="ZxT-mA-1xU" firstAttribute="centerX" secondItem="a9g-pf-bHy" secondAttribute="centerX" id="eV9-Wr-xF9"/>
<constraint firstItem="w5l-pw-1ET" firstAttribute="width" secondItem="a9g-pf-bHy" secondAttribute="width" id="sXZ-Jz-OmC"/>
<constraint firstAttribute="trailing" secondItem="RHx-cL-CV5" secondAttribute="trailing" constant="15" id="pgj-7m-5gr"/>
<constraint firstAttribute="bottom" secondItem="RHx-cL-CV5" secondAttribute="bottom" constant="30" id="z8B-uv-Vcb"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="a9g-pf-bHy" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="Kgd-1N-Hij"/>
<constraint firstItem="a9g-pf-bHy" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="X3f-ZS-P0M"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="a9g-pf-bHy" secondAttribute="bottom" id="svV-zg-XlK"/>
<constraint firstAttribute="bottom" secondItem="a9g-pf-bHy" secondAttribute="bottom" id="YHm-ET-yjX"/>
<constraint firstItem="a9g-pf-bHy" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" priority="750" id="ZI5-4F-WCS"/>
<constraint firstItem="a9g-pf-bHy" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="uv2-qL-KQX"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<point key="canvasLocation" x="32.799999999999997" y="68.815592203898049"/>
<point key="canvasLocation" x="32.799999999999997" y="111.54422788605699"/>
</view>
</objects>
<resources>
......
This diff is collapsed.
......@@ -310,7 +310,12 @@ class CallViewModel: Stateable, ViewModel {
let seconds = interval % 60
let minutes = (interval / 60) % 60
let hours = (interval / 3600)
return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
switch hours {
case 0:
return String(format: "%02d:%02d", minutes, seconds)
default:
return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
}
}
func cancelCall() {
......
......@@ -23,6 +23,15 @@ import UIKit
public extension UIDevice {
var hasNotch: Bool {
var bottom: CGFloat = 0
if #available(iOS 11.0, *) {
bottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
} else {
bottom = 0
}
return bottom > 0
}
static let modelName: String = {
var systemInfo = utsname()
uname(&systemInfo)
......
......@@ -48,7 +48,6 @@ 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)
......
......@@ -350,7 +350,7 @@ class ConversationViewModel: Stateable, ViewModel {
if self.conversation.value.messages.isEmpty {
self.sendContactRequest()
}
self.stateSubject.onNext(ConversationState.startCall(contactRingId: self.conversation.value.recipientRingId, userName: self.userName.value))
self.stateSubject.onNext(ConversationState.startCall(contactRingId: self.conversation.value.recipientRingId, userName: self.displayName.value ?? self.userName.value))
}
func startAudioCall() {
......
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