MESSENGER-5575 ACL status event handling in the timeline

This commit is contained in:
Frank Rotermund
2024-03-01 07:25:42 +01:00
parent d07f992659
commit 2867bae23e
16 changed files with 162 additions and 33 deletions

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22ZM10.4709 7.16895C10.3959 6.31395 11.0259 5.56395 11.8809 5.50395C12.7209 5.44395 13.4709 6.07395 13.5609 6.92895V7.16895L13.0809 13.169C13.0359 13.724 12.5709 14.144 12.0159 14.144H11.9259C11.4009 14.099 10.9959 13.694 10.9509 13.169L10.4709 7.16895ZM13.3202 17.0842C13.3202 17.8132 12.7292 18.4042 12.0002 18.4042C11.2712 18.4042 10.6802 17.8132 10.6802 17.0842C10.6802 16.3551 11.2712 15.7642 12.0002 15.7642C12.7292 15.7642 13.3202 16.3551 13.3202 17.0842Z" fill="#A9B2BC"/>
</svg>

After

Width:  |  Height:  |  Size: 743 B

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "!-dark.svg",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Warning.svg",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22ZM10.4709 7.16895C10.3959 6.31395 11.0259 5.56395 11.8809 5.50395C12.7209 5.44395 13.4709 6.07395 13.5609 6.92895V7.16895L13.0809 13.169C13.0359 13.724 12.5709 14.144 12.0159 14.144H11.9259C11.4009 14.099 10.9959 13.694 10.9509 13.169L10.4709 7.16895ZM13.3202 17.0842C13.3202 17.8132 12.7292 18.4042 12.0002 18.4042C11.2712 18.4042 10.6802 17.8132 10.6802 17.0842C10.6802 16.3551 11.2712 15.7642 12.0002 15.7642C12.7292 15.7642 13.3202 16.3551 13.3202 17.0842Z" fill="#737D8C"/>
</svg>

After

Width:  |  Height:  |  Size: 743 B

View File

@@ -705,4 +705,5 @@
"event_formatter_acl_allow_federation" = "Dieser Raum wurde vom Administrator für eine Föderation zugelassen.";
"event_formatter_acl_disallow_federation" = "Die Föderation für diesen Raum wurde aufgehoben. Alle föderierten Mitglieder werden automatisch entfernt.";
"event_formatter_acl_disallow_at_start" = "Die Föderation für diesen Raum wurde nicht zugelassen.";
"event_formatter_acl_collapsed" = "Föderationseinstellung geändert.";
"event_formatter_acl_collapsed" = "%tu Föderationseinstellungen wurden geändert.";
"event_formatter_acl_and_other_collapsed" = "%tu Föderations und weitere Einstellungen geändert.";

View File

@@ -614,4 +614,5 @@
"event_formatter_acl_allow_federation" = "This room has been federated by the admin.";
"event_formatter_acl_disallow_federation" = "The federation has been withdrawn. All federated members where automatically removed.";
"event_formatter_acl_disallow_at_start" = "The federation was not approved for this room.";
"event_formatter_acl_collapsed" = "Federation settings changed.";
"event_formatter_acl_collapsed" = "%tu Federation settings changed.";
"event_formatter_acl_and_other_collapsed" = "%tu Federation and other settings changed.";

View File

