Split spoiler effect by words

This commit is contained in:
Ilya Laktyushin 2021-12-02 05:14:05 +04:00
parent bd2e843086
commit e888f8e5be
2 changed files with 21 additions and 5 deletions

View File

@ -1083,10 +1083,26 @@ public class TextNode: ASDisplayNode {
var descent: CGFloat = 0.0
CTLineGetTypographicBounds(coreTextLine, &ascent, &descent, nil)
let lowerX = floor(CTLineGetOffsetForStringIndex(coreTextLine, range.location, nil))
let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil))
let x = lowerX < upperX ? lowerX : upperX
spoilers.append(TextNodeSpoiler(range: range, frame: CGRect(x: x, y: descent - (ascent + descent), width: abs(upperX - lowerX), height: ascent + descent)))
(attributedString.string as NSString).enumerateSubstrings(in: range, options: .byWords) { _, range, _, _ in
let startIndex = range.location
let endIndex = range.location + range.length
var secondaryLeftOffset: CGFloat = 0.0
let rawLeftOffset = CTLineGetOffsetForStringIndex(coreTextLine, startIndex, &secondaryLeftOffset)
var leftOffset = ceil(rawLeftOffset)
if !rawLeftOffset.isEqual(to: secondaryLeftOffset) {
leftOffset = ceil(secondaryLeftOffset)
}
var secondaryRightOffset: CGFloat = 0.0
let rawRighOffset = CTLineGetOffsetForStringIndex(coreTextLine, endIndex, &secondaryRightOffset)
var rightOffset = ceil(rawRighOffset)
if !rawRighOffset.isEqual(to: secondaryRightOffset) {
rightOffset = ceil(secondaryRightOffset)
}
spoilers.append(TextNodeSpoiler(range: range, frame: CGRect(x: min(leftOffset, rightOffset), y: descent - (ascent + descent), width: abs(rightOffset - leftOffset), height: ascent + descent)))
}
} else if let _ = attributes[NSAttributedString.Key.strikethroughStyle] {
let lowerX = floor(CTLineGetOffsetForStringIndex(coreTextLine, range.location, nil))
let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil))

View File

@ -402,7 +402,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
strongSelf.dustNode = dustNode
strongSelf.insertSubnode(dustNode, aboveSubnode: spoilerTextNode)
}
dustNode.update(size: textFrame.size, color: messageTheme.primaryTextColor, rects: textLayout.spoilers.map { $0.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: -2.0, dy: 0.0) })
dustNode.update(size: textFrame.size, color: messageTheme.primaryTextColor, rects: textLayout.spoilers.map { $0.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) })
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
} else if let spoilerTextNode = strongSelf.spoilerTextNode {
strongSelf.spoilerTextNode = nil