diff --git a/submodules/InstantPageUI/Sources/InstantPageLayout.swift b/submodules/InstantPageUI/Sources/InstantPageLayout.swift index 1a9ff938f4..3a149628f7 100644 --- a/submodules/InstantPageUI/Sources/InstantPageLayout.swift +++ b/submodules/InstantPageUI/Sources/InstantPageLayout.swift @@ -35,10 +35,12 @@ private func setupStyleStack(_ stack: InstantPageTextStyleStack, theme: InstantP stack.push(.linkColor(theme.linkColor)) stack.push(.linkMarkerColor(theme.linkHighlightColor)) switch attributes.font.style { - case .sans: - stack.push(.fontSerif(false)) - case .serif: - stack.push(.fontSerif(true)) + case .sans: + stack.push(.fontSerif(false)) + case .serif: + stack.push(.fontSerif(true)) + case .monospace: + stack.push(.fontFixed(true)) } stack.push(.fontSize(attributes.font.size)) stack.push(.lineSpacingFactor(attributes.font.lineSpacingFactor)) @@ -85,6 +87,16 @@ private func instantPageFont(style: InstantPageTextAttributes, bold: Bool = fals } else { return Font.regular(size) } + case .monospace: + if bold && italic { + return Font.semiboldItalicMonospace(size) + } else if bold { + return Font.semiboldMonospace(size) + } else if italic { + return Font.italicMonospace(size) + } else { + return Font.monospace(size) + } } } diff --git a/submodules/InstantPageUI/Sources/InstantPageLayoutSpacings.swift b/submodules/InstantPageUI/Sources/InstantPageLayoutSpacings.swift index bd1e281844..efe2d7bbb9 100644 --- a/submodules/InstantPageUI/Sources/InstantPageLayoutSpacings.swift +++ b/submodules/InstantPageUI/Sources/InstantPageLayoutSpacings.swift @@ -54,8 +54,6 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi } else { return 31.0 } - case (.preformatted, .paragraph): - return 19.0 case (.formula, .paragraph): return 19.0 case (.paragraph, .paragraph): @@ -64,8 +62,6 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi } else { return 25.0 } - case (_, .paragraph): - return 20.0 case (.title, .formula), (.authorDate, .formula): return 34.0 case (.header, .formula), (.subheader, .formula), (.heading, .formula): @@ -76,8 +72,6 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi } case (.list, .formula): return 31.0 - case (.preformatted, .formula): - return 19.0 case (.paragraph, .formula): return 19.0 case (_, .formula): @@ -86,8 +80,12 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi return 34.0 case (.header, .list), (.subheader, .list), (.heading, .list): return 31.0 - case (.preformatted, .list): - return 19.0 + case (.preformatted, _), (_, .preformatted): + if fitToWidth { + return 0.0 + } else { + return 19.0 + } case (.formula, .list): if fitToWidth { return 10.0 @@ -100,12 +98,6 @@ func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fi } else { return 25.0 } - case (.paragraph, .preformatted): - return 19.0 - case (.formula, .preformatted): - return 19.0 - case (_, .preformatted): - return 20.0 case (_, .header), (_, .subheader), (_, .heading): return 32.0 default: diff --git a/submodules/InstantPageUI/Sources/InstantPageTheme.swift b/submodules/InstantPageUI/Sources/InstantPageTheme.swift index a1857d1ef5..d3cd70e803 100644 --- a/submodules/InstantPageUI/Sources/InstantPageTheme.swift +++ b/submodules/InstantPageUI/Sources/InstantPageTheme.swift @@ -7,6 +7,7 @@ import TelegramUIPreferences public enum InstantPageFontStyle { case sans case serif + case monospace } public struct InstantPageFont { @@ -50,6 +51,7 @@ enum InstantPageTextCategoryType { case credit case table case article + case codeBlock } public struct InstantPageTextCategories { @@ -61,8 +63,9 @@ public struct InstantPageTextCategories { let credit: InstantPageTextAttributes let table: InstantPageTextAttributes let article: InstantPageTextAttributes + let codeBlock: InstantPageTextAttributes - public init(kicker: InstantPageTextAttributes, header: InstantPageTextAttributes, subheader: InstantPageTextAttributes, paragraph: InstantPageTextAttributes, caption: InstantPageTextAttributes, credit: InstantPageTextAttributes, table: InstantPageTextAttributes, article: InstantPageTextAttributes) { + public init(kicker: InstantPageTextAttributes, header: InstantPageTextAttributes, subheader: InstantPageTextAttributes, paragraph: InstantPageTextAttributes, caption: InstantPageTextAttributes, credit: InstantPageTextAttributes, table: InstantPageTextAttributes, article: InstantPageTextAttributes, codeBlock: InstantPageTextAttributes) { self.kicker = kicker self.header = header self.subheader = subheader @@ -71,26 +74,29 @@ public struct InstantPageTextCategories { self.credit = credit self.table = table self.article = article + self.codeBlock = codeBlock } func attributes(type: InstantPageTextCategoryType, link: Bool) -> InstantPageTextAttributes { switch type { - case .kicker: - return self.kicker.withUnderline(link) - case .header: - return self.header.withUnderline(link) - case .subheader: - return self.subheader.withUnderline(link) - case .paragraph: - return self.paragraph.withUnderline(link) - case .caption: - return self.caption.withUnderline(link) - case .credit: - return self.credit.withUnderline(link) - case .table: - return self.table.withUnderline(link) - case .article: - return self.article.withUnderline(link) + case .kicker: + return self.kicker.withUnderline(link) + case .header: + return self.header.withUnderline(link) + case .subheader: + return self.subheader.withUnderline(link) + case .paragraph: + return self.paragraph.withUnderline(link) + case .caption: + return self.caption.withUnderline(link) + case .credit: + return self.credit.withUnderline(link) + case .table: + return self.table.withUnderline(link) + case .article: + return self.article.withUnderline(link) + case .codeBlock: + return self.codeBlock.withUnderline(link) } } @@ -103,7 +109,8 @@ public struct InstantPageTextCategories { caption: self.caption.withUpdatedFontStyles(sizeMultiplier: sizeMultiplier, lineSpacingFactor: lineSpacingFactor, forceSerif: forceSerif), credit: self.credit.withUpdatedFontStyles(sizeMultiplier: sizeMultiplier, lineSpacingFactor: lineSpacingFactor, forceSerif: forceSerif), table: self.table.withUpdatedFontStyles(sizeMultiplier: sizeMultiplier, lineSpacingFactor: lineSpacingFactor, forceSerif: forceSerif), - article: self.article.withUpdatedFontStyles(sizeMultiplier: sizeMultiplier, lineSpacingFactor: lineSpacingFactor, forceSerif: forceSerif) + article: self.article.withUpdatedFontStyles(sizeMultiplier: sizeMultiplier, lineSpacingFactor: lineSpacingFactor, forceSerif: forceSerif), + codeBlock: self.codeBlock.withUpdatedFontStyles(sizeMultiplier: sizeMultiplier, lineSpacingFactor: lineSpacingFactor, forceSerif: forceSerif) ) } } @@ -214,7 +221,8 @@ private let lightTheme = InstantPageTheme( caption: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x79828b)), credit: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 13.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x79828b)), table: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: .black), - article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: .black) + article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: .black), + codeBlock: InstantPageTextAttributes(font: InstantPageFont(style: .monospace, size: 14.0, lineSpacingFactor: 1.0), color: .black) ), serif: false, codeBlockBackgroundColor: UIColor(rgb: 0xf5f8fc), @@ -247,7 +255,8 @@ private let sepiaTheme = InstantPageTheme( caption: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x927e6b)), credit: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 13.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x927e6b)), table: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x4f321d)), - article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x4f321d)) + article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x4f321d)), + codeBlock: InstantPageTextAttributes(font: InstantPageFont(style: .monospace, size: 14.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x4f321d)) ), serif: false, codeBlockBackgroundColor: UIColor(rgb: 0xefe7d6), @@ -280,7 +289,8 @@ private let grayTheme = InstantPageTheme( caption: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xa0a0a0)), credit: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 13.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xa0a0a0)), table: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xcecece)), - article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xcecece)) + article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xcecece)), + codeBlock: InstantPageTextAttributes(font: InstantPageFont(style: .monospace, size: 14.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xcecece)) ), serif: false, codeBlockBackgroundColor: UIColor(rgb: 0x555556), @@ -313,7 +323,8 @@ private let darkTheme = InstantPageTheme( caption: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x6a6a6a)), credit: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 13.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0x6a6a6a)), table: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xb0b0b0)), - article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xb0b0b0)) + article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xb0b0b0)), + codeBlock: InstantPageTextAttributes(font: InstantPageFont(style: .monospace, size: 14.0, lineSpacingFactor: 1.0), color: UIColor(rgb: 0xb0b0b0)) ), serif: false, codeBlockBackgroundColor: UIColor(rgb: 0x131313), diff --git a/submodules/InstantPageUI/Sources/InstantPageV2Layout.swift b/submodules/InstantPageUI/Sources/InstantPageV2Layout.swift index d160481213..f134c554e6 100644 --- a/submodules/InstantPageUI/Sources/InstantPageV2Layout.swift +++ b/submodules/InstantPageUI/Sources/InstantPageV2Layout.swift @@ -1921,11 +1921,8 @@ private func layoutCodeBlock( horizontalInset: CGFloat, context: inout LayoutContext ) -> [InstantPageV2LaidOutItem] { - // V1 InstantPageLayout.swift line 330: backgroundInset = 14.0 (top + bottom padding). - let backgroundInset: CGFloat = 14.0 - // V1 line 342: text x offset is 17.0 (hardcoded, not backgroundInset). - let textXOffset: CGFloat = 17.0 - // V1 line 348: shape is .rect — no corner radius. + let backgroundInset: CGFloat = 15.0 + let textXOffset: CGFloat = 11.0 let cornerRadius: CGFloat = 0.0 let attributedString: NSAttributedString @@ -1940,7 +1937,7 @@ private func layoutCodeBlock( } else { // V1 lines 335–338: fall back to plain paragraph style when no language. let styleStack = InstantPageTextStyleStack() - setupStyleStack(styleStack, theme: context.theme, category: .paragraph, link: false) + setupStyleStack(styleStack, theme: context.theme, category: .codeBlock, link: false) attributedString = attributedStringForRichText(text, styleStack: styleStack) } @@ -2528,10 +2525,12 @@ private func setupStyleStack(_ stack: InstantPageTextStyleStack, theme: InstantP stack.push(.linkColor(theme.linkColor)) stack.push(.linkMarkerColor(theme.linkHighlightColor)) switch attributes.font.style { - case .sans: - stack.push(.fontSerif(false)) - case .serif: - stack.push(.fontSerif(true)) + case .sans: + stack.push(.fontSerif(false)) + case .serif: + stack.push(.fontSerif(true)) + case .monospace: + stack.push(.fontFixed(true)) } stack.push(.fontSize(attributes.font.size)) stack.push(.lineSpacingFactor(attributes.font.lineSpacingFactor)) @@ -2578,6 +2577,16 @@ private func instantPageFont(style: InstantPageTextAttributes, bold: Bool = fals } else { return Font.regular(size) } + case .monospace: + if bold && italic { + return Font.semiboldItalicMonospace(size) + } else if bold { + return Font.semiboldMonospace(size) + } else if italic { + return Font.italicMonospace(size) + } else { + return Font.monospace(size) + } } } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/Sources/ChatMessageRichDataBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/Sources/ChatMessageRichDataBubbleContentNode.swift index d643d7f132..5aa00c1209 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/Sources/ChatMessageRichDataBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageRichDataBubbleContentNode/Sources/ChatMessageRichDataBubbleContentNode.swift @@ -228,9 +228,9 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode nameColors = nil } + let codeBlockBackgroundColor: UIColor let codeBlockTitleColor: UIColor let codeBlockAccentColor: UIColor - let codeBlockBackgroundColor: UIColor if !isIncoming { mainColor = messageTheme.accentTextColor if let _ = nameColors?.secondary { @@ -243,12 +243,12 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode if item.presentationData.theme.theme.overallDarkAppearance { codeBlockTitleColor = .white codeBlockAccentColor = UIColor(white: 1.0, alpha: 0.5) - codeBlockBackgroundColor = UIColor(white: 0.0, alpha: 0.25) } else { codeBlockTitleColor = mainColor codeBlockAccentColor = mainColor - codeBlockBackgroundColor = mainColor.withMultipliedAlpha(0.1) } + + codeBlockBackgroundColor = mainColor.withMultipliedAlpha(0.1) } else { let authorNameColor = nameColors?.main secondaryColor = nameColors?.secondary @@ -263,11 +263,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode codeBlockTitleColor = mainColor codeBlockAccentColor = mainColor - if item.presentationData.theme.theme.overallDarkAppearance { - codeBlockBackgroundColor = UIColor(white: 0.0, alpha: 0.65) - } else { - codeBlockBackgroundColor = UIColor(white: 0.0, alpha: 0.05) - } + codeBlockBackgroundColor = mainColor.withMultipliedAlpha(0.1) } let _ = secondaryColor @@ -284,7 +280,8 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode caption: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: messageTheme.secondaryTextColor), credit: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 13.0, lineSpacingFactor: 1.0), color: messageTheme.secondaryTextColor), table: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: messageTheme.primaryTextColor), - article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: messageTheme.primaryTextColor) + article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: messageTheme.primaryTextColor), + codeBlock: InstantPageTextAttributes(font: InstantPageFont(style: .monospace, size: 14.0, lineSpacingFactor: 1.0), color: messageTheme.primaryTextColor), ) let pageTheme = InstantPageTheme( type: isDark ? .dark : .light, @@ -307,7 +304,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode 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), - secondaryControlColor: messageTheme.secondaryTextColor + secondaryControlColor: messageTheme.secondaryTextColor.mixedWith(mainColor.withMultipliedAlpha(0.2), alpha: 0.3) ) var hasDraft = false @@ -320,6 +317,15 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode } if let attribute = item.message.richText { + #if DEBUG && false + let instantPage = InstantPage(blocks: [.thinking(.concat([ + .textCustomEmoji(fileId: 5384559872899555845, alt: "a"), + .plain("Thinking...") + ]))], media: [:], isComplete: true, rtl: false, url: "", views: nil) + #else + let instantPage = attribute.instantPage + #endif + let webpage = TelegramMediaWebpage(webpageId: EngineMedia.Id(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent( url: "", displayUrl: "", @@ -339,7 +345,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode file: nil, story: nil, attributes: [], - instantPage: attribute.instantPage + instantPage: instantPage ))) pageWebpage = webpage @@ -352,9 +358,17 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode current.messageStableVersion == currentMessageStableVersion { pageLayout = current.layout } else { + #if DEBUG && false + let instantPage = InstantPage(blocks: [.thinking(.concat([ + .textCustomEmoji(fileId: 5384559872899555845, alt: "a"), + .plain("Thinking...") + ]))], media: [:], isComplete: true, rtl: false, url: "", views: nil) + #else + let instantPage = attribute.instantPage + #endif pageLayout = layoutInstantPageV2( webpage: webpage, - instantPage: attribute.instantPage, + instantPage: instantPage, userLocation: .other, boundingWidth: suggestedBoundingWidth - 2.0, horizontalInset: pageHorizontalInset, diff --git a/submodules/TelegramUI/Sources/Chat/ChatSendMessageRichTextPreview.swift b/submodules/TelegramUI/Sources/Chat/ChatSendMessageRichTextPreview.swift index ae797425cf..fb9ef20eb8 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatSendMessageRichTextPreview.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatSendMessageRichTextPreview.swift @@ -96,7 +96,8 @@ final class ChatSendMessageRichTextPreview: ChatSendMessageContextScreenRichText caption: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: messageTheme.secondaryTextColor), credit: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 13.0, lineSpacingFactor: 1.0), color: messageTheme.secondaryTextColor), table: InstantPageTextAttributes(font: InstantPageFont(style: .sans, size: 15.0, lineSpacingFactor: 1.0), color: messageTheme.primaryTextColor), - article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: messageTheme.primaryTextColor) + article: InstantPageTextAttributes(font: InstantPageFont(style: .serif, size: 18.0, lineSpacingFactor: 1.0), color: messageTheme.primaryTextColor), + codeBlock: InstantPageTextAttributes(font: InstantPageFont(style: .monospace, size: 14.0, lineSpacingFactor: 1.0), color: messageTheme.primaryTextColor) ) let pageTheme = InstantPageTheme( type: isDark ? .dark : .light,