301 lines
12 KiB
Swift
301 lines
12 KiB
Swift
//
|
|
// SBUMessageSearchResultCell.swift
|
|
// SendbirdUIKit
|
|
//
|
|
// Created by Hoon Sung on 2021/02/09.
|
|
// Copyright © 2021 Sendbird, Inc. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import SendbirdChatSDK
|
|
|
|
open class SBUMessageSearchResultCell: SBUTableViewCell {
|
|
|
|
// MARK: - Properties (View)
|
|
public private(set) lazy var coverImage = SBUCoverImageView()
|
|
public private(set) lazy var titleLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.numberOfLines = 1
|
|
label.lineBreakMode = .byTruncatingTail
|
|
|
|
return label
|
|
}()
|
|
|
|
public private(set) lazy var messageLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.numberOfLines = 2
|
|
label.lineBreakMode = .byTruncatingTail
|
|
|
|
return label
|
|
}()
|
|
|
|
public private(set) lazy var fileMessageLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.numberOfLines = 1
|
|
label.lineBreakMode = .byTruncatingMiddle
|
|
|
|
return label
|
|
}()
|
|
|
|
public private(set) lazy var fileMessageIcon: UIImageView = {
|
|
let imageView = UIImageView()
|
|
imageView.contentMode = .center
|
|
imageView.layer.cornerRadius = 8
|
|
imageView.layer.masksToBounds = false
|
|
|
|
return imageView
|
|
}()
|
|
|
|
public private(set) lazy var fileStackView: UIStackView = {
|
|
let stackView = UIStackView()
|
|
stackView.axis = .horizontal
|
|
stackView.spacing = 4
|
|
|
|
return stackView
|
|
}()
|
|
|
|
public private(set) lazy var createdAtLabel: UILabel = UILabel()
|
|
public private(set) var separatorLine = UIView()
|
|
|
|
// MARK: - Properties
|
|
|
|
@SBUThemeWrapper(theme: SBUTheme.messageSearchResultCellTheme)
|
|
public var theme: SBUMessageSearchResultCellTheme
|
|
|
|
private let coverImageSize: CGSize = CGSize(value: 56)
|
|
private let fileIconSize: CGSize = CGSize(value: 26)
|
|
private var message: BaseMessage?
|
|
|
|
// MARK: - View Lifecycle
|
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
|
self.setupViews()
|
|
self.setupLayouts()
|
|
self.setupActions()
|
|
}
|
|
|
|
required public init?(coder: NSCoder) {
|
|
super.init(coder: coder)
|
|
self.setupViews()
|
|
self.setupLayouts()
|
|
self.setupActions()
|
|
}
|
|
|
|
open override func awakeFromNib() {
|
|
super.awakeFromNib()
|
|
}
|
|
|
|
/// This function handles the initialization of views.
|
|
open override func setupViews() {
|
|
self.coverImage.clipsToBounds = true
|
|
self.coverImage.frame = CGRect(origin: .zero, size: self.coverImageSize)
|
|
self.coverImage.layer.cornerRadius = coverImageSize.height / 2
|
|
|
|
self.fileMessageIcon.frame = CGRect(origin: .zero, size: fileIconSize)
|
|
self.fileStackView.addArrangedSubview(self.fileMessageIcon)
|
|
self.fileStackView.addArrangedSubview(self.fileMessageLabel)
|
|
|
|
self.contentView.addSubview(self.coverImage)
|
|
self.contentView.addSubview(self.titleLabel)
|
|
self.contentView.addSubview(self.createdAtLabel)
|
|
self.contentView.addSubview(self.messageLabel)
|
|
self.contentView.addSubview(self.fileStackView)
|
|
self.contentView.addSubview(self.separatorLine)
|
|
}
|
|
|
|
/// This function handles the initialization of actions.
|
|
open override func setupActions() {
|
|
}
|
|
|
|
/// This function handles the initialization of autolayouts.
|
|
open override func setupLayouts() {
|
|
self.coverImage.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
self.coverImage.widthAnchor.constraint(equalToConstant: self.coverImageSize.width),
|
|
self.coverImage.heightAnchor.constraint(equalToConstant: self.coverImageSize.height),
|
|
self.coverImage.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 16),
|
|
self.coverImage.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor)
|
|
])
|
|
|
|
self.titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
self.titleLabel.leadingAnchor.constraint(equalTo: self.coverImage.trailingAnchor, constant: 16),
|
|
self.titleLabel.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10),
|
|
self.titleLabel.bottomAnchor.constraint(equalTo: self.messageLabel.topAnchor, constant: -2)
|
|
])
|
|
|
|
self.messageLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
self.messageLabel.leadingAnchor.constraint(equalTo: self.titleLabel.leadingAnchor),
|
|
self.messageLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 2),
|
|
self.messageLabel.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -16),
|
|
self.messageLabel.bottomAnchor.constraint(lessThanOrEqualTo: self.contentView.bottomAnchor, constant: -10)
|
|
])
|
|
|
|
self.fileMessageIcon.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
self.fileMessageIcon.widthAnchor.constraint(equalToConstant: self.fileIconSize.width),
|
|
self.fileMessageIcon.heightAnchor.constraint(equalToConstant: self.fileIconSize.height)
|
|
])
|
|
|
|
self.fileStackView.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
self.fileStackView.leadingAnchor.constraint(equalTo: self.titleLabel.leadingAnchor),
|
|
self.fileStackView.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 6),
|
|
self.fileStackView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -16),
|
|
])
|
|
|
|
self.createdAtLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
self.createdAtLabel.leadingAnchor.constraint(greaterThanOrEqualTo: self.titleLabel.trailingAnchor, constant: 4),
|
|
self.createdAtLabel.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 12),
|
|
self.createdAtLabel.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -16),
|
|
self.createdAtLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 30)
|
|
])
|
|
|
|
self.separatorLine.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
self.separatorLine.leadingAnchor.constraint(equalTo: self.coverImage.trailingAnchor, constant: 16),
|
|
self.separatorLine.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor),
|
|
self.separatorLine.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor),
|
|
self.separatorLine.heightAnchor.constraint(equalToConstant: 0.5)
|
|
])
|
|
|
|
self.titleLabel.setContentHuggingPriority(UILayoutPriority(249), for: .horizontal)
|
|
self.titleLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
|
|
|
self.messageLabel.setContentHuggingPriority(.defaultLow, for: .vertical)
|
|
self.createdAtLabel.setContentCompressionResistancePriority(UILayoutPriority(751), for: .horizontal)
|
|
}
|
|
|
|
/// This function handles the initialization of styles.
|
|
open override func setupStyles() {
|
|
self.backgroundColor = theme.backgroundColor
|
|
|
|
self.titleLabel.font = theme.titleFont
|
|
self.titleLabel.textColor = theme.titleTextColor
|
|
|
|
self.messageLabel.font = theme.descriptionFont
|
|
self.messageLabel.textColor = theme.descriptionTextColor
|
|
|
|
self.fileMessageLabel.font = theme.fileMessageFont
|
|
self.fileMessageLabel.textColor = theme.fileMessageTextColor
|
|
|
|
self.createdAtLabel.font = theme.updatedAtFont
|
|
self.createdAtLabel.textColor = theme.updatedAtTextColor
|
|
|
|
self.separatorLine.backgroundColor = theme.separatorLineColor
|
|
|
|
self.setupFileIcon()
|
|
}
|
|
|
|
deinit {
|
|
SBULog.info("")
|
|
}
|
|
|
|
/// This function configure a cell using `BaseMessage` information.
|
|
/// - Parameter message: `BaseMessage` object
|
|
open func configure(message: BaseMessage) {
|
|
self.message = message
|
|
|
|
self.selectionStyle = .none
|
|
|
|
if let profileURL = self.message?.sender?.profileURL {
|
|
self.coverImage.setImage(with: profileURL, makeCircle: true)
|
|
} else {
|
|
self.coverImage.setPlaceholder(
|
|
type: .iconUser,
|
|
iconSize: SBUIconSetType.Metric.defaultIconSizeLarge
|
|
)
|
|
}
|
|
|
|
if let sender = message.sender {
|
|
let username: String = SBUUser(user: sender).refinedNickname()
|
|
self.titleLabel.text = username
|
|
} else {
|
|
self.titleLabel.text = SBUStringSet.User_No_Name
|
|
}
|
|
|
|
self.messageLabel.isHidden = true
|
|
self.fileStackView.isHidden = true
|
|
|
|
switch message {
|
|
case let fileMessage as FileMessage:
|
|
self.fileStackView.isHidden = false
|
|
self.fileMessageIcon.isHidden = false
|
|
|
|
if SBUUtils.getFileType(by: fileMessage) == .voice {
|
|
self.fileMessageLabel.text = SBUStringSet.VoiceMessage.Preview.searchResult
|
|
} else {
|
|
self.fileMessageLabel.text = fileMessage.name
|
|
}
|
|
|
|
let iconType: SBUIconSetType
|
|
switch SBUUtils.getFileType(by: fileMessage) {
|
|
case .image:
|
|
if fileMessage.type.hasPrefix("image/gif") {
|
|
iconType = SBUIconSetType.iconGif
|
|
} else {
|
|
iconType = SBUIconSetType.iconPhoto
|
|
}
|
|
case .video:
|
|
iconType = SBUIconSetType.iconPlay
|
|
case .audio:
|
|
iconType = SBUIconSetType.iconFileAudio
|
|
case .voice:
|
|
iconType = SBUIconSetType.iconEmpty
|
|
self.fileMessageIcon.isHidden = true
|
|
case .pdf:
|
|
iconType = SBUIconSetType.iconPhoto
|
|
case .etc:
|
|
iconType = SBUIconSetType.iconFileDocument
|
|
}
|
|
|
|
self.fileMessageIcon.image = iconType.image(
|
|
with: self.theme.fileMessageIconTintColor,
|
|
to: SBUIconSetType.Metric.defaultIconSizeMedium
|
|
)
|
|
self.fileMessageIcon.backgroundColor = self.theme.fileMessageIconBackgroundColor
|
|
default:
|
|
self.messageLabel.isHidden = false
|
|
self.messageLabel.text = message.message
|
|
}
|
|
|
|
self.createdAtLabel.text = Date.lastUpdatedTimeForMessageSearchResultCell(
|
|
baseTimestamp: message.createdAt
|
|
)
|
|
}
|
|
|
|
/// Sets file message icon depending on the message's file type using `SBUUtils.getFileType(by: fileMessage)`.
|
|
public func setupFileIcon() {
|
|
// TODO: File icon will be removed.
|
|
guard let fileMessage = self.message as? FileMessage else { return }
|
|
let iconType: SBUIconSetType
|
|
|
|
switch SBUUtils.getFileType(by: fileMessage) {
|
|
case .image:
|
|
if fileMessage.type.hasPrefix("image/gif") {
|
|
iconType = SBUIconSetType.iconGif
|
|
} else {
|
|
iconType = SBUIconSetType.iconPhoto
|
|
}
|
|
case .video:
|
|
iconType = SBUIconSetType.iconPlay
|
|
case .audio:
|
|
iconType = SBUIconSetType.iconFileAudio
|
|
case .voice:
|
|
iconType = SBUIconSetType.iconEmpty
|
|
case .pdf:
|
|
iconType = SBUIconSetType.iconPhoto
|
|
case .etc:
|
|
iconType = SBUIconSetType.iconFileDocument
|
|
}
|
|
|
|
self.fileMessageIcon.image = iconType.image(
|
|
with: self.theme.fileMessageIconTintColor,
|
|
to: SBUIconSetType.Metric.defaultIconSizeMedium
|
|
)
|
|
self.fileMessageIcon.backgroundColor = self.theme.fileMessageIconBackgroundColor
|
|
}
|
|
}
|