123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- import UIKit
- import DcCore
- public class BaseMessageCell: UITableViewCell {
- static var defaultPadding: CGFloat = 12
- static var containerPadding: CGFloat = -6
- typealias BMC = BaseMessageCell
- lazy var avatarView: InitialsBadge = {
- let view = InitialsBadge(size: 28)
- view.setColor(UIColor.gray)
- view.translatesAutoresizingMaskIntoConstraints = false
- return view
- }()
- lazy var topLabel: UILabel = {
- let label = UILabel()
- label.translatesAutoresizingMaskIntoConstraints = false
- label.text = "title"
- label.font = UIFont.preferredFont(for: .caption1, weight: .regular)
- return label
- }()
- lazy var mainContentView: UIStackView = {
- let view = UIStackView()
- view.translatesAutoresizingMaskIntoConstraints = false
- view.axis = .horizontal
- return view
- }()
- lazy var bottomContentView: UIStackView = {
- let view = UIStackView(arrangedSubviews: [bottomLabel])
- view.translatesAutoresizingMaskIntoConstraints = false
- view.axis = .horizontal
- return view
- }()
- lazy var bottomLabel: UILabel = {
- let label = UILabel()
- label.translatesAutoresizingMaskIntoConstraints = false
- label.font = UIFont.preferredFont(for: .caption1, weight: .regular)
- return label
- }()
- private lazy var contentContainer: UIStackView = {
- let view = UIStackView(arrangedSubviews: [topLabel, mainContentView, bottomContentView])
- view.translatesAutoresizingMaskIntoConstraints = false
- view.axis = .vertical
- return view
- }()
- private lazy var messageBackgroundContainer: BackgroundContainer = {
- let container = BackgroundContainer()
- container.image = UIImage(color: UIColor.blue)
- container.contentMode = .scaleToFill
- container.clipsToBounds = true
- container.translatesAutoresizingMaskIntoConstraints = false
- return container
- }()
- override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
- super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
- setupSubviews()
- }
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- func setupSubviews() {
- contentView.addSubview(avatarView)
- contentView.addSubview(messageBackgroundContainer)
- contentView.addSubview(contentContainer)
- contentView.addConstraints([
- avatarView.constraintAlignTopTo(contentView, paddingTop: BMC.defaultPadding),
- avatarView.constraintAlignLeadingTo(contentView),
- avatarView.constraintAlignBottomTo(contentView, paddingBottom: BMC.defaultPadding, priority: .defaultLow),
- contentContainer.constraintToTrailingOf(avatarView, paddingLeading: BMC.defaultPadding),
- contentContainer.constraintAlignTrailingTo(contentView, paddingTrailing: BMC.defaultPadding),
- contentContainer.constraintAlignTopTo(contentView, paddingTop: BMC.defaultPadding),
- contentContainer.constraintAlignBottomTo(contentView, paddingBottom: BMC.defaultPadding),
- messageBackgroundContainer.constraintAlignLeadingTo(contentContainer, paddingLeading: BMC.containerPadding),
- messageBackgroundContainer.constraintAlignTopTo(contentContainer, paddingTop: BMC.containerPadding),
- messageBackgroundContainer.constraintAlignBottomTo(contentContainer, paddingBottom: BMC.containerPadding),
- messageBackgroundContainer.constraintAlignTrailingTo(contentContainer, paddingTrailing: BMC.containerPadding)
- ])
- }
- // update classes inheriting BaseMessageCell first before calling super.update(...)
- func update(msg: DcMsg, messageStyle: UIRectCorner) {
- topLabel.text = msg.fromContact.displayName
- avatarView.setName(msg.fromContact.displayName)
- avatarView.setColor(msg.fromContact.color)
- messageBackgroundContainer.update(rectCorners: messageStyle,
- color: msg.isFromCurrentSender ? DcColors.messagePrimaryColor : DcColors.messageSecondaryColor)
- if !msg.isInfo {
- bottomLabel.attributedText = getFormattedBottomLine(message: msg)
- }
- }
- func getFormattedBottomLine(message: DcMsg) -> NSAttributedString {
- var timestampAttributes: [NSAttributedString.Key: Any] = [
- .font: UIFont.systemFont(ofSize: 12),
- .foregroundColor: DcColors.grayDateColor,
- .paragraphStyle: NSParagraphStyle()
- ]
- let text = NSMutableAttributedString()
- if message.fromContactId == Int(DC_CONTACT_ID_SELF) {
- if let style = NSMutableParagraphStyle.default.mutableCopy() as? NSMutableParagraphStyle {
- style.alignment = .right
- timestampAttributes[.paragraphStyle] = style
- }
- text.append(NSAttributedString(string: message.formattedSentDate(), attributes: timestampAttributes))
- if message.showPadlock() {
- attachPadlock(to: text)
- }
- attachSendingState(message.state, to: text)
- return text
- }
- text.append(NSAttributedString(string: message.formattedSentDate(), attributes: timestampAttributes))
- if message.showPadlock() {
- attachPadlock(to: text)
- }
- return text
- }
- private func attachPadlock(to text: NSMutableAttributedString) {
- let imageAttachment = NSTextAttachment()
- imageAttachment.image = UIImage(named: "ic_lock")
- imageAttachment.image?.accessibilityIdentifier = String.localized("encrypted_message")
- let imageString = NSMutableAttributedString(attachment: imageAttachment)
- imageString.addAttributes([NSAttributedString.Key.baselineOffset: -1], range: NSRange(location: 0, length: 1))
- text.append(NSAttributedString(string: " "))
- text.append(imageString)
- }
- private func attachSendingState(_ state: Int, to text: NSMutableAttributedString) {
- let imageAttachment = NSTextAttachment()
- var offset = -4
- switch Int32(state) {
- case DC_STATE_OUT_PENDING, DC_STATE_OUT_PREPARING:
- imageAttachment.image = #imageLiteral(resourceName: "ic_hourglass_empty_white_36pt").scaleDownImage(toMax: 16)?.maskWithColor(color: DcColors.grayDateColor)
- imageAttachment.image?.accessibilityIdentifier = String.localized("a11y_delivery_status_sending")
- offset = -2
- case DC_STATE_OUT_DELIVERED:
- imageAttachment.image = #imageLiteral(resourceName: "ic_done_36pt").scaleDownImage(toMax: 18)
- imageAttachment.image?.accessibilityIdentifier = String.localized("a11y_delivery_status_delivered")
- case DC_STATE_OUT_MDN_RCVD:
- imageAttachment.image = #imageLiteral(resourceName: "ic_done_all_36pt").scaleDownImage(toMax: 18)
- imageAttachment.image?.accessibilityIdentifier = String.localized("a11y_delivery_status_read")
- text.append(NSAttributedString(string: " "))
- case DC_STATE_OUT_FAILED:
- imageAttachment.image = #imageLiteral(resourceName: "ic_error_36pt").scaleDownImage(toMax: 16)
- imageAttachment.image?.accessibilityIdentifier = String.localized("a11y_delivery_status_error")
- offset = -2
- default:
- imageAttachment.image = nil
- }
- let imageString = NSMutableAttributedString(attachment: imageAttachment)
- imageString.addAttributes([.baselineOffset: offset],
- range: NSRange(location: 0, length: 1))
- text.append(imageString)
- }
- override public func prepareForReuse() {
- textLabel?.text = nil
- textLabel?.attributedText = nil
- topLabel.text = nil
- avatarView.reset()
- messageBackgroundContainer.prepareForReuse()
- }
- }
|