mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-29 04:36:58 +02:00
Merge branch 'develop' into gil/SP1_space_creation
This commit is contained in:
@@ -107,7 +107,7 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat
|
||||
}
|
||||
else
|
||||
{
|
||||
self.tag = RoomBubbleCellDataTagRoomCreateConfiguration;
|
||||
self.tag = RoomBubbleCellDataTagRoomCreationIntro;
|
||||
}
|
||||
|
||||
// Membership events can be collapsed together
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
const CGFloat kTypingCellHeight = 24;
|
||||
|
||||
@interface RoomDataSource() <BubbleReactionsViewModelDelegate, URLPreviewViewDelegate, ThreadSummaryViewDelegate>
|
||||
@interface RoomDataSource() <BubbleReactionsViewModelDelegate, URLPreviewViewDelegate, ThreadSummaryViewDelegate, MXThreadingServiceDelegate>
|
||||
{
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
@@ -92,12 +92,9 @@ const CGFloat kTypingCellHeight = 24;
|
||||
[self reload];
|
||||
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(newThreadCreated:)
|
||||
name:MXThreadingService.newThreadCreated
|
||||
object:nil];
|
||||
|
||||
|
||||
[matrixSession.threadingService addDelegate:self];
|
||||
|
||||
[self registerKeyVerificationRequestNotification];
|
||||
[self registerKeyVerificationTransactionNotification];
|
||||
[self registerTrustLevelDidChangeNotifications];
|
||||
@@ -177,6 +174,8 @@ const CGFloat kTypingCellHeight = 24;
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self.keyVerificationTransactionDidChangeNotificationObserver];
|
||||
}
|
||||
|
||||
[self.mxSession.threadingService removeDelegate:self];
|
||||
|
||||
[super destroy];
|
||||
}
|
||||
@@ -232,7 +231,6 @@ const CGFloat kTypingCellHeight = 24;
|
||||
}
|
||||
|
||||
[self fetchEncryptionTrustedLevel];
|
||||
[self enableRoomCreationIntroCellDisplayIfNeeded];
|
||||
}
|
||||
|
||||
- (void)fetchEncryptionTrustedLevel
|
||||
@@ -241,11 +239,6 @@ const CGFloat kTypingCellHeight = 24;
|
||||
[self.roomDataSourceDelegate roomDataSourceDidUpdateEncryptionTrustLevel:self];
|
||||
}
|
||||
|
||||
- (void)roomDidSet
|
||||
{
|
||||
[self enableRoomCreationIntroCellDisplayIfNeeded];
|
||||
}
|
||||
|
||||
- (BOOL)shouldQueueEventForProcessing:(MXEvent *)event roomState:(MXRoomState *)roomState direction:(MXTimelineDirection)direction
|
||||
{
|
||||
if (self.threadId)
|
||||
@@ -303,8 +296,6 @@ const CGFloat kTypingCellHeight = 24;
|
||||
// Enable the containsLastMessage flag for the cell data which contains the last message.
|
||||
@synchronized(bubbles)
|
||||
{
|
||||
[self insertRoomCreationIntroCellDataIfNeeded];
|
||||
|
||||
// Reset first all cell data
|
||||
for (RoomBubbleCellData *cellData in bubbles)
|
||||
{
|
||||
@@ -973,15 +964,20 @@ const CGFloat kTypingCellHeight = 24;
|
||||
cell.attachmentView.accessibilityLabel = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Threads
|
||||
#pragma mark - MXThreadingServiceDelegate
|
||||
|
||||
- (void)newThreadCreated:(NSNotification *)notification
|
||||
- (void)threadingService:(MXThreadingService *)service didCreateNewThread:(MXThread *)thread direction:(MXTimelineDirection)direction
|
||||
{
|
||||
if (self.threadId)
|
||||
{
|
||||
// no need to reload the thread screen
|
||||
return;
|
||||
}
|
||||
if (direction == MXTimelineDirectionBackwards)
|
||||
{
|
||||
// no need to reload when paginating back
|
||||
return;
|
||||
}
|
||||
NSUInteger count = 0;
|
||||
@synchronized (bubbles)
|
||||
{
|
||||
@@ -1091,83 +1087,6 @@ const CGFloat kTypingCellHeight = 24;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Room creation intro cell
|
||||
|
||||
- (BOOL)canShowRoomCreationIntroCell
|
||||
{
|
||||
NSString* userId = self.mxSession.myUser.userId;
|
||||
|
||||
if (!userId || !self.isLive || self.isPeeking)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Room creation cell is only shown for the creator
|
||||
return [self.room.summary.creatorUserId isEqualToString:userId];
|
||||
}
|
||||
|
||||
- (void)enableRoomCreationIntroCellDisplayIfNeeded
|
||||
{
|
||||
self.showRoomCreationCell = [self canShowRoomCreationIntroCell];
|
||||
}
|
||||
|
||||
// Insert the room creation intro cell at the begining
|
||||
- (void)insertRoomCreationIntroCellDataIfNeeded
|
||||
{
|
||||
@synchronized(bubbles)
|
||||
{
|
||||
NSUInteger existingRoomCreationCellDataIndex = [self roomBubbleDataIndexWithTag:RoomBubbleCellDataTagRoomCreationIntro];
|
||||
|
||||
if (existingRoomCreationCellDataIndex != NSNotFound)
|
||||
{
|
||||
[bubbles removeObjectAtIndex:existingRoomCreationCellDataIndex];
|
||||
}
|
||||
|
||||
if (self.showRoomCreationCell)
|
||||
{
|
||||
NSUInteger roomCreationConfigCellDataIndex = [self roomBubbleDataIndexWithTag:RoomBubbleCellDataTagRoomCreateConfiguration];
|
||||
|
||||
// Only add room creation intro cell if `bubbles` array contains the room creation event
|
||||
if (roomCreationConfigCellDataIndex != NSNotFound)
|
||||
{
|
||||
if (!self.roomCreationCellData)
|
||||
{
|
||||
MXEvent *event = [MXEvent new];
|
||||
MXRoomState *roomState = [MXRoomState new];
|
||||
RoomBubbleCellData *roomBubbleCellData = [[RoomBubbleCellData alloc] initWithEvent:event andRoomState:roomState andRoomDataSource:self];
|
||||
roomBubbleCellData.tag = RoomBubbleCellDataTagRoomCreationIntro;
|
||||
|
||||
self.roomCreationCellData = roomBubbleCellData;
|
||||
}
|
||||
|
||||
[bubbles insertObject:self.roomCreationCellData atIndex:0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.roomCreationCellData = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)roomBubbleDataIndexWithTag:(RoomBubbleCellDataTag)tag
|
||||
{
|
||||
@synchronized(bubbles)
|
||||
{
|
||||
return [bubbles indexOfObjectPassingTest:^BOOL(id<MXKRoomBubbleCellDataStoring> _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
if ([obj isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
RoomBubbleCellData *roomBubbleCellData = (RoomBubbleCellData*)obj;
|
||||
if (roomBubbleCellData.tag == tag)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - URLPreviewViewDelegate
|
||||
|
||||
- (void)didOpenURLFromPreviewView:(URLPreviewView *)previewView for:(NSString *)eventID in:(NSString *)roomID
|
||||
|
||||
@@ -102,6 +102,11 @@ typedef NS_ENUM(NSUInteger, MXKRoomViewControllerJoinRoomResult) {
|
||||
*/
|
||||
@property (nonatomic, readonly) MXKRoomDataSource *roomDataSource;
|
||||
|
||||
/**
|
||||
The data source associated to live timeline, in the case the view controller show timeline not live.
|
||||
*/
|
||||
@property (nonatomic) MXKRoomDataSource *roomDataSourceLive;
|
||||
|
||||
/**
|
||||
Flag indicating if this instance has the memory ownership of its `roomDataSource`.
|
||||
If YES, it will release it on [self destroy] call;
|
||||
|
||||
@@ -680,9 +680,9 @@
|
||||
|
||||
if (dataSource)
|
||||
{
|
||||
if (!dataSource.isLive || dataSource.isPeeking)
|
||||
if (dataSource.isPeeking)
|
||||
{
|
||||
// Remove the input toolbar if the displayed timeline is not a live one or in case of peeking.
|
||||
// Remove the input toolbar in case of peeking.
|
||||
// We do not let the user type message in this case.
|
||||
[self setRoomInputToolbarViewClass:nil];
|
||||
}
|
||||
@@ -1085,9 +1085,9 @@
|
||||
inputToolbarView = nil;
|
||||
}
|
||||
|
||||
if (roomDataSource && (!roomDataSource.isLive || roomDataSource.isPeeking))
|
||||
if (roomDataSource && roomDataSource.isPeeking)
|
||||
{
|
||||
// Do not show the input toolbar if the displayed timeline is not a live one, or in case of peeking.
|
||||
// Do not show the input toolbar if the displayed timeline in case of peeking.
|
||||
// We do not let the user type message in this case.
|
||||
roomInputToolbarViewClass = nil;
|
||||
}
|
||||
@@ -2348,6 +2348,12 @@
|
||||
{
|
||||
// Do a full reload
|
||||
[_bubblesTableView reloadData];
|
||||
if (shouldScrollToBottom) {
|
||||
// If we need to scroll to the bottom after the reload, layout refresh needs to be triggered,
|
||||
// otherwise contentSize of the table view will not be up-to-date
|
||||
// e.g. https://stackoverflow.com/a/31324129
|
||||
[_bubblesTableView layoutIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldScrollToBottom)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
import CommonKit
|
||||
import MatrixSDK
|
||||
|
||||
final class RoomInfoListViewController: UIViewController {
|
||||
|
||||
@@ -38,7 +40,7 @@ final class RoomInfoListViewController: UIViewController {
|
||||
private var viewModel: RoomInfoListViewModelType!
|
||||
private var theme: Theme!
|
||||
private var errorPresenter: MXKErrorPresentation!
|
||||
private var activityPresenter: ActivityIndicatorPresenter!
|
||||
private var activityPresenter: ActivityIndicatorPresenterType!
|
||||
private var isRoomDirect: Bool = false
|
||||
private var screenTimer = AnalyticsScreenTimer(screen: .roomDetails)
|
||||
|
||||
@@ -114,7 +116,14 @@ final class RoomInfoListViewController: UIViewController {
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
self.setupViews()
|
||||
self.activityPresenter = ActivityIndicatorPresenter()
|
||||
if BuildSettings.useAppUserIndicators {
|
||||
self.activityPresenter = FullscreenActivityIndicatorPresenter(
|
||||
label: VectorL10n.roomParticipantsLeaveProcessing,
|
||||
viewController: self
|
||||
)
|
||||
} else {
|
||||
self.activityPresenter = ActivityIndicatorPresenter()
|
||||
}
|
||||
self.errorPresenter = MXKErrorAlertPresentation()
|
||||
|
||||
self.registerThemeServiceDidChangeThemeNotification()
|
||||
@@ -143,6 +152,7 @@ final class RoomInfoListViewController: UIViewController {
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
screenTimer.stop()
|
||||
activityPresenter.removeCurrentActivityIndicator(animated: animated)
|
||||
}
|
||||
|
||||
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
|
||||
@@ -1073,15 +1073,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
self.jumpToLastUnreadBannerContainer.hidden = YES;
|
||||
|
||||
[super leaveRoomOnEvent:event];
|
||||
|
||||
if (self.delegate)
|
||||
{
|
||||
[self.delegate roomViewControllerDidLeaveRoom:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[AppDelegate theDelegate] restoreInitialDisplay:nil];
|
||||
}
|
||||
[self notifyDelegateOnLeaveRoomIfNecessary];
|
||||
}
|
||||
|
||||
// Set the input toolbar according to the current display
|
||||
@@ -1261,33 +1253,69 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
|
||||
- (void)sendTextMessage:(NSString*)msgTxt
|
||||
{
|
||||
if (self.inputToolBarSendMode == RoomInputToolbarViewSendModeReply && customizedRoomDataSource.selectedEventId)
|
||||
// The event modified is always fetch from the actual data source
|
||||
MXEvent *eventModified = [self.roomDataSource eventWithEventId:customizedRoomDataSource.selectedEventId];
|
||||
|
||||
// In the case the event is a reply or and edit, and it's done on a non-live timeline
|
||||
// we have to fetch live timeline in order to display the event properly
|
||||
[self setupRoomDataSourceToResolveEvent:^(MXKRoomDataSource *roomDataSource) {
|
||||
if (self.inputToolBarSendMode == RoomInputToolbarViewSendModeReply && eventModified)
|
||||
{
|
||||
[roomDataSource sendReplyToEvent:eventModified withTextMessage:msgTxt success:nil failure:^(NSError *error) {
|
||||
// Just log the error. The message will be displayed in red in the room history
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
else if (self.inputToolBarSendMode == RoomInputToolbarViewSendModeEdit && eventModified)
|
||||
{
|
||||
[roomDataSource replaceTextMessageForEvent:eventModified withTextMessage:msgTxt success:nil failure:^(NSError *error) {
|
||||
// Just log the error. The message will be displayed in red
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let the datasource send it and manage the local echo
|
||||
[roomDataSource sendTextMessage:msgTxt success:nil failure:^(NSError *error)
|
||||
{
|
||||
// Just log the error. The message will be displayed in red in the room history
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
|
||||
if (self->customizedRoomDataSource.selectedEventId)
|
||||
{
|
||||
[self cancelEventSelection];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setupRoomDataSourceToResolveEvent: (void (^)(MXKRoomDataSource *roomDataSource))onComplete
|
||||
{
|
||||
// If the event occur on timeline not live, use the live data source to resolve event
|
||||
BOOL isLive = self.roomDataSource.isLive;
|
||||
if (!isLive)
|
||||
{
|
||||
[self.roomDataSource sendReplyToEventWithId:customizedRoomDataSource.selectedEventId withTextMessage:msgTxt success:nil failure:^(NSError *error) {
|
||||
// Just log the error. The message will be displayed in red in the room history
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
else if (self.inputToolBarSendMode == RoomInputToolbarViewSendModeEdit && customizedRoomDataSource.selectedEventId)
|
||||
{
|
||||
[self.roomDataSource replaceTextMessageForEventWithId:customizedRoomDataSource.selectedEventId withTextMessage:msgTxt success:nil failure:^(NSError *error) {
|
||||
// Just log the error. The message will be displayed in red
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
if (self.roomDataSourceLive == nil)
|
||||
{
|
||||
MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:self.mainSession];
|
||||
|
||||
[roomDataSourceManager roomDataSourceForRoom:self.roomDataSource.roomId
|
||||
create:YES
|
||||
onComplete:^(MXKRoomDataSource *roomDataSource) {
|
||||
self.roomDataSourceLive = roomDataSource;
|
||||
[self.roomDataSourceLive finalizeInitialization];
|
||||
onComplete(self.roomDataSourceLive);
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
onComplete(self.roomDataSourceLive);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let the datasource send it and manage the local echo
|
||||
[self.roomDataSource sendTextMessage:msgTxt success:nil failure:^(NSError *error)
|
||||
{
|
||||
// Just log the error. The message will be displayed in red in the room history
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
|
||||
if (customizedRoomDataSource.selectedEventId)
|
||||
{
|
||||
[self cancelEventSelection];
|
||||
onComplete(self.roomDataSource);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2201,16 +2229,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
[self.roomDataSource.room leave:^{
|
||||
|
||||
[self stopActivityIndicator];
|
||||
|
||||
// We remove the current view controller.
|
||||
if (self.delegate)
|
||||
{
|
||||
[self.delegate roomViewControllerDidLeaveRoom:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[AppDelegate theDelegate] restoreInitialDisplay:^{}];
|
||||
}
|
||||
[self notifyDelegateOnLeaveRoomIfNecessary];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
@@ -2220,6 +2239,22 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)notifyDelegateOnLeaveRoomIfNecessary {
|
||||
if (self.delegate)
|
||||
{
|
||||
// Leaving room often triggers multiple events, incl local delegate callbacks as well as global notifications,
|
||||
// which may lead to multiple identical UI changes (navigating to home, displaying notification etc).
|
||||
// To avoid this, as soon as we notify the delegate the first time, we nilify it, preventing future messages
|
||||
// from being passed along, assuming that after leaving a room there is nothing else to communicate to the delegate.
|
||||
[self.delegate roomViewControllerDidLeaveRoom:self];
|
||||
self.delegate = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
[[AppDelegate theDelegate] restoreInitialDisplay:^{}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)roomPreviewDidTapCancelAction
|
||||
{
|
||||
// Decline this invitation = leave this page
|
||||
@@ -7040,14 +7075,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
|
||||
- (void)roomInfoCoordinatorBridgePresenterDelegateDidLeaveRoom:(RoomInfoCoordinatorBridgePresenter *)coordinatorBridgePresenter
|
||||
{
|
||||
if (self.delegate)
|
||||
{
|
||||
[self.delegate roomViewControllerDidLeaveRoom:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[AppDelegate theDelegate] restoreInitialDisplay:nil];
|
||||
}
|
||||
[self notifyDelegateOnLeaveRoomIfNecessary];
|
||||
}
|
||||
|
||||
- (void)roomInfoCoordinatorBridgePresenter:(RoomInfoCoordinatorBridgePresenter *)coordinatorBridgePresenter didReplaceRoomWithReplacementId:(NSString *)roomId
|
||||
|
||||
@@ -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" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" 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="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
@@ -189,7 +189,7 @@
|
||||
<constraint firstAttribute="bottom" secondItem="BGD-sd-SQR" secondAttribute="bottom" constant="41" id="1SD-y2-oTg"/>
|
||||
<constraint firstItem="Xt7-83-dQh" firstAttribute="leading" secondItem="QpJ-1u-4ii" secondAttribute="leading" id="6lr-Tx-pEb"/>
|
||||
<constraint firstItem="QpJ-1u-4ii" firstAttribute="trailing" secondItem="Ih9-EU-BOU" secondAttribute="trailing" constant="16" id="6rq-lR-0sB"/>
|
||||
<constraint firstItem="54r-18-K1g" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="7Ft-EV-Br0"/>
|
||||
<constraint firstItem="54r-18-K1g" firstAttribute="top" secondItem="QpJ-1u-4ii" secondAttribute="top" id="7Ft-EV-Br0"/>
|
||||
<constraint firstItem="gt1-EO-UVY" firstAttribute="leading" secondItem="QpJ-1u-4ii" secondAttribute="leading" id="8Ff-Ot-h3F"/>
|
||||
<constraint firstItem="Xt7-83-dQh" firstAttribute="bottom" secondItem="iN0-l3-epB" secondAttribute="bottom" id="9g2-wm-4M9"/>
|
||||
<constraint firstItem="fmF-ad-erE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="DtG-PR-F24"/>
|
||||
|
||||
@@ -124,7 +124,7 @@ class BaseRoomCell: MXKRoomBubbleTableViewCell, BaseRoomCellProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
override var readMarkerViewLeadingConstraint: NSLayoutConstraint! {
|
||||
override var readMarkerViewLeadingConstraint: NSLayoutConstraint? {
|
||||
get {
|
||||
if self is RoomCellReadMarkerDisplayable {
|
||||
return self.roomCellContentView?.readMarkerViewLeadingConstraint
|
||||
@@ -141,7 +141,7 @@ class BaseRoomCell: MXKRoomBubbleTableViewCell, BaseRoomCellProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
override var readMarkerViewTrailingConstraint: NSLayoutConstraint! {
|
||||
override var readMarkerViewTrailingConstraint: NSLayoutConstraint? {
|
||||
get {
|
||||
if self is RoomCellReadMarkerDisplayable {
|
||||
return self.roomCellContentView?.readMarkerViewTrailingConstraint
|
||||
|
||||
@@ -228,11 +228,11 @@ extern NSString *const kMXKRoomBubbleCellUrlItemInteraction;
|
||||
/**
|
||||
The read marker view and its layout constraints (nil by default).
|
||||
*/
|
||||
@property (nonatomic) UIView *readMarkerView;
|
||||
@property (nonatomic) NSLayoutConstraint *readMarkerViewTopConstraint;
|
||||
@property (nonatomic) NSLayoutConstraint *readMarkerViewLeadingConstraint;
|
||||
@property (nonatomic) NSLayoutConstraint *readMarkerViewTrailingConstraint;
|
||||
@property (nonatomic) NSLayoutConstraint *readMarkerViewHeightConstraint;
|
||||
@property (nonatomic, nullable) UIView *readMarkerView;
|
||||
@property (nonatomic, nullable) NSLayoutConstraint *readMarkerViewTopConstraint;
|
||||
@property (nonatomic, nullable) NSLayoutConstraint *readMarkerViewLeadingConstraint;
|
||||
@property (nonatomic, nullable) NSLayoutConstraint *readMarkerViewTrailingConstraint;
|
||||
@property (nonatomic, nullable) NSLayoutConstraint *readMarkerViewHeightConstraint;
|
||||
|
||||
/**
|
||||
The potential webview used to render an attachment (for example an animated gif).
|
||||
|
||||
@@ -273,8 +273,8 @@ class PlainRoomTimelineCellDecorator: RoomTimelineCellDecorator {
|
||||
|
||||
let readMarkerContainerViewHalfWidth = readMarkerContainerView.frame.size.width/2
|
||||
|
||||
cell.readMarkerViewLeadingConstraint.constant = readMarkerContainerViewHalfWidth
|
||||
cell.readMarkerViewTrailingConstraint.constant = -readMarkerContainerViewHalfWidth
|
||||
cell.readMarkerViewLeadingConstraint?.constant = readMarkerContainerViewHalfWidth
|
||||
cell.readMarkerViewTrailingConstraint?.constant = -readMarkerContainerViewHalfWidth
|
||||
|
||||
UIView.animate(withDuration: 1.5,
|
||||
delay: 0.3,
|
||||
|
||||
Reference in New Issue
Block a user