@@ -835,9 +835,13 @@ public class BWIL10n: NSObject {
public static var eventFormatterAclAllowFederation: String {
return BWIL10n.tr("Bwi", "event_formatter_acl_allow_federation")
}
/// Föderationseinstellung geändert.
public static var eventFormatterAclCollapsed: String {
return BWIL10n.tr("Bwi", "event_formatter_acl_collapsed")
/// %tu Föderations und weitere Einstellungen geändert.
public static func eventFormatterAclAndOtherCollapsed(_ p1: Int) -> String {
return BWIL10n.tr("Bwi", "event_formatter_acl_and_other_collapsed", p1)
}
/// %tu Föderationseinstellungen wurden geändert.
public static func eventFormatterAclCollapsed(_ p1: Int) -> String {
return BWIL10n.tr("Bwi", "event_formatter_acl_collapsed", p1)
}
/// Die Föderation für diesen Raum wurde nicht zugelassen.
public static var eventFormatterAclDisallowAtStart: String {

View File

@@ -44,11 +44,14 @@ internal class Asset: NSObject {
internal static let authenticationSsoIconGoogle = ImageAsset(name: "authentication_sso_icon_google")
internal static let authenticationSsoIconTwitter = ImageAsset(name: "authentication_sso_icon_twitter")
internal static let authenticationTermsIcon = ImageAsset(name: "authentication_terms_icon")
internal static let dark = ImageAsset(name: "!-dark")
internal static let binoculars = ImageAsset(name: "binoculars")
internal static let birthdayCake = ImageAsset(name: "birthday_cake")
internal static let buttonNewDark = ImageAsset(name: "button_new_dark")
internal static let buttonNewLight = ImageAsset(name: "button_new_light")
internal static let bwiSettingsFilled = ImageAsset(name: "bwi_settings_filled")
internal static let federationExclamationMarkDark = ImageAsset(name: "federation_exclamation_mark_dark")
internal static let federationExclamationMarkLight = ImageAsset(name: "federation_exclamation_mark_light")
internal static let federationPillDeBumDark = ImageAsset(name: "federation_pill_de_bum_dark")
internal static let federationPillDeBumLight = ImageAsset(name: "federation_pill_de_bum_light")
internal static let federationPillEnBumDark = ImageAsset(name: "federation_pill_en_bum_dark")

View File

@@ -1673,8 +1673,9 @@ static NSString *const kRepliedTextPattern = @"<mx-reply>.*<blockquote>.*<br>(.*
displayText = [MXBeaconInfo modelFromJSON:event.content].desc;
break;
}
// bwi #5575 ACL events get there own texts
case MXEventTypeRoomServerACL: {
displayText = [[[FederationEventHelper alloc] init] statusInTimelineForEventWithEvent:event roomState:roomState];
displayText = [[FederationEventHelper shared] statusInTimelineForEventWithEvent:event roomState:roomState];
break;
}
default:

View File

@@ -125,11 +125,8 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat
case MXEventTypeRoomAvatar:
case MXEventTypeRoomJoinRules:
{
if (event.prevContent == nil) {
self.tag = RoomBubbleCellDataTagRoomCreateConfiguration;
} else {
self.tag = RoomBubbleCellDataTagRoomConfiguration;
}
self.tag = RoomBubbleCellDataTagRoomCreateConfiguration;
// Membership events can be collapsed together
self.collapsable = YES;
@@ -138,11 +135,12 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat
self.collapsed = YES;
}
break;
// bwi #5575 ACL events can be collapsed together
case MXEventTypeRoomServerACL:
{
self.tag = RoomBubbleCellDataTagACL;
// ACL events can be collapsed together
self.collapsable = YES;
self.collapsed = YES;
}
@@ -396,6 +394,16 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat
break;
case RoomBubbleCellDataTagVoiceBroadcastNoDisplay:
break;
// bwi #5575 ACL events and membership events should be displayed (and could be filtered later)
// this does not work at the moment but i'll leave it commented out for later reevaluation
// case RoomBubbleCellDataTagACL:
// case RoomBubbleCellDataTagRoomCreateConfiguration:
// if (!self.collapsedAttributedTextMessage) {
// hasNoDisplay = NO;
// } else {
// hasNoDisplay = [super hasNoDisplay];
// }
// break;
default:
hasNoDisplay = [super hasNoDisplay];
break;

View File

@@ -3300,6 +3300,7 @@ static CGSize kThreadListBarButtonItemImageSize;
{
cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierKeyVerificationConclusionWithPaginationTitle : RoomTimelineCellIdentifierKeyVerificationConclusion;
}
// bwi #5575 provide correct cell for ACL status messages -> Same as Membership cells
else if (bubbleData.tag == RoomBubbleCellDataTagMembership || bubbleData.tag == RoomBubbleCellDataTagACL)
{
if (bubbleData.collapsed)
@@ -3319,11 +3320,11 @@ static CGSize kThreadListBarButtonItemImageSize;
// The cell (and its series) is not collapsed but this cell is the first
// of the series. So, use the cell with the "collapse" button.
cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierMembershipExpandedWithPaginationTitle : RoomTimelineCellIdentifierMembershipExpanded;
}
}
else
{
cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierMembershipWithPaginationTitle : RoomTimelineCellIdentifierMembership;
}
}
}
else if (bubbleData.tag == RoomBubbleCellDataTagRoomCreateConfiguration || bubbleData.tag == RoomBubbleCellDataTagRoomConfiguration)
{

View File

@@ -221,6 +221,12 @@ static BOOL _disableLongPressGestureOnEvent;
// Add a long gesture recognizer on avatar (in order to display for example the member details)
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPressGesture:)];
[self.pictureView addGestureRecognizer:longPress];
// bwi #5575 check for ACL picture here. this is done to avoid having differing cell types and sometimes the render method is not called at the proper time
if (bubbleData.tag == RoomBubbleCellDataTagACL) {
self.pictureView.enableInMemoryCache = YES;
self.pictureView.imageView.image = [FederationIconHelper.shared getFederationExclamationMarkImage];
}
}
- (void)setupMessageTextView
@@ -512,15 +518,21 @@ static BOOL _disableLongPressGestureOnEvent;
// Check whether the sender's picture is actually displayed before loading it.
if (self.pictureView)
{
self.pictureView.enableInMemoryCache = YES;
// Consider here the sender avatar is stored unencrypted on Matrix media repo
[self.pictureView setImageURI:bubbleData.senderAvatarUrl
withType:nil
andImageOrientation:UIImageOrientationUp
toFitViewSize:self.pictureView.frame.size
withMethod:MXThumbnailingMethodCrop
previewImage:bubbleData.senderAvatarPlaceholder ? bubbleData.senderAvatarPlaceholder : self.picturePlaceholder
mediaManager:bubbleData.mxSession.mediaManager];
// bwi #5575 check for ACL picture here. this is done to avoid having differing cell types
if (bubbleData.tag == RoomBubbleCellDataTagACL) {
self.pictureView.enableInMemoryCache = YES;
self.pictureView.image = [FederationIconHelper.shared getFederationExclamationMarkImage];
} else {
self.pictureView.enableInMemoryCache = YES;
// Consider here the sender avatar is stored unencrypted on Matrix media repo
[self.pictureView setImageURI:bubbleData.senderAvatarUrl
withType:nil
andImageOrientation:UIImageOrientationUp
toFitViewSize:self.pictureView.frame.size
withMethod:MXThumbnailingMethodCrop
previewImage:bubbleData.senderAvatarPlaceholder ? bubbleData.senderAvatarPlaceholder : self.picturePlaceholder
mediaManager:bubbleData.mxSession.mediaManager];
}
}
if (self.attachmentView && bubbleData.isAttachmentWithThumbnail)

