apply last character font size to the attachment

This commit is contained in:
Mauro Romito
2026-05-13 11:49:44 +02:00
committed by Mauro
parent 25318175b9
commit 690a177f6b
11 changed files with 49 additions and 19 deletions
+22 -2
View File
@@ -102,14 +102,34 @@ struct MessageText: UIViewRepresentable {
size: CGSize(width: trailingReservedSize.width,
height: max(trailingReservedSize.height, 1)))
// Inherit the font from the preceding character so the appended runs
// (newline and attachment) carry the same line metrics as the surrounding
// text — otherwise a small default font on those characters can shrink the
// line height and clip e.g. a font-boosted lone emoji.
let trailingFont = baseText.length > 0
? baseText.attribute(.font, at: baseText.length - 1, effectiveRange: nil)
: nil
// When the last paragraph's natural text direction doesn't match the layout
// direction, the inline attachment would land on the wrong side and overlap the
// overlaid timestamp. Force it onto its own line so the bubble just grows taller.
if !lastParagraphDirectionMatchesLayout(in: combined) {
combined.append(NSAttributedString(string: "\n"))
let newlineString = NSMutableAttributedString(string: "\n")
if let trailingFont {
newlineString.addAttribute(.font,
value: trailingFont,
range: NSRange(location: 0, length: newlineString.length))
}
combined.append(newlineString)
}
combined.append(NSAttributedString(attachment: attachment))
let attachmentString = NSMutableAttributedString(attachment: attachment)
if let trailingFont {
attachmentString.addAttribute(.font,
value: trailingFont,
range: NSRange(location: 0, length: attachmentString.length))
}
combined.append(attachmentString)
}
return combined
@@ -152,6 +152,15 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
canBeRepliedTo: true,
sender: .test,
content: .init(body: "באמת! -- house!"))
static let bigEmoji = TextRoomTimelineItem(id: .randomEvent,
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
shouldBoost: true,
sender: .test,
content: .init(body: "😮"))
static var testView: some View {
VStack(spacing: 0) {
@@ -172,6 +181,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
TextRoomTimelineView(timelineItem: rtlStringThatContainsLtr)
TextRoomTimelineView(timelineItem: ltrStringThatFinishesInRtl)
TextRoomTimelineView(timelineItem: rtlStringThatFinishesInLtr)
TextRoomTimelineView(timelineItem: bigEmoji)
}
}
@@ -24,7 +24,7 @@ struct FormattedBodyText: View {
private var attributedComponents: [AttributedStringBuilderComponent] {
var adjustedAttributedString = attributedString
// Required to allow the underlying TextView to use body font when no font is specifie in the AttributedString.
// Required to allow the underlying TextView to use body font when no font is specified in the AttributedString.
adjustedAttributedString.mergeAttributes(defaultAttributesContainer, mergePolicy: .keepCurrent)
let string = String(attributedString.characters)