TM-SGNL-iOS/Signal/ConversationView/CellViews/CVContactShareView.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

121 lines
4.7 KiB
Swift

//
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
public import SignalUI
public class CVContactShareView: ManualStackView {
struct State: Equatable {
let contactShare: ContactShareViewModel
let isIncoming: Bool
let conversationStyle: ConversationStyle
let avatar: UIImage?
}
private let labelStack = ManualStackView(name: "CVContactShareView.labelStack")
private let avatarView: AvatarImageView = AvatarImageView(shouldDeactivateConstraints: true)
private let contactNameLabel = CVLabel()
private let disclosureImageView = CVImageView()
static func buildState(
contactShare: ContactShareViewModel,
isIncoming: Bool,
conversationStyle: ConversationStyle,
transaction: SDSAnyReadTransaction
) -> State {
let avatar = contactShare.getAvatarImage(diameter: Self.avatarSize,
transaction: transaction)
owsAssertDebug(avatar != nil)
return State(contactShare: contactShare,
isIncoming: isIncoming,
conversationStyle: conversationStyle,
avatar: avatar)
}
private static var avatarSize: CGFloat { CGFloat(AvatarBuilder.standardAvatarSizePoints) }
private static let disclosureIconSize = CGSize.square(20)
func configureForRendering(state: State, cellMeasurement: CVCellMeasurement) {
let labelConfig = Self.contactNameLabelConfig(state: state)
labelConfig.applyForRendering(label: contactNameLabel)
avatarView.image = state.avatar
let disclosureColor = state.isIncoming ? UIColor.ows_gray25 : UIColor.ows_whiteAlpha80
disclosureImageView.setTemplateImage(UIImage(imageLiteralResourceName: "chevron-right-20"),
tintColor: disclosureColor)
self.configure(config: Self.outerStackConfig,
cellMeasurement: cellMeasurement,
measurementKey: Self.measurementKey_outerStack,
subviews: [
avatarView,
contactNameLabel,
disclosureImageView
])
}
private static var outerStackConfig: CVStackViewConfig {
CVStackViewConfig(axis: .horizontal,
alignment: .center,
spacing: 12,
layoutMargins: UIEdgeInsets(hMargin: 0, vMargin: 4))
}
private static func contactNameLabelConfig(state: State) -> CVLabelConfig {
let textColor = state.conversationStyle.bubbleTextColor(isIncoming: state.isIncoming)
return CVLabelConfig.unstyledText(
state.contactShare.displayName,
font: .dynamicTypeBody,
textColor: textColor,
lineBreakMode: .byTruncatingTail
)
}
private static let measurementKey_outerStack = "CVContactShareView.measurementKey_outerStack"
static func measure(maxWidth: CGFloat,
measurementBuilder: CVCellMeasurement.Builder,
state: State) -> CGSize {
owsAssertDebug(maxWidth > 0)
var maxContentWidth = (maxWidth -
(Self.avatarSize +
disclosureIconSize.width +
outerStackConfig.spacing * 2))
maxContentWidth = max(0, maxContentWidth)
let labelConfig = self.contactNameLabelConfig(state: state)
let labelSize = CVText.measureLabel(config: labelConfig, maxWidth: maxContentWidth)
var outerSubviewInfos = [ManualStackSubviewInfo]()
let avatarSize = CGSize(square: Self.avatarSize)
outerSubviewInfos.append(avatarSize.asManualSubviewInfo(hasFixedSize: true))
outerSubviewInfos.append(labelSize.asManualSubviewInfo)
outerSubviewInfos.append(disclosureIconSize.asManualSubviewInfo(hasFixedSize: true))
let outerStackMeasurement = ManualStackView.measure(config: outerStackConfig,
measurementBuilder: measurementBuilder,
measurementKey: Self.measurementKey_outerStack,
subviewInfos: outerSubviewInfos,
maxWidth: maxWidth)
return outerStackMeasurement.measuredSize
}
public override func reset() {
super.reset()
labelStack.reset()
avatarView.image = nil
contactNameLabel.text = nil
disclosureImageView.image = nil
}
}