View File

@@ -55,9 +55,14 @@
// Add up to 5 avatars to self.avatarsView
RoomBubbleCellData *nextBubbleData = (RoomBubbleCellData*)bubbleData;
do
{
// bwi #5575 don't show collapsed images
if ([[FederationEventHelper shared] isCollapsedACLEventsWithEvents:nextBubbleData.events] != CollapsedACLEventsNone) {
continue;
}
MXKImageView *avatarView = [[MXKImageView alloc] initWithFrame:CGRectMake(12 * self.avatarsView.subviews.count, 0, 16, 16)];
// Handle user's picture by considering it is stored unencrypted on Matrix media repository
@@ -68,7 +73,7 @@
MXEvent *firstEvent = nextBubbleData.events.firstObject;
MXRoomMemberEventContent *content = [MXRoomMemberEventContent modelFromJSON:firstEvent.content];
// We want to display the avatar of the invitee.
// In case of a join event, the invitee is the sender. Otherwise, the invitee is the target.
if (![content.membership isEqualToString:kMXMembershipStringJoin])

View File

@@ -335,7 +335,7 @@ static NSString *const kEventFormatterTimeFormat = @"HH:mm";
withRoomState:roomState
andLatestRoomState:latestRoomState
error:error];
if (event.sentState == MXEventSentStateSent
&& [event.decryptionError.domain isEqualToString:MXDecryptingErrorDomain])
{
@@ -444,14 +444,26 @@ static NSString *const kEventFormatterTimeFormat = @"HH:mm";
// return a non-nil value
return [NSMutableAttributedString new];
}
else if (events[0].eventType == MXEventTypeRoomMember)
// This is a series for cells tagged with RoomBubbleCellDataTagMembership
// TODO: Build a complete summary like Riot-web
// bwi #5575 correct texts for collapsed acl events
else if (events[0].eventType == MXEventTypeRoomMember || events[0].eventType == MXEventTypeRoomServerACL)
{
// This is a series for cells tagged with RoomBubbleCellDataTagMembership
// TODO: Build a complete summary like Riot-web
displayText = [VectorL10n eventFormatterMemberUpdates:events.count];
}
else if (events[0].eventType == MXEventTypeRoomServerACL) {
displayText = BWIL10n.eventFormatterAclCollapsed;
CollapsedACLEvents eventsType = [[FederationEventHelper shared] isCollapsedACLEventsWithEvents:events];
switch (eventsType) {
case CollapsedACLEventsNone:
displayText = [VectorL10n eventFormatterMemberUpdates:events.count];
break;
case CollapsedACLEventsMixed:
displayText = [BWIL10n eventFormatterAclAndOtherCollapsed:events.count];
break;
case CollapsedACLEventsAll:
displayText = [BWIL10n eventFormatterAclCollapsed:events.count];
break;
default:
displayText = [VectorL10n eventFormatterMemberUpdates:events.count];
}
}
}

