Do not linkify message bodies if there is a pending message request.

This commit is contained in:
Matthew Chen 2021-02-01 15:13:10 -03:00
parent 402309d631
commit 3a98384275
4 changed files with 41 additions and 17 deletions

View File

@ -971,34 +971,34 @@ fileprivate extension CVComponentState.Builder {
owsFailDebug("Invalid attachment.")
}
mediaAlbumItems.append(CVMediaAlbumItem(attachment: attachment,
attachmentStream: nil,
caption: caption,
mediaSize: mediaSize))
attachmentStream: nil,
caption: caption,
mediaSize: mediaSize))
continue
}
guard attachmentStream.isValidVisualMedia else {
Logger.warn("Filtering invalid media.")
mediaAlbumItems.append(CVMediaAlbumItem(attachment: attachment,
attachmentStream: nil,
caption: caption,
mediaSize: .zero))
attachmentStream: nil,
caption: caption,
mediaSize: .zero))
continue
}
let mediaSize = attachmentStream.imageSize()
if mediaSize.width <= 0 || mediaSize.height <= 0 {
Logger.warn("Filtering media with invalid size.")
mediaAlbumItems.append(CVMediaAlbumItem(attachment: attachment,
attachmentStream: nil,
caption: caption,
mediaSize: .zero))
attachmentStream: nil,
caption: caption,
mediaSize: .zero))
continue
}
mediaAlbumItems.append(CVMediaAlbumItem(attachment: attachment,
attachmentStream: attachmentStream,
caption: caption,
mediaSize: mediaSize))
attachmentStream: attachmentStream,
caption: caption,
mediaSize: mediaSize))
}
return mediaAlbumItems
}

View File

@ -13,6 +13,7 @@ public class CVComponentBodyText: CVComponentBase, CVComponent {
let searchText: String?
let hasTapForMore: Bool
let shouldUseAttributedText: Bool
let hasPendingMessageRequest: Bool
public var canUseDedicatedCell: Bool {
if hasTapForMore || searchText != nil {
@ -49,6 +50,9 @@ public class CVComponentBodyText: CVComponentBase, CVComponent {
private var hasTapForMore: Bool {
bodyTextState.hasTapForMore
}
private var hasPendingMessageRequest: Bool {
bodyTextState.hasPendingMessageRequest
}
public var shouldUseAttributedText: Bool {
bodyTextState.shouldUseAttributedText
}
@ -104,10 +108,15 @@ public class CVComponentBodyText: CVComponentBase, CVComponent {
private static let unfairLock = UnfairLock()
private static func shouldUseAttributedText(text: String,
hasPendingMessageRequest: Bool,
shouldAllowLinkification: Bool) -> Bool {
// Use a lock to ensure that measurement on and off the main thread
// don't conflict.
unfairLock.withLock {
guard !hasPendingMessageRequest else {
// Do not linkify if there is a pending message request.
return false
}
// NSDataDetector and UIDataDetector behavior should be aligned.
//
// TODO: We might want to move this detection logic into
@ -117,14 +126,16 @@ public class CVComponentBodyText: CVComponentBase, CVComponent {
owsFailDebug("Could not build dataDetector.")
return true
}
return !detector.matches(in: text, options: [], range: text.entireRange).isEmpty
let hasLinks = !detector.matches(in: text, options: [], range: text.entireRange).isEmpty
return hasLinks
}
}
static func buildState(interaction: TSInteraction,
bodyText: CVComponentState.BodyText,
viewStateSnapshot: CVViewStateSnapshot,
hasTapForMore: Bool) -> State {
hasTapForMore: Bool,
hasPendingMessageRequest: Bool) -> State {
let textExpansion = viewStateSnapshot.textExpansion
let searchText = viewStateSnapshot.searchText
let isTextExpanded = textExpansion.isTextExpanded(interactionId: interaction.uniqueId)
@ -147,6 +158,7 @@ public class CVComponentBodyText: CVComponentBase, CVComponent {
} else {
let shouldAllowLinkification = displayableText.shouldAllowLinkification
shouldUseAttributedText = self.shouldUseAttributedText(text: text,
hasPendingMessageRequest: hasPendingMessageRequest,
shouldAllowLinkification: shouldAllowLinkification)
}
case .attributedText:
@ -158,7 +170,8 @@ public class CVComponentBodyText: CVComponentBase, CVComponent {
isTextExpanded: isTextExpanded,
searchText: searchText,
hasTapForMore: hasTapForMore,
shouldUseAttributedText: shouldUseAttributedText)
shouldUseAttributedText: shouldUseAttributedText,
hasPendingMessageRequest: hasPendingMessageRequest)
}
static func buildComponentState(message: TSMessage,
@ -303,7 +316,12 @@ public class CVComponentBodyText: CVComponentBase, CVComponent {
}
textView.shouldIgnoreEvents = shouldIgnoreEvents
textView.ensureShouldLinkifyText(displayableText.shouldAllowLinkification)
if hasPendingMessageRequest {
// Do not linkify test if there is a pending message request for this conversation.
textView.dataDetectorTypes = []
} else {
textView.ensureShouldLinkifyText(displayableText.shouldAllowLinkification)
}
textViewConfig.applyForRendering(textView: textView)

View File

@ -159,6 +159,7 @@ struct CVItemModelBuilder: CVItemBuilding {
previousItem: previousItem,
nextItem: nextItem,
thread: thread,
threadViewModel: threadViewModel,
viewStateSnapshot: viewStateSnapshot,
transaction: transaction)
}
@ -170,6 +171,7 @@ struct CVItemModelBuilder: CVItemBuilding {
public static func buildStandaloneItem(interaction: TSInteraction,
thread: TSThread,
threadViewModel: ThreadViewModel,
itemBuildingContext: CVItemBuildingContext,
transaction: SDSAnyReadTransaction) -> CVItemModel? {
AssertIsOnMainThread()
@ -188,6 +190,7 @@ struct CVItemModelBuilder: CVItemBuilding {
previousItem: nil,
nextItem: nil,
thread: thread,
threadViewModel: threadViewModel,
viewStateSnapshot: viewStateSnapshot,
transaction: transaction)
@ -198,6 +201,7 @@ struct CVItemModelBuilder: CVItemBuilding {
previousItem: ItemBuilder?,
nextItem: ItemBuilder?,
thread: TSThread,
threadViewModel: ThreadViewModel,
viewStateSnapshot: CVViewStateSnapshot,
transaction: SDSAnyReadTransaction) {
let itemViewState = item.itemViewState
@ -231,7 +235,8 @@ struct CVItemModelBuilder: CVItemBuilding {
itemViewState.bodyTextState = CVComponentBodyText.buildState(interaction: interaction,
bodyText: bodyText,
viewStateSnapshot: viewStateSnapshot,
hasTapForMore: hasTapForMore)
hasTapForMore: hasTapForMore,
hasPendingMessageRequest: threadViewModel.hasPendingMessageRequest)
}
itemViewState.isShowingSelectionUI = viewStateSnapshot.isShowingSelectionUI

View File

@ -291,6 +291,7 @@ public class CVLoader: NSObject {
avatarBuilder: avatarBuilder)
guard let itemModel = CVItemModelBuilder.buildStandaloneItem(interaction: interaction,
thread: thread,
threadViewModel: threadViewModel,
itemBuildingContext: itemBuildingContext,
transaction: transaction) else {
owsFailDebug("Couldn't build item model.")