mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-24 18:42:47 +02:00
Merge branch 'develop' into ismail/5096_thread_notifications
This commit is contained in:
@@ -34,6 +34,8 @@ class BaseBubbleCell: MXKRoomBubbleTableViewCell, BaseBubbleCellType {
|
||||
|
||||
weak var bubbleCellContentView: BubbleCellContentView?
|
||||
|
||||
private(set) var theme: Theme?
|
||||
|
||||
// Overrides
|
||||
|
||||
override var bubbleInfoContainer: UIView! {
|
||||
@@ -205,6 +207,7 @@ class BaseBubbleCell: MXKRoomBubbleTableViewCell, BaseBubbleCellType {
|
||||
// MARK: - Themable
|
||||
|
||||
func update(theme: Theme) {
|
||||
self.theme = theme
|
||||
self.bubbleCellContentView?.update(theme: theme)
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ final class BubbleCellContentView: UIView, NibLoadable {
|
||||
|
||||
@IBOutlet weak var innerContentView: UIView!
|
||||
|
||||
@IBOutlet weak var innerContentViewLeadingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var innerContentViewTrailingConstraint: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var encryptionStatusContainerView: UIView!
|
||||
@IBOutlet weak var encryptionImageView: UIImageView!
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<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="18093"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -234,6 +234,8 @@
|
||||
<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="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"/>
|
||||
@@ -246,7 +248,7 @@
|
||||
<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="-976.08695652173924" y="-1318.1919642857142"/>
|
||||
<point key="canvasLocation" x="-1092" y="-1332"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -217,6 +217,7 @@ extern NSString *const kMXKRoomBubbleCellUrlItemInteraction;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewTopConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewBottomConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewLeadingConstraint;
|
||||
@property (weak, nonatomic) NSLayoutConstraint *attachViewTrailingConstraint;
|
||||
|
||||
/**
|
||||
The constraints which defines the relationship between bubbleInfoContainer and its superview
|
||||
@@ -329,4 +330,7 @@ extern NSString *const kMXKRoomBubbleCellUrlItemInteraction;
|
||||
/// Add temporary subview to `tmpSubviews` property.
|
||||
- (void)addTemporarySubview:(UIView*)subview;
|
||||
|
||||
/// Called when content view cell is tapped
|
||||
- (IBAction)onContentViewTap:(UITapGestureRecognizer*)sender;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1069,10 +1069,7 @@ static BOOL _disableLongPressGestureOnEvent;
|
||||
|
||||
- (BOOL)isBubbleDataContainsFileAttachment
|
||||
{
|
||||
return bubbleData.attachment
|
||||
&& (bubbleData.attachment.type == MXKAttachmentTypeFile || bubbleData.attachment.type == MXKAttachmentTypeAudio || bubbleData.attachment.type == MXKAttachmentTypeVoiceMessage)
|
||||
&& bubbleData.attachment.contentURL
|
||||
&& bubbleData.attachment.contentInfo;
|
||||
return bubbleData.isAttachment;
|
||||
}
|
||||
|
||||
- (MXKRoomBubbleComponent*)closestBubbleComponentForGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer locationInView:(UIView*)view
|
||||
|
||||
@@ -49,7 +49,7 @@ class PollBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplayable {
|
||||
}
|
||||
|
||||
// The normal flow for tapping on cell content views doesn't work for bubbles without attributed strings
|
||||
func onContentViewTap(_ sender: UITapGestureRecognizer) {
|
||||
override func onContentViewTap(_ sender: UITapGestureRecognizer) {
|
||||
guard let event = self.event else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -67,6 +67,25 @@ typedef NS_ENUM(NSUInteger, RoomTimelineCellIdentifier) {
|
||||
RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithPaginationTitle,
|
||||
|
||||
// - Attachment without thumbnail
|
||||
// --- Clear
|
||||
RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnail,
|
||||
RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailWithPaginationTitle,
|
||||
// --- Encrypted
|
||||
RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncrypted,
|
||||
RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncryptedWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncryptedWithPaginationTitle,
|
||||
// -- Outgoing
|
||||
// --- Clear
|
||||
RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnail,
|
||||
RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailWithPaginationTitle,
|
||||
// --- Encrypted
|
||||
RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncrypted,
|
||||
RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncryptedWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncryptedWithPaginationTitle,
|
||||
|
||||
// - Room membership
|
||||
RoomTimelineCellIdentifierMembership,
|
||||
RoomTimelineCellIdentifierMembershipWithPaginationTitle,
|
||||
@@ -92,19 +111,29 @@ typedef NS_ENUM(NSUInteger, RoomTimelineCellIdentifier) {
|
||||
RoomTimelineCellIdentifierGroupCallStatus,
|
||||
|
||||
// - Voice message
|
||||
RoomTimelineCellIdentifierVoiceMessage,
|
||||
RoomTimelineCellIdentifierVoiceMessageWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierVoiceMessageWithPaginationTitle,
|
||||
|
||||
// -- Incoming
|
||||
RoomTimelineCellIdentifierIncomingVoiceMessage,
|
||||
RoomTimelineCellIdentifierIncomingVoiceMessageWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierIncomingVoiceMessageWithPaginationTitle,
|
||||
// -- Outgoing
|
||||
RoomTimelineCellIdentifierOutgoingVoiceMessage,
|
||||
RoomTimelineCellIdentifierOutgoingVoiceMessageWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierOutgoingVoiceMessageWithPaginationTitle,
|
||||
|
||||
// - Poll
|
||||
RoomTimelineCellIdentifierPoll,
|
||||
RoomTimelineCellIdentifierPollWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierPollWithPaginationTitle,
|
||||
|
||||
// - Location sharing
|
||||
RoomTimelineCellIdentifierLocation,
|
||||
RoomTimelineCellIdentifierLocationWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierLocationWithPaginationTitle,
|
||||
// -- Incoming
|
||||
RoomTimelineCellIdentifierIncomingLocation,
|
||||
RoomTimelineCellIdentifierIncomingLocationWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierIncomingLocationWithPaginationTitle,
|
||||
// -- Outgoing
|
||||
RoomTimelineCellIdentifierOutgoingLocation,
|
||||
RoomTimelineCellIdentifierOutgoingLocationWithoutSenderInfo,
|
||||
RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle,
|
||||
|
||||
// - Others
|
||||
RoomTimelineCellIdentifierEmpty,
|
||||
|
||||
@@ -121,6 +121,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared];
|
||||
|
||||
[timelineConfiguration.currentStyle.cellLayoutUpdater updateLayoutForSelectedStickerCell:self];
|
||||
|
||||
// Retrieve the suitable content size for the attachment thumbnail
|
||||
CGSize contentSize = bubbleData.contentSize;
|
||||
// Update image view frame in order to center loading wheel (if any)
|
||||
|
||||
+54
-10
@@ -24,11 +24,11 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating {
|
||||
private var theme: Theme
|
||||
|
||||
private var incomingColor: UIColor {
|
||||
return self.theme.colors.system
|
||||
return self.theme.roomCellIncomingBubbleBackgroundColor
|
||||
}
|
||||
|
||||
private var outgoingColor: UIColor {
|
||||
return self.theme.colors.accent.withAlphaComponent(0.10)
|
||||
return self.theme.roomCellOutgoingBubbleBackgroundColor
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
@@ -41,10 +41,10 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating {
|
||||
|
||||
func updateLayoutIfNeeded(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) {
|
||||
|
||||
if cellData.isSenderCurrentUser {
|
||||
self.updateLayout(forOutgoingTextMessageCell: cell, andCellData: cellData)
|
||||
} else {
|
||||
if cellData.isIncoming {
|
||||
self.updateLayout(forIncomingTextMessageCell: cell, andCellData: cellData)
|
||||
} else {
|
||||
self.updateLayout(forOutgoingTextMessageCell: cell, andCellData: cellData)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,22 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating {
|
||||
self.setupOutgoingFileAttachViewMargins(for: cell)
|
||||
}
|
||||
|
||||
func setupLayout(forIncomingFileAttachmentCell cell: MXKRoomBubbleTableViewCell) {
|
||||
|
||||
self.setupIncomingFileAttachViewMargins(for: cell)
|
||||
}
|
||||
|
||||
func updateLayout(forSelectedStickerCell cell: RoomSelectedStickerBubbleCell) {
|
||||
|
||||
if cell.bubbleData.isIncoming {
|
||||
self.setupLayout(forIncomingFileAttachmentCell: cell)
|
||||
} else {
|
||||
self.setupLayout(forOutgoingFileAttachmentCell: cell)
|
||||
cell.userNameLabel?.isHidden = true
|
||||
cell.pictureView?.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Themable
|
||||
|
||||
func update(theme: Theme) {
|
||||
@@ -160,13 +176,13 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating {
|
||||
|
||||
switch firstEvent.eventType {
|
||||
case .roomMessage:
|
||||
if let messageTypeString = firstEvent.content["msgtype"] as? String {
|
||||
|
||||
let messageType = MXMessageType(identifier: messageTypeString)
|
||||
|
||||
if let messageType = firstEvent.messageType {
|
||||
switch messageType {
|
||||
case .text, .emote, .file:
|
||||
case .text, .file:
|
||||
return true
|
||||
case .emote:
|
||||
// Explicitely disable bubble for emotes
|
||||
return false
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -341,5 +357,33 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating {
|
||||
NSLayoutConstraint.activate([
|
||||
rightConstraint
|
||||
])
|
||||
|
||||
cell.attachViewTrailingConstraint = rightConstraint
|
||||
}
|
||||
|
||||
private func setupIncomingFileAttachViewMargins(for cell: MXKRoomBubbleTableViewCell) {
|
||||
|
||||
guard let attachmentView = cell.attachmentView,
|
||||
cell.attachViewLeadingConstraint == nil || cell.attachViewLeadingConstraint.isActive == false else {
|
||||
return
|
||||
}
|
||||
|
||||
if let attachViewTrailingConstraint = cell.attachViewTrailingConstraint {
|
||||
attachViewTrailingConstraint.isActive = false
|
||||
cell.attachViewTrailingConstraint = nil
|
||||
}
|
||||
|
||||
let contentView = cell.contentView
|
||||
|
||||
// TODO: Use constants
|
||||
let leftMargin: CGFloat = 67
|
||||
|
||||
let leftConstraint = attachmentView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: -leftMargin)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
leftConstraint
|
||||
])
|
||||
|
||||
cell.attachViewLeadingConstraint = leftConstraint
|
||||
}
|
||||
}
|
||||
|
||||
+149
-67
@@ -28,39 +28,61 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
}
|
||||
|
||||
override func addTimestampLabel(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) {
|
||||
|
||||
|
||||
// If cell contains a bubble background, add the timestamp inside of it
|
||||
if let bubbleBackgroundView = cell.messageBubbleBackgroundView, bubbleBackgroundView.isHidden == false {
|
||||
|
||||
let componentIndex = cellData.mostRecentComponentIndex
|
||||
|
||||
guard let bubbleComponents = cellData.bubbleComponents,
|
||||
componentIndex < bubbleComponents.count else {
|
||||
return
|
||||
}
|
||||
|
||||
let component = bubbleComponents[componentIndex]
|
||||
|
||||
let timestampLabel = self.createTimestampLabel(cellData: cellData,
|
||||
bubbleComponent: component,
|
||||
viewTag: componentIndex)
|
||||
timestampLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
cell.addTemporarySubview(timestampLabel)
|
||||
|
||||
bubbleBackgroundView.addSubview(timestampLabel)
|
||||
|
||||
let rightMargin: CGFloat = 8.0
|
||||
let bottomMargin: CGFloat = 4.0
|
||||
|
||||
let trailingConstraint = timestampLabel.trailingAnchor.constraint(equalTo: bubbleBackgroundView.trailingAnchor, constant: -rightMargin)
|
||||
|
||||
let bottomConstraint = timestampLabel.bottomAnchor.constraint(equalTo: bubbleBackgroundView.bottomAnchor, constant: -bottomMargin)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
trailingConstraint,
|
||||
bottomConstraint
|
||||
])
|
||||
if let bubbleBackgroundView = cell.messageBubbleBackgroundView, bubbleBackgroundView.isHidden == false, let timestampLabel = self.createTimestampLabel(for: cellData) {
|
||||
|
||||
self.addTimestampLabel(timestampLabel,
|
||||
to: cell,
|
||||
on: bubbleBackgroundView,
|
||||
constrainingView: bubbleBackgroundView)
|
||||
|
||||
} else if cellData.isAttachmentWithThumbnail {
|
||||
|
||||
if cellData.attachment?.type == .sticker,
|
||||
let attachmentView = cell.attachmentView,
|
||||
let timestampLabel = self.createTimestampLabel(for: cellData) {
|
||||
|
||||
// Prevent overlap with send status icon
|
||||
let bottomMargin: CGFloat = 20.0
|
||||
let rightMargin: CGFloat = -27.0
|
||||
|
||||
self.addTimestampLabel(timestampLabel,
|
||||
to: cell,
|
||||
on: cell.contentView,
|
||||
constrainingView: attachmentView,
|
||||
rightMargin: rightMargin,
|
||||
bottomMargin: bottomMargin)
|
||||
|
||||
} else if let attachmentView = cell.attachmentView, let timestampLabel = self.createTimestampLabel(for: cellData, textColor: self.theme.baseIconPrimaryColor) {
|
||||
// For media with thumbnail cells, add timestamp inside thumbnail
|
||||
|
||||
self.addTimestampLabel(timestampLabel,
|
||||
to: cell,
|
||||
on: cell.contentView,
|
||||
constrainingView: attachmentView)
|
||||
|
||||
} else {
|
||||
super.addTimestampLabel(toCell: cell, cellData: cellData)
|
||||
}
|
||||
} else if let voiceMessageCell = cell as? VoiceMessageBubbleCell, let playbackView = voiceMessageCell.playbackController?.playbackView, let timestampLabel = self.createTimestampLabel(for: cellData) {
|
||||
|
||||
// Add timestamp on cell inherting from VoiceMessageBubbleCell
|
||||
|
||||
self.addTimestampLabel(timestampLabel,
|
||||
to: cell,
|
||||
on: cell.contentView,
|
||||
constrainingView: playbackView)
|
||||
|
||||
} else if let fileWithoutThumbnailCell = cell as? FileWithoutThumbnailBaseBubbleCell, let fileAttachementView = fileWithoutThumbnailCell.fileAttachementView, let timestampLabel = self.createTimestampLabel(for: cellData) {
|
||||
|
||||
// Add timestamp on cell inherting from VoiceMessageBubbleCell
|
||||
|
||||
self.addTimestampLabel(timestampLabel,
|
||||
to: cell,
|
||||
on: fileAttachementView,
|
||||
constrainingView: fileAttachementView)
|
||||
|
||||
} else {
|
||||
super.addTimestampLabel(toCell: cell, cellData: cellData)
|
||||
}
|
||||
@@ -86,24 +108,9 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
let topMargin: CGFloat = 4.0
|
||||
let leftMargin: CGFloat
|
||||
let rightMargin: CGFloat
|
||||
|
||||
// Outgoing message
|
||||
if cellData.isSenderCurrentUser {
|
||||
reactionsView.alignment = .right
|
||||
|
||||
// TODO: Use constants
|
||||
var outgointLeftMargin: CGFloat = 80.0
|
||||
|
||||
if cellData.containsBubbleComponentWithEncryptionBadge {
|
||||
outgointLeftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin
|
||||
}
|
||||
|
||||
leftMargin = outgointLeftMargin
|
||||
|
||||
// TODO: Use constants
|
||||
rightMargin = 33
|
||||
} else {
|
||||
// Incoming message
|
||||
|
||||
// Incoming message
|
||||
if cellData.isIncoming {
|
||||
|
||||
var incomingLeftMargin = RoomBubbleCellLayout.reactionsViewLeftMargin
|
||||
|
||||
@@ -117,6 +124,22 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
let messageViewMarginRight: CGFloat = 42.0
|
||||
|
||||
rightMargin = messageViewMarginRight
|
||||
} else {
|
||||
// Outgoing message
|
||||
|
||||
reactionsView.alignment = .right
|
||||
|
||||
// TODO: Use constants
|
||||
var outgoingLeftMargin: CGFloat = 80.0
|
||||
|
||||
if cellData.containsBubbleComponentWithEncryptionBadge {
|
||||
outgoingLeftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin
|
||||
}
|
||||
|
||||
leftMargin = outgoingLeftMargin
|
||||
|
||||
// TODO: Use constants
|
||||
rightMargin = 33
|
||||
}
|
||||
|
||||
let leadingConstraint = reactionsView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, constant: leftMargin)
|
||||
@@ -152,16 +175,10 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
|
||||
let leadingOrTrailingConstraint: NSLayoutConstraint
|
||||
|
||||
// Outgoing message
|
||||
if cellData.isSenderCurrentUser {
|
||||
|
||||
// TODO: Use constants
|
||||
let rightMargin: CGFloat = 34.0
|
||||
|
||||
leadingOrTrailingConstraint = urlPreviewView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, constant: -rightMargin)
|
||||
} else {
|
||||
// Incoming message
|
||||
|
||||
|
||||
// Incoming message
|
||||
if cellData.isIncoming {
|
||||
|
||||
var leftMargin = RoomBubbleCellLayout.reactionsViewLeftMargin
|
||||
if cellData.containsBubbleComponentWithEncryptionBadge {
|
||||
leftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin
|
||||
@@ -170,6 +187,13 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
leftMargin-=5.0
|
||||
|
||||
leadingOrTrailingConstraint = urlPreviewView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, constant: leftMargin)
|
||||
} else {
|
||||
// Outgoing message
|
||||
|
||||
// TODO: Use constants
|
||||
let rightMargin: CGFloat = 34.0
|
||||
|
||||
leadingOrTrailingConstraint = urlPreviewView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, constant: -rightMargin)
|
||||
}
|
||||
|
||||
let topMargin = contentViewPositionY + RoomBubbleCellLayout.urlPreviewViewTopMargin + RoomBubbleCellLayout.reactionsViewTopMargin
|
||||
@@ -183,14 +207,16 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func createTimestampLabel(cellData: MXKRoomBubbleCellData, bubbleComponent: MXKRoomBubbleComponent, viewTag: Int) -> UILabel {
|
||||
// MARK: Timestamp management
|
||||
|
||||
private func createTimestampLabel(cellData: MXKRoomBubbleCellData, bubbleComponent: MXKRoomBubbleComponent, viewTag: Int, textColor: UIColor) -> UILabel {
|
||||
|
||||
let timeLabel = UILabel()
|
||||
|
||||
timeLabel.text = cellData.eventFormatter.timeString(from: bubbleComponent.date)
|
||||
timeLabel.textAlignment = .right
|
||||
timeLabel.textColor = ThemeService.shared().theme.textSecondaryColor
|
||||
timeLabel.font = UIFont.systemFont(ofSize: 11, weight: .light)
|
||||
timeLabel.textColor = textColor
|
||||
timeLabel.font = self.theme.fonts.caption2
|
||||
timeLabel.adjustsFontSizeToFitWidth = true
|
||||
timeLabel.tag = viewTag
|
||||
timeLabel.accessibilityIdentifier = "timestampLabel"
|
||||
@@ -198,6 +224,23 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
return timeLabel
|
||||
}
|
||||
|
||||
func createTimestampLabel(for cellData: RoomBubbleCellData) -> UILabel? {
|
||||
return self.createTimestampLabel(for: cellData, textColor: self.theme.textSecondaryColor)
|
||||
}
|
||||
|
||||
private func createTimestampLabel(for cellData: RoomBubbleCellData, textColor: UIColor) -> UILabel? {
|
||||
|
||||
let componentIndex = cellData.mostRecentComponentIndex
|
||||
|
||||
guard let bubbleComponents = cellData.bubbleComponents, componentIndex < bubbleComponents.count else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let component = bubbleComponents[componentIndex]
|
||||
|
||||
return self.createTimestampLabel(cellData: cellData, bubbleComponent: component, viewTag: componentIndex, textColor: textColor)
|
||||
}
|
||||
|
||||
private func canShowTimestamp(forCellData cellData: MXKRoomBubbleCellData) -> Bool {
|
||||
|
||||
guard cellData.isCollapsableAndCollapsed == false else {
|
||||
@@ -208,12 +251,29 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
return false
|
||||
}
|
||||
|
||||
switch cellData.cellDataTag {
|
||||
case .location:
|
||||
return true
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if let attachmentType = cellData.attachment?.type {
|
||||
switch attachmentType {
|
||||
case .voiceMessage, .audio:
|
||||
return true
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if cellData.isAttachmentWithThumbnail {
|
||||
return true
|
||||
}
|
||||
|
||||
switch firstEvent.eventType {
|
||||
case .roomMessage:
|
||||
if let messageTypeString = firstEvent.content["msgtype"] as? String {
|
||||
|
||||
let messageType = MXMessageType(identifier: messageTypeString)
|
||||
|
||||
if let messageType = firstEvent.messageType {
|
||||
switch messageType {
|
||||
case .text, .emote, .file:
|
||||
return true
|
||||
@@ -227,4 +287,26 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private func addTimestampLabel(_ timestampLabel: UILabel,
|
||||
to cell: MXKRoomBubbleTableViewCell,
|
||||
on containerView: UIView,
|
||||
constrainingView: UIView,
|
||||
rightMargin: CGFloat = 8.0,
|
||||
bottomMargin: CGFloat = 4.0) {
|
||||
timestampLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
cell.addTemporarySubview(timestampLabel)
|
||||
|
||||
containerView.addSubview(timestampLabel)
|
||||
|
||||
let trailingConstraint = timestampLabel.trailingAnchor.constraint(equalTo: constrainingView.trailingAnchor, constant: -rightMargin)
|
||||
|
||||
let bottomConstraint = timestampLabel.bottomAnchor.constraint(equalTo: constrainingView.bottomAnchor, constant: -bottomMargin)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
trailingConstraint,
|
||||
bottomConstraint
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,56 @@
|
||||
#import "RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h"
|
||||
#import "RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h"
|
||||
|
||||
#import "GeneratedInterface-Swift.h"
|
||||
|
||||
@implementation BubbleRoomTimelineCellProvider
|
||||
|
||||
#pragma mark - Registration
|
||||
|
||||
- (void)registerCellsForTableView:(UITableView *)tableView
|
||||
{
|
||||
[super registerCellsForTableView:tableView];
|
||||
|
||||
[self registerFileWithoutThumbnailCellsForTableView:tableView];
|
||||
}
|
||||
|
||||
- (void)registerVoiceMessageCellsForTableView:(UITableView*)tableView
|
||||
{
|
||||
// Incoming
|
||||
[tableView registerClass:VoiceMessageIncomingBubbleCell.class forCellReuseIdentifier:VoiceMessageIncomingBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:VoiceMessageIncomingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:VoiceMessageIncomingWithoutSenderInfoBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:VoiceMessageIncomingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:VoiceMessageIncomingWithPaginationTitleBubbleCell.defaultReuseIdentifier];
|
||||
// Outgoing
|
||||
[tableView registerClass:VoiceMessageOutgoingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:VoiceMessageOutgoingWithoutSenderInfoBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:VoiceMessageOutgoingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:VoiceMessageOutgoingWithPaginationTitleBubbleCell.defaultReuseIdentifier];
|
||||
}
|
||||
|
||||
- (void)registerLocationCellsForTableView:(UITableView*)tableView
|
||||
{
|
||||
// Incoming
|
||||
[tableView registerClass:LocationIncomingBubbleCell.class forCellReuseIdentifier:LocationIncomingBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:LocationIncomingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:LocationIncomingWithoutSenderInfoBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:LocationIncomingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:LocationIncomingWithPaginationTitleBubbleCell.defaultReuseIdentifier];
|
||||
|
||||
// Outgoing
|
||||
[tableView registerClass:LocationOutgoingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:LocationOutgoingWithoutSenderInfoBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:LocationOutgoingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:LocationOutgoingWithPaginationTitleBubbleCell.defaultReuseIdentifier];
|
||||
}
|
||||
|
||||
- (void)registerFileWithoutThumbnailCellsForTableView:(UITableView*)tableView
|
||||
{
|
||||
// Incoming
|
||||
[tableView registerClass:FileWithoutThumbnailIncomingBubbleCell.class forCellReuseIdentifier:FileWithoutThumbnailIncomingBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:FileWithoutThumbnailIncomingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:FileWithoutThumbnailIncomingWithoutSenderInfoBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:FileWithoutThumbnailIncomingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:FileWithoutThumbnailIncomingWithPaginationTitleBubbleCell.defaultReuseIdentifier];
|
||||
|
||||
// Outgoing
|
||||
[tableView registerClass:FileWithoutThumbnailOutoingWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:FileWithoutThumbnailOutoingWithoutSenderInfoBubbleCell.defaultReuseIdentifier];
|
||||
[tableView registerClass:FileWithoutThumbnailOutoingWithPaginationTitleBubbleCell.class forCellReuseIdentifier:FileWithoutThumbnailOutoingWithPaginationTitleBubbleCell.defaultReuseIdentifier];
|
||||
}
|
||||
|
||||
#pragma mark - Mapping
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)outgoingTextMessageCellsMapping
|
||||
{
|
||||
// Hide sender info and avatar for bubble outgoing messages
|
||||
@@ -87,4 +135,60 @@
|
||||
};
|
||||
}
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)incomingAttachmentWithoutThumbnailCellsMapping
|
||||
{
|
||||
return @{
|
||||
// Clear
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnail) : FileWithoutThumbnailIncomingBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailWithoutSenderInfo) : FileWithoutThumbnailIncomingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailWithPaginationTitle) : FileWithoutThumbnailIncomingWithPaginationTitleBubbleCell.class,
|
||||
// Encrypted
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncrypted) : FileWithoutThumbnailIncomingBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncryptedWithoutSenderInfo) : FileWithoutThumbnailIncomingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncryptedWithPaginationTitle) : FileWithoutThumbnailIncomingWithPaginationTitleBubbleCell.class
|
||||
};
|
||||
}
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)outgoingAttachmentWithoutThumbnailCellsMapping
|
||||
{
|
||||
return @{
|
||||
// Clear
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnail) : FileWithoutThumbnailOutoingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailWithoutSenderInfo) : FileWithoutThumbnailOutoingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailWithPaginationTitle) : FileWithoutThumbnailOutoingWithPaginationTitleBubbleCell.class,
|
||||
// Encrypted
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncrypted) : FileWithoutThumbnailOutoingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncryptedWithoutSenderInfo) : FileWithoutThumbnailOutoingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncryptedWithPaginationTitle) : FileWithoutThumbnailOutoingWithPaginationTitleBubbleCell.class
|
||||
};
|
||||
}
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)voiceMessageCellsMapping
|
||||
{
|
||||
return @{
|
||||
// Incoming
|
||||
@(RoomTimelineCellIdentifierIncomingVoiceMessage) : VoiceMessageIncomingBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingVoiceMessageWithoutSenderInfo) : VoiceMessageIncomingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingVoiceMessageWithPaginationTitle) : VoiceMessageIncomingWithPaginationTitleBubbleCell.class,
|
||||
// Outgoing
|
||||
@(RoomTimelineCellIdentifierOutgoingVoiceMessage) : VoiceMessageOutgoingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingVoiceMessageWithoutSenderInfo) : VoiceMessageOutgoingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingVoiceMessageWithPaginationTitle) : VoiceMessageOutgoingWithPaginationTitleBubbleCell.class,
|
||||
};
|
||||
}
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)locationCellsMapping
|
||||
{
|
||||
return @{
|
||||
// Incoming
|
||||
@(RoomTimelineCellIdentifierIncomingLocation) : LocationIncomingBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingLocationWithoutSenderInfo) : LocationIncomingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingLocationWithPaginationTitle) : LocationIncomingWithPaginationTitleBubbleCell.class,
|
||||
// Outgoing
|
||||
@(RoomTimelineCellIdentifierOutgoingLocation) : LocationOutgoingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingLocationWithoutSenderInfo) : LocationOutgoingWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle) : LocationOutgoingWithPaginationTitleBubbleCell.class
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class FileWithoutThumbnailBaseBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplayable {
|
||||
|
||||
weak var fileAttachementView: FileWithoutThumbnailCellContentView?
|
||||
|
||||
override func render(_ cellData: MXKCellData!) {
|
||||
super.render(cellData)
|
||||
|
||||
guard let data = cellData as? RoomBubbleCellData else {
|
||||
return
|
||||
}
|
||||
|
||||
self.fileAttachementView?.title = data.attributedTextMessage.string
|
||||
|
||||
self.update(theme: ThemeService.shared().theme)
|
||||
}
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.backgroundColor = .clear
|
||||
|
||||
guard let contentView = bubbleCellContentView?.innerContentView else {
|
||||
return
|
||||
}
|
||||
|
||||
let fileAttachementView = FileWithoutThumbnailCellContentView.instantiate()
|
||||
|
||||
contentView.vc_addSubViewMatchingParent(fileAttachementView)
|
||||
|
||||
self.fileAttachementView = fileAttachementView
|
||||
}
|
||||
|
||||
override func onContentViewTap(_ sender: UITapGestureRecognizer!) {
|
||||
|
||||
if let bubbleData = self.bubbleData, bubbleData.isAttachment {
|
||||
self.delegate.cell(self, didRecognizeAction: kMXKRoomBubbleCellTapOnAttachmentView, userInfo: nil)
|
||||
} else {
|
||||
super.onContentViewTap(sender)
|
||||
}
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// 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
|
||||
import Reusable
|
||||
|
||||
final class FileWithoutThumbnailCellContentView: UIView, NibLoadable {
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
private enum Constants {
|
||||
// TODO: Reuse constants, same as bubble bg
|
||||
static let cornerRadius: CGFloat = 12.0
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Outlets
|
||||
|
||||
@IBOutlet private weak var iconImageView: UIImageView!
|
||||
@IBOutlet private weak var titleLabel: UILabel!
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var badgeImage: UIImage? {
|
||||
get {
|
||||
return self.iconImageView.image
|
||||
}
|
||||
set {
|
||||
self.iconImageView.image = newValue
|
||||
}
|
||||
}
|
||||
|
||||
var title: String? {
|
||||
get {
|
||||
return self.titleLabel.text
|
||||
}
|
||||
set {
|
||||
self.titleLabel.text = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
static func instantiate() -> FileWithoutThumbnailCellContentView {
|
||||
return FileWithoutThumbnailCellContentView.loadFromNib()
|
||||
}
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
self.layer.masksToBounds = true
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
self.layer.cornerRadius = Constants.cornerRadius
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func update(theme: Theme) {
|
||||
self.titleLabel.textColor = theme.textPrimaryColor
|
||||
}
|
||||
}
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?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="8T9-hj-ply" customClass="FileWithoutThumbnailCellContentView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="313" height="42"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="tvT-jE-0OH">
|
||||
<rect key="frame" x="20" y="15" width="253" height="12"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" image="file_attachment" translatesAutoresizingMaskIntoConstraints="NO" id="Pse-Mu-Gle">
|
||||
<rect key="frame" x="0.0" y="0.0" width="16" height="12"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Filename.docx" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eCx-a1-1CO">
|
||||
<rect key="frame" x="32" y="0.0" width="221" height="12"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" systemColor="systemGray2Color"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.95294117649999999" green="0.97254901959999995" blue="0.99215686270000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="tvT-jE-0OH" secondAttribute="trailing" constant="40" id="At8-ah-N7j"/>
|
||||
<constraint firstItem="tvT-jE-0OH" firstAttribute="top" secondItem="8T9-hj-ply" secondAttribute="top" constant="15" id="C7r-6f-Bqf"/>
|
||||
<constraint firstItem="tvT-jE-0OH" firstAttribute="leading" secondItem="8T9-hj-ply" secondAttribute="leading" constant="20" id="Yh6-91-Thq"/>
|
||||
<constraint firstAttribute="bottom" secondItem="tvT-jE-0OH" secondAttribute="bottom" constant="15" id="yHE-fi-Paj"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="iconImageView" destination="Pse-Mu-Gle" id="pAQ-jI-GDj"/>
|
||||
<outlet property="titleLabel" destination="eCx-a1-1CO" id="Oj5-X3-Rop"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-1454.3478260869567" y="-405.80357142857139"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="file_attachment" width="16" height="16"/>
|
||||
<systemColor name="systemGray2Color">
|
||||
<color red="0.68235294117647061" green="0.68235294117647061" blue="0.69803921568627447" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class FileWithoutThumbnailIncomingBubbleCell: FileWithoutThumbnailBaseBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showSenderInfo = true
|
||||
|
||||
// TODO: Use constants
|
||||
let messageViewMarginRight: CGFloat = 80
|
||||
let messageLeftMargin: CGFloat = 48
|
||||
|
||||
bubbleCellContentView?.innerContentViewTrailingConstraint.constant = messageViewMarginRight
|
||||
bubbleCellContentView?.innerContentViewLeadingConstraint.constant = messageLeftMargin
|
||||
}
|
||||
|
||||
override func update(theme: Theme) {
|
||||
super.update(theme: theme)
|
||||
|
||||
self.fileAttachementView?.backgroundColor = theme.roomCellIncomingBubbleBackgroundColor
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class FileWithoutThumbnailIncomingWithPaginationTitleBubbleCell: FileWithoutThumbnailIncomingBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showPaginationTitle = true
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class FileWithoutThumbnailIncomingWithoutSenderInfoBubbleCell: FileWithoutThumbnailIncomingBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showSenderInfo = false
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class FileWithoutThumbnailOutoingWithPaginationTitleBubbleCell: FileWithoutThumbnailOutoingWithoutSenderInfoBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showPaginationTitle = true
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class FileWithoutThumbnailOutoingWithoutSenderInfoBubbleCell: FileWithoutThumbnailBaseBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showSenderInfo = false
|
||||
|
||||
// TODO: Use constants
|
||||
// Same as outgoing message
|
||||
let rightMargin: CGFloat = 34.0
|
||||
let leftMargin: CGFloat = 80.0
|
||||
|
||||
bubbleCellContentView?.innerContentViewTrailingConstraint.constant = rightMargin
|
||||
bubbleCellContentView?.innerContentViewLeadingConstraint.constant = leftMargin
|
||||
}
|
||||
|
||||
override func update(theme: Theme) {
|
||||
super.update(theme: theme)
|
||||
|
||||
self.fileAttachementView?.backgroundColor = theme.roomCellOutgoingBubbleBackgroundColor
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class LocationIncomingBubbleCell: LocationBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
// TODO: Use constants
|
||||
let messageViewMarginRight: CGFloat = 80
|
||||
let messageLeftMargin: CGFloat = 48
|
||||
|
||||
bubbleCellContentView?.innerContentViewTrailingConstraint.constant = messageViewMarginRight
|
||||
bubbleCellContentView?.innerContentViewLeadingConstraint.constant = messageLeftMargin
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class LocationIncomingWithPaginationTitleBubbleCell: LocationIncomingBubbleCell {
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showPaginationTitle = true
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class LocationIncomingWithoutSenderInfoBubbleCell: LocationIncomingBubbleCell {
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showSenderInfo = false
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class LocationOutgoingWithPaginationTitleBubbleCell: LocationOutgoingWithoutSenderInfoBubbleCell {
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showPaginationTitle = true
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class LocationOutgoingWithoutSenderInfoBubbleCell: LocationBubbleCell {
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showSenderInfo = false
|
||||
|
||||
// TODO: Use constants
|
||||
// Same as outgoing message
|
||||
let rightMargin: CGFloat = 34.0
|
||||
let leftMargin: CGFloat = 80.0
|
||||
|
||||
bubbleCellContentView?.innerContentViewTrailingConstraint.constant = rightMargin
|
||||
bubbleCellContentView?.innerContentViewLeadingConstraint.constant = leftMargin
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class VoiceMessageIncomingBubbleCell: VoiceMessageBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
// TODO: Use constants
|
||||
let messageViewMarginRight: CGFloat = 80
|
||||
let messageLeftMargin: CGFloat = 48
|
||||
let playbackViewRightMargin: CGFloat = 40
|
||||
|
||||
bubbleCellContentView?.innerContentViewTrailingConstraint.constant = messageViewMarginRight
|
||||
bubbleCellContentView?.innerContentViewLeadingConstraint.constant = messageLeftMargin
|
||||
|
||||
playbackController.playbackView.stackViewTrailingContraint.constant = playbackViewRightMargin
|
||||
}
|
||||
|
||||
override func update(theme: Theme) {
|
||||
|
||||
guard let playbackController = playbackController else {
|
||||
return
|
||||
}
|
||||
|
||||
playbackController.playbackView.customBackgroundViewColor = theme.roomCellIncomingBubbleBackgroundColor
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class VoiceMessageIncomingWithPaginationTitleBubbleCell: VoiceMessageIncomingBubbleCell {
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showPaginationTitle = true
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class VoiceMessageIncomingWithoutSenderInfoBubbleCell: VoiceMessageIncomingBubbleCell {
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showSenderInfo = false
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class VoiceMessageOutgoingWithPaginationTitleBubbleCell: VoiceMessageOutgoingWithoutSenderInfoBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showPaginationTitle = true
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class VoiceMessageOutgoingWithoutSenderInfoBubbleCell: VoiceMessageBubbleCell {
|
||||
|
||||
override func setupViews() {
|
||||
super.setupViews()
|
||||
|
||||
bubbleCellContentView?.showSenderInfo = false
|
||||
|
||||
// TODO: Use constants
|
||||
// Same as outgoing message
|
||||
let rightMargin: CGFloat = 34.0
|
||||
let leftMargin: CGFloat = 80.0
|
||||
let playbackViewRightMargin: CGFloat = 40
|
||||
|
||||
bubbleCellContentView?.innerContentViewTrailingConstraint.constant = rightMargin
|
||||
bubbleCellContentView?.innerContentViewLeadingConstraint.constant = leftMargin
|
||||
|
||||
playbackController.playbackView.stackViewTrailingContraint.constant = playbackViewRightMargin
|
||||
}
|
||||
|
||||
override func update(theme: Theme) {
|
||||
|
||||
guard let playbackController = playbackController else {
|
||||
return
|
||||
}
|
||||
|
||||
playbackController.playbackView.customBackgroundViewColor = theme.roomCellOutgoingBubbleBackgroundColor
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,15 @@ import UIKit
|
||||
@objcMembers
|
||||
class PlainRoomTimelineCellDecorator: RoomTimelineCellDecorator {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// TODO: Conforms to Themable and don't use ThemeService
|
||||
var theme: Theme {
|
||||
return ThemeService.shared().theme
|
||||
}
|
||||
|
||||
// MARK: - RoomTimelineCellDecorator
|
||||
|
||||
func addTimestampLabelIfNeeded(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) {
|
||||
|
||||
guard cellData.containsLastMessage && cellData.isCollapsableAndCollapsed == false else {
|
||||
|
||||
@@ -20,10 +20,26 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface PlainRoomTimelineCellProvider: NSObject<RoomTimelineCellProvider>
|
||||
|
||||
#pragma mark - Registration
|
||||
|
||||
- (void)registerVoiceMessageCellsForTableView:(UITableView*)tableView;
|
||||
|
||||
- (void)registerLocationCellsForTableView:(UITableView*)tableView;
|
||||
|
||||
#pragma mark - Mapping
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)outgoingTextMessageCellsMapping;
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)outgoingAttachmentCellsMapping;
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)incomingAttachmentWithoutThumbnailCellsMapping;
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)outgoingAttachmentWithoutThumbnailCellsMapping;
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)voiceMessageCellsMapping;
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)locationCellsMapping;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -283,6 +283,12 @@
|
||||
NSDictionary *outgoingAttachmentCellsMapping = [self outgoingAttachmentCellsMapping];
|
||||
[cellClasses addEntriesFromDictionary:outgoingAttachmentCellsMapping];
|
||||
|
||||
NSDictionary *outgoingAttachmentWithoutThumbnailCellsMapping = [self outgoingAttachmentWithoutThumbnailCellsMapping];
|
||||
[cellClasses addEntriesFromDictionary:outgoingAttachmentWithoutThumbnailCellsMapping];
|
||||
|
||||
NSDictionary *incomingAttachmentWithoutThumbnailCellsMapping = [self incomingAttachmentWithoutThumbnailCellsMapping];
|
||||
[cellClasses addEntriesFromDictionary:incomingAttachmentWithoutThumbnailCellsMapping];
|
||||
|
||||
// Other cells
|
||||
|
||||
NSDictionary *roomMembershipCellsMapping = [self membershipCellsMapping];
|
||||
@@ -382,6 +388,34 @@
|
||||
};
|
||||
}
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)incomingAttachmentWithoutThumbnailCellsMapping
|
||||
{
|
||||
return @{
|
||||
// Clear
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnail) : RoomIncomingTextMsgBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailWithoutSenderInfo) : RoomIncomingTextMsgWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailWithPaginationTitle) : RoomIncomingTextMsgWithPaginationTitleBubbleCell.class,
|
||||
// Encrypted
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncrypted) : RoomIncomingEncryptedTextMsgBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncryptedWithoutSenderInfo) : RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingAttachmentWithoutThumbnailEncryptedWithPaginationTitle) : RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.class
|
||||
};
|
||||
}
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)outgoingAttachmentWithoutThumbnailCellsMapping
|
||||
{
|
||||
return @{
|
||||
// Clear
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnail) : RoomOutgoingTextMsgBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailWithoutSenderInfo) : RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailWithPaginationTitle) : RoomOutgoingTextMsgWithPaginationTitleBubbleCell.class,
|
||||
// Encrypted
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncrypted) : RoomOutgoingEncryptedTextMsgBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncryptedWithoutSenderInfo) : RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingAttachmentWithoutThumbnailEncryptedWithPaginationTitle) : RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.class
|
||||
};
|
||||
}
|
||||
|
||||
- (NSDictionary<NSNumber*, Class>*)membershipCellsMapping
|
||||
{
|
||||
return @{
|
||||
@@ -425,9 +459,14 @@
|
||||
- (NSDictionary<NSNumber*, Class>*)voiceMessageCellsMapping
|
||||
{
|
||||
return @{
|
||||
@(RoomTimelineCellIdentifierVoiceMessage) : VoiceMessageBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierVoiceMessageWithoutSenderInfo) : VoiceMessageWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierVoiceMessageWithPaginationTitle) : VoiceMessageWithPaginationTitleBubbleCell.class,
|
||||
// Incoming
|
||||
@(RoomTimelineCellIdentifierIncomingVoiceMessage) : VoiceMessageBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingVoiceMessageWithoutSenderInfo) : VoiceMessageWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingVoiceMessageWithPaginationTitle) : VoiceMessageWithPaginationTitleBubbleCell.class,
|
||||
// Outoing
|
||||
@(RoomTimelineCellIdentifierOutgoingVoiceMessage) : VoiceMessageBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingVoiceMessageWithoutSenderInfo) : VoiceMessageWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingVoiceMessageWithPaginationTitle) : VoiceMessageWithPaginationTitleBubbleCell.class
|
||||
};
|
||||
}
|
||||
|
||||
@@ -443,9 +482,14 @@
|
||||
- (NSDictionary<NSNumber*, Class>*)locationCellsMapping
|
||||
{
|
||||
return @{
|
||||
@(RoomTimelineCellIdentifierLocation) : LocationBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierLocationWithoutSenderInfo) : LocationWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierLocationWithPaginationTitle) : LocationWithPaginationTitleBubbleCell.class
|
||||
// Incoming
|
||||
@(RoomTimelineCellIdentifierIncomingLocation) : LocationBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingLocationWithoutSenderInfo) : LocationWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierIncomingLocationWithPaginationTitle) : LocationWithPaginationTitleBubbleCell.class,
|
||||
// Outgoing
|
||||
@(RoomTimelineCellIdentifierOutgoingLocation) : LocationBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingLocationWithoutSenderInfo) : LocationWithoutSenderInfoBubbleCell.class,
|
||||
@(RoomTimelineCellIdentifierOutgoingLocationWithPaginationTitle) : LocationWithPaginationTitleBubbleCell.class
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,4 +27,6 @@ protocol RoomCellLayoutUpdating: Themable {
|
||||
func setupLayout(forOutgoingTextMessageCell cell: MXKRoomBubbleTableViewCell)
|
||||
|
||||
func setupLayout(forOutgoingFileAttachmentCell cell: MXKRoomBubbleTableViewCell)
|
||||
|
||||
func updateLayout(forSelectedStickerCell cell: RoomSelectedStickerBubbleCell)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import Foundation
|
||||
|
||||
class VoiceMessageBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplayable {
|
||||
|
||||
private var playbackController: VoiceMessagePlaybackController!
|
||||
private(set) var playbackController: VoiceMessagePlaybackController!
|
||||
|
||||
override func render(_ cellData: MXKCellData!) {
|
||||
super.render(cellData)
|
||||
@@ -27,13 +27,15 @@ class VoiceMessageBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplaya
|
||||
return
|
||||
}
|
||||
|
||||
guard data.attachment.type == MXKAttachmentTypeVoiceMessage || data.attachment.type == MXKAttachmentTypeAudio else {
|
||||
guard data.attachment.type == .voiceMessage || data.attachment.type == .audio else {
|
||||
fatalError("Invalid attachment type passed to a voice message cell.")
|
||||
}
|
||||
|
||||
if playbackController.attachment != data.attachment {
|
||||
playbackController.attachment = data.attachment
|
||||
}
|
||||
|
||||
self.update(theme: ThemeService.shared().theme)
|
||||
}
|
||||
|
||||
override func setupViews() {
|
||||
@@ -52,4 +54,15 @@ class VoiceMessageBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplaya
|
||||
|
||||
contentView.vc_addSubViewMatchingParent(playbackController.playbackView)
|
||||
}
|
||||
|
||||
override func update(theme: Theme) {
|
||||
|
||||
super.update(theme: theme)
|
||||
|
||||
guard let playbackController = playbackController else {
|
||||
return
|
||||
}
|
||||
|
||||
playbackController.playbackView.update(theme: theme)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user