Use latest user data for mention pills

This commit is contained in:
aringenbach
2022-06-16 17:07:47 +02:00
parent 87915a9e30
commit 4c8bed38c2
24 changed files with 357 additions and 97 deletions
@@ -48,7 +48,11 @@
self.readReceipts = [NSMutableDictionary dictionary];
// Create the bubble component based on matrix event
MXKRoomBubbleComponent *firstComponent = [[MXKRoomBubbleComponent alloc] initWithEvent:event roomState:roomState eventFormatter:roomDataSource.eventFormatter session:roomDataSource.mxSession];
MXKRoomBubbleComponent *firstComponent = [[MXKRoomBubbleComponent alloc] initWithEvent:event
roomState:roomState
andLatestRoomState:roomDataSource.roomState
eventFormatter:roomDataSource.eventFormatter
session:roomDataSource.mxSession];
if (firstComponent)
{
bubbleComponents = [NSMutableArray array];
@@ -125,6 +129,21 @@
bubbleComponents = nil;
}
- (void)refreshProfilesIfNeeded:(MXRoomState *)latestRoomState
{
if (RiotSettings.shared.roomScreenUseOnlyLatestUserAvatarAndName)
{
[self setRoomState:latestRoomState];
}
}
/**
Sets the `MXRoomState` for a buble cell. This allows to adapt the display
of a cell with a different room state than its historical. This won't update critical
flag/status, such as `isEncryptedRoom`.
@param roomState the `MXRoomState` to use for this cell.
*/
- (void)setRoomState:(MXRoomState *)roomState;
{
MXEvent* firstEvent = self.events.firstObject;
@@ -156,7 +175,10 @@
MXKRoomBubbleComponent *roomBubbleComponent = [bubbleComponents objectAtIndex:index];
if ([roomBubbleComponent.event.eventId isEqualToString:eventId])
{
[roomBubbleComponent updateWithEvent:event roomState:roomDataSource.roomState session:self.mxSession];
[roomBubbleComponent updateWithEvent:event
roomState:roomDataSource.roomState
andLatestRoomState:nil
session:self.mxSession];
if (!roomBubbleComponent.textMessage.length)
{
[bubbleComponents removeObjectAtIndex:index];
@@ -237,13 +237,11 @@
- (instancetype)initWithEvent:(MXEvent*)event andRoomState:(MXRoomState*)roomState andRoomDataSource:(MXKRoomDataSource*)roomDataSource;
/**
Sets the `MXRoomState` for a buble cell. This allows to adapt the display
of a cell with a different room state than its historical. This won't update critical
flag/status, such as `isEncryptedRoom`.
Refresh avatars and display names (AKA profiles) displayed in the cell if needed.
@param roomState the `MXRoomState` to use for this cell.
@param latestRoomState the latest `MXRoomState` from the data source.
*/
- (void)setRoomState:(MXRoomState *)roomState;
- (void)refreshProfilesIfNeeded:(MXRoomState *)latestRoomState;
/**
Update the event because its sent state changed or it is has been redacted.
@@ -78,7 +78,11 @@ static NSAttributedString *messageSeparator = nil;
}
// Create new message component
MXKRoomBubbleComponent *addedComponent = [[MXKRoomBubbleComponent alloc] initWithEvent:event roomState:roomState eventFormatter:roomDataSource.eventFormatter session:self.mxSession];
MXKRoomBubbleComponent *addedComponent = [[MXKRoomBubbleComponent alloc] initWithEvent:event
roomState:roomState
andLatestRoomState:roomDataSource.roomState
eventFormatter:roomDataSource.eventFormatter
session:self.mxSession];
if (addedComponent)
{
[self addComponent:addedComponent];
@@ -115,20 +115,29 @@ typedef enum : NSUInteger {
@param event the event used to compose the bubble component.
@param roomState the room state when the event occured.
@param latestRoomState the latest room state of the room containing this event.
@param eventFormatter object used to format event into displayable string.
@param session the related matrix session.
@return the newly created instance.
*/
- (instancetype)initWithEvent:(MXEvent*)event roomState:(MXRoomState*)roomState eventFormatter:(MXKEventFormatter*)eventFormatter session:(MXSession*)session;
- (instancetype)initWithEvent:(MXEvent*)event
roomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
eventFormatter:(MXKEventFormatter*)eventFormatter
session:(MXSession*)session;
/**
Update the event because its sent state changed or it is has been redacted.
@param event the new event data.
@param roomState the up-to-date state of the room.
@param latestRoomState the latest room state of the room containing this event.
@param session the related matrix session.
*/
- (void)updateWithEvent:(MXEvent*)event roomState:(MXRoomState*)roomState session:(MXSession*)session;
- (void)updateWithEvent:(MXEvent*)event
roomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
session:(MXSession*)session;
@end
@@ -28,7 +28,11 @@
@implementation MXKRoomBubbleComponent
- (instancetype)initWithEvent:(MXEvent*)event roomState:(MXRoomState*)roomState eventFormatter:(MXKEventFormatter*)eventFormatter session:(MXSession*)session;
- (instancetype)initWithEvent:(MXEvent*)event
roomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
eventFormatter:(MXKEventFormatter*)eventFormatter
session:(MXSession*)session;
{
if (self = [super init])
{
@@ -36,7 +40,10 @@
_eventFormatter = eventFormatter;
MXKEventFormatterError error;
NSAttributedString *eventString = [_eventFormatter attributedStringFromEvent:event withRoomState:roomState error:&error];
NSAttributedString *eventString = [_eventFormatter attributedStringFromEvent:event
withRoomState:roomState
andLatestRoomState:latestRoomState
error:&error];
// Store the potential error
event.mxkEventFormatterError = error;
@@ -84,7 +91,10 @@
return self;
}
- (void)updateWithEvent:(MXEvent*)event roomState:(MXRoomState*)roomState session:(MXSession*)session
- (void)updateWithEvent:(MXEvent*)event
roomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
session:(MXSession*)session
{
// Report the new event
_event = event;
@@ -101,7 +111,10 @@
_textMessage = nil;
MXKEventFormatterError error;
_attributedTextMessage = [_eventFormatter attributedStringFromEvent:event withRoomState:roomState error:&error];
_attributedTextMessage = [_eventFormatter attributedStringFromEvent:event
withRoomState:roomState
andLatestRoomState:latestRoomState
error:&error];
_showEncryptionBadge = [self shouldShowWarningBadgeForEvent:event roomState:roomState session:session];
@@ -1021,13 +1021,13 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
MXStrongifyAndReturnIfNil(self);
if (event.eventType == MXEventTypeRoomMember && event.isUserProfileChange)
{
[self refreshProfilesIfNeeded];
}
if (MXTimelineDirectionForwards == direction)
{
if (event.eventType == MXEventTypeRoomMember && event.isUserProfileChange)
{
[self refreshProfilesIfNeeded];
}
// Check for local echo suppression
MXEvent *localEcho;
if (self.room.outgoingMessages.count && [event.sender isEqualToString:self.mxSession.myUser.userId])
@@ -3668,7 +3668,10 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
while ((nextBubbleData = nextBubbleData.nextCollapsableCellData));
// Build the summary string for the series
bubbleData.collapsedAttributedTextMessage = [self.eventFormatter attributedStringFromEvents:events withRoomState:bubbleData.collapseState error:nil];
bubbleData.collapsedAttributedTextMessage = [self.eventFormatter attributedStringFromEvents:events
withRoomState:bubbleData.collapseState
andLatestRoomState:self.roomState
error:nil];
// Release collapseState objects, even the one of collapsableSeriesAtStart.
// We do not need to keep its state because if an collapsable event comes before collapsableSeriesAtStart,
@@ -4359,18 +4362,14 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
#pragma mark - Use Only Latest Profiles
/**
Refreshes the avatars and display names if needed. This has no effect
if `roomScreenUseOnlyLatestUserAvatarAndName` is disabled.
Refreshes the avatars and display names if needed.
*/
- (void)refreshProfilesIfNeeded
{
if (RiotSettings.shared.roomScreenUseOnlyLatestUserAvatarAndName)
{
@synchronized (bubbles) {
for (id<MXKRoomBubbleCellDataStoring> bubble in bubbles)
{
[bubble setRoomState:self.roomState];
}
@synchronized (bubbles) {
for (id<MXKRoomBubbleCellDataStoring> bubble in bubbles)
{
[bubble refreshProfilesIfNeeded:self.roomState];
}
}
}
@@ -182,30 +182,42 @@ typedef enum : NSUInteger {
@param event the event to format.
@param roomState the room state right before the event.
@param latestRoomState the latest room state of the room containing this event.
@param error the error code. In case of formatting error, the formatter may return non nil string as a proposal.
@return the display text for the event.
*/
- (NSString*)stringFromEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error;
- (NSString*)stringFromEvent:(MXEvent*)event
withRoomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
error:(MXKEventFormatterError*)error;
/**
Generate a displayable attributed string representating the event.
@param event the event to format.
@param roomState the room state right before the event.
@param latestRoomState the latest room state of the room containing this event.
@param error the error code. In case of formatting error, the formatter may return non nil string as a proposal.
@return the attributed string for the event.
*/
- (NSAttributedString*)attributedStringFromEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error;
- (NSAttributedString*)attributedStringFromEvent:(MXEvent*)event
withRoomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
error:(MXKEventFormatterError*)error;
/**
Generate a displayable attributed string representating a summary for the provided events.
@param events the series of events to format.
@param roomState the room state right before the first event in the series.
@param latestRoomState the latest room state of the room containing this event.
@param error the error code. In case of formatting error, the formatter may return non nil string as a proposal.
@return the attributed string.
*/
- (NSAttributedString*)attributedStringFromEvents:(NSArray<MXEvent*>*)events withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error;
- (NSAttributedString*)attributedStringFromEvents:(NSArray<MXEvent*>*)events
withRoomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
error:(MXKEventFormatterError*)error;
/**
Render a random string into an attributed string with the font and the text color
@@ -226,7 +238,10 @@ typedef enum : NSUInteger {
@param roomState the room state right before the event. If nil, replies will not get constructed or formatted.
@return an attributed string.
*/
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString forEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState;
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString
forEvent:(MXEvent*)event
withRoomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState;
/**
Defines the replacement attributed string for a redacted message.
@@ -296,10 +296,16 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=(?:'|\")(.*?)(?:'|\")>(
#pragma mark - Events to strings conversion methods
- (NSString*)stringFromEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error
- (NSString*)stringFromEvent:(MXEvent*)event
withRoomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
error:(MXKEventFormatterError*)error
{
NSString *stringFromEvent;
NSAttributedString *attributedStringFromEvent = [self attributedStringFromEvent:event withRoomState:roomState error:error];
NSAttributedString *attributedStringFromEvent = [self attributedStringFromEvent:event
withRoomState:roomState
andLatestRoomState:latestRoomState
error:error];
if (*error == MXKEventFormatterErrorNone)
{
stringFromEvent = attributedStringFromEvent.string;
@@ -308,7 +314,10 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=(?:'|\")(.*?)(?:'|\")>(
return stringFromEvent;
}
- (NSAttributedString *)attributedStringFromEvent:(MXEvent *)event withRoomState:(MXRoomState *)roomState error:(MXKEventFormatterError *)error
- (NSAttributedString *)attributedStringFromEvent:(MXEvent*)event
withRoomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
error:(MXKEventFormatterError *)error
{
// Check we can output the error
NSParameterAssert(error);
@@ -1360,7 +1369,10 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=(?:'|\")(.*?)(?:'|\")>(
if (isHTML)
{
// Build the attributed string from the HTML string
attributedDisplayText = [self renderHTMLString:body forEvent:event withRoomState:roomState];
attributedDisplayText = [self renderHTMLString:body
forEvent:event
withRoomState:roomState
andLatestRoomState:latestRoomState];
}
else
{
@@ -1664,7 +1676,10 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=(?:'|\")(.*?)(?:'|\")>(
return attributedDisplayText;
}
- (NSAttributedString*)attributedStringFromEvents:(NSArray<MXEvent*>*)events withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error
- (NSAttributedString*)attributedStringFromEvents:(NSArray<MXEvent*>*)events
withRoomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
error:(MXKEventFormatterError*)error
{
// TODO: Do a full summary
return nil;
@@ -1752,7 +1767,10 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=(?:'|\")(.*?)(?:'|\")>(
return str;
}
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString forEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString
forEvent:(MXEvent*)event
withRoomState:(MXRoomState*)roomState
andLatestRoomState:(MXRoomState*)latestRoomState
{
NSString *html = htmlString;
MXEvent *repliedEvent;
@@ -2126,7 +2144,10 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=(?:'|\")(.*?)(?:'|\")>(
// Note that we use the current room state (roomState) because when we display
// users displaynames, we want current displaynames
MXKEventFormatterError error;
NSString *lastMessageString = [self stringFromEvent:event withRoomState:roomState error:&error];
NSString *lastMessageString = [self stringFromEvent:event
withRoomState:roomState
andLatestRoomState:nil
error:&error];
if (0 == lastMessageString.length)
{