Improve instant view v2 layout
This commit is contained in:
parent
e0899a01d5
commit
bf2f6eb560
5 changed files with 25 additions and 19 deletions
|
|
@ -16,7 +16,7 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi
|
|||
return 0.0
|
||||
case (.divider, _), (_, .divider):
|
||||
if fitToWidth {
|
||||
return 20.0
|
||||
return 21.0
|
||||
} else {
|
||||
return 25.0
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi
|
|||
return 31.0
|
||||
case (.preformatted, _), (_, .preformatted):
|
||||
if fitToWidth {
|
||||
return 5.0
|
||||
return 12.0
|
||||
} else {
|
||||
return 19.0
|
||||
}
|
||||
|
|
@ -113,11 +113,11 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi
|
|||
case .topLevel:
|
||||
switch lower {
|
||||
case .heading:
|
||||
return 13.0
|
||||
case .paragraph:
|
||||
return 0.0
|
||||
default:
|
||||
return 6.0
|
||||
case .table:
|
||||
return 10.0
|
||||
default:
|
||||
return 5.0
|
||||
}
|
||||
case .cell:
|
||||
return 0.0
|
||||
|
|
@ -133,8 +133,8 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi
|
|||
case .topLevel:
|
||||
if case .relatedArticles = upper {
|
||||
return 0.0
|
||||
} else if case .paragraph = upper {
|
||||
return 0.0
|
||||
} else if case .thinking = upper {
|
||||
return 2.0
|
||||
} else {
|
||||
if fitToWidth {
|
||||
return 5.0
|
||||
|
|
|
|||
|
|
@ -960,7 +960,11 @@ func attributedStringForRichText(_ text: RichText, styleStack: InstantPageTextSt
|
|||
}
|
||||
let attributes = styleStack.textAttributes()
|
||||
let font = (attributes[NSAttributedString.Key.font] as? UIFont) ?? UIFont.systemFont(ofSize: 17.0)
|
||||
let itemSize = font.pointSize * 24.0 / 17.0
|
||||
// Size the inline emoji to the font's line height (A + D) plus a 4pt bump at the 17pt
|
||||
// body font (scaled proportionally). Must match the V2 layout's emoji cell size
|
||||
// (InstantPageV2Layout.swift). The run delegate still reports the font's own
|
||||
// ascent/descent (below), so the line height is unchanged — only the emoji width changes.
|
||||
let itemSize = font.ascender - font.descender + 4.0 * font.pointSize / 17.0
|
||||
let extentBuffer = UnsafeMutablePointer<RunStruct>.allocate(capacity: 1)
|
||||
extentBuffer.initialize(to: RunStruct(ascent: font.ascender, descent: font.descender, width: itemSize))
|
||||
var callbacks = CTRunDelegateCallbacks(version: kCTRunDelegateVersion1, dealloc: { pointer in
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ public func lastTextLineFrame(in layout: InstantPageV2Layout) -> CGRect? {
|
|||
/// Also returns `trailingBottomPadding`: the renderer draws the baseline at the line frame's maxY,
|
||||
/// so the visible text of a plain line sits ~5pt below it. A status that *trails on the line* should
|
||||
/// anchor at `maxY + trailingBottomPadding` to align with where the text actually renders. The pad
|
||||
/// is 0 when the line is taller than its font line height (an inline animated emoji, ~pointSize·24/17,
|
||||
/// is 0 when the line is taller than its font line height (a tall inline attachment, e.g. a formula,
|
||||
/// already pushes maxY down to the right spot). Callers should NOT apply the pad when the status
|
||||
/// wraps onto its own line below the text — there it should sit at the bare maxY.
|
||||
public func lastTextLineFrameIfLastItemIsText(in layout: InstantPageV2Layout) -> (frame: CGRect, trailingBottomPadding: CGFloat)? {
|
||||
|
|
@ -1899,17 +1899,14 @@ private func layoutDivider(
|
|||
boundingWidth: CGFloat,
|
||||
context: LayoutContext
|
||||
) -> [InstantPageV2LaidOutItem] {
|
||||
// Geometry matches V1 InstantPageLayout.swift lines 361–363:
|
||||
// lineWidth = floor(boundingWidth / 2.0), x = floor((boundingWidth - lineWidth) / 2.0), h = 1pt.
|
||||
// Color matches V1: theme.textCategories.caption.color.
|
||||
let lineWidth = floor(boundingWidth / 2.0)
|
||||
let frame = CGRect(
|
||||
x: floor((boundingWidth - lineWidth) / 2.0),
|
||||
y: 0.0,
|
||||
width: lineWidth,
|
||||
height: 1.0
|
||||
height: UIScreenPixel
|
||||
)
|
||||
return [.divider(InstantPageV2DividerItem(frame: frame, color: context.theme.textCategories.caption.color))]
|
||||
return [.divider(InstantPageV2DividerItem(frame: frame, color: context.theme.separatorColor))]
|
||||
}
|
||||
|
||||
// MARK: - Code block layout (ported from V1 InstantPageLayout.swift lines 329–351)
|
||||
|
|
@ -2848,7 +2845,12 @@ func layoutTextItem(
|
|||
} else if let emoji = attributes[ChatTextInputAttributes.customEmoji] as? ChatTextInputTextCustomEmojiAttribute {
|
||||
let xOffset = CTLineGetOffsetForStringIndex(line, range.location, nil)
|
||||
let font = (attributes[NSAttributedString.Key.font] as? UIFont) ?? UIFont.systemFont(ofSize: 17.0)
|
||||
let itemSize = font.pointSize * 24.0 / 17.0
|
||||
// Size the inline emoji to the font's line height (A + D = the true
|
||||
// line-box height) plus a 4pt bump at the 17pt body font (scaled
|
||||
// proportionally) so it reads a touch larger than the bare line box.
|
||||
// The line is NOT inflated (lineAscent stays fontLineHeight). Must match
|
||||
// the run-delegate width in attributedStringForRichText (InstantPageTextItem.swift).
|
||||
let itemSize = font.ascender - font.descender + 4.0 * font.pointSize / 17.0
|
||||
pendingEmoji.append(PendingV2EmojiAttachment(xOffset: xOffset, range: range, emoji: emoji, size: itemSize))
|
||||
}
|
||||
}
|
||||
|
|
@ -2914,7 +2916,7 @@ func layoutTextItem(
|
|||
extraDescent = max(0.0, lineDescent - baselineToNextTopSlack)
|
||||
// A centered attachment taller than the line bleeds below the baseline; grow the
|
||||
// descent so the following line isn't overlapped (mirrors V1's extraDescent handling).
|
||||
// Emoji at the default 24/17 ratio stay within the line slack and contribute nothing.
|
||||
// Emoji sized to the font line height (A + D) fit the line box, so they contribute nothing.
|
||||
for imageItem in lineImageItems {
|
||||
extraDescent = max(extraDescent, imageItem.frame.maxY - (baselineY + baselineToNextTopSlack))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode
|
|||
controlColor: messageTheme.accentControlColor,
|
||||
imageTintColor: nil,
|
||||
overlayPanelColor: isDark ? UIColor(white: 0.0, alpha: 0.13) : UIColor(white: 1.0, alpha: 0.13),
|
||||
separatorColor: isIncoming ? UIColor(white: 0.0, alpha: 0.25): messageTheme.accentControlColor.withMultipliedAlpha(0.25),
|
||||
separatorColor: messageTheme.secondaryTextColor.mixedWith(mainColor.withMultipliedAlpha(0.2), alpha: 0.3),
|
||||
secondaryControlColor: messageTheme.secondaryTextColor.mixedWith(mainColor.withMultipliedAlpha(0.2), alpha: 0.3)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ final class ChatSendMessageRichTextPreview: ChatSendMessageContextScreenRichText
|
|||
tableHeaderColor: messageTheme.accentControlColor.withMultipliedAlpha(0.1),
|
||||
controlColor: messageTheme.accentControlColor,
|
||||
imageTintColor: nil,
|
||||
overlayPanelColor: isDark ? UIColor(white: 0.0, alpha: 0.13) : UIColor(white: 1.0, alpha: 0.13),
|
||||
overlayPanelColor: messageTheme.accentControlColor.withMultipliedAlpha(0.25),
|
||||
separatorColor: messageTheme.accentControlColor.withMultipliedAlpha(0.25),
|
||||
secondaryControlColor: messageTheme.secondaryTextColor
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue