134 lines
4.2 KiB
Swift
134 lines
4.2 KiB
Swift
//
|
|
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
@objc
|
|
public class CVComponentDateHeader: CVComponentBase, CVRootComponent {
|
|
|
|
public var cellReuseIdentifier: CVCellReuseIdentifier {
|
|
CVCellReuseIdentifier.dateHeader
|
|
}
|
|
|
|
public let isDedicatedCell = true
|
|
|
|
struct State: Equatable {
|
|
let text: String
|
|
}
|
|
private let dateHeaderState: State
|
|
|
|
required init(itemModel: CVItemModel, dateHeaderState: State) {
|
|
self.dateHeaderState = dateHeaderState
|
|
|
|
super.init(itemModel: itemModel)
|
|
}
|
|
|
|
public func configure(cellView: UIView,
|
|
cellMeasurement: CVCellMeasurement,
|
|
componentDelegate: CVComponentDelegate,
|
|
cellSelection: CVCellSelection,
|
|
swipeToReplyState: CVSwipeToReplyState,
|
|
componentView: CVComponentView) {
|
|
|
|
configureForRendering(componentView: componentView,
|
|
cellMeasurement: cellMeasurement,
|
|
componentDelegate: componentDelegate)
|
|
|
|
let rootView = componentView.rootView
|
|
if rootView.superview == nil {
|
|
owsAssertDebug(cellView.layoutMargins == .zero)
|
|
owsAssertDebug(cellView.subviews.isEmpty)
|
|
|
|
cellView.addSubview(rootView)
|
|
cellView.layoutMargins = cellLayoutMargins
|
|
rootView.autoPinEdgesToSuperviewMargins()
|
|
}
|
|
}
|
|
|
|
private var cellLayoutMargins: UIEdgeInsets {
|
|
UIEdgeInsets(top: 8,
|
|
leading: conversationStyle.headerGutterLeading,
|
|
bottom: 8,
|
|
trailing: conversationStyle.headerGutterTrailing)
|
|
}
|
|
|
|
public func buildComponentView(componentDelegate: CVComponentDelegate) -> CVComponentView {
|
|
CVComponentViewDateHeader()
|
|
}
|
|
|
|
public func configureForRendering(componentView: CVComponentView,
|
|
cellMeasurement: CVCellMeasurement,
|
|
componentDelegate: CVComponentDelegate) {
|
|
guard let componentView = componentView as? CVComponentViewDateHeader else {
|
|
owsFailDebug("Unexpected componentView.")
|
|
return
|
|
}
|
|
|
|
titleLabelConfig.applyForRendering(label: componentView.titleLabel)
|
|
}
|
|
|
|
static func buildState(interaction: TSInteraction) -> State {
|
|
let date = Date(millisecondsSince1970: interaction.timestamp)
|
|
let text = DateUtil.formatDate(forConversationDateBreaks: date)
|
|
return State(text: text)
|
|
}
|
|
|
|
private var titleLabelConfig: CVLabelConfig {
|
|
return CVLabelConfig(text: dateHeaderState.text,
|
|
font: UIFont.ows_dynamicTypeFootnote.ows_semibold,
|
|
textColor: Theme.secondaryTextAndIconColor,
|
|
lineBreakMode: .byTruncatingTail,
|
|
textAlignment: .center)
|
|
}
|
|
|
|
public func measure(maxWidth: CGFloat, measurementBuilder: CVCellMeasurement.Builder) -> CGSize {
|
|
owsAssertDebug(maxWidth > 0)
|
|
|
|
// Full width.
|
|
let width = maxWidth
|
|
|
|
let cellLayoutMargins = self.cellLayoutMargins
|
|
var height: CGFloat = cellLayoutMargins.totalHeight
|
|
|
|
let availableWidth = max(0, maxWidth - cellLayoutMargins.totalWidth)
|
|
let labelSize = CVText.measureLabel(config: titleLabelConfig, maxWidth: availableWidth)
|
|
|
|
height += labelSize.height
|
|
|
|
return CGSizeCeil(CGSize(width: width, height: height))
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
// Used for rendering some portion of an Conversation View item.
|
|
// It could be the entire item or some part thereof.
|
|
@objc
|
|
public class CVComponentViewDateHeader: NSObject, CVComponentView {
|
|
|
|
fileprivate let titleLabel = UILabel()
|
|
|
|
public var isDedicatedCellView = false
|
|
|
|
public var rootView: UIView {
|
|
titleLabel
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
override required init() {
|
|
}
|
|
|
|
public func setIsCellVisible(_ isCellVisible: Bool) {}
|
|
|
|
public func reset() {
|
|
owsAssertDebug(isDedicatedCellView)
|
|
|
|
if !isDedicatedCellView {
|
|
titleLabel.removeFromSuperview()
|
|
}
|
|
titleLabel.text = nil
|
|
}
|
|
}
|
|
}
|