mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-30 21:26:57 +02:00
Rename BaseBubbleCell folder to BaseRoomCell.
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
Copyright 2020 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
|
||||
|
||||
@objc protocol BaseBubbleCellType: Themable {
|
||||
var bubbleCellContentView: BubbleCellContentView? { get }
|
||||
}
|
||||
|
||||
/// `BaseBubbleCell` allows a bubble cell that inherits from this class to embed and manage the default room message outer views and add an inner content view.
|
||||
@objcMembers
|
||||
class BaseBubbleCell: MXKRoomBubbleTableViewCell, BaseBubbleCellType {
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
private var areViewsSetup: Bool = false
|
||||
|
||||
// MARK: Public
|
||||
|
||||
weak var bubbleCellContentView: BubbleCellContentView?
|
||||
|
||||
private(set) var theme: Theme?
|
||||
|
||||
// Overrides
|
||||
|
||||
override var bubbleInfoContainer: UIView! {
|
||||
get {
|
||||
guard let infoContainer = self.bubbleCellContentView?.bubbleInfoContainer else {
|
||||
fatalError("[BaseBubbleCell] bubbleInfoContainer should not be used before set")
|
||||
}
|
||||
return infoContainer
|
||||
}
|
||||
set {
|
||||
super.bubbleInfoContainer = newValue
|
||||
}
|
||||
}
|
||||
|
||||
override var bubbleOverlayContainer: UIView! {
|
||||
get {
|
||||
guard let overlayContainer = self.bubbleCellContentView?.bubbleOverlayContainer else {
|
||||
fatalError("[BaseBubbleCell] bubbleOverlayContainer should not be used before set")
|
||||
}
|
||||
return overlayContainer
|
||||
}
|
||||
set {
|
||||
super.bubbleInfoContainer = newValue
|
||||
}
|
||||
}
|
||||
|
||||
override var bubbleInfoContainerTopConstraint: NSLayoutConstraint! {
|
||||
get {
|
||||
guard let infoContainerTopConstraint = self.bubbleCellContentView?.bubbleInfoContainerTopConstraint else {
|
||||
fatalError("[BaseBubbleCell] bubbleInfoContainerTopConstraint should not be used before set")
|
||||
}
|
||||
return infoContainerTopConstraint
|
||||
}
|
||||
set {
|
||||
super.bubbleInfoContainerTopConstraint = newValue
|
||||
}
|
||||
}
|
||||
|
||||
override var pictureView: MXKImageView! {
|
||||
get {
|
||||
guard let bubbleCellContentView = self.bubbleCellContentView,
|
||||
bubbleCellContentView.showSenderAvatar else {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let pictureView = self.bubbleCellContentView?.avatarImageView else {
|
||||
fatalError("[BaseBubbleCell] pictureView should not be used before set")
|
||||
}
|
||||
return pictureView
|
||||
}
|
||||
set {
|
||||
super.pictureView = newValue
|
||||
}
|
||||
}
|
||||
|
||||
override var userNameLabel: UILabel! {
|
||||
get {
|
||||
guard let bubbleCellContentView = self.bubbleCellContentView, bubbleCellContentView.showSenderName else {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let userNameLabel = bubbleCellContentView.userNameLabel else {
|
||||
fatalError("[BaseBubbleCell] userNameLabel should not be used before set")
|
||||
}
|
||||
return userNameLabel
|
||||
}
|
||||
set {
|
||||
super.userNameLabel = newValue
|
||||
}
|
||||
}
|
||||
|
||||
override var userNameTapGestureMaskView: UIView! {
|
||||
get {
|
||||
guard let bubbleCellContentView = self.bubbleCellContentView,
|
||||
bubbleCellContentView.showSenderName else {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let userNameTapGestureMaskView = self.bubbleCellContentView?.userNameTouchMaskView else {
|
||||
fatalError("[BaseBubbleCell] userNameTapGestureMaskView should not be used before set")
|
||||
}
|
||||
return userNameTapGestureMaskView
|
||||
}
|
||||
set {
|
||||
super.userNameTapGestureMaskView = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
required override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
self.commonInit()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
self.selectionStyle = .none
|
||||
self.setupContentView()
|
||||
self.update(theme: ThemeService.shared().theme)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func removeDecorationViews() {
|
||||
if let bubbleCellReadReceiptsDisplayable = self as? BubbleCellReadReceiptsDisplayable {
|
||||
bubbleCellReadReceiptsDisplayable.removeReadReceiptsView()
|
||||
}
|
||||
|
||||
if let bubbleCellReactionsDisplayable = self as? BubbleCellReactionsDisplayable {
|
||||
bubbleCellReactionsDisplayable.removeReactionsView()
|
||||
}
|
||||
|
||||
if let bubbleCellThreadSummaryDisplayable = self as? BubbleCellThreadSummaryDisplayable {
|
||||
bubbleCellThreadSummaryDisplayable.removeThreadSummaryView()
|
||||
}
|
||||
|
||||
if let timestampDisplayable = self as? TimestampDisplayable {
|
||||
timestampDisplayable.removeTimestampView()
|
||||
}
|
||||
|
||||
if let urlPreviewDisplayable = self as? RoomCellURLPreviewDisplayable {
|
||||
urlPreviewDisplayable.removeURLPreviewView()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Overrides
|
||||
|
||||
override var isTextViewNeedsPositioningVerticalSpace: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
let showEncryptionStatus = bubbleCellContentView?.showEncryptionStatus ?? false
|
||||
|
||||
if showEncryptionStatus {
|
||||
self.setupEncryptionStatusViewTapGestureRecognizer()
|
||||
}
|
||||
}
|
||||
|
||||
override class func defaultReuseIdentifier() -> String! {
|
||||
return String(describing: self)
|
||||
}
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
|
||||
self.removeDecorationViews()
|
||||
}
|
||||
|
||||
override func render(_ cellData: MXKCellData!) {
|
||||
// In `MXKRoomBubbleTableViewCell` setupViews() is called in awakeFromNib() that is not called here, so call it only on first render() call
|
||||
self.setupViewsIfNeeded()
|
||||
|
||||
super.render(cellData)
|
||||
|
||||
guard let bubbleCellContentView = self.bubbleCellContentView else {
|
||||
return
|
||||
}
|
||||
|
||||
if let bubbleData = self.bubbleData,
|
||||
let paginationDate = bubbleData.date,
|
||||
bubbleCellContentView.showPaginationTitle {
|
||||
bubbleCellContentView.paginationLabel.text = bubbleData.eventFormatter.dateString(from: paginationDate, withTime: false)?.uppercased()
|
||||
}
|
||||
|
||||
if bubbleCellContentView.showEncryptionStatus {
|
||||
self.updateEncryptionStatusViewImage()
|
||||
}
|
||||
|
||||
self.updateUserNameColor()
|
||||
}
|
||||
|
||||
override func customizeRendering() {
|
||||
super.customizeRendering()
|
||||
self.updateUserNameColor()
|
||||
}
|
||||
|
||||
// MARK: - Themable
|
||||
|
||||
func update(theme: Theme) {
|
||||
self.theme = theme
|
||||
self.bubbleCellContentView?.update(theme: theme)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func setupViewsIfNeeded() {
|
||||
guard self.areViewsSetup == false else {
|
||||
return
|
||||
}
|
||||
self.setupViews()
|
||||
self.areViewsSetup = true
|
||||
}
|
||||
|
||||
private func setupContentView() {
|
||||
guard self.bubbleCellContentView == nil else {
|
||||
return
|
||||
}
|
||||
let bubbleCellContentView = BubbleCellContentView.instantiate()
|
||||
self.contentView.vc_addSubViewMatchingParent(bubbleCellContentView)
|
||||
self.bubbleCellContentView = bubbleCellContentView
|
||||
}
|
||||
|
||||
// MARK: - RoomCellURLPreviewDisplayable
|
||||
// Cannot use default implementation with ObjC protocol, if self conforms to BubbleCellReadReceiptsDisplayable method below will be used
|
||||
|
||||
func addURLPreviewView(_ urlPreviewView: UIView) {
|
||||
self.bubbleCellContentView?.addURLPreviewView(urlPreviewView)
|
||||
|
||||
// tmpSubviews is used for touch detection in MXKRoomBubbleTableViewCell
|
||||
self.addTemporarySubview(urlPreviewView)
|
||||
}
|
||||
|
||||
func removeURLPreviewView() {
|
||||
self.bubbleCellContentView?.removeURLPreviewView()
|
||||
}
|
||||
|
||||
// MARK: - BubbleCellReadReceiptsDisplayable
|
||||
// Cannot use default implementation with ObjC protocol, if self conforms to BubbleCellReadReceiptsDisplayable method below will be used
|
||||
|
||||
func addReadReceiptsView(_ readReceiptsView: UIView) {
|
||||
self.bubbleCellContentView?.addReadReceiptsView(readReceiptsView)
|
||||
|
||||
// tmpSubviews is used for touch detection in MXKRoomBubbleTableViewCell
|
||||
self.addTemporarySubview(readReceiptsView)
|
||||
}
|
||||
|
||||
func removeReadReceiptsView() {
|
||||
self.bubbleCellContentView?.removeReadReceiptsView()
|
||||
}
|
||||
|
||||
// MARK: - BubbleCellReactionsDisplayable
|
||||
// Cannot use default implementation with ObjC protocol, if self conforms to BubbleCellReactionsDisplayable method below will be used
|
||||
|
||||
func addReactionsView(_ reactionsView: UIView) {
|
||||
self.bubbleCellContentView?.addReactionsView(reactionsView)
|
||||
|
||||
// tmpSubviews is used for touch detection in MXKRoomBubbleTableViewCell
|
||||
self.addTemporarySubview(reactionsView)
|
||||
}
|
||||
|
||||
func removeReactionsView() {
|
||||
self.bubbleCellContentView?.removeReactionsView()
|
||||
}
|
||||
|
||||
// MARK: - BubbleCellThreadSummaryDisplayable
|
||||
|
||||
func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView) {
|
||||
self.bubbleCellContentView?.addThreadSummaryView(threadSummaryView)
|
||||
|
||||
// tmpSubviews is used for touch detection in MXKRoomBubbleTableViewCell
|
||||
self.addTemporarySubview(threadSummaryView)
|
||||
}
|
||||
|
||||
func removeThreadSummaryView() {
|
||||
self.bubbleCellContentView?.removeThreadSummaryView()
|
||||
}
|
||||
|
||||
// Encryption status
|
||||
|
||||
private func updateEncryptionStatusViewImage() {
|
||||
guard let component = self.bubbleData.getFirstBubbleComponentWithDisplay() else {
|
||||
return
|
||||
}
|
||||
self.bubbleCellContentView?.encryptionImageView.image = RoomEncryptedDataBubbleCell.encryptionIcon(for: component)
|
||||
}
|
||||
|
||||
private func setupEncryptionStatusViewTapGestureRecognizer() {
|
||||
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleEncryptionStatusContainerViewTap(_:)))
|
||||
tapGestureRecognizer.delegate = self
|
||||
self.bubbleCellContentView?.encryptionImageView.isUserInteractionEnabled = true
|
||||
}
|
||||
|
||||
@objc private func handleEncryptionStatusContainerViewTap(_ gestureRecognizer: UITapGestureRecognizer) {
|
||||
guard let delegate = self.delegate else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let component = self.bubbleData.getFirstBubbleComponentWithDisplay() else {
|
||||
return
|
||||
}
|
||||
|
||||
let userInfo: [AnyHashable: Any]?
|
||||
|
||||
if let tappedEvent = component.event {
|
||||
userInfo = [kMXKRoomBubbleCellEventKey: tappedEvent]
|
||||
} else {
|
||||
userInfo = nil
|
||||
}
|
||||
|
||||
delegate.cell(self, didRecognizeAction: kRoomEncryptedDataBubbleCellTapOnEncryptionIcon, userInfo: userInfo)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
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
|
||||
|
||||
/// `BubbleCellContentView` is a container view that display the default room message outer views and enables to manage them. Like pagination title, sender info, read receipts, reactions, encryption status.
|
||||
@objcMembers
|
||||
final class BubbleCellContentView: UIView, NibLoadable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Outlets
|
||||
|
||||
@IBOutlet weak var paginationTitleContainerView: UIView!
|
||||
@IBOutlet weak var paginationLabel: UILabel!
|
||||
@IBOutlet weak var paginationSeparatorView: UIView!
|
||||
|
||||
@IBOutlet weak var userNameContainerView: UIView!
|
||||
@IBOutlet weak var userNameLabel: UILabel!
|
||||
@IBOutlet weak var userNameTouchMaskView: UIView!
|
||||
|
||||
@IBOutlet weak var avatarContainerView: UIView!
|
||||
@IBOutlet weak var avatarImageView: MXKImageView!
|
||||
|
||||
@IBOutlet weak var innerContentView: UIView!
|
||||
|
||||
@IBOutlet weak var innerContentViewLeadingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var innerContentViewTrailingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var innerContentViewBottomContraint: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var encryptionStatusContainerView: UIView!
|
||||
@IBOutlet weak var encryptionImageView: UIImageView!
|
||||
|
||||
@IBOutlet weak var bubbleInfoContainer: UIView!
|
||||
@IBOutlet weak var bubbleInfoContainerTopConstraint: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var urlPreviewContainerView: UIView!
|
||||
@IBOutlet weak var urlPreviewContentView: UIView!
|
||||
@IBOutlet weak var urlPreviewContentViewLeadingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var urlPreviewContentViewTrailingConstraint: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var readReceiptsContainerView: UIView!
|
||||
@IBOutlet weak var readReceiptsContentView: UIView!
|
||||
|
||||
@IBOutlet weak var reactionsContainerView: UIView!
|
||||
@IBOutlet weak var reactionsContentView: UIView!
|
||||
@IBOutlet weak var reactionsContentViewLeadingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var reactionsContentViewTrailingConstraint: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var threadSummaryContainerView: UIView!
|
||||
@IBOutlet weak var threadSummaryContentView: UIView!
|
||||
@IBOutlet weak var threadSummaryContentViewLeadingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var threadSummaryContentViewTrailingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var threadSummaryContentViewBottomConstraint: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var bubbleOverlayContainer: UIView!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var showURLPreview: Bool {
|
||||
get {
|
||||
return !self.urlPreviewContainerView.isHidden
|
||||
}
|
||||
set {
|
||||
self.urlPreviewContainerView.isHidden = !newValue
|
||||
}
|
||||
}
|
||||
|
||||
private var showReadReceipts: Bool {
|
||||
get {
|
||||
return !self.readReceiptsContainerView.isHidden
|
||||
}
|
||||
set {
|
||||
self.readReceiptsContainerView.isHidden = !newValue
|
||||
}
|
||||
}
|
||||
|
||||
private var showReactions: Bool {
|
||||
get {
|
||||
return !self.reactionsContainerView.isHidden
|
||||
}
|
||||
set {
|
||||
self.reactionsContainerView.isHidden = !newValue
|
||||
}
|
||||
}
|
||||
|
||||
private var showThreadSummary: Bool {
|
||||
get {
|
||||
return !self.threadSummaryContainerView.isHidden
|
||||
} set {
|
||||
self.threadSummaryContainerView.isHidden = !newValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var showPaginationTitle: Bool {
|
||||
get {
|
||||
return !self.paginationTitleContainerView.isHidden
|
||||
}
|
||||
set {
|
||||
self.paginationTitleContainerView.isHidden = !newValue
|
||||
}
|
||||
}
|
||||
|
||||
var showSenderInfo: Bool {
|
||||
get {
|
||||
return self.showSenderAvatar && self.showSenderName
|
||||
}
|
||||
set {
|
||||
self.showSenderAvatar = newValue
|
||||
self.showSenderName = newValue
|
||||
}
|
||||
}
|
||||
|
||||
var showSenderAvatar: Bool {
|
||||
get {
|
||||
return !self.avatarContainerView.isHidden
|
||||
}
|
||||
set {
|
||||
self.avatarContainerView.isHidden = !newValue
|
||||
}
|
||||
}
|
||||
|
||||
var showSenderName: Bool {
|
||||
get {
|
||||
return !self.userNameContainerView.isHidden
|
||||
}
|
||||
set {
|
||||
self.userNameContainerView.isHidden = !newValue
|
||||
}
|
||||
}
|
||||
|
||||
var showEncryptionStatus: Bool {
|
||||
get {
|
||||
return !self.encryptionStatusContainerView.isHidden
|
||||
}
|
||||
set {
|
||||
self.encryptionStatusContainerView.isHidden = !newValue
|
||||
}
|
||||
}
|
||||
|
||||
var decorationViewsAlignment: RoomCellDecorationAlignment = .left
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
class func instantiate() -> BubbleCellContentView {
|
||||
return BubbleCellContentView.loadFromNib()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func update(theme: Theme) {
|
||||
self.backgroundColor = theme.backgroundColor
|
||||
self.paginationLabel.textColor = theme.tintColor
|
||||
self.paginationSeparatorView.backgroundColor = theme.tintColor
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - BubbleCellReadReceiptsDisplayable
|
||||
extension BubbleCellContentView: BubbleCellReadReceiptsDisplayable {
|
||||
|
||||
func addReadReceiptsView(_ readReceiptsView: UIView) {
|
||||
self.readReceiptsContentView.vc_removeAllSubviews()
|
||||
self.readReceiptsContentView.vc_addSubViewMatchingParent(readReceiptsView)
|
||||
self.showReadReceipts = true
|
||||
}
|
||||
|
||||
func removeReadReceiptsView() {
|
||||
self.showReadReceipts = false
|
||||
self.readReceiptsContentView.vc_removeAllSubviews()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - BubbleCellReactionsDisplayable
|
||||
extension BubbleCellContentView: BubbleCellReactionsDisplayable {
|
||||
|
||||
func addReactionsView(_ reactionsView: UIView) {
|
||||
self.reactionsContentView.vc_removeAllSubviews()
|
||||
|
||||
// Update reactions alignment according to current decoration alignment
|
||||
if let bubbleReactionsView = reactionsView as? BubbleReactionsView {
|
||||
|
||||
let reactionsAlignment: BubbleReactionsViewAlignment
|
||||
|
||||
switch self.decorationViewsAlignment {
|
||||
case .left:
|
||||
reactionsAlignment = .left
|
||||
case .right:
|
||||
reactionsAlignment = .right
|
||||
}
|
||||
|
||||
bubbleReactionsView.alignment = reactionsAlignment
|
||||
}
|
||||
|
||||
self.reactionsContentView.vc_addSubViewMatchingParent(reactionsView)
|
||||
|
||||
self.showReactions = true
|
||||
}
|
||||
|
||||
func removeReactionsView() {
|
||||
self.showReactions = false
|
||||
self.reactionsContentView.vc_removeAllSubviews()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - BubbleCellThreadSummaryDisplayable
|
||||
extension BubbleCellContentView: BubbleCellThreadSummaryDisplayable {
|
||||
|
||||
func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView) {
|
||||
|
||||
guard let containerView = self.threadSummaryContentView else {
|
||||
return
|
||||
}
|
||||
|
||||
containerView.vc_removeAllSubviews()
|
||||
|
||||
containerView.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerView.addSubview(threadSummaryView)
|
||||
|
||||
let leadingConstraint: NSLayoutConstraint
|
||||
let trailingConstraint: NSLayoutConstraint
|
||||
|
||||
if self.decorationViewsAlignment == .right {
|
||||
leadingConstraint = threadSummaryView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
|
||||
trailingConstraint = threadSummaryView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor)
|
||||
} else {
|
||||
leadingConstraint = threadSummaryView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor)
|
||||
trailingConstraint = threadSummaryView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
|
||||
}
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
leadingConstraint,
|
||||
threadSummaryView.topAnchor.constraint(equalTo: containerView.topAnchor),
|
||||
threadSummaryView.heightAnchor.constraint(equalToConstant: RoomBubbleCellLayout.threadSummaryViewHeight),
|
||||
threadSummaryView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
|
||||
trailingConstraint
|
||||
])
|
||||
|
||||
self.showThreadSummary = true
|
||||
}
|
||||
|
||||
func removeThreadSummaryView() {
|
||||
self.showThreadSummary = false
|
||||
self.threadSummaryContentView.vc_removeAllSubviews()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - RoomCellURLPreviewDisplayable
|
||||
extension BubbleCellContentView: RoomCellURLPreviewDisplayable {
|
||||
|
||||
func addURLPreviewView(_ urlPreviewView: UIView) {
|
||||
|
||||
guard let containerView = self.urlPreviewContentView else {
|
||||
return
|
||||
}
|
||||
|
||||
containerView.vc_removeAllSubviews()
|
||||
|
||||
containerView.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerView.addSubview(urlPreviewView)
|
||||
|
||||
if let urlPreviewView = urlPreviewView as? URLPreviewView {
|
||||
urlPreviewView.availableWidth = containerView.frame.width
|
||||
}
|
||||
|
||||
let leadingConstraint: NSLayoutConstraint
|
||||
let trailingConstraint: NSLayoutConstraint
|
||||
|
||||
if self.decorationViewsAlignment == .right {
|
||||
leadingConstraint = urlPreviewView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
|
||||
trailingConstraint = urlPreviewView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor)
|
||||
} else {
|
||||
leadingConstraint = urlPreviewView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor)
|
||||
trailingConstraint = urlPreviewView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
|
||||
}
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
leadingConstraint,
|
||||
urlPreviewView.topAnchor.constraint(equalTo: containerView.topAnchor),
|
||||
urlPreviewView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
|
||||
trailingConstraint
|
||||
])
|
||||
|
||||
self.showURLPreview = true
|
||||
}
|
||||
|
||||
func removeURLPreviewView() {
|
||||
self.showURLPreview = false
|
||||
self.urlPreviewContentView.vc_removeAllSubviews()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<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="zG5-YA-Ijy" customClass="BubbleCellContentView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="97"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XQw-Mj-NZY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="97"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="5GX-gn-bK1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="97"/>
|
||||
<subviews>
|
||||
<view hidden="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="u1e-Q2-PhY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="44"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ro1-vP-6Ha" userLabel="Pagination Title View">
|
||||
<rect key="frame" x="56" y="10" width="529" height="24"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="r7y-FK-GWS" userLabel="Pagination Label">
|
||||
<rect key="frame" x="0.0" y="0.0" width="519" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="18" id="uCj-An-Yc2"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||
<color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ytv-tA-NmI" userLabel="Pagination Separator View">
|
||||
<rect key="frame" x="0.0" y="23" width="529" height="1"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="PaginationTitleView"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="24" id="5bk-I2-Cw6"/>
|
||||
<constraint firstAttribute="bottom" secondItem="ytv-tA-NmI" secondAttribute="bottom" id="5oD-hl-YNI"/>
|
||||
<constraint firstAttribute="trailing" secondItem="ytv-tA-NmI" secondAttribute="trailing" id="Cfu-Jn-urV"/>
|
||||
<constraint firstItem="r7y-FK-GWS" firstAttribute="leading" secondItem="Ro1-vP-6Ha" secondAttribute="leading" id="Fpo-9J-9Ci"/>
|
||||
<constraint firstItem="r7y-FK-GWS" firstAttribute="top" secondItem="Ro1-vP-6Ha" secondAttribute="top" id="Rpc-oi-muy"/>
|
||||
<constraint firstItem="ytv-tA-NmI" firstAttribute="top" secondItem="r7y-FK-GWS" secondAttribute="bottom" constant="5" id="lam-eF-rEV"/>
|
||||
<constraint firstItem="ytv-tA-NmI" firstAttribute="leading" secondItem="Ro1-vP-6Ha" secondAttribute="leading" id="oBH-4x-jgt"/>
|
||||
<constraint firstAttribute="trailing" secondItem="r7y-FK-GWS" secondAttribute="trailing" constant="10" id="r4y-XW-aAD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Ro1-vP-6Ha" firstAttribute="top" secondItem="u1e-Q2-PhY" secondAttribute="top" constant="10" id="5kZ-rt-pvq"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Ro1-vP-6Ha" secondAttribute="trailing" constant="10" id="8P7-ZL-7pg"/>
|
||||
<constraint firstItem="Ro1-vP-6Ha" firstAttribute="leading" secondItem="u1e-Q2-PhY" secondAttribute="leading" constant="56" id="A4v-WV-EGn"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Ro1-vP-6Ha" secondAttribute="bottom" constant="10" id="UcW-P4-rQv"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1cK-e6-Mg5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="0.0"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="yXz-Za-4yR" customClass="MXKImageView">
|
||||
<rect key="frame" x="13" y="10" width="30" height="30"/>
|
||||
<color key="backgroundColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="PictureView"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="FbD-UB-dqc"/>
|
||||
<constraint firstAttribute="width" constant="30" id="y7F-jl-kEF"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="yXz-Za-4yR" firstAttribute="leading" secondItem="1cK-e6-Mg5" secondAttribute="leading" constant="13" id="UjU-eY-ARJ"/>
|
||||
<constraint firstItem="yXz-Za-4yR" firstAttribute="top" secondItem="1cK-e6-Mg5" secondAttribute="top" constant="10" id="jlf-dg-fp0"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="w0C-6a-f5M">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="31"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ohU-Sc-mgb">
|
||||
<rect key="frame" x="46" y="4" width="534" height="30"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="User name:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="meG-P8-61b">
|
||||
<rect key="frame" x="56" y="10" width="524" height="18"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="UserNameLabel"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="18" placeholder="YES" id="Jma-ST-usg"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="meG-P8-61b" secondAttribute="bottom" constant="3" id="HDT-eS-UWo"/>
|
||||
<constraint firstItem="ohU-Sc-mgb" firstAttribute="trailing" secondItem="meG-P8-61b" secondAttribute="trailing" id="Lbz-vD-hax"/>
|
||||
<constraint firstItem="ohU-Sc-mgb" firstAttribute="bottom" secondItem="meG-P8-61b" secondAttribute="bottom" constant="6" id="U50-ZB-dRG"/>
|
||||
<constraint firstItem="meG-P8-61b" firstAttribute="top" secondItem="w0C-6a-f5M" secondAttribute="top" constant="10" id="baE-tR-0Ck"/>
|
||||
<constraint firstItem="ohU-Sc-mgb" firstAttribute="leading" secondItem="meG-P8-61b" secondAttribute="leading" constant="-10" id="ktD-JC-hfG"/>
|
||||
<constraint firstItem="ohU-Sc-mgb" firstAttribute="top" secondItem="meG-P8-61b" secondAttribute="top" constant="-6" id="s5V-Fj-iNL"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vcq-cR-uBc">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="97"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4d4-XQ-ido">
|
||||
<rect key="frame" x="0.0" y="0.0" width="0.0" height="97"/>
|
||||
<subviews>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uHE-o7-sCe">
|
||||
<rect key="frame" x="0.0" y="16" width="16" height="97"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="encryption_warning" translatesAutoresizingMaskIntoConstraints="NO" id="Ujc-3c-e5B">
|
||||
<rect key="frame" x="0.0" y="3" width="16" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="16" id="8ck-Jh-jur"/>
|
||||
<constraint firstAttribute="width" constant="16" id="bGQ-Ha-arJ"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Ujc-3c-e5B" firstAttribute="top" secondItem="uHE-o7-sCe" secondAttribute="top" constant="3" id="d8G-zC-zPx"/>
|
||||
<constraint firstAttribute="width" constant="16" id="uSI-O4-RCY"/>
|
||||
<constraint firstItem="Ujc-3c-e5B" firstAttribute="centerX" secondItem="uHE-o7-sCe" secondAttribute="centerX" id="z4k-EX-K17"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Y6-Py-paB">
|
||||
<rect key="frame" x="0.0" y="16" width="50" height="97"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="BubbleInfoContainer"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="50" id="LtA-zk-OCc"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="uHE-o7-sCe" firstAttribute="height" secondItem="4d4-XQ-ido" secondAttribute="height" id="DhB-EC-rCE"/>
|
||||
<constraint firstItem="7Y6-Py-paB" firstAttribute="top" secondItem="4d4-XQ-ido" secondAttribute="top" constant="16" id="Wx9-0o-vzm"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="oeI-eO-mFK">
|
||||
<rect key="frame" x="56" y="3" width="524" height="78"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="oeI-eO-mFK" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="vcq-cR-uBc" secondAttribute="leading" constant="56" id="0Fr-0L-9tU"/>
|
||||
<constraint firstAttribute="bottom" secondItem="oeI-eO-mFK" secondAttribute="bottom" constant="16" id="8M5-uW-82s"/>
|
||||
<constraint firstItem="oeI-eO-mFK" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="4d4-XQ-ido" secondAttribute="trailing" constant="6" id="9By-U1-wTY"/>
|
||||
<constraint firstAttribute="trailing" secondItem="oeI-eO-mFK" secondAttribute="trailing" constant="15" id="Pbe-4d-q6Y"/>
|
||||
<constraint firstAttribute="bottom" secondItem="4d4-XQ-ido" secondAttribute="bottom" id="Tkw-p1-CYF"/>
|
||||
<constraint firstItem="4d4-XQ-ido" firstAttribute="leading" secondItem="vcq-cR-uBc" secondAttribute="leading" id="cbh-iX-gKz"/>
|
||||
<constraint firstItem="4d4-XQ-ido" firstAttribute="top" secondItem="vcq-cR-uBc" secondAttribute="top" id="hOM-gq-1au"/>
|
||||
<constraint firstAttribute="height" priority="250" id="lRu-Kd-3JZ"/>
|
||||
<constraint firstItem="oeI-eO-mFK" firstAttribute="top" secondItem="vcq-cR-uBc" secondAttribute="top" constant="3" id="uZZ-I6-Xtq"/>
|
||||
<constraint firstItem="oeI-eO-mFK" firstAttribute="leading" secondItem="vcq-cR-uBc" secondAttribute="leading" priority="750" id="vsh-pW-S46"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" clipsSubviews="YES" contentMode="scaleAspectFit" verticalHuggingPriority="254" translatesAutoresizingMaskIntoConstraints="NO" id="57V-Sl-EmD">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="0.0"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="vpX-Nl-AEt">
|
||||
<rect key="frame" x="56" y="0.0" width="524" height="0.0"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" priority="250" placeholder="YES" id="0Sv-R6-k3e"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="vpX-Nl-AEt" secondAttribute="trailing" constant="15" id="ZmA-Ns-chh"/>
|
||||
<constraint firstAttribute="bottom" secondItem="vpX-Nl-AEt" secondAttribute="bottom" id="blD-s1-b1N"/>
|
||||
<constraint firstItem="vpX-Nl-AEt" firstAttribute="top" secondItem="57V-Sl-EmD" secondAttribute="top" id="sFV-XK-lE4"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" clipsSubviews="YES" contentMode="scaleAspectFit" verticalHuggingPriority="252" translatesAutoresizingMaskIntoConstraints="NO" id="Dj1-m6-1Jw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="0.0"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="SNw-aM-ILI">
|
||||
<rect key="frame" x="56" y="0.0" width="524" height="0.0"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" priority="250" placeholder="YES" id="kBO-PM-cjY"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="SNw-aM-ILI" firstAttribute="top" secondItem="Dj1-m6-1Jw" secondAttribute="top" id="1PE-go-s7Z"/>
|
||||
<constraint firstAttribute="bottom" secondItem="SNw-aM-ILI" secondAttribute="bottom" id="SBT-1C-CPb"/>
|
||||
<constraint firstAttribute="trailing" secondItem="SNw-aM-ILI" secondAttribute="trailing" constant="15" id="ynR-d4-6cf"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" verticalHuggingPriority="253" translatesAutoresizingMaskIntoConstraints="NO" id="4zo-V8-CNe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="16"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rQt-NH-Cb0">
|
||||
<rect key="frame" x="439" y="0.0" width="150" height="16"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="16" id="WZx-xk-gav"/>
|
||||
<constraint firstAttribute="width" constant="150" id="fsY-DK-hUg"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="rQt-NH-Cb0" secondAttribute="bottom" id="6yV-vn-doj"/>
|
||||
<constraint firstItem="rQt-NH-Cb0" firstAttribute="top" secondItem="4zo-V8-CNe" secondAttribute="top" id="DNc-jy-Urh"/>
|
||||
<constraint firstAttribute="trailing" secondItem="rQt-NH-Cb0" secondAttribute="trailing" constant="6" id="lq2-AY-Lus"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" clipsSubviews="YES" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="2eB-kB-m20">
|
||||
<rect key="frame" x="0.0" y="0.0" width="595" height="0.0"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="snf-Ea-To0">
|
||||
<rect key="frame" x="56" y="0.0" width="524" height="0.0"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" priority="250" placeholder="YES" id="ymW-ys-P0T"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="snf-Ea-To0" secondAttribute="bottom" id="4tt-w0-4JE"/>
|
||||
<constraint firstItem="snf-Ea-To0" firstAttribute="top" secondItem="2eB-kB-m20" secondAttribute="top" id="Im9-Z0-ieI"/>
|
||||
<constraint firstAttribute="trailing" secondItem="snf-Ea-To0" secondAttribute="trailing" constant="15" id="Qwm-Of-Zgc"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Dj1-m6-1Jw" firstAttribute="width" secondItem="5GX-gn-bK1" secondAttribute="width" id="0Px-jL-CMJ"/>
|
||||
<constraint firstItem="1cK-e6-Mg5" firstAttribute="width" secondItem="5GX-gn-bK1" secondAttribute="width" id="2De-xT-k5e"/>
|
||||
<constraint firstItem="meG-P8-61b" firstAttribute="trailing" secondItem="oeI-eO-mFK" secondAttribute="trailing" id="2Dy-o0-r33"/>
|
||||
<constraint firstItem="snf-Ea-To0" firstAttribute="leading" secondItem="oeI-eO-mFK" secondAttribute="leading" id="2lm-T3-dEu"/>
|
||||
<constraint firstItem="w0C-6a-f5M" firstAttribute="width" secondItem="5GX-gn-bK1" secondAttribute="width" id="5nl-Le-VDi"/>
|
||||
<constraint firstItem="u1e-Q2-PhY" firstAttribute="width" secondItem="5GX-gn-bK1" secondAttribute="width" id="KrJ-dm-TaV"/>
|
||||
<constraint firstItem="57V-Sl-EmD" firstAttribute="width" secondItem="5GX-gn-bK1" secondAttribute="width" id="a2p-Bn-M5e"/>
|
||||
<constraint firstItem="4zo-V8-CNe" firstAttribute="width" secondItem="5GX-gn-bK1" secondAttribute="width" id="bdq-sQ-NQy"/>
|
||||
<constraint firstItem="vpX-Nl-AEt" firstAttribute="leading" secondItem="oeI-eO-mFK" secondAttribute="leading" id="lTt-Qx-fuQ"/>
|
||||
<constraint firstItem="meG-P8-61b" firstAttribute="leading" secondItem="oeI-eO-mFK" secondAttribute="leading" id="lq1-xP-tea"/>
|
||||
<constraint firstItem="SNw-aM-ILI" firstAttribute="leading" secondItem="oeI-eO-mFK" secondAttribute="leading" id="x1n-oT-dez"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.95294117649999999" green="0.97254901959999995" blue="0.99215686270000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="5GX-gn-bK1" firstAttribute="leading" secondItem="zG5-YA-Ijy" secondAttribute="leading" id="36u-ut-l3G"/>
|
||||
<constraint firstItem="5GX-gn-bK1" firstAttribute="top" secondItem="zG5-YA-Ijy" secondAttribute="top" id="As1-dI-9ba"/>
|
||||
<constraint firstItem="XQw-Mj-NZY" firstAttribute="top" secondItem="zG5-YA-Ijy" secondAttribute="top" id="BuL-ri-8kT"/>
|
||||
<constraint firstAttribute="bottom" secondItem="5GX-gn-bK1" secondAttribute="bottom" id="cNV-Or-YPg"/>
|
||||
<constraint firstAttribute="trailing" secondItem="5GX-gn-bK1" secondAttribute="trailing" id="deR-Cu-Brh"/>
|
||||
<constraint firstAttribute="trailing" secondItem="XQw-Mj-NZY" secondAttribute="trailing" id="eJl-Fg-neU"/>
|
||||
<constraint firstAttribute="bottom" secondItem="XQw-Mj-NZY" secondAttribute="bottom" id="kPs-G8-HdC"/>
|
||||
<constraint firstItem="XQw-Mj-NZY" firstAttribute="leading" secondItem="zG5-YA-Ijy" secondAttribute="leading" id="w8M-8g-ZQD"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="avatarContainerView" destination="1cK-e6-Mg5" id="8j5-Km-Jfj"/>
|
||||
<outlet property="avatarImageView" destination="yXz-Za-4yR" id="f56-93-gxa"/>
|
||||
<outlet property="bubbleInfoContainer" destination="7Y6-Py-paB" id="uLv-MM-HIL"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="Wx9-0o-vzm" id="nLG-nC-lwV"/>
|
||||
<outlet property="bubbleOverlayContainer" destination="XQw-Mj-NZY" id="6d1-EN-LPY"/>
|
||||
<outlet property="encryptionImageView" destination="Ujc-3c-e5B" id="7zc-Y7-1jT"/>
|
||||
<outlet property="encryptionStatusContainerView" destination="uHE-o7-sCe" id="Dl7-QS-WKl"/>
|
||||
<outlet property="innerContentView" destination="oeI-eO-mFK" id="ap1-He-C6g"/>
|
||||
<outlet property="innerContentViewBottomContraint" destination="8M5-uW-82s" id="Vn0-6C-LSW"/>
|
||||
<outlet property="innerContentViewLeadingConstraint" destination="0Fr-0L-9tU" id="ByY-oe-d8Y"/>
|
||||
<outlet property="innerContentViewTrailingConstraint" destination="Pbe-4d-q6Y" id="24b-AS-hX4"/>
|
||||
<outlet property="paginationLabel" destination="r7y-FK-GWS" id="R9V-ix-mDu"/>
|
||||
<outlet property="paginationSeparatorView" destination="ytv-tA-NmI" id="sgk-n1-KQi"/>
|
||||
<outlet property="paginationTitleContainerView" destination="u1e-Q2-PhY" id="Osl-dF-fpA"/>
|
||||
<outlet property="reactionsContainerView" destination="Dj1-m6-1Jw" id="p5e-n1-Wca"/>
|
||||
<outlet property="reactionsContentView" destination="SNw-aM-ILI" id="wMe-f0-qhq"/>
|
||||
<outlet property="reactionsContentViewLeadingConstraint" destination="x1n-oT-dez" id="LUh-3Q-SVr"/>
|
||||
<outlet property="reactionsContentViewTrailingConstraint" destination="ynR-d4-6cf" id="Sy0-o9-vAC"/>
|
||||
<outlet property="readReceiptsContainerView" destination="4zo-V8-CNe" id="7ek-u4-CX8"/>
|
||||
<outlet property="readReceiptsContentView" destination="rQt-NH-Cb0" id="tqw-je-kp9"/>
|
||||
<outlet property="threadSummaryContainerView" destination="2eB-kB-m20" id="0Y4-4E-I9K"/>
|
||||
<outlet property="threadSummaryContentView" destination="snf-Ea-To0" id="6Oo-Gj-e4Z"/>
|
||||
<outlet property="threadSummaryContentViewBottomConstraint" destination="4tt-w0-4JE" id="6db-Jz-jys"/>
|
||||
<outlet property="threadSummaryContentViewLeadingConstraint" destination="2lm-T3-dEu" id="jR6-sh-Nul"/>
|
||||
<outlet property="threadSummaryContentViewTrailingConstraint" destination="Qwm-Of-Zgc" id="dfE-aR-MQQ"/>
|
||||
<outlet property="urlPreviewContainerView" destination="57V-Sl-EmD" id="9c6-ai-BY8"/>
|
||||
<outlet property="urlPreviewContentView" destination="vpX-Nl-AEt" id="P8S-Fg-VFQ"/>
|
||||
<outlet property="urlPreviewContentViewLeadingConstraint" destination="lTt-Qx-fuQ" id="5Fc-zl-b1j"/>
|
||||
<outlet property="urlPreviewContentViewTrailingConstraint" destination="ZmA-Ns-chh" id="EXg-Rr-cuJ"/>
|
||||
<outlet property="userNameContainerView" destination="w0C-6a-f5M" id="fZE-vY-0nR"/>
|
||||
<outlet property="userNameLabel" destination="meG-P8-61b" id="ETK-ag-WYR"/>
|
||||
<outlet property="userNameTouchMaskView" destination="ohU-Sc-mgb" id="FwW-aL-kc5"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-1092" y="-1332"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="encryption_warning" width="12" height="12"/>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2020 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
|
||||
|
||||
/// `BubbleCellReactionsDisplayable` is a protocol indicating that a cell support displaying reactions.
|
||||
@objc protocol BubbleCellReactionsDisplayable {
|
||||
func addReactionsView(_ reactionsView: UIView)
|
||||
func removeReactionsView()
|
||||
}
|
||||
@@ -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
|
||||
|
||||
/// `BubbleCellReadReceiptsDisplayable` is a protocol indicating that a cell support displaying read receipts.
|
||||
@objc protocol BubbleCellReadReceiptsDisplayable {
|
||||
func addReadReceiptsView(_ readReceiptsView: UIView)
|
||||
func removeReadReceiptsView()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
|
||||
/// `BubbleCellThreadSummaryDisplayable` is a protocol indicating that a cell support displaying a thread summary.
|
||||
@objc protocol BubbleCellThreadSummaryDisplayable {
|
||||
func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView)
|
||||
func removeThreadSummaryView()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
|
||||
/// BubbleCellContentView decoration view items alignment
|
||||
enum RoomCellDecorationAlignment {
|
||||
case left
|
||||
case right
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
|
||||
/// `RoomCellURLPreviewDisplayable` is a protocol indicating that a cell support displaying a URL preview.
|
||||
@objc protocol RoomCellURLPreviewDisplayable {
|
||||
func addURLPreviewView(_ urlPreviewView: UIView)
|
||||
func removeURLPreviewView()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
|
||||
/// `TimestampDisplayable` is a protocol indicating that a view supports displaying a timestamp.
|
||||
@objc protocol TimestampDisplayable {
|
||||
func addTimestampView(_ timestampView: UIView)
|
||||
func removeTimestampView()
|
||||
}
|
||||
Reference in New Issue
Block a user