Create DM key verification cells.

This commit is contained in:
SBiOSoftWhare
2019-12-20 10:42:28 +01:00
parent 1dfe23c6dd
commit a04d8c6ec8
10 changed files with 888 additions and 0 deletions
@@ -0,0 +1,223 @@
/*
Copyright 2019 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
@objcMembers
class KeyVerificationBaseBubbleCell: MXKRoomBubbleTableViewCell {
// MARK: - Constants
private enum Sizing {
static var sizes = Set<SizingViewHeight>()
}
// MARK: - Properties
// MARK: Public
weak var keyVerificationCellInnerContentView: KeyVerificationCellInnerContentView?
weak var bubbleCellWithoutSenderInfoContentView: BubbleCellWithoutSenderInfoContentView?
override var bubbleInfoContainer: UIView! {
get {
guard let infoContainer = self.bubbleCellWithoutSenderInfoContentView?.bubbleInfoContainer else {
fatalError("[KeyVerificationBaseBubbleCell] bubbleInfoContainer should not be used before set")
}
return infoContainer
}
set {
super.bubbleInfoContainer = newValue
}
}
override var bubbleOverlayContainer: UIView! {
get {
guard let overlayContainer = self.bubbleCellWithoutSenderInfoContentView?.bubbleOverlayContainer else {
fatalError("[KeyVerificationBaseBubbleCell] bubbleOverlayContainer should not be used before set")
}
return overlayContainer
}
set {
super.bubbleInfoContainer = newValue
}
}
override var bubbleInfoContainerTopConstraint: NSLayoutConstraint! {
get {
guard let infoContainerTopConstraint = self.bubbleCellWithoutSenderInfoContentView?.bubbleInfoContainerTopConstraint else {
fatalError("[KeyVerificationBaseBubbleCell] bubbleInfoContainerTopConstraint should not be used before set")
}
return infoContainerTopConstraint
}
set {
super.bubbleInfoContainerTopConstraint = newValue
}
}
// MARK: - Setup
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func commonInit() {
self.selectionStyle = .none
self.setupContentView()
self.update(theme: ThemeService.shared().theme)
super.setupViews()
}
// MARK: - Public
func update(theme: Theme) {
self.bubbleCellWithoutSenderInfoContentView?.update(theme: theme)
self.keyVerificationCellInnerContentView?.update(theme: theme)
}
func buildUserInfoText(with userId: String, userDisplayName: String?) -> String {
let userInfoText: String
if let userDisplayName = userDisplayName {
userInfoText = "\(userId) (\(userDisplayName))"
} else {
userInfoText = userId
}
return userInfoText
}
func senderId(from bubbleCellData: MXKRoomBubbleCellData) -> String {
return bubbleCellData.senderId ?? ""
}
func senderDisplayName(from bubbleCellData: MXKRoomBubbleCellData) -> String? {
let senderId = self.senderId(from: bubbleCellData)
guard let senderDisplayName = bubbleCellData.senderDisplayName, senderId != senderDisplayName else {
return nil
}
return senderDisplayName
}
class func sizingView() -> MXKRoomBubbleTableViewCell {
fatalError("[KeyVerificationBaseBubbleCell] Subclass should implement this method")
}
// TODO: Implement thiscmethod in subclasses
class func sizingHeightHashValue(from bubbleData: MXKRoomBubbleCellData) -> Int {
return bubbleData.hashValue
}
// MARK: - Overrides
override class func defaultReuseIdentifier() -> String! {
return String(describing: self)
}
override func didEndDisplay() {
super.didEndDisplay()
self.removeReadReceiptsView()
}
override class func height(for cellData: MXKCellData!, withMaximumWidth maxWidth: CGFloat) -> CGFloat {
guard let cellData = cellData else {
return 0
}
guard let roomBubbleCellData = cellData as? MXKRoomBubbleCellData else {
return 0
}
let height: CGFloat
let sizingViewHeight = self.findOrCreateSizingViewHeight(from: roomBubbleCellData)
if let cachedHeight = sizingViewHeight.heights[maxWidth] {
height = cachedHeight
} else {
height = self.contentViewHeight(for: roomBubbleCellData, fitting: maxWidth)
sizingViewHeight.heights[maxWidth] = height
}
return height
}
// MARK: - Private
private func setupContentView() {
if self.bubbleCellWithoutSenderInfoContentView == nil {
let bubbleCellWithoutSenderInfoContentView = BubbleCellWithoutSenderInfoContentView.instantiate()
let innerContentView = KeyVerificationCellInnerContentView.instantiate()
bubbleCellWithoutSenderInfoContentView.innerContentView.vc_addSubViewMatchingParent(innerContentView)
self.contentView.vc_addSubViewMatchingParent(bubbleCellWithoutSenderInfoContentView)
self.bubbleCellWithoutSenderInfoContentView = bubbleCellWithoutSenderInfoContentView
self.keyVerificationCellInnerContentView = innerContentView
}
}
private static func findOrCreateSizingViewHeight(from bubbleData: MXKRoomBubbleCellData) -> SizingViewHeight {
let sizingViewHeight: SizingViewHeight
let bubbleDataHashValue = bubbleData.hashValue
if let foundSizingViewHeight = self.Sizing.sizes.first(where: { (sizingViewHeight) -> Bool in
return sizingViewHeight.uniqueIdentifier == bubbleDataHashValue
}) {
sizingViewHeight = foundSizingViewHeight
} else {
sizingViewHeight = SizingViewHeight(uniqueIdentifier: bubbleDataHashValue)
}
return sizingViewHeight
}
private static func contentViewHeight(for cellData: MXKCellData, fitting width: CGFloat) -> CGFloat {
let sizingView = self.sizingView()
sizingView.render(cellData)
sizingView.layoutIfNeeded()
let fittingSize = CGSize(width: width, height: UIView.layoutFittingCompressedSize.height)
let height = sizingView.systemLayoutSizeFitting(fittingSize).height
return height
}
}
// MARK: - BubbleCellReadReceiptsDisplayable
extension KeyVerificationBaseBubbleCell: BubbleCellReadReceiptsDisplayable {
func addReadReceiptsView(_ readReceiptsView: UIView) {
self.bubbleCellWithoutSenderInfoContentView?.addReadReceiptsView(readReceiptsView)
}
func removeReadReceiptsView() {
self.bubbleCellWithoutSenderInfoContentView?.removeReadReceiptsView()
}
}
@@ -0,0 +1,159 @@
/*
Copyright 2019 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
final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
// MARK: - Constants
private enum Constants {
static let cornerRadius: CGFloat = 8.0
static let buttonBackgroundColorAlpha: CGFloat = 0.8
static let buttonCornerRadius: CGFloat = 6.0
}
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var badgeImageView: UIImageView!
@IBOutlet private weak var titleLabel: UILabel!
@IBOutlet private weak var userInformationsLabel: UILabel!
@IBOutlet private weak var requestStatusLabel: UILabel!
@IBOutlet private weak var acceptButton: UIButton!
@IBOutlet private weak var declineButton: UIButton!
// MARK: Public
var isButtonsHidden: Bool {
get {
return self.acceptButton.isHidden && self.declineButton.isHidden
}
set {
self.acceptButton.isHidden = newValue
self.declineButton.isHidden = newValue
}
}
var isRequestStatusHidden: Bool {
get {
return self.requestStatusLabel.isHidden
}
set {
self.requestStatusLabel.isHidden = newValue
}
}
var badgeImage: UIImage? {
get {
return self.badgeImageView.image
}
set {
self.badgeImageView.image = newValue
}
}
var title: String? {
get {
return self.titleLabel.text
}
set {
self.titleLabel.text = newValue
}
}
var requestStatusText: String? {
get {
return self.requestStatusLabel.text
}
set {
self.requestStatusLabel.text = newValue
}
}
var acceptActionHandler: (() -> Void)?
var declineActionHandler: (() -> Void)?
// MARK: - Setup
static func instantiate() -> KeyVerificationCellInnerContentView {
let view = KeyVerificationCellInnerContentView.loadFromNib()
return view
}
// MARK: - Life cycle
override func awakeFromNib() {
super.awakeFromNib()
self.layer.masksToBounds = true
}
override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = Constants.cornerRadius
if self.isButtonsHidden == false {
self.acceptButton.layer.cornerRadius = Constants.buttonCornerRadius
self.declineButton.layer.cornerRadius = Constants.buttonCornerRadius
}
}
// MARK: - Public
func update(theme: Theme) {
self.backgroundColor = theme.headerBackgroundColor
self.titleLabel.textColor = theme.textPrimaryColor
self.userInformationsLabel.textColor = theme.textSecondaryColor
self.acceptButton.vc_setBackgroundColor(theme.tintColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
self.declineButton.vc_setBackgroundColor(theme.noticeColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
}
func updateSenderInfo(with userId: String, userDisplayName: String?) {
self.userInformationsLabel.text = self.buildUserInfoText(with: userId, userDisplayName: userDisplayName)
}
// MARK: - Private
private func buildUserInfoText(with userId: String, userDisplayName: String?) -> String {
let userInfoText: String
if let userDisplayName = userDisplayName {
userInfoText = "\(userId) (\(userDisplayName))"
} else {
userInfoText = userId
}
return userInfoText
}
@IBAction private func declineButtonAction(_ sender: Any) {
self.declineActionHandler?()
}
@IBAction private func acceptButtonAction(_ sender: Any) {
self.acceptActionHandler?()
}
}
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="KeyVerificationCellInnerContentView" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="313" height="159"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="17" translatesAutoresizingMaskIntoConstraints="NO" id="2Sr-GM-aAU">
<rect key="frame" x="10" y="10" width="293" height="139"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="5gD-pX-GFz">
<rect key="frame" x="70" y="0.0" width="153.5" height="18"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="encryption_normal" translatesAutoresizingMaskIntoConstraints="NO" id="EHJ-3L-OPJ">
<rect key="frame" x="0.0" y="0.0" width="16" height="18"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Verification request" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BOd-4B-LQX">
<rect key="frame" x="20" y="0.0" width="133.5" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="User (@user:matrix.org)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e1n-WP-GTb">
<rect key="frame" x="83.5" y="35" width="126" height="13.5"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.1803921568627451" green="0.18431372549019609" blue="0.19607843137254902" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Waiting..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e6I-aZ-RRO">
<rect key="frame" x="118" y="65.5" width="57" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.38039215686274508" green="0.4392156862745098" blue="0.54509803921568623" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="WxG-vh-Bn0">
<rect key="frame" x="44.5" y="98.5" width="204" height="40.5"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="atD-LF-sGH">
<rect key="frame" x="0.0" y="11.5" width="105" height="18"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="Decline (60)">
<color key="titleColor" red="1" green="0.29411764705882354" blue="0.33333333333333331" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="declineButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="dS6-Xr-6jZ"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="irs-8W-qcs">
<rect key="frame" x="135" y="11.5" width="69" height="18"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="Accept">
<color key="titleColor" red="0.011764705882352941" green="0.70196078431372544" blue="0.50588235294117645" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="acceptButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="IQ6-be-vJt"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" red="0.95294117647058818" green="0.97254901960784312" blue="0.99215686274509807" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="2Sr-GM-aAU" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="M7S-MY-Jxk"/>
<constraint firstItem="2Sr-GM-aAU" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="SfH-5W-p30"/>
<constraint firstAttribute="trailing" secondItem="2Sr-GM-aAU" secondAttribute="trailing" constant="10" id="rVw-1F-ch3"/>
<constraint firstAttribute="bottom" secondItem="2Sr-GM-aAU" secondAttribute="bottom" constant="10" id="vL2-dm-qbe"/>
</constraints>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="acceptButton" destination="irs-8W-qcs" id="LKq-qE-bbg"/>
<outlet property="badgeImageView" destination="EHJ-3L-OPJ" id="eNW-bg-eYy"/>
<outlet property="declineButton" destination="atD-LF-sGH" id="CfI-FW-ySy"/>
<outlet property="requestStatusLabel" destination="e6I-aZ-RRO" id="zQf-qy-3Rq"/>
<outlet property="titleLabel" destination="BOd-4B-LQX" id="4sw-3J-faF"/>
<outlet property="userInformationsLabel" destination="e1n-WP-GTb" id="jhY-gH-QnO"/>
</connections>
<point key="canvasLocation" x="-408" y="-225"/>
</view>
</objects>
<resources>
<image name="encryption_normal" width="16" height="16"/>
</resources>
</document>
@@ -0,0 +1,103 @@
/*
Copyright 2019 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
@objcMembers
final class KeyVerificationConclusionBubbleCell: KeyVerificationBaseBubbleCell {
// MARK: - Constants
private enum Sizing {
static let view = KeyVerificationConclusionBubbleCell(style: .default, reuseIdentifier: nil)
}
// MARK: - Setup
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func commonInit() {
self.keyVerificationCellInnerContentView?.isButtonsHidden = true
self.keyVerificationCellInnerContentView?.isRequestStatusHidden = true
}
// MARK: - Overrides
override func render(_ cellData: MXKCellData!) {
super.render(cellData)
guard let keyVerificationCellInnerContentView = self.keyVerificationCellInnerContentView,
let bubbleData = self.bubbleData,
let viewData = self.viewData(from: bubbleData) else {
NSLog("[KeyVerificationConclusionBubbleCell] Fail to render \(String(describing: cellData))")
return
}
keyVerificationCellInnerContentView.badgeImage = viewData.badgeImage
keyVerificationCellInnerContentView.title = viewData.title
keyVerificationCellInnerContentView.updateSenderInfo(with: viewData.senderId, userDisplayName: viewData.senderDisplayName)
}
override class func sizingView() -> MXKRoomBubbleTableViewCell {
return self.Sizing.view
}
// MARK: - Private
// TODO: Handle view data filling
private func viewData(from bubbleData: MXKRoomBubbleCellData) -> KeyVerificationConclusionViewData? {
guard let event = bubbleData.bubbleComponents.first?.event else {
return nil
}
let viewData: KeyVerificationConclusionViewData?
let senderId = self.senderId(from: bubbleData)
let senderDisplayName = self.senderDisplayName(from: bubbleData)
let title: String?
let badgeImage: UIImage?
switch event.eventType {
case .keyVerificationDone:
title = "Verified"
badgeImage = Asset.Images.encryptionTrusted.image
case .keyVerificationCancel:
title = "Cancelled"
badgeImage = Asset.Images.encryptionNormal.image
default:
badgeImage = nil
title = nil
}
if let title = title, let badgeImage = badgeImage {
viewData = KeyVerificationConclusionViewData(badgeImage: badgeImage,
title: title,
senderId: senderId,
senderDisplayName: senderDisplayName)
} else {
viewData = nil
}
return viewData
}
}
@@ -0,0 +1,24 @@
/*
Copyright 2019 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
struct KeyVerificationConclusionViewData {
let badgeImage: UIImage
let title: String
let senderId: String
let senderDisplayName: String?
}
@@ -0,0 +1,99 @@
/*
Copyright 2019 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
@objcMembers
final class KeyVerificationIncomingRequestApprovalBubbleCell: KeyVerificationBaseBubbleCell {
// MARK: - Constants
private enum Sizing {
static let view = KeyVerificationConclusionBubbleCell(style: .default, reuseIdentifier: nil)
}
// MARK: - Setup
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func commonInit() {
guard let keyVerificationCellInnerContentView = self.keyVerificationCellInnerContentView else {
fatalError("[KeyVerificationIncomingRequestApprovalBubbleCell] keyVerificationCellInnerContentView should not be nil")
}
keyVerificationCellInnerContentView.isButtonsHidden = false
keyVerificationCellInnerContentView.isRequestStatusHidden = true
keyVerificationCellInnerContentView.badgeImage = Asset.Images.encryptionNormal.image
}
// MARK: - Overrides
override func prepareForReuse() {
super.prepareForReuse()
self.keyVerificationCellInnerContentView?.acceptActionHandler = nil
self.keyVerificationCellInnerContentView?.declineActionHandler = nil
}
override func render(_ cellData: MXKCellData!) {
super.render(cellData)
guard let keyVerificationCellInnerContentView = self.keyVerificationCellInnerContentView,
let bubbleData = self.bubbleData,
let viewData = self.viewData(from: bubbleData) else {
NSLog("[KeyVerificationIncomingRequestApprovalBubbleCell] Fail to render \(String(describing: cellData))")
return
}
keyVerificationCellInnerContentView.title = viewData.title
keyVerificationCellInnerContentView.updateSenderInfo(with: viewData.senderId, userDisplayName: viewData.senderDisplayName)
keyVerificationCellInnerContentView.acceptActionHandler = { [weak self] in
// TODO: Use correct action identifier
self?.delegate?.cell(self, didRecognizeAction: kMXKRoomBubbleCellTapOnContentView, userInfo: nil)
}
keyVerificationCellInnerContentView.declineActionHandler = { [weak self] in
// TODO: Use correct action identifier
self?.delegate?.cell(self, didRecognizeAction: kMXKRoomBubbleCellTapOnContentView, userInfo: nil)
}
}
override class func sizingView() -> MXKRoomBubbleTableViewCell {
return self.Sizing.view
}
// MARK: - Private
// TODO: Handle view data filling
private func viewData(from bubbleData: MXKRoomBubbleCellData) -> KeyVerificationIncomingRequestApprovalViewData? {
let senderId = self.senderId(from: bubbleData)
let senderDisplayName = self.senderDisplayName(from: bubbleData)
let title = "Verification request"
return KeyVerificationIncomingRequestApprovalViewData(title: title,
senderId: senderId,
senderDisplayName: senderDisplayName)
}
}
@@ -0,0 +1,23 @@
/*
Copyright 2019 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
struct KeyVerificationIncomingRequestApprovalViewData {
let title: String
let senderId: String
let senderDisplayName: String?
}
@@ -0,0 +1,91 @@
/*
Copyright 2019 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
@objcMembers
final class KeyVerificationRequestStatusBubbleCell: KeyVerificationBaseBubbleCell {
// MARK: - Constants
private enum Sizing {
static let view = KeyVerificationRequestStatusBubbleCell(style: .default, reuseIdentifier: nil)
}
// MARK: - Setup
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func commonInit() {
guard let keyVerificationCellInnerContentView = self.keyVerificationCellInnerContentView else {
fatalError("[KeyVerificationRequestStatusBubbleCell] keyVerificationCellInnerContentView should not be nil")
}
keyVerificationCellInnerContentView.isButtonsHidden = true
keyVerificationCellInnerContentView.isRequestStatusHidden = false
keyVerificationCellInnerContentView.badgeImage = Asset.Images.encryptionNormal.image
}
// MARK: - Overrides
override func render(_ cellData: MXKCellData!) {
super.render(cellData)
guard let keyVerificationCellInnerContentView = self.keyVerificationCellInnerContentView,
let bubbleData = self.bubbleData,
let viewData = self.viewData(from: bubbleData) else {
NSLog("[KeyVerificationRequestStatusBubbleCell] Fail to render \(String(describing: cellData))")
return
}
keyVerificationCellInnerContentView.title = viewData.title
keyVerificationCellInnerContentView.updateSenderInfo(with: viewData.senderId, userDisplayName: viewData.senderDisplayName)
keyVerificationCellInnerContentView.requestStatusText = viewData.statusText
}
override class func sizingView() -> MXKRoomBubbleTableViewCell {
return self.Sizing.view
}
// MARK: - Private
// TODO: Handle view data filling
private func viewData(from bubbleData: MXKRoomBubbleCellData) -> KeyVerificationRequestStatusViewData? {
let senderId = self.senderId(from: bubbleData)
let senderDisplayName = self.senderDisplayName(from: bubbleData)
let title: String
let statusText: String = "You accepted"
if senderId.isEmpty == false {
title = "Verification request"
} else {
title = "Verification sent"
}
return KeyVerificationRequestStatusViewData(title: title,
senderId: senderId,
senderDisplayName: senderDisplayName,
statusText: statusText)
}
}
@@ -0,0 +1,24 @@
/*
Copyright 2019 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
struct KeyVerificationRequestStatusViewData {
let title: String
let senderId: String
let senderDisplayName: String?
let statusText: String
}
@@ -0,0 +1,43 @@
/*
Copyright 2019 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
final class SizingViewHeight: Hashable, Equatable {
// MARK: - Properties
let uniqueIdentifier: Int
var heights: [CGFloat /* width */: CGFloat /* height */] = [:]
// MARK: - Setup
init(uniqueIdentifier: Int) {
self.uniqueIdentifier = uniqueIdentifier
}
// MARK: - Hashable
func hash(into hasher: inout Hasher) {
hasher.combine(self.uniqueIdentifier)
}
// MARK: - Equatable
static func == (lhs: SizingViewHeight, rhs: SizingViewHeight) -> Bool {
return lhs.uniqueIdentifier == rhs.uniqueIdentifier
}
}