View File

@@ -17,7 +17,15 @@
import Foundation
@objc enum CollapsedACLEvents : Int {
case none = 0
case mixed = 1
case all = 2
}
@objc class FederationEventHelper: NSObject {
@objc static let shared = FederationEventHelper()
@objc func statusInTimelineForEvent( event: MXEvent, roomState: MXRoomState ) -> String {
if let allowedServerList = event.wireContent["allow"] as? [String] {
if allowedServerList.count > 1 || allowedServerList.first == "*" {
@@ -48,4 +56,24 @@ import Foundation
return true
}
@objc func isCollapsedACLEvents( events: [MXEvent]) -> CollapsedACLEvents {
var aclEventCount = 0, memberEventCount = 0
//events[0].eventType == MXEventTypeRoomMember || events[0].eventType == MXEventTypeRoomServerACL
for event in events {
if event.eventType == .roomMember {
memberEventCount += 1
} else if event.eventType == .roomServerACL {
aclEventCount += 1
}
}
if aclEventCount > 0 && memberEventCount == 0 {
return .all
} else if aclEventCount > 0 && memberEventCount > 0 {
return .mixed
} else {
return .none
}
}
}

View File

@@ -77,6 +77,11 @@ import Foundation
return image
}
// bwi 5575 insert acl exclamationmark here
@objc func getFederationExclamationMarkImage() -> UIImage {
return ThemeService.shared().isCurrentThemeDark() ? Asset.Images.federationExclamationMarkDark.image : Asset.Images.federationExclamationMarkLight.image
}
private func calculateFederationPillBounds(image: UIImage, pillHeight: CGFloat, font: UIFont) -> CGRect
{
let aspectRatio = image.size.width / image.size.height