Audio route menu and item views

This commit is contained in:
ismailgulek 2021-06-28 02:21:40 +03:00
parent 4807445efc
commit 592ea5bf8d
No known key found for this signature in database
GPG key ID: E96336D42D9470A9
3 changed files with 265 additions and 0 deletions

View file

@ -0,0 +1,104 @@
//
// Copyright 2021 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
@objc
protocol CallAudioRouteMenuViewDelegate: AnyObject {
func callAudioRouteMenuView(_ view: CallAudioRouteMenuView, didSelectRoute route: MXAudioOutputRoute)
}
@objcMembers
class CallAudioRouteMenuView: UIStackView {
private enum Constants {
static let routeHeight: CGFloat = 62
}
let routes: [MXAudioOutputRoute]
let currentRoute: MXAudioOutputRoute?
private var theme: Theme = DefaultTheme()
weak var delegate: CallAudioRouteMenuViewDelegate?
init(withRoutes routes: [MXAudioOutputRoute],
currentRoute: MXAudioOutputRoute?) {
self.routes = routes
self.currentRoute = currentRoute
super.init(frame: .zero)
setup()
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
axis = .vertical
alignment = .fill
distribution = .fillEqually
for (index, route) in routes.enumerated() {
let routeView = CallAudioRouteView(withRoute: route,
isSelected: route == currentRoute,
isBottomLineHidden: index == routes.count - 1)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(routeTapped(_:)))
routeView.addGestureRecognizer(tapGesture)
addArrangedSubview(routeView)
}
update(theme: theme)
}
@objc
private func routeTapped(_ sender: UITapGestureRecognizer) {
if let routeView = sender.view as? CallAudioRouteView {
delegate?.callAudioRouteMenuView(self, didSelectRoute: routeView.route)
}
}
}
extension CallAudioRouteMenuView: Themable {
func update(theme: Theme) {
self.theme = DefaultTheme()
backgroundColor = self.theme.colors.navigation
for view in arrangedSubviews {
if let view = view as? Themable {
view.update(theme: self.theme)
}
}
}
}
extension CallAudioRouteMenuView: SlidingModalPresentable {
func allowsDismissOnBackgroundTap() -> Bool {
return true
}
func layoutHeightFittingWidth(_ width: CGFloat) -> CGFloat {
return CGFloat(routes.count) * Constants.routeHeight
}
}

View file

@ -0,0 +1,83 @@
//
// Copyright 2021 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import UIKit
import Reusable
class CallAudioRouteView: UIView {
@IBOutlet private weak var iconImageView: UIImageView!
@IBOutlet private weak var titleLabel: UILabel!
@IBOutlet private weak var selectedIconImageView: UIImageView!
@IBOutlet private weak var bottomLineView: UIView!
let route: MXAudioOutputRoute
private let isSelected: Bool
private let isBottomLineHidden: Bool
private var theme: Theme = ThemeService.shared().theme
init(withRoute route: MXAudioOutputRoute,
isSelected: Bool,
isBottomLineHidden: Bool = false) {
self.route = route
self.isSelected = isSelected
self.isBottomLineHidden = isBottomLineHidden
super.init(frame: .zero)
loadNibContent()
setup()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
selectedIconImageView.isHidden = !isSelected
bottomLineView.isHidden = isBottomLineHidden
switch route.routeType {
case .builtIn:
iconImageView.image = Asset.Images.callAudioRouteBuiltin.image
titleLabel.text = route.name
case .loudSpeakers:
iconImageView.image = Asset.Images.callAudioRouteSpeakers.image
titleLabel.text = Bundle.mxk_localizedString(forKey: "call_more_actions_audio_use_device")
case .externalWired, .externalBluetooth, .externalCar:
iconImageView.image = Asset.Images.callAudioRouteHeadphones.image
titleLabel.text = route.name
}
update(theme: theme)
}
}
extension CallAudioRouteView: NibOwnerLoadable {}
extension CallAudioRouteView: Themable {
func update(theme: Theme) {
self.theme = theme
backgroundColor = theme.colors.navigation
iconImageView.tintColor = theme.colors.secondaryContent
titleLabel.textColor = theme.colors.primaryContent
selectedIconImageView.tintColor = theme.colors.primaryContent
bottomLineView.backgroundColor = theme.colors.secondaryContent
}
}

View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CallAudioRouteView" customModule="Riot" customModuleProvider="target">
<connections>
<outlet property="bottomLineView" destination="LBR-tU-UxC" id="1tu-bV-izu"/>
<outlet property="iconImageView" destination="jLA-5c-Zt1" id="7NK-9l-u5P"/>
<outlet property="selectedIconImageView" destination="RKb-uU-qR6" id="F09-lz-bN4"/>
<outlet property="titleLabel" destination="diN-eC-pOA" id="FII-J4-ZnN"/>
</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="414" height="61"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LBR-tU-UxC">
<rect key="frame" x="0.0" y="60" width="414" height="1"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="m9B-0N-ugj"/>
</constraints>
</view>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="jLA-5c-Zt1">
<rect key="frame" x="12" y="18.5" width="24" height="24"/>
<constraints>
<constraint firstAttribute="height" constant="24" id="TXK-r1-bOI"/>
<constraint firstAttribute="width" constant="24" id="Whn-3a-Cvz"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="checkmark" translatesAutoresizingMaskIntoConstraints="NO" id="RKb-uU-qR6">
<rect key="frame" x="374" y="18.5" width="24" height="24"/>
<constraints>
<constraint firstAttribute="width" constant="24" id="KkM-xG-8Es"/>
<constraint firstAttribute="height" constant="24" id="UGP-Up-jBV"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="diN-eC-pOA">
<rect key="frame" x="44" y="8" width="322" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="19"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="LBR-tU-UxC" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="3yO-XI-bnL"/>
<constraint firstItem="LBR-tU-UxC" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="85A-Hu-UvO"/>
<constraint firstItem="LBR-tU-UxC" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Efb-YZ-r7n"/>
<constraint firstItem="diN-eC-pOA" firstAttribute="leading" secondItem="jLA-5c-Zt1" secondAttribute="trailing" constant="8" id="InE-KY-BCr"/>
<constraint firstItem="LBR-tU-UxC" firstAttribute="top" secondItem="diN-eC-pOA" secondAttribute="bottom" constant="8" id="JgK-T8-UEb"/>
<constraint firstItem="jLA-5c-Zt1" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="Lzk-Ok-frf"/>
<constraint firstItem="diN-eC-pOA" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="8" id="lT9-3y-xRk"/>
<constraint firstItem="jLA-5c-Zt1" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="12" id="mqI-PE-ePl"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="RKb-uU-qR6" secondAttribute="trailing" constant="16" id="p6S-dx-14q"/>
<constraint firstItem="RKb-uU-qR6" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="rd7-Kc-7eL"/>
<constraint firstItem="RKb-uU-qR6" firstAttribute="leading" secondItem="diN-eC-pOA" secondAttribute="trailing" constant="8" id="szb-mp-nYy"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="5.7971014492753632" y="-147.65625"/>
</view>
</objects>
<resources>
<image name="checkmark" width="16" height="12.5"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>