WIP
This commit is contained in:
parent
50da64adfa
commit
13a153aff2
67 changed files with 64681 additions and 62438 deletions
|
|
@ -333,7 +333,7 @@ private enum MarkdownTaskListState {
|
|||
|
||||
private final class MarkdownConversionContext {
|
||||
private let context: AccountContext
|
||||
fileprivate let documentURL: URL
|
||||
fileprivate let documentURL: URL?
|
||||
fileprivate let formulasByPlaceholder: [String: MarkdownFormulaDescriptor]
|
||||
fileprivate let budget: MarkdownConversionBudget
|
||||
private var nextRemoteMediaId: Int64 = 0
|
||||
|
|
@ -341,7 +341,7 @@ private final class MarkdownConversionContext {
|
|||
|
||||
private(set) var media: [EngineMedia.Id: EngineRawMedia] = [:]
|
||||
|
||||
init(context: AccountContext, documentURL: URL, formulasByPlaceholder: [String: MarkdownFormulaDescriptor], budget: MarkdownConversionBudget) {
|
||||
init(context: AccountContext, documentURL: URL?, formulasByPlaceholder: [String: MarkdownFormulaDescriptor], budget: MarkdownConversionBudget) {
|
||||
self.context = context
|
||||
self.documentURL = documentURL
|
||||
self.formulasByPlaceholder = formulasByPlaceholder
|
||||
|
|
@ -977,14 +977,27 @@ func markdownWebpage(context: AccountContext, file: FileMediaReference) -> (webP
|
|||
guard let data = try? Data(contentsOf: fileURL) else {
|
||||
return nil
|
||||
}
|
||||
guard let webPage = markdownWebpage(context: context, file: file, fileURL: fileURL, data: data) else {
|
||||
guard let webPage = markdownWebpage(context: context, file: (file, fileURL), data: data) else {
|
||||
return nil
|
||||
}
|
||||
return (webPage, fileURL)
|
||||
}
|
||||
|
||||
public func inputRichTextAttributeFromText(context: AccountContext, text: String) -> RichTextMessageAttribute? {
|
||||
guard #available(iOS 15.0, *) else {
|
||||
return nil
|
||||
}
|
||||
guard let data = text.data(using: .utf8) else {
|
||||
return nil
|
||||
}
|
||||
guard let webpage = markdownWebpage(context: context, file: nil, data: data), case let .Loaded(content) = webpage.content, let instantPage = content.instantPage else {
|
||||
return nil
|
||||
}
|
||||
return RichTextMessageAttribute(instantPage: instantPage._parse())
|
||||
}
|
||||
|
||||
@available(iOS 15.0, *)
|
||||
private func markdownWebpage(context: AccountContext, file: FileMediaReference, fileURL: URL, data: Data) -> TelegramMediaWebpage? {
|
||||
private func markdownWebpage(context: AccountContext, file: (file: FileMediaReference, url: URL)?, data: Data) -> TelegramMediaWebpage? {
|
||||
let limits = markdownSafetyLimits
|
||||
guard markdownPassesPreflight(data: data, limits: limits) else {
|
||||
return nil
|
||||
|
|
@ -996,17 +1009,23 @@ private func markdownWebpage(context: AccountContext, file: FileMediaReference,
|
|||
|
||||
let attributedString: NSAttributedString
|
||||
do {
|
||||
let baseURL: URL?
|
||||
if let file {
|
||||
baseURL = file.url.deletingLastPathComponent()
|
||||
} else {
|
||||
baseURL = nil
|
||||
}
|
||||
attributedString = try NSAttributedString(
|
||||
markdown: Data(preparedSource.text.utf8),
|
||||
options: .init(),
|
||||
baseURL: fileURL.deletingLastPathComponent()
|
||||
baseURL: baseURL
|
||||
)
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
|
||||
let budget = MarkdownConversionBudget(limits: limits)
|
||||
let conversionContext = MarkdownConversionContext(context: context, documentURL: fileURL, formulasByPlaceholder: preparedSource.formulasByPlaceholder, budget: budget)
|
||||
let conversionContext = MarkdownConversionContext(context: context, documentURL: file?.url, formulasByPlaceholder: preparedSource.formulasByPlaceholder, budget: budget)
|
||||
guard let pageResult = markdownPageResult(from: attributedString, context: conversionContext) else {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1015,14 +1034,17 @@ private func markdownWebpage(context: AccountContext, file: FileMediaReference,
|
|||
return nil
|
||||
}
|
||||
|
||||
let title = markdownTitle(from: blocks, file: file, fileURL: fileURL)
|
||||
var title: String?
|
||||
if let file {
|
||||
title = markdownTitle(from: blocks, file: file.file, fileURL: file.url)
|
||||
}
|
||||
let text = markdownFirstParagraphText(from: blocks)
|
||||
let instantPage = InstantPage(
|
||||
blocks: blocks,
|
||||
media: pageResult.media,
|
||||
isComplete: true,
|
||||
rtl: false,
|
||||
url: fileURL.absoluteString,
|
||||
url: file?.url.absoluteString ?? "",
|
||||
views: nil
|
||||
)
|
||||
|
||||
|
|
@ -1030,8 +1052,8 @@ private func markdownWebpage(context: AccountContext, file: FileMediaReference,
|
|||
webpageId: EngineMedia.Id(namespace: 0, id: 0),
|
||||
content: .Loaded(
|
||||
TelegramMediaWebpageLoadedContent(
|
||||
url: fileURL.absoluteString,
|
||||
displayUrl: fileURL.absoluteString,
|
||||
url: file?.url.absoluteString ?? "",
|
||||
displayUrl: file?.url.absoluteString ?? "",
|
||||
hash: 0,
|
||||
type: "article",
|
||||
websiteName: nil,
|
||||
|
|
@ -1764,7 +1786,7 @@ private func markdownInlineImageDimensions(attributes: [NSAttributedString.Key:
|
|||
return PixelDimensions(width: side, height: side)
|
||||
}
|
||||
|
||||
private func markdownLink(attributes: [NSAttributedString.Key: Any], documentURL: URL) -> String? {
|
||||
private func markdownLink(attributes: [NSAttributedString.Key: Any], documentURL: URL?) -> String? {
|
||||
if let value = attributes[markdownLinkAttribute] as? URL {
|
||||
return markdownNormalizedLink(value, documentURL: documentURL)
|
||||
}
|
||||
|
|
@ -1783,14 +1805,14 @@ private func markdownLink(attributes: [NSAttributedString.Key: Any], documentURL
|
|||
return nil
|
||||
}
|
||||
|
||||
private func markdownNormalizedLink(_ url: URL, documentURL: URL) -> String {
|
||||
private func markdownNormalizedLink(_ url: URL, documentURL: URL?) -> String {
|
||||
if url.baseURL != nil {
|
||||
let relative = url.relativeString
|
||||
if relative.hasPrefix("#") {
|
||||
return relative
|
||||
}
|
||||
}
|
||||
if let fragment = url.fragment, markdownMatchesDocument(url, documentURL: documentURL) {
|
||||
if let documentURL, let fragment = url.fragment, markdownMatchesDocument(url, documentURL: documentURL) {
|
||||
return "#\(fragment)"
|
||||
}
|
||||
return url.absoluteString
|
||||
|
|
|
|||
|
|
@ -77,6 +77,176 @@ private func paidContentGroupType(paidContent: TelegramMediaPaidContent) -> Mess
|
|||
return currentType
|
||||
}
|
||||
|
||||
extension RichText {
|
||||
func previewText() -> String {
|
||||
switch self {
|
||||
case .empty:
|
||||
return ""
|
||||
case let .plain(value):
|
||||
return value
|
||||
case let .bold(value):
|
||||
return value.previewText()
|
||||
case let .italic(value):
|
||||
return value.previewText()
|
||||
case let .underline(value):
|
||||
return value.previewText()
|
||||
case let .strikethrough(value):
|
||||
return value.previewText()
|
||||
case let .fixed(value):
|
||||
return value.previewText()
|
||||
case let .url(value, _, _):
|
||||
return value.previewText()
|
||||
case let .email(value, _):
|
||||
return value.previewText()
|
||||
case let .concat(values):
|
||||
var result = ""
|
||||
for value in values {
|
||||
result.append(value.previewText())
|
||||
}
|
||||
return result
|
||||
case let .`subscript`(value):
|
||||
return value.previewText()
|
||||
case let .superscript(value):
|
||||
return value.previewText()
|
||||
case let .marked(value):
|
||||
return value.previewText()
|
||||
case let .phone(value, _):
|
||||
return value.previewText()
|
||||
case .image:
|
||||
//TODO:localize
|
||||
return "Photo"
|
||||
case let .anchor(value, _):
|
||||
return value.previewText()
|
||||
case let .formula(latex):
|
||||
return latex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension InstantPageListItem {
|
||||
func previewText() -> String {
|
||||
switch self {
|
||||
case .unknown:
|
||||
return ""
|
||||
case let .text(text, num):
|
||||
if let num, !num.isEmpty {
|
||||
return "\(num). \(text.previewText())"
|
||||
} else {
|
||||
return text.previewText()
|
||||
}
|
||||
case let .blocks(blocks, num):
|
||||
var blocksText = ""
|
||||
for block in blocks {
|
||||
if !blocksText.isEmpty {
|
||||
blocksText.append("\n")
|
||||
}
|
||||
blocksText.append(block.previewText())
|
||||
}
|
||||
if let num {
|
||||
return "\(num). \(blocksText)"
|
||||
} else {
|
||||
return blocksText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension InstantPageBlock {
|
||||
func previewText() -> String {
|
||||
switch self {
|
||||
case .unsupported:
|
||||
return ""
|
||||
case let .title(text):
|
||||
return text.previewText()
|
||||
case let .subtitle(text):
|
||||
return text.previewText()
|
||||
case let .authorDate(author, _):
|
||||
return author.previewText()
|
||||
case let .header(text):
|
||||
return text.previewText()
|
||||
case let .subheader(text):
|
||||
return text.previewText()
|
||||
case let .heading(text, _):
|
||||
return text.previewText()
|
||||
case let .formula(latex):
|
||||
return latex
|
||||
case let .paragraph(text):
|
||||
return text.previewText()
|
||||
case let .preformatted(text, _):
|
||||
return text.previewText()
|
||||
case let .footer(text):
|
||||
return text.previewText()
|
||||
case .divider:
|
||||
return "\n"
|
||||
case .anchor:
|
||||
return ""
|
||||
case let .list(items, _):
|
||||
var result = ""
|
||||
for item in items {
|
||||
if !result.isEmpty {
|
||||
result.append("\n")
|
||||
}
|
||||
result.append(item.previewText())
|
||||
}
|
||||
return result
|
||||
case let .blockQuote(text, caption):
|
||||
return text.previewText() + caption.previewText()
|
||||
case let .pullQuote(text, caption):
|
||||
return text.previewText() + caption.previewText()
|
||||
case .image(_, _, _, _):
|
||||
//TODO:localize
|
||||
return "Photo"
|
||||
case .video(_, _, _, _):
|
||||
//TODO:localize
|
||||
return "Video"
|
||||
case .audio:
|
||||
//TODO:localize
|
||||
return "Audio"
|
||||
case .cover:
|
||||
return ""
|
||||
case .webEmbed:
|
||||
return ""
|
||||
case .postEmbed:
|
||||
return ""
|
||||
case .collage:
|
||||
return ""
|
||||
case .slideshow:
|
||||
return ""
|
||||
case .channelBanner:
|
||||
return ""
|
||||
case .kicker:
|
||||
return ""
|
||||
case .table:
|
||||
//TODO:localize
|
||||
return "Table"
|
||||
case .details:
|
||||
return ""
|
||||
case .relatedArticles:
|
||||
return ""
|
||||
case .map:
|
||||
//TODO:localize
|
||||
return "Map"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension InstantPage {
|
||||
func previewText() -> String {
|
||||
let maxLength: Int = 200
|
||||
var result = ""
|
||||
for block in self.blocks {
|
||||
if !result.isEmpty {
|
||||
result.append("\n")
|
||||
}
|
||||
result.append(block.previewText())
|
||||
if result.count > maxLength {
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, contentSettings: ContentSettings, messages: [EngineMessage], chatPeer: EngineRenderedPeer, accountPeerId: EnginePeer.Id, enableMediaEmoji: Bool = true, isPeerGroup: Bool = false) -> (peer: EnginePeer?, hideAuthor: Bool, messageText: String, messageEntities: [MessageTextEntity], spoilers: [NSRange]?, customEmojiRanges: [(NSRange, ChatTextInputTextCustomEmojiAttribute)]?) {
|
||||
let peer: EnginePeer?
|
||||
|
||||
|
|
@ -103,7 +273,10 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder:
|
|||
|
||||
messageText = ""
|
||||
for message in messages {
|
||||
if !message.text.isEmpty {
|
||||
if let richText = message.richText {
|
||||
messageText = richText.instantPage.previewText()
|
||||
messageEntities = []
|
||||
} else if !message.text.isEmpty {
|
||||
messageText = message.text
|
||||
messageEntities = message._asMessage().textEntitiesAttribute?.entities ?? []
|
||||
for entity in messageEntities {
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ private func instantPageFirstTextLineMidY(in items: [InstantPageItem]) -> CGFloa
|
|||
return nil
|
||||
}
|
||||
|
||||
public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation: MediaResourceUserLocation, rtl: Bool, block: InstantPageBlock, boundingWidth: CGFloat, horizontalInset: CGFloat, safeInset: CGFloat, isCover: Bool, previousItems: [InstantPageItem], fillToSize: CGSize?, media: [EngineMedia.Id: EngineMedia], mediaIndexCounter: inout Int, embedIndexCounter: inout Int, detailsIndexCounter: inout Int, theme: InstantPageTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, webEmbedHeights: [Int : CGFloat] = [:], cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, excludeCaptions: Bool, isLast: Bool) -> InstantPageLayout {
|
||||
public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation: MediaResourceUserLocation, rtl: Bool, block: InstantPageBlock, boundingWidth: CGFloat, horizontalInset: CGFloat, safeInset: CGFloat, isCover: Bool, previousItems: [InstantPageItem], fillToSize: CGSize?, media: [EngineMedia.Id: EngineMedia], mediaIndexCounter: inout Int, embedIndexCounter: inout Int, detailsIndexCounter: inout Int, theme: InstantPageTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, webEmbedHeights: [Int : CGFloat] = [:], cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, excludeCaptions: Bool, isLast: Bool, fitToWidth: Bool) -> InstantPageLayout {
|
||||
let layoutCaption: (InstantPageCaption, CGSize) -> ([InstantPageItem], CGSize) = { caption, contentSize in
|
||||
var items: [InstantPageItem] = []
|
||||
var offset = contentSize.height
|
||||
|
|
@ -177,7 +177,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
offset += 14.0
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .caption, link: false)
|
||||
let (textItem, captionItems, captionContentSize) = layoutTextItemWithString(attributedStringForRichText(caption.text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: offset), media: media, webpage: webpage)
|
||||
let (textItem, captionItems, captionContentSize) = layoutTextItemWithString(attributedStringForRichText(caption.text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: offset), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
contentSize.height += captionContentSize.height
|
||||
offset += captionContentSize.height
|
||||
items.append(contentsOf: captionItems)
|
||||
|
|
@ -196,7 +196,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
}
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .credit, link: false)
|
||||
let (_, captionItems, captionContentSize) = layoutTextItemWithString(attributedStringForRichText(caption.credit, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, alignment: rtl ? .right : .natural, offset: CGPoint(x: horizontalInset, y: offset), media: media, webpage: webpage)
|
||||
let (_, captionItems, captionContentSize) = layoutTextItemWithString(attributedStringForRichText(caption.credit, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, alignment: rtl ? .right : .natural, offset: CGPoint(x: horizontalInset, y: offset), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
contentSize.height += captionContentSize.height
|
||||
offset += captionContentSize.height
|
||||
items.append(contentsOf: captionItems)
|
||||
|
|
@ -217,16 +217,16 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
|
||||
switch block {
|
||||
case let .cover(block):
|
||||
return layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: block, boundingWidth: boundingWidth, horizontalInset: horizontalInset, safeInset: safeInset, isCover: true, previousItems:previousItems, fillToSize: fillToSize, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: true)
|
||||
return layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: block, boundingWidth: boundingWidth, horizontalInset: horizontalInset, safeInset: safeInset, isCover: true, previousItems:previousItems, fillToSize: fillToSize, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: true, fitToWidth: fitToWidth)
|
||||
case let .title(text):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .header, link: false)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
case let .subtitle(text):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .subheader, link: false)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
case let .authorDate(author: author, date: date):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
|
|
@ -265,7 +265,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
if let previousItem = previousItems.last as? InstantPageTextItem, previousItem.containsRTL {
|
||||
previousItemHasRTL = true
|
||||
}
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, alignment: rtl || previousItemHasRTL ? .right : .natural, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, alignment: rtl || previousItemHasRTL ? .right : .natural, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
} else {
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: CGSize(), items: [])
|
||||
|
|
@ -273,22 +273,22 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
case let .kicker(text):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .kicker, link: false)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
case let .header(text):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .header, link: false)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
case let .subheader(text):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .subheader, link: false)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
case let .heading(text, level):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, attributes: theme.headingTextAttributes(level: level, link: false))
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
case let .formula(latex):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
|
|
@ -298,7 +298,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
let fontSize = (attributes[NSAttributedString.Key.font] as? UIFont)?.pointSize ?? theme.textCategories.paragraph.font.size
|
||||
|
||||
guard let attachment = instantPageMathAttachment(latex: latex, fontSize: fontSize, textColor: textColor, mode: .block) else {
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(.plain(latex), styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(.plain(latex), styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +324,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
case let .paragraph(text):
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .paragraph, link: false)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, horizontalInset: horizontalInset, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage)
|
||||
let (_, items, contentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, horizontalInset: horizontalInset, offset: CGPoint(x: horizontalInset, y: 0.0), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
case let .preformatted(text, language):
|
||||
let backgroundInset: CGFloat = 14.0
|
||||
|
|
@ -342,6 +342,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
offset: CGPoint(x: 17.0, y: backgroundInset),
|
||||
media: media,
|
||||
webpage: webpage,
|
||||
fitToWidth: fitToWidth,
|
||||
opaqueBackground: true
|
||||
)
|
||||
let backgroundItem = InstantPageShapeItem(frame: CGRect(origin: CGPoint(), size: CGSize(width: boundingWidth, height: contentSize.height + backgroundInset * 2.0)), shapeFrame: CGRect(origin: CGPoint(), size: CGSize(width: boundingWidth, height: contentSize.height + backgroundInset * 2.0)), shape: .rect, color: theme.codeBlockBackgroundColor)
|
||||
|
|
@ -407,7 +408,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
} else {
|
||||
value = "\(i + 1)."
|
||||
}
|
||||
let (textItem, _, _) = layoutTextItemWithString(attributedStringForRichText(.plain(value), styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint())
|
||||
let (textItem, _, _) = layoutTextItemWithString(attributedStringForRichText(.plain(value), styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, offset: CGPoint(), fitToWidth: fitToWidth)
|
||||
if let textItem = textItem, let line = textItem.lines.first {
|
||||
textItem.selectable = false
|
||||
maxIndexWidth = max(maxIndexWidth, line.frame.width)
|
||||
|
|
@ -420,8 +421,12 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
}
|
||||
let indexSpacing: CGFloat = ordered ? (hasTaskMarkers ? 16.0 : 12.0) : (hasTaskMarkers ? 24.0 : 20.0)
|
||||
for (i, item) in contentItems.enumerated() {
|
||||
if (i != 0) {
|
||||
contentSize.height += 18.0
|
||||
if i != 0 {
|
||||
if fitToWidth {
|
||||
contentSize.height += 12.0
|
||||
} else {
|
||||
contentSize.height += 18.0
|
||||
}
|
||||
}
|
||||
let styleStack = InstantPageTextStyleStack()
|
||||
setupStyleStack(styleStack, theme: theme, category: .paragraph, link: false)
|
||||
|
|
@ -432,7 +437,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
}
|
||||
switch effectiveItem {
|
||||
case let .text(text, _):
|
||||
let (textItem, textItems, textItemSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0 - indexSpacing - maxIndexWidth, offset: CGPoint(x: horizontalInset + indexSpacing + maxIndexWidth, y: contentSize.height), media: media, webpage: webpage)
|
||||
let (textItem, textItems, textItemSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0 - indexSpacing - maxIndexWidth, offset: CGPoint(x: horizontalInset + indexSpacing + maxIndexWidth, y: contentSize.height), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
|
||||
contentSize.height += textItemSize.height
|
||||
let indexItem = indexItems[i]
|
||||
|
|
@ -467,9 +472,9 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
var firstBlockLineMidY: CGFloat?
|
||||
for i in 0 ..< blocks.count {
|
||||
let subBlock = blocks[i]
|
||||
let subLayout = layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: subBlock, boundingWidth: boundingWidth - horizontalInset * 2.0 - indexSpacing - maxIndexWidth, horizontalInset: 0.0, safeInset: 0.0, isCover: false, previousItems: listItems, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: i == blocks.count - 1)
|
||||
let subLayout = layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: subBlock, boundingWidth: boundingWidth - horizontalInset * 2.0 - indexSpacing - maxIndexWidth, horizontalInset: 0.0, safeInset: 0.0, isCover: false, previousItems: listItems, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: i == blocks.count - 1, fitToWidth: fitToWidth)
|
||||
|
||||
let spacing: CGFloat = previousBlock != nil && subLayout.contentSize.height > 0.0 ? spacingBetweenBlocks(upper: previousBlock, lower: subBlock) : 0.0
|
||||
let spacing: CGFloat = previousBlock != nil && subLayout.contentSize.height > 0.0 ? spacingBetweenBlocks(upper: previousBlock, lower: subBlock, fitToWidth: fitToWidth) : 0.0
|
||||
let blockItems = subLayout.flattenedItemsWithOrigin(CGPoint(x: horizontalInset + indexSpacing + maxIndexWidth, y: contentSize.height + spacing))
|
||||
if previousBlock == nil {
|
||||
originY += spacing
|
||||
|
|
@ -520,7 +525,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
setupStyleStack(styleStack, theme: theme, category: .paragraph, link: false)
|
||||
styleStack.push(.italic)
|
||||
|
||||
let (_, textItems, textContentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0 - lineInset, offset: CGPoint(x: horizontalInset + lineInset, y: contentSize.height), media: media, webpage: webpage)
|
||||
let (_, textItems, textContentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0 - lineInset, offset: CGPoint(x: horizontalInset + lineInset, y: contentSize.height), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
|
||||
contentSize.height += textContentSize.height
|
||||
items.append(contentsOf: textItems)
|
||||
|
|
@ -554,7 +559,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
setupStyleStack(styleStack, theme: theme, category: .paragraph, link: false)
|
||||
styleStack.push(.italic)
|
||||
|
||||
let (_, textItems, textContentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, alignment: .center, offset: CGPoint(x: 0.0, y: contentSize.height), media: media, webpage: webpage)
|
||||
let (_, textItems, textContentSize) = layoutTextItemWithString(attributedStringForRichText(text, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0, alignment: .center, offset: CGPoint(x: 0.0, y: contentSize.height), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
for var item in textItems {
|
||||
item.frame = item.frame.offsetBy(dx: horizontalInset, dy: 0.0)
|
||||
}
|
||||
|
|
@ -684,7 +689,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
var i = 0
|
||||
for subItem in innerItems {
|
||||
let frame = mosaicLayout[i].0
|
||||
let subLayout = layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: subItem, boundingWidth: frame.width, horizontalInset: 0.0, safeInset: 0.0, isCover: false, previousItems: items, fillToSize: frame.size, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: true, isLast: false)
|
||||
let subLayout = layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: subItem, boundingWidth: frame.width, horizontalInset: 0.0, safeInset: 0.0, isCover: false, previousItems: items, fillToSize: frame.size, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: true, isLast: false, fitToWidth: false)
|
||||
items.append(contentsOf: subLayout.flattenedItemsWithOrigin(frame.origin))
|
||||
i += 1
|
||||
}
|
||||
|
|
@ -731,7 +736,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
setupStyleStack(styleStack, theme: theme, category: .paragraph, link: false)
|
||||
styleStack.push(.bold)
|
||||
|
||||
let (_, textItems, textContentSize) = layoutTextItemWithString(attributedStringForRichText(.plain(author), styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0 - lineInset - avatarInset, offset: CGPoint(x: horizontalInset + lineInset + avatarInset, y: contentSize.height + avatarVerticalInset), media: media, webpage: webpage)
|
||||
let (_, textItems, textContentSize) = layoutTextItemWithString(attributedStringForRichText(.plain(author), styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0 - lineInset - avatarInset, offset: CGPoint(x: horizontalInset + lineInset + avatarInset, y: contentSize.height + avatarVerticalInset), media: media, webpage: webpage, fitToWidth: fitToWidth)
|
||||
items.append(contentsOf: textItems)
|
||||
|
||||
contentSize.height += textContentSize.height + avatarVerticalInset
|
||||
|
|
@ -759,9 +764,9 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
var previousBlock: InstantPageBlock?
|
||||
for i in 0 ..< blocks.count {
|
||||
let subBlock = blocks[i]
|
||||
let subLayout = layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: subBlock, boundingWidth: boundingWidth - horizontalInset * 2.0 - lineInset, horizontalInset: 0.0, safeInset: 0.0, isCover: false, previousItems: items, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: i == blocks.count - 1)
|
||||
let subLayout = layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: subBlock, boundingWidth: boundingWidth - horizontalInset * 2.0 - lineInset, horizontalInset: 0.0, safeInset: 0.0, isCover: false, previousItems: items, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: i == blocks.count - 1, fitToWidth: fitToWidth)
|
||||
|
||||
let spacing = spacingBetweenBlocks(upper: previousBlock, lower: subBlock)
|
||||
let spacing = spacingBetweenBlocks(upper: previousBlock, lower: subBlock, fitToWidth: false)
|
||||
let blockItems = subLayout.flattenedItemsWithOrigin(CGPoint(x: horizontalInset + lineInset, y: contentSize.height + spacing))
|
||||
items.append(contentsOf: blockItems)
|
||||
contentSize.height += subLayout.contentSize.height + spacing
|
||||
|
|
@ -943,9 +948,9 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
var previousBlock: InstantPageBlock?
|
||||
for i in 0 ..< blocks.count {
|
||||
let subBlock = blocks[i]
|
||||
let subLayout = layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: subBlock, boundingWidth: boundingWidth, horizontalInset: horizontalInset, safeInset: safeInset, isCover: false, previousItems: subitems, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &subDetailsIndex, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: i == blocks.count - 1)
|
||||
let subLayout = layoutInstantPageBlock(webpage: webpage, userLocation: userLocation, rtl: rtl, block: subBlock, boundingWidth: boundingWidth, horizontalInset: horizontalInset, safeInset: safeInset, isCover: false, previousItems: subitems, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &subDetailsIndex, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: i == blocks.count - 1, fitToWidth: fitToWidth)
|
||||
|
||||
let spacing = spacingBetweenBlocks(upper: previousBlock, lower: subBlock)
|
||||
let spacing = spacingBetweenBlocks(upper: previousBlock, lower: subBlock, fitToWidth: false)
|
||||
let blockItems = subLayout.flattenedItemsWithOrigin(CGPoint(x: 0.0, y: contentSize.height + spacing))
|
||||
subitems.append(contentsOf: blockItems)
|
||||
contentSize.height += subLayout.contentSize.height + spacing
|
||||
|
|
@ -953,7 +958,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
}
|
||||
|
||||
if !blocks.isEmpty {
|
||||
let closingSpacing = spacingBetweenBlocks(upper: previousBlock, lower: nil)
|
||||
let closingSpacing = spacingBetweenBlocks(upper: previousBlock, lower: nil, fitToWidth: false)
|
||||
contentSize.height += closingSpacing
|
||||
}
|
||||
|
||||
|
|
@ -971,7 +976,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
setupStyleStack(styleStack, theme: theme, category: .paragraph, link: false)
|
||||
styleStack.push(.bold)
|
||||
let backgroundInset: CGFloat = 14.0
|
||||
let (_, textItems, textContentSize) = layoutTextItemWithString(attributedStringForRichText(title, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0 - backgroundInset * 2.0, offset: CGPoint(x: horizontalInset, y: backgroundInset), media: media, webpage: webpage, opaqueBackground: true)
|
||||
let (_, textItems, textContentSize) = layoutTextItemWithString(attributedStringForRichText(title, styleStack: styleStack), boundingWidth: boundingWidth - horizontalInset * 2.0 - backgroundInset * 2.0, offset: CGPoint(x: horizontalInset, y: backgroundInset), media: media, webpage: webpage, fitToWidth: fitToWidth, opaqueBackground: true)
|
||||
let backgroundItem = InstantPageShapeItem(frame: CGRect(origin: CGPoint(), size: CGSize(width: boundingWidth, height: textContentSize.height + backgroundInset * 2.0)), shapeFrame: CGRect(origin: CGPoint(), size: CGSize(width: boundingWidth, height: textContentSize.height + backgroundInset * 2.0)), shape: .rect, color: theme.panelBackgroundColor)
|
||||
items.append(backgroundItem)
|
||||
items.append(contentsOf: textItems)
|
||||
|
|
@ -1054,7 +1059,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
|||
}
|
||||
}
|
||||
|
||||
public func instantPageLayoutForWebPage(_ webPage: TelegramMediaWebpage, instantPage: InstantPage?, userLocation: MediaResourceUserLocation, boundingWidth: CGFloat, sideInset: CGFloat, safeInset: CGFloat, strings: PresentationStrings, theme: InstantPageTheme, dateTimeFormat: PresentationDateTimeFormat, webEmbedHeights: [Int : CGFloat] = [:], cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, addFeedback: Bool = true) -> InstantPageLayout {
|
||||
public func instantPageLayoutForWebPage(_ webPage: TelegramMediaWebpage, instantPage: InstantPage?, userLocation: MediaResourceUserLocation, boundingWidth: CGFloat, sideInset: CGFloat, safeInset: CGFloat, strings: PresentationStrings, theme: InstantPageTheme, dateTimeFormat: PresentationDateTimeFormat, webEmbedHeights: [Int : CGFloat] = [:], cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, addFeedback: Bool = true, fitToWidth: Bool = false) -> InstantPageLayout {
|
||||
var maybeLoadedContent: TelegramMediaWebpageLoadedContent?
|
||||
if case let .Loaded(content) = webPage.content {
|
||||
maybeLoadedContent = content
|
||||
|
|
@ -1084,8 +1089,8 @@ public func instantPageLayoutForWebPage(_ webPage: TelegramMediaWebpage, instant
|
|||
var previousBlock: InstantPageBlock?
|
||||
for i in 0 ..< pageBlocks.count {
|
||||
let block = pageBlocks[i]
|
||||
let blockLayout = layoutInstantPageBlock(webpage: webPage, userLocation: userLocation, rtl: rtl, block: block, boundingWidth: boundingWidth, horizontalInset: sideInset + safeInset, safeInset: safeInset, isCover: false, previousItems: items, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: i == pageBlocks.count - 1)
|
||||
let spacing = spacingBetweenBlocks(upper: previousBlock, lower: block)
|
||||
let blockLayout = layoutInstantPageBlock(webpage: webPage, userLocation: userLocation, rtl: rtl, block: block, boundingWidth: boundingWidth, horizontalInset: sideInset + safeInset, safeInset: safeInset, isCover: false, previousItems: items, fillToSize: nil, media: media, mediaIndexCounter: &mediaIndexCounter, embedIndexCounter: &embedIndexCounter, detailsIndexCounter: &detailsIndexCounter, theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, webEmbedHeights: webEmbedHeights, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight, excludeCaptions: false, isLast: i == pageBlocks.count - 1, fitToWidth: fitToWidth)
|
||||
let spacing = spacingBetweenBlocks(upper: previousBlock, lower: block, fitToWidth: fitToWidth)
|
||||
let blockItems = blockLayout.flattenedItemsWithOrigin(CGPoint(x: 0.0, y: contentSize.height + spacing))
|
||||
items.append(contentsOf: blockItems)
|
||||
if CGFloat(0.0).isLess(than: blockLayout.contentSize.height) {
|
||||
|
|
@ -1094,7 +1099,7 @@ public func instantPageLayoutForWebPage(_ webPage: TelegramMediaWebpage, instant
|
|||
}
|
||||
}
|
||||
|
||||
let closingSpacing = spacingBetweenBlocks(upper: previousBlock, lower: nil)
|
||||
let closingSpacing = spacingBetweenBlocks(upper: previousBlock, lower: nil, fitToWidth: fitToWidth)
|
||||
contentSize.height += closingSpacing
|
||||
|
||||
if webPage.webpageId.id != 0 && addFeedback {
|
||||
|
|
@ -1103,5 +1108,13 @@ public func instantPageLayoutForWebPage(_ webPage: TelegramMediaWebpage, instant
|
|||
items.append(feedbackItem)
|
||||
}
|
||||
|
||||
if fitToWidth {
|
||||
contentSize.width = 0.0
|
||||
for item in items {
|
||||
contentSize.width = max(contentSize.width, ceil(item.frame.maxX) + sideInset)
|
||||
}
|
||||
contentSize.width = min(contentSize.width, boundingWidth)
|
||||
}
|
||||
|
||||
return InstantPageLayout(origin: CGPoint(), contentSize: contentSize, items: items)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,82 +2,114 @@ import Foundation
|
|||
import UIKit
|
||||
import TelegramCore
|
||||
|
||||
func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?) -> CGFloat {
|
||||
if let upper = upper, let lower = lower {
|
||||
func spacingBetweenBlocks(upper: InstantPageBlock?, lower: InstantPageBlock?, fitToWidth: Bool) -> CGFloat {
|
||||
if let upper, let lower {
|
||||
switch (upper, lower) {
|
||||
case (_, .cover), (_, .channelBanner), (.details, .details), (.relatedArticles, _), (_, .anchor):
|
||||
return 0.0
|
||||
case (.divider, _), (_, .divider):
|
||||
case (_, .cover), (_, .channelBanner), (.details, .details), (.relatedArticles, _), (_, .anchor):
|
||||
return 0.0
|
||||
case (.divider, _), (_, .divider):
|
||||
if fitToWidth {
|
||||
return 10.0
|
||||
} else {
|
||||
return 25.0
|
||||
case (_, .blockQuote), (.blockQuote, _), (_, .pullQuote), (.pullQuote, _):
|
||||
return 27.0
|
||||
case (.kicker, .title), (.cover, .title):
|
||||
return 16.0
|
||||
case (_, .title):
|
||||
return 20.0
|
||||
case (.title, .authorDate), (.subtitle, .authorDate):
|
||||
return 18.0
|
||||
case (_, .authorDate):
|
||||
return 20.0
|
||||
case (.title, .paragraph), (.authorDate, .paragraph):
|
||||
return 34.0
|
||||
case (.header, .paragraph), (.subheader, .paragraph), (.heading, .paragraph):
|
||||
}
|
||||
case (_, .blockQuote), (.blockQuote, _), (_, .pullQuote), (.pullQuote, _):
|
||||
return 27.0
|
||||
case (.kicker, .title), (.cover, .title):
|
||||
return 16.0
|
||||
case (_, .title):
|
||||
return 20.0
|
||||
case (.title, .authorDate), (.subtitle, .authorDate):
|
||||
return 18.0
|
||||
case (_, .authorDate):
|
||||
return 20.0
|
||||
case (.title, .paragraph), (.authorDate, .paragraph):
|
||||
return 34.0
|
||||
case (.header, .paragraph), (.subheader, .paragraph), (.heading, .paragraph):
|
||||
if fitToWidth {
|
||||
return 10.0
|
||||
} else {
|
||||
return 25.0
|
||||
case (.list, .paragraph):
|
||||
return 31.0
|
||||
case (.preformatted, .paragraph):
|
||||
return 19.0
|
||||
case (.formula, .paragraph):
|
||||
return 19.0
|
||||
case (.paragraph, .paragraph):
|
||||
}
|
||||
case (.list, .paragraph):
|
||||
return 31.0
|
||||
case (.preformatted, .paragraph):
|
||||
return 19.0
|
||||
case (.formula, .paragraph):
|
||||
return 19.0
|
||||
case (.paragraph, .paragraph):
|
||||
if fitToWidth {
|
||||
return 10.0
|
||||
} else {
|
||||
return 25.0
|
||||
case (_, .paragraph):
|
||||
return 20.0
|
||||
case (.title, .formula), (.authorDate, .formula):
|
||||
return 34.0
|
||||
case (.header, .formula), (.subheader, .formula), (.heading, .formula):
|
||||
}
|
||||
case (_, .paragraph):
|
||||
return 20.0
|
||||
case (.title, .formula), (.authorDate, .formula):
|
||||
return 34.0
|
||||
case (.header, .formula), (.subheader, .formula), (.heading, .formula):
|
||||
if fitToWidth {
|
||||
return 10.0
|
||||
} else {
|
||||
return 25.0
|
||||
case (.list, .formula):
|
||||
return 31.0
|
||||
case (.preformatted, .formula):
|
||||
return 19.0
|
||||
case (.paragraph, .formula):
|
||||
return 19.0
|
||||
case (_, .formula):
|
||||
return 20.0
|
||||
case (.title, .list), (.authorDate, .list):
|
||||
return 34.0
|
||||
case (.header, .list), (.subheader, .list), (.heading, .list):
|
||||
return 31.0
|
||||
case (.preformatted, .list):
|
||||
return 19.0
|
||||
case (.formula, .list):
|
||||
}
|
||||
case (.list, .formula):
|
||||
return 31.0
|
||||
case (.preformatted, .formula):
|
||||
return 19.0
|
||||
case (.paragraph, .formula):
|
||||
return 19.0
|
||||
case (_, .formula):
|
||||
return 20.0
|
||||
case (.title, .list), (.authorDate, .list):
|
||||
return 34.0
|
||||
case (.header, .list), (.subheader, .list), (.heading, .list):
|
||||
return 31.0
|
||||
case (.preformatted, .list):
|
||||
return 19.0
|
||||
case (.formula, .list):
|
||||
if fitToWidth {
|
||||
return 10.0
|
||||
} else {
|
||||
return 25.0
|
||||
case (_, .list):
|
||||
}
|
||||
case (_, .list):
|
||||
if fitToWidth {
|
||||
return 10.0
|
||||
} 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:
|
||||
return 20.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:
|
||||
return 20.0
|
||||
}
|
||||
} else if let lower = lower {
|
||||
} else if let lower {
|
||||
switch lower {
|
||||
case .cover, .channelBanner, .details, .anchor:
|
||||
return 0.0
|
||||
default:
|
||||
case .cover, .channelBanner, .details, .anchor:
|
||||
return 0.0
|
||||
default:
|
||||
if fitToWidth {
|
||||
return 10.0
|
||||
} else {
|
||||
return 25.0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let upper = upper, case .relatedArticles = upper {
|
||||
return 0.0
|
||||
} else {
|
||||
return 25.0
|
||||
if fitToWidth {
|
||||
return 10.0
|
||||
} else {
|
||||
return 25.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -820,7 +820,7 @@ func attributedStringForRichText(_ text: RichText, styleStack: InstantPageTextSt
|
|||
}
|
||||
}
|
||||
|
||||
func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFloat, horizontalInset: CGFloat = 0.0, alignment: NSTextAlignment = .natural, offset: CGPoint, media: [EngineMedia.Id: EngineMedia] = [:], webpage: TelegramMediaWebpage? = nil, minimizeWidth: Bool = false, maxNumberOfLines: Int = 0, opaqueBackground: Bool = false) -> (InstantPageTextItem?, [InstantPageItem], CGSize) {
|
||||
func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFloat, horizontalInset: CGFloat = 0.0, alignment: NSTextAlignment = .natural, offset: CGPoint, media: [EngineMedia.Id: EngineMedia] = [:], webpage: TelegramMediaWebpage? = nil, minimizeWidth: Bool = false, fitToWidth: Bool = false, maxNumberOfLines: Int = 0, opaqueBackground: Bool = false) -> (InstantPageTextItem?, [InstantPageItem], CGSize) {
|
||||
if string.length == 0 {
|
||||
return (nil, [], CGSize())
|
||||
}
|
||||
|
|
@ -1091,6 +1091,9 @@ func layoutTextItemWithString(_ string: NSAttributedString, boundingWidth: CGFlo
|
|||
}
|
||||
|
||||
var textWidth = boundingWidth
|
||||
if fitToWidth {
|
||||
textWidth = maxLineWidth
|
||||
}
|
||||
var requiresScroll = false
|
||||
if (!imageItems.isEmpty || !formulaItems.isEmpty) && maxLineWidth > boundingWidth + 10.0 {
|
||||
textWidth = maxLineWidth
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1605510357] = { return Api.ChatAdminRights.parse_chatAdminRights($0) }
|
||||
dict[-219353309] = { return Api.ChatAdminWithInvites.parse_chatAdminWithInvites($0) }
|
||||
dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) }
|
||||
dict[-455036259] = { return Api.ChatFull.parse_channelFull($0) }
|
||||
dict[-1605464774] = { return Api.ChatFull.parse_channelFull($0) }
|
||||
dict[640893467] = { return Api.ChatFull.parse_chatFull($0) }
|
||||
dict[1553807106] = { return Api.ChatInvite.parse_chatInvite($0) }
|
||||
dict[1516793212] = { return Api.ChatInvite.parse_chatInviteAlready($0) }
|
||||
|
|
@ -232,7 +232,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[878246344] = { return Api.ChatTheme.parse_chatThemeUniqueGift($0) }
|
||||
dict[-1390068360] = { return Api.CodeSettings.parse_codeSettings($0) }
|
||||
dict[-870702050] = { return Api.Config.parse_config($0) }
|
||||
dict[-849058964] = { return Api.ConnectedBot.parse_connectedBot($0) }
|
||||
dict[54448129] = { return Api.ConnectedBot.parse_connectedBot($0) }
|
||||
dict[429997937] = { return Api.ConnectedBotStarRef.parse_connectedBotStarRef($0) }
|
||||
dict[341499403] = { return Api.Contact.parse_contact($0) }
|
||||
dict[496600883] = { return Api.ContactBirthday.parse_contactBirthday($0) }
|
||||
|
|
@ -443,6 +443,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1548122514] = { return Api.InputNotifyPeer.parse_inputNotifyForumTopic($0) }
|
||||
dict[-1195615476] = { return Api.InputNotifyPeer.parse_inputNotifyPeer($0) }
|
||||
dict[423314455] = { return Api.InputNotifyPeer.parse_inputNotifyUsers($0) }
|
||||
dict[2105227266] = { return Api.InputPageListOrderedItem.parse_inputPageListOrderedItemBlocks($0) }
|
||||
dict[-1682665696] = { return Api.InputPageListOrderedItem.parse_inputPageListOrderedItemText($0) }
|
||||
dict[1528613672] = { return Api.InputPasskeyCredential.parse_inputPasskeyCredentialFirebasePNV($0) }
|
||||
dict[1009235855] = { return Api.InputPasskeyCredential.parse_inputPasskeyCredentialPublicKey($0) }
|
||||
dict[-1021329078] = { return Api.InputPasskeyResponse.parse_inputPasskeyResponseLogin($0) }
|
||||
|
|
@ -493,6 +495,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1003796418] = { return Api.InputReplyTo.parse_inputReplyToMessage($0) }
|
||||
dict[1775660101] = { return Api.InputReplyTo.parse_inputReplyToMonoForum($0) }
|
||||
dict[1484862010] = { return Api.InputReplyTo.parse_inputReplyToStory($0) }
|
||||
dict[-1865309654] = { return Api.InputRichMessage.parse_inputRichMessage($0) }
|
||||
dict[-251549057] = { return Api.InputSavedStarGift.parse_inputSavedStarGiftChat($0) }
|
||||
dict[545636920] = { return Api.InputSavedStarGift.parse_inputSavedStarGiftSlug($0) }
|
||||
dict[1764202389] = { return Api.InputSavedStarGift.parse_inputSavedStarGiftUser($0) }
|
||||
|
|
@ -548,6 +551,10 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[736157604] = { return Api.JSONValue.parse_jsonNumber($0) }
|
||||
dict[-1715350371] = { return Api.JSONValue.parse_jsonObject($0) }
|
||||
dict[-1222740358] = { return Api.JSONValue.parse_jsonString($0) }
|
||||
dict[-1374344599] = { return Api.JoinChatBotResult.parse_joinChatBotResultApproved($0) }
|
||||
dict[251265428] = { return Api.JoinChatBotResult.parse_joinChatBotResultDeclined($0) }
|
||||
dict[-1734105024] = { return Api.JoinChatBotResult.parse_joinChatBotResultQueued($0) }
|
||||
dict[-689719277] = { return Api.JoinChatBotResult.parse_joinChatBotResultWebView($0) }
|
||||
dict[45580630] = { return Api.KeyboardButton.parse_inputKeyboardButtonRequestPeer($0) }
|
||||
dict[1744911986] = { return Api.KeyboardButton.parse_inputKeyboardButtonUrlAuth($0) }
|
||||
dict[2103314375] = { return Api.KeyboardButton.parse_inputKeyboardButtonUserProfile($0) }
|
||||
|
|
@ -585,7 +592,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1098720356] = { return Api.MediaArea.parse_mediaAreaVenue($0) }
|
||||
dict[1235637404] = { return Api.MediaArea.parse_mediaAreaWeather($0) }
|
||||
dict[-808853502] = { return Api.MediaAreaCoordinates.parse_mediaAreaCoordinates($0) }
|
||||
dict[-1779470549] = { return Api.Message.parse_message($0) }
|
||||
dict[1979759059] = { return Api.Message.parse_message($0) }
|
||||
dict[-1868117372] = { return Api.Message.parse_messageEmpty($0) }
|
||||
dict[2055212554] = { return Api.Message.parse_messageService($0) }
|
||||
dict[-872240531] = { return Api.MessageAction.parse_messageActionBoostApply($0) }
|
||||
|
|
@ -746,6 +753,11 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1261946036] = { return Api.NotifyPeer.parse_notifyUsers($0) }
|
||||
dict[1001931436] = { return Api.OutboxReadDate.parse_outboxReadDate($0) }
|
||||
dict[-1738178803] = { return Api.Page.parse_page($0) }
|
||||
dict[-1715334046] = { return Api.PageBlock.parse_inputPageBlockAudio($0) }
|
||||
dict[1464557951] = { return Api.PageBlock.parse_inputPageBlockMap($0) }
|
||||
dict[-1186155733] = { return Api.PageBlock.parse_inputPageBlockOrderedList($0) }
|
||||
dict[719646565] = { return Api.PageBlock.parse_inputPageBlockPhoto($0) }
|
||||
dict[-249943466] = { return Api.PageBlock.parse_inputPageBlockVideo($0) }
|
||||
dict[-837994576] = { return Api.PageBlock.parse_pageBlockAnchor($0) }
|
||||
dict[-2143067670] = { return Api.PageBlock.parse_pageBlockAudio($0) }
|
||||
dict[-1162877472] = { return Api.PageBlock.parse_pageBlockAuthorDate($0) }
|
||||
|
|
@ -759,9 +771,16 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-229005301] = { return Api.PageBlock.parse_pageBlockEmbedPost($0) }
|
||||
dict[1216809369] = { return Api.PageBlock.parse_pageBlockFooter($0) }
|
||||
dict[-1076861716] = { return Api.PageBlock.parse_pageBlockHeader($0) }
|
||||
dict[-1157691601] = { return Api.PageBlock.parse_pageBlockHeading1($0) }
|
||||
dict[158018284] = { return Api.PageBlock.parse_pageBlockHeading2($0) }
|
||||
dict[1743204781] = { return Api.PageBlock.parse_pageBlockHeading3($0) }
|
||||
dict[-1254983893] = { return Api.PageBlock.parse_pageBlockHeading4($0) }
|
||||
dict[-608277398] = { return Api.PageBlock.parse_pageBlockHeading5($0) }
|
||||
dict[1747599785] = { return Api.PageBlock.parse_pageBlockHeading6($0) }
|
||||
dict[504660880] = { return Api.PageBlock.parse_pageBlockKicker($0) }
|
||||
dict[-454524911] = { return Api.PageBlock.parse_pageBlockList($0) }
|
||||
dict[-1538310410] = { return Api.PageBlock.parse_pageBlockMap($0) }
|
||||
dict[1493699616] = { return Api.PageBlock.parse_pageBlockMath($0) }
|
||||
dict[-1702174239] = { return Api.PageBlock.parse_pageBlockOrderedList($0) }
|
||||
dict[1182402406] = { return Api.PageBlock.parse_pageBlockParagraph($0) }
|
||||
dict[391759200] = { return Api.PageBlock.parse_pageBlockPhoto($0) }
|
||||
|
|
@ -776,10 +795,10 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[324435594] = { return Api.PageBlock.parse_pageBlockUnsupported($0) }
|
||||
dict[2089805750] = { return Api.PageBlock.parse_pageBlockVideo($0) }
|
||||
dict[1869903447] = { return Api.PageCaption.parse_pageCaption($0) }
|
||||
dict[635466748] = { return Api.PageListItem.parse_pageListItemBlocks($0) }
|
||||
dict[-1188055347] = { return Api.PageListItem.parse_pageListItemText($0) }
|
||||
dict[-1730311882] = { return Api.PageListOrderedItem.parse_pageListOrderedItemBlocks($0) }
|
||||
dict[1577484359] = { return Api.PageListOrderedItem.parse_pageListOrderedItemText($0) }
|
||||
dict[1674209194] = { return Api.PageListItem.parse_pageListItemBlocks($0) }
|
||||
dict[794323004] = { return Api.PageListItem.parse_pageListItemText($0) }
|
||||
dict[1109995988] = { return Api.PageListOrderedItem.parse_pageListOrderedItemBlocks($0) }
|
||||
dict[-851533770] = { return Api.PageListOrderedItem.parse_pageListOrderedItemText($0) }
|
||||
dict[-1282352120] = { return Api.PageRelatedArticle.parse_pageRelatedArticle($0) }
|
||||
dict[878078826] = { return Api.PageTableCell.parse_pageTableCell($0) }
|
||||
dict[-524237339] = { return Api.PageTableRow.parse_pageTableRow($0) }
|
||||
|
|
@ -922,15 +941,19 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1258914157] = { return Api.RequirementToContact.parse_requirementToContactPaidMessages($0) }
|
||||
dict[-444472087] = { return Api.RequirementToContact.parse_requirementToContactPremium($0) }
|
||||
dict[-797791052] = { return Api.RestrictionReason.parse_restrictionReason($0) }
|
||||
dict[-1158439541] = { return Api.RichMessage.parse_richMessage($0) }
|
||||
dict[764156522] = { return Api.RichText.parse_inputTextImage($0) }
|
||||
dict[894777186] = { return Api.RichText.parse_textAnchor($0) }
|
||||
dict[1730456516] = { return Api.RichText.parse_textBold($0) }
|
||||
dict[2120376535] = { return Api.RichText.parse_textConcat($0) }
|
||||
dict[-1570679104] = { return Api.RichText.parse_textCustomEmoji($0) }
|
||||
dict[-564523562] = { return Api.RichText.parse_textEmail($0) }
|
||||
dict[-599948721] = { return Api.RichText.parse_textEmpty($0) }
|
||||
dict[1816074681] = { return Api.RichText.parse_textFixed($0) }
|
||||
dict[136105807] = { return Api.RichText.parse_textImage($0) }
|
||||
dict[-653089380] = { return Api.RichText.parse_textItalic($0) }
|
||||
dict[55281185] = { return Api.RichText.parse_textMarked($0) }
|
||||
dict[-1657885545] = { return Api.RichText.parse_textMath($0) }
|
||||
dict[483104362] = { return Api.RichText.parse_textPhone($0) }
|
||||
dict[1950782688] = { return Api.RichText.parse_textPlain($0) }
|
||||
dict[-1678197867] = { return Api.RichText.parse_textStrike($0) }
|
||||
|
|
@ -1109,7 +1132,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1964652166] = { return Api.Update.parse_updateBotBusinessConnect($0) }
|
||||
dict[-1177566067] = { return Api.Update.parse_updateBotCallbackQuery($0) }
|
||||
dict[-1873947492] = { return Api.Update.parse_updateBotChatBoost($0) }
|
||||
dict[299870598] = { return Api.Update.parse_updateBotChatInviteRequester($0) }
|
||||
dict[2092125561] = { return Api.Update.parse_updateBotChatInviteRequester($0) }
|
||||
dict[1299263278] = { return Api.Update.parse_updateBotCommands($0) }
|
||||
dict[-1607821266] = { return Api.Update.parse_updateBotDeleteBusinessMessage($0) }
|
||||
dict[132077692] = { return Api.Update.parse_updateBotEditBusinessMessage($0) }
|
||||
|
|
@ -1177,6 +1200,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-667783411] = { return Api.Update.parse_updateGroupCallMessage($0) }
|
||||
dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
|
||||
dict[1763610706] = { return Api.Update.parse_updateInlineBotCallbackQuery($0) }
|
||||
dict[-1112768912] = { return Api.Update.parse_updateJoinChatWebViewDecision($0) }
|
||||
dict[1442983757] = { return Api.Update.parse_updateLangPack($0) }
|
||||
dict[1180041828] = { return Api.Update.parse_updateLangPackTooLong($0) }
|
||||
dict[1448076945] = { return Api.Update.parse_updateLoginToken($0) }
|
||||
|
|
@ -1189,6 +1213,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1618924792] = { return Api.Update.parse_updateMonoForumNoPaidException($0) }
|
||||
dict[-2030252155] = { return Api.Update.parse_updateMoveStickerSetToTop($0) }
|
||||
dict[-1991136273] = { return Api.Update.parse_updateNewAuthorization($0) }
|
||||
dict[-1306491994] = { return Api.Update.parse_updateNewBotConnection($0) }
|
||||
dict[1656358105] = { return Api.Update.parse_updateNewChannelMessage($0) }
|
||||
dict[314359194] = { return Api.Update.parse_updateNewEncryptedMessage($0) }
|
||||
dict[522914557] = { return Api.Update.parse_updateNewMessage($0) }
|
||||
|
|
@ -1257,6 +1282,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[88680979] = { return Api.Update.parse_updateUserPhone($0) }
|
||||
dict[-440534818] = { return Api.Update.parse_updateUserStatus($0) }
|
||||
dict[706199388] = { return Api.Update.parse_updateUserTyping($0) }
|
||||
dict[335872721] = { return Api.Update.parse_updateWebBrowserException($0) }
|
||||
dict[-1013306658] = { return Api.Update.parse_updateWebBrowserSettings($0) }
|
||||
dict[2139689491] = { return Api.Update.parse_updateWebPage($0) }
|
||||
dict[361936797] = { return Api.Update.parse_updateWebViewResultSent($0) }
|
||||
dict[2027216577] = { return Api.Updates.parse_updateShort($0) }
|
||||
|
|
@ -1290,6 +1317,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1493633966] = { return Api.WebAuthorization.parse_webAuthorization($0) }
|
||||
dict[475467473] = { return Api.WebDocument.parse_webDocument($0) }
|
||||
dict[-104284986] = { return Api.WebDocument.parse_webDocumentNoProxy($0) }
|
||||
dict[-1824741993] = { return Api.WebDomainException.parse_webDomainException($0) }
|
||||
dict[-392411726] = { return Api.WebPage.parse_webPage($0) }
|
||||
dict[555358088] = { return Api.WebPage.parse_webPageEmpty($0) }
|
||||
dict[1930545681] = { return Api.WebPage.parse_webPageNotModified($0) }
|
||||
|
|
@ -1341,6 +1369,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-842824308] = { return Api.account.WallPapers.parse_wallPapers($0) }
|
||||
dict[471437699] = { return Api.account.WallPapers.parse_wallPapersNotModified($0) }
|
||||
dict[-313079300] = { return Api.account.WebAuthorizations.parse_webAuthorizations($0) }
|
||||
dict[2045480115] = { return Api.account.WebBrowserSettings.parse_webBrowserSettings($0) }
|
||||
dict[-1021538482] = { return Api.account.WebBrowserSettings.parse_webBrowserSettingsNotModified($0) }
|
||||
dict[1822232318] = { return Api.aicompose.Tones.parse_tones($0) }
|
||||
dict[-1040948989] = { return Api.aicompose.Tones.parse_tonesNotModified($0) }
|
||||
dict[782418132] = { return Api.auth.Authorization.parse_authorization($0) }
|
||||
|
|
@ -1452,6 +1482,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1231326505] = { return Api.messages.ChatAdminsWithInvites.parse_chatAdminsWithInvites($0) }
|
||||
dict[-438840932] = { return Api.messages.ChatFull.parse_chatFull($0) }
|
||||
dict[-2118733814] = { return Api.messages.ChatInviteImporters.parse_chatInviteImporters($0) }
|
||||
dict[1146512295] = { return Api.messages.ChatInviteJoinResult.parse_chatInviteJoinResultOk($0) }
|
||||
dict[2001452532] = { return Api.messages.ChatInviteJoinResult.parse_chatInviteJoinResultWebView($0) }
|
||||
dict[1694474197] = { return Api.messages.Chats.parse_chats($0) }
|
||||
dict[-1663561404] = { return Api.messages.Chats.parse_chatsSlice($0) }
|
||||
dict[-1571952873] = { return Api.messages.CheckedHistoryImportPeer.parse_checkedHistoryImportPeer($0) }
|
||||
|
|
@ -1998,6 +2030,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputNotifyPeer:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputPageListOrderedItem:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputPasskeyCredential:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputPasskeyResponse:
|
||||
|
|
@ -2020,6 +2054,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputReplyTo:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputRichMessage:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputSavedStarGift:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputSecureFile:
|
||||
|
|
@ -2058,6 +2094,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.JSONValue:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.JoinChatBotResult:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.KeyboardButton:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.KeyboardButtonRow:
|
||||
|
|
@ -2240,6 +2278,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.RestrictionReason:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.RichMessage:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.RichText:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.SavedContact:
|
||||
|
|
@ -2428,6 +2468,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.WebDocument:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.WebDomainException:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.WebPage:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.WebPageAttribute:
|
||||
|
|
@ -2492,6 +2534,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.WebAuthorizations:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.WebBrowserSettings:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.aicompose.Tones:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.auth.Authorization:
|
||||
|
|
@ -2628,6 +2672,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.ChatInviteImporters:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.ChatInviteJoinResult:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.Chats:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.CheckedHistoryImportPeer:
|
||||
|
|
|
|||
|
|
@ -1451,85 +1451,131 @@ public extension Api {
|
|||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum InputPasskeyCredential: TypeConstructorDescription {
|
||||
public class Cons_inputPasskeyCredentialFirebasePNV: TypeConstructorDescription {
|
||||
public var pnvToken: String
|
||||
public init(pnvToken: String) {
|
||||
self.pnvToken = pnvToken
|
||||
indirect enum InputPageListOrderedItem: TypeConstructorDescription {
|
||||
public class Cons_inputPageListOrderedItemBlocks: TypeConstructorDescription {
|
||||
public var flags: Int32
|
||||
public var blocks: [Api.PageBlock]
|
||||
public var value: Int32?
|
||||
public var type: String?
|
||||
public init(flags: Int32, blocks: [Api.PageBlock], value: Int32?, type: String?) {
|
||||
self.flags = flags
|
||||
self.blocks = blocks
|
||||
self.value = value
|
||||
self.type = type
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("inputPasskeyCredentialFirebasePNV", [("pnvToken", ConstructorParameterDescription(self.pnvToken))])
|
||||
return ("inputPageListOrderedItemBlocks", [("flags", ConstructorParameterDescription(self.flags)), ("blocks", ConstructorParameterDescription(self.blocks)), ("value", ConstructorParameterDescription(self.value)), ("type", ConstructorParameterDescription(self.type))])
|
||||
}
|
||||
}
|
||||
public class Cons_inputPasskeyCredentialPublicKey: TypeConstructorDescription {
|
||||
public var id: String
|
||||
public var rawId: String
|
||||
public var response: Api.InputPasskeyResponse
|
||||
public init(id: String, rawId: String, response: Api.InputPasskeyResponse) {
|
||||
self.id = id
|
||||
self.rawId = rawId
|
||||
self.response = response
|
||||
public class Cons_inputPageListOrderedItemText: TypeConstructorDescription {
|
||||
public var flags: Int32
|
||||
public var text: Api.RichText
|
||||
public var value: Int32?
|
||||
public var type: String?
|
||||
public init(flags: Int32, text: Api.RichText, value: Int32?, type: String?) {
|
||||
self.flags = flags
|
||||
self.text = text
|
||||
self.value = value
|
||||
self.type = type
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("inputPasskeyCredentialPublicKey", [("id", ConstructorParameterDescription(self.id)), ("rawId", ConstructorParameterDescription(self.rawId)), ("response", ConstructorParameterDescription(self.response))])
|
||||
return ("inputPageListOrderedItemText", [("flags", ConstructorParameterDescription(self.flags)), ("text", ConstructorParameterDescription(self.text)), ("value", ConstructorParameterDescription(self.value)), ("type", ConstructorParameterDescription(self.type))])
|
||||
}
|
||||
}
|
||||
case inputPasskeyCredentialFirebasePNV(Cons_inputPasskeyCredentialFirebasePNV)
|
||||
case inputPasskeyCredentialPublicKey(Cons_inputPasskeyCredentialPublicKey)
|
||||
case inputPageListOrderedItemBlocks(Cons_inputPageListOrderedItemBlocks)
|
||||
case inputPageListOrderedItemText(Cons_inputPageListOrderedItemText)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .inputPasskeyCredentialFirebasePNV(let _data):
|
||||
case .inputPageListOrderedItemBlocks(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(1528613672)
|
||||
buffer.appendInt32(2105227266)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(_data.blocks.count))
|
||||
for item in _data.blocks {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(_data.flags) & Int(1 << 2) != 0 {
|
||||
serializeInt32(_data.value!, buffer: buffer, boxed: false)
|
||||
}
|
||||
if Int(_data.flags) & Int(1 << 3) != 0 {
|
||||
serializeString(_data.type!, buffer: buffer, boxed: false)
|
||||
}
|
||||
serializeString(_data.pnvToken, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .inputPasskeyCredentialPublicKey(let _data):
|
||||
case .inputPageListOrderedItemText(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(1009235855)
|
||||
buffer.appendInt32(-1682665696)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
_data.text.serialize(buffer, true)
|
||||
if Int(_data.flags) & Int(1 << 2) != 0 {
|
||||
serializeInt32(_data.value!, buffer: buffer, boxed: false)
|
||||
}
|
||||
if Int(_data.flags) & Int(1 << 3) != 0 {
|
||||
serializeString(_data.type!, buffer: buffer, boxed: false)
|
||||
}
|
||||
serializeString(_data.id, buffer: buffer, boxed: false)
|
||||
serializeString(_data.rawId, buffer: buffer, boxed: false)
|
||||
_data.response.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
switch self {
|
||||
case .inputPasskeyCredentialFirebasePNV(let _data):
|
||||
return ("inputPasskeyCredentialFirebasePNV", [("pnvToken", ConstructorParameterDescription(_data.pnvToken))])
|
||||
case .inputPasskeyCredentialPublicKey(let _data):
|
||||
return ("inputPasskeyCredentialPublicKey", [("id", ConstructorParameterDescription(_data.id)), ("rawId", ConstructorParameterDescription(_data.rawId)), ("response", ConstructorParameterDescription(_data.response))])
|
||||
case .inputPageListOrderedItemBlocks(let _data):
|
||||
return ("inputPageListOrderedItemBlocks", [("flags", ConstructorParameterDescription(_data.flags)), ("blocks", ConstructorParameterDescription(_data.blocks)), ("value", ConstructorParameterDescription(_data.value)), ("type", ConstructorParameterDescription(_data.type))])
|
||||
case .inputPageListOrderedItemText(let _data):
|
||||
return ("inputPageListOrderedItemText", [("flags", ConstructorParameterDescription(_data.flags)), ("text", ConstructorParameterDescription(_data.text)), ("value", ConstructorParameterDescription(_data.value)), ("type", ConstructorParameterDescription(_data.type))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_inputPasskeyCredentialFirebasePNV(_ reader: BufferReader) -> InputPasskeyCredential? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
public static func parse_inputPageListOrderedItemBlocks(_ reader: BufferReader) -> InputPageListOrderedItem? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.PageBlock]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PageBlock.self)
|
||||
}
|
||||
var _3: Int32?
|
||||
if Int(_1 ?? 0) & Int(1 << 2) != 0 {
|
||||
_3 = reader.readInt32()
|
||||
}
|
||||
var _4: String?
|
||||
if Int(_1 ?? 0) & Int(1 << 3) != 0 {
|
||||
_4 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.InputPasskeyCredential.inputPasskeyCredentialFirebasePNV(Cons_inputPasskeyCredentialFirebasePNV(pnvToken: _1!))
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1 ?? 0) & Int(1 << 2) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1 ?? 0) & Int(1 << 3) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.InputPageListOrderedItem.inputPageListOrderedItemBlocks(Cons_inputPageListOrderedItemBlocks(flags: _1!, blocks: _2!, value: _3, type: _4))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_inputPasskeyCredentialPublicKey(_ reader: BufferReader) -> InputPasskeyCredential? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Api.InputPasskeyResponse?
|
||||
public static func parse_inputPageListOrderedItemText(_ reader: BufferReader) -> InputPageListOrderedItem? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.InputPasskeyResponse
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
var _3: Int32?
|
||||
if Int(_1 ?? 0) & Int(1 << 2) != 0 {
|
||||
_3 = reader.readInt32()
|
||||
}
|
||||
var _4: String?
|
||||
if Int(_1 ?? 0) & Int(1 << 3) != 0 {
|
||||
_4 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.InputPasskeyCredential.inputPasskeyCredentialPublicKey(Cons_inputPasskeyCredentialPublicKey(id: _1!, rawId: _2!, response: _3!))
|
||||
let _c3 = (Int(_1 ?? 0) & Int(1 << 2) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1 ?? 0) & Int(1 << 3) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.InputPageListOrderedItem.inputPageListOrderedItemText(Cons_inputPageListOrderedItemText(flags: _1!, text: _2!, value: _3, type: _4))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -1,3 +1,90 @@
|
|||
public extension Api {
|
||||
enum InputPasskeyCredential: TypeConstructorDescription {
|
||||
public class Cons_inputPasskeyCredentialFirebasePNV: TypeConstructorDescription {
|
||||
public var pnvToken: String
|
||||
public init(pnvToken: String) {
|
||||
self.pnvToken = pnvToken
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("inputPasskeyCredentialFirebasePNV", [("pnvToken", ConstructorParameterDescription(self.pnvToken))])
|
||||
}
|
||||
}
|
||||
public class Cons_inputPasskeyCredentialPublicKey: TypeConstructorDescription {
|
||||
public var id: String
|
||||
public var rawId: String
|
||||
public var response: Api.InputPasskeyResponse
|
||||
public init(id: String, rawId: String, response: Api.InputPasskeyResponse) {
|
||||
self.id = id
|
||||
self.rawId = rawId
|
||||
self.response = response
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("inputPasskeyCredentialPublicKey", [("id", ConstructorParameterDescription(self.id)), ("rawId", ConstructorParameterDescription(self.rawId)), ("response", ConstructorParameterDescription(self.response))])
|
||||
}
|
||||
}
|
||||
case inputPasskeyCredentialFirebasePNV(Cons_inputPasskeyCredentialFirebasePNV)
|
||||
case inputPasskeyCredentialPublicKey(Cons_inputPasskeyCredentialPublicKey)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .inputPasskeyCredentialFirebasePNV(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(1528613672)
|
||||
}
|
||||
serializeString(_data.pnvToken, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .inputPasskeyCredentialPublicKey(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(1009235855)
|
||||
}
|
||||
serializeString(_data.id, buffer: buffer, boxed: false)
|
||||
serializeString(_data.rawId, buffer: buffer, boxed: false)
|
||||
_data.response.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
switch self {
|
||||
case .inputPasskeyCredentialFirebasePNV(let _data):
|
||||
return ("inputPasskeyCredentialFirebasePNV", [("pnvToken", ConstructorParameterDescription(_data.pnvToken))])
|
||||
case .inputPasskeyCredentialPublicKey(let _data):
|
||||
return ("inputPasskeyCredentialPublicKey", [("id", ConstructorParameterDescription(_data.id)), ("rawId", ConstructorParameterDescription(_data.rawId)), ("response", ConstructorParameterDescription(_data.response))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_inputPasskeyCredentialFirebasePNV(_ reader: BufferReader) -> InputPasskeyCredential? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.InputPasskeyCredential.inputPasskeyCredentialFirebasePNV(Cons_inputPasskeyCredentialFirebasePNV(pnvToken: _1!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_inputPasskeyCredentialPublicKey(_ reader: BufferReader) -> InputPasskeyCredential? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Api.InputPasskeyResponse?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.InputPasskeyResponse
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.InputPasskeyCredential.inputPasskeyCredentialPublicKey(Cons_inputPasskeyCredentialPublicKey(id: _1!, rawId: _2!, response: _3!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum InputPasskeyResponse: TypeConstructorDescription {
|
||||
public class Cons_inputPasskeyResponseLogin: TypeConstructorDescription {
|
||||
|
|
@ -882,246 +969,3 @@ public extension Api {
|
|||
}
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum InputPrivacyRule: TypeConstructorDescription {
|
||||
public class Cons_inputPrivacyValueAllowChatParticipants: TypeConstructorDescription {
|
||||
public var chats: [Int64]
|
||||
public init(chats: [Int64]) {
|
||||
self.chats = chats
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("inputPrivacyValueAllowChatParticipants", [("chats", ConstructorParameterDescription(self.chats))])
|
||||
}
|
||||
}
|
||||
public class Cons_inputPrivacyValueAllowUsers: TypeConstructorDescription {
|
||||
public var users: [Api.InputUser]
|
||||
public init(users: [Api.InputUser]) {
|
||||
self.users = users
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("inputPrivacyValueAllowUsers", [("users", ConstructorParameterDescription(self.users))])
|
||||
}
|
||||
}
|
||||
public class Cons_inputPrivacyValueDisallowChatParticipants: TypeConstructorDescription {
|
||||
public var chats: [Int64]
|
||||
public init(chats: [Int64]) {
|
||||
self.chats = chats
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("inputPrivacyValueDisallowChatParticipants", [("chats", ConstructorParameterDescription(self.chats))])
|
||||
}
|
||||
}
|
||||
public class Cons_inputPrivacyValueDisallowUsers: TypeConstructorDescription {
|
||||
public var users: [Api.InputUser]
|
||||
public init(users: [Api.InputUser]) {
|
||||
self.users = users
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("inputPrivacyValueDisallowUsers", [("users", ConstructorParameterDescription(self.users))])
|
||||
}
|
||||
}
|
||||
case inputPrivacyValueAllowAll
|
||||
case inputPrivacyValueAllowBots
|
||||
case inputPrivacyValueAllowChatParticipants(Cons_inputPrivacyValueAllowChatParticipants)
|
||||
case inputPrivacyValueAllowCloseFriends
|
||||
case inputPrivacyValueAllowContacts
|
||||
case inputPrivacyValueAllowPremium
|
||||
case inputPrivacyValueAllowUsers(Cons_inputPrivacyValueAllowUsers)
|
||||
case inputPrivacyValueDisallowAll
|
||||
case inputPrivacyValueDisallowBots
|
||||
case inputPrivacyValueDisallowChatParticipants(Cons_inputPrivacyValueDisallowChatParticipants)
|
||||
case inputPrivacyValueDisallowContacts
|
||||
case inputPrivacyValueDisallowUsers(Cons_inputPrivacyValueDisallowUsers)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .inputPrivacyValueAllowAll:
|
||||
if boxed {
|
||||
buffer.appendInt32(407582158)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueAllowBots:
|
||||
if boxed {
|
||||
buffer.appendInt32(1515179237)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueAllowChatParticipants(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2079962673)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(_data.chats.count))
|
||||
for item in _data.chats {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueAllowCloseFriends:
|
||||
if boxed {
|
||||
buffer.appendInt32(793067081)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueAllowContacts:
|
||||
if boxed {
|
||||
buffer.appendInt32(218751099)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueAllowPremium:
|
||||
if boxed {
|
||||
buffer.appendInt32(2009975281)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueAllowUsers(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(320652927)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(_data.users.count))
|
||||
for item in _data.users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueDisallowAll:
|
||||
if boxed {
|
||||
buffer.appendInt32(-697604407)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueDisallowBots:
|
||||
if boxed {
|
||||
buffer.appendInt32(-991594219)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueDisallowChatParticipants(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-380694650)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(_data.chats.count))
|
||||
for item in _data.chats {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueDisallowContacts:
|
||||
if boxed {
|
||||
buffer.appendInt32(195371015)
|
||||
}
|
||||
break
|
||||
case .inputPrivacyValueDisallowUsers(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1877932953)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(_data.users.count))
|
||||
for item in _data.users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
switch self {
|
||||
case .inputPrivacyValueAllowAll:
|
||||
return ("inputPrivacyValueAllowAll", [])
|
||||
case .inputPrivacyValueAllowBots:
|
||||
return ("inputPrivacyValueAllowBots", [])
|
||||
case .inputPrivacyValueAllowChatParticipants(let _data):
|
||||
return ("inputPrivacyValueAllowChatParticipants", [("chats", ConstructorParameterDescription(_data.chats))])
|
||||
case .inputPrivacyValueAllowCloseFriends:
|
||||
return ("inputPrivacyValueAllowCloseFriends", [])
|
||||
case .inputPrivacyValueAllowContacts:
|
||||
return ("inputPrivacyValueAllowContacts", [])
|
||||
case .inputPrivacyValueAllowPremium:
|
||||
return ("inputPrivacyValueAllowPremium", [])
|
||||
case .inputPrivacyValueAllowUsers(let _data):
|
||||
return ("inputPrivacyValueAllowUsers", [("users", ConstructorParameterDescription(_data.users))])
|
||||
case .inputPrivacyValueDisallowAll:
|
||||
return ("inputPrivacyValueDisallowAll", [])
|
||||
case .inputPrivacyValueDisallowBots:
|
||||
return ("inputPrivacyValueDisallowBots", [])
|
||||
case .inputPrivacyValueDisallowChatParticipants(let _data):
|
||||
return ("inputPrivacyValueDisallowChatParticipants", [("chats", ConstructorParameterDescription(_data.chats))])
|
||||
case .inputPrivacyValueDisallowContacts:
|
||||
return ("inputPrivacyValueDisallowContacts", [])
|
||||
case .inputPrivacyValueDisallowUsers(let _data):
|
||||
return ("inputPrivacyValueDisallowUsers", [("users", ConstructorParameterDescription(_data.users))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_inputPrivacyValueAllowAll(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueAllowAll
|
||||
}
|
||||
public static func parse_inputPrivacyValueAllowBots(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueAllowBots
|
||||
}
|
||||
public static func parse_inputPrivacyValueAllowChatParticipants(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueAllowChatParticipants(Cons_inputPrivacyValueAllowChatParticipants(chats: _1!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_inputPrivacyValueAllowCloseFriends(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueAllowCloseFriends
|
||||
}
|
||||
public static func parse_inputPrivacyValueAllowContacts(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueAllowContacts
|
||||
}
|
||||
public static func parse_inputPrivacyValueAllowPremium(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueAllowPremium
|
||||
}
|
||||
public static func parse_inputPrivacyValueAllowUsers(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
var _1: [Api.InputUser]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputUser.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueAllowUsers(Cons_inputPrivacyValueAllowUsers(users: _1!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_inputPrivacyValueDisallowAll(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueDisallowAll
|
||||
}
|
||||
public static func parse_inputPrivacyValueDisallowBots(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueDisallowBots
|
||||
}
|
||||
public static func parse_inputPrivacyValueDisallowChatParticipants(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueDisallowChatParticipants(Cons_inputPrivacyValueDisallowChatParticipants(chats: _1!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_inputPrivacyValueDisallowContacts(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueDisallowContacts
|
||||
}
|
||||
public static func parse_inputPrivacyValueDisallowUsers(_ reader: BufferReader) -> InputPrivacyRule? {
|
||||
var _1: [Api.InputUser]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputUser.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.InputPrivacyRule.inputPrivacyValueDisallowUsers(Cons_inputPrivacyValueDisallowUsers(users: _1!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1450,7 +1450,8 @@ public extension Api {
|
|||
public var stargiftsCount: Int32?
|
||||
public var sendPaidMessagesStars: Int64?
|
||||
public var mainTab: Api.ProfileTab?
|
||||
public init(flags: Int32, flags2: Int32, id: Int64, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int64?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int64?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttlPeriod: Int32?, pendingSuggestions: [String]?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, defaultSendAs: Api.Peer?, availableReactions: Api.ChatReactions?, reactionsLimit: Int32?, stories: Api.PeerStories?, wallpaper: Api.WallPaper?, boostsApplied: Int32?, boostsUnrestrict: Int32?, emojiset: Api.StickerSet?, botVerification: Api.BotVerification?, stargiftsCount: Int32?, sendPaidMessagesStars: Int64?, mainTab: Api.ProfileTab?) {
|
||||
public var guardBotId: Int64?
|
||||
public init(flags: Int32, flags2: Int32, id: Int64, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int64?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int64?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttlPeriod: Int32?, pendingSuggestions: [String]?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, defaultSendAs: Api.Peer?, availableReactions: Api.ChatReactions?, reactionsLimit: Int32?, stories: Api.PeerStories?, wallpaper: Api.WallPaper?, boostsApplied: Int32?, boostsUnrestrict: Int32?, emojiset: Api.StickerSet?, botVerification: Api.BotVerification?, stargiftsCount: Int32?, sendPaidMessagesStars: Int64?, mainTab: Api.ProfileTab?, guardBotId: Int64?) {
|
||||
self.flags = flags
|
||||
self.flags2 = flags2
|
||||
self.id = id
|
||||
|
|
@ -1498,9 +1499,10 @@ public extension Api {
|
|||
self.stargiftsCount = stargiftsCount
|
||||
self.sendPaidMessagesStars = sendPaidMessagesStars
|
||||
self.mainTab = mainTab
|
||||
self.guardBotId = guardBotId
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("channelFull", [("flags", ConstructorParameterDescription(self.flags)), ("flags2", ConstructorParameterDescription(self.flags2)), ("id", ConstructorParameterDescription(self.id)), ("about", ConstructorParameterDescription(self.about)), ("participantsCount", ConstructorParameterDescription(self.participantsCount)), ("adminsCount", ConstructorParameterDescription(self.adminsCount)), ("kickedCount", ConstructorParameterDescription(self.kickedCount)), ("bannedCount", ConstructorParameterDescription(self.bannedCount)), ("onlineCount", ConstructorParameterDescription(self.onlineCount)), ("readInboxMaxId", ConstructorParameterDescription(self.readInboxMaxId)), ("readOutboxMaxId", ConstructorParameterDescription(self.readOutboxMaxId)), ("unreadCount", ConstructorParameterDescription(self.unreadCount)), ("chatPhoto", ConstructorParameterDescription(self.chatPhoto)), ("notifySettings", ConstructorParameterDescription(self.notifySettings)), ("exportedInvite", ConstructorParameterDescription(self.exportedInvite)), ("botInfo", ConstructorParameterDescription(self.botInfo)), ("migratedFromChatId", ConstructorParameterDescription(self.migratedFromChatId)), ("migratedFromMaxId", ConstructorParameterDescription(self.migratedFromMaxId)), ("pinnedMsgId", ConstructorParameterDescription(self.pinnedMsgId)), ("stickerset", ConstructorParameterDescription(self.stickerset)), ("availableMinId", ConstructorParameterDescription(self.availableMinId)), ("folderId", ConstructorParameterDescription(self.folderId)), ("linkedChatId", ConstructorParameterDescription(self.linkedChatId)), ("location", ConstructorParameterDescription(self.location)), ("slowmodeSeconds", ConstructorParameterDescription(self.slowmodeSeconds)), ("slowmodeNextSendDate", ConstructorParameterDescription(self.slowmodeNextSendDate)), ("statsDc", ConstructorParameterDescription(self.statsDc)), ("pts", ConstructorParameterDescription(self.pts)), ("call", ConstructorParameterDescription(self.call)), ("ttlPeriod", ConstructorParameterDescription(self.ttlPeriod)), ("pendingSuggestions", ConstructorParameterDescription(self.pendingSuggestions)), ("groupcallDefaultJoinAs", ConstructorParameterDescription(self.groupcallDefaultJoinAs)), ("themeEmoticon", ConstructorParameterDescription(self.themeEmoticon)), ("requestsPending", ConstructorParameterDescription(self.requestsPending)), ("recentRequesters", ConstructorParameterDescription(self.recentRequesters)), ("defaultSendAs", ConstructorParameterDescription(self.defaultSendAs)), ("availableReactions", ConstructorParameterDescription(self.availableReactions)), ("reactionsLimit", ConstructorParameterDescription(self.reactionsLimit)), ("stories", ConstructorParameterDescription(self.stories)), ("wallpaper", ConstructorParameterDescription(self.wallpaper)), ("boostsApplied", ConstructorParameterDescription(self.boostsApplied)), ("boostsUnrestrict", ConstructorParameterDescription(self.boostsUnrestrict)), ("emojiset", ConstructorParameterDescription(self.emojiset)), ("botVerification", ConstructorParameterDescription(self.botVerification)), ("stargiftsCount", ConstructorParameterDescription(self.stargiftsCount)), ("sendPaidMessagesStars", ConstructorParameterDescription(self.sendPaidMessagesStars)), ("mainTab", ConstructorParameterDescription(self.mainTab))])
|
||||
return ("channelFull", [("flags", ConstructorParameterDescription(self.flags)), ("flags2", ConstructorParameterDescription(self.flags2)), ("id", ConstructorParameterDescription(self.id)), ("about", ConstructorParameterDescription(self.about)), ("participantsCount", ConstructorParameterDescription(self.participantsCount)), ("adminsCount", ConstructorParameterDescription(self.adminsCount)), ("kickedCount", ConstructorParameterDescription(self.kickedCount)), ("bannedCount", ConstructorParameterDescription(self.bannedCount)), ("onlineCount", ConstructorParameterDescription(self.onlineCount)), ("readInboxMaxId", ConstructorParameterDescription(self.readInboxMaxId)), ("readOutboxMaxId", ConstructorParameterDescription(self.readOutboxMaxId)), ("unreadCount", ConstructorParameterDescription(self.unreadCount)), ("chatPhoto", ConstructorParameterDescription(self.chatPhoto)), ("notifySettings", ConstructorParameterDescription(self.notifySettings)), ("exportedInvite", ConstructorParameterDescription(self.exportedInvite)), ("botInfo", ConstructorParameterDescription(self.botInfo)), ("migratedFromChatId", ConstructorParameterDescription(self.migratedFromChatId)), ("migratedFromMaxId", ConstructorParameterDescription(self.migratedFromMaxId)), ("pinnedMsgId", ConstructorParameterDescription(self.pinnedMsgId)), ("stickerset", ConstructorParameterDescription(self.stickerset)), ("availableMinId", ConstructorParameterDescription(self.availableMinId)), ("folderId", ConstructorParameterDescription(self.folderId)), ("linkedChatId", ConstructorParameterDescription(self.linkedChatId)), ("location", ConstructorParameterDescription(self.location)), ("slowmodeSeconds", ConstructorParameterDescription(self.slowmodeSeconds)), ("slowmodeNextSendDate", ConstructorParameterDescription(self.slowmodeNextSendDate)), ("statsDc", ConstructorParameterDescription(self.statsDc)), ("pts", ConstructorParameterDescription(self.pts)), ("call", ConstructorParameterDescription(self.call)), ("ttlPeriod", ConstructorParameterDescription(self.ttlPeriod)), ("pendingSuggestions", ConstructorParameterDescription(self.pendingSuggestions)), ("groupcallDefaultJoinAs", ConstructorParameterDescription(self.groupcallDefaultJoinAs)), ("themeEmoticon", ConstructorParameterDescription(self.themeEmoticon)), ("requestsPending", ConstructorParameterDescription(self.requestsPending)), ("recentRequesters", ConstructorParameterDescription(self.recentRequesters)), ("defaultSendAs", ConstructorParameterDescription(self.defaultSendAs)), ("availableReactions", ConstructorParameterDescription(self.availableReactions)), ("reactionsLimit", ConstructorParameterDescription(self.reactionsLimit)), ("stories", ConstructorParameterDescription(self.stories)), ("wallpaper", ConstructorParameterDescription(self.wallpaper)), ("boostsApplied", ConstructorParameterDescription(self.boostsApplied)), ("boostsUnrestrict", ConstructorParameterDescription(self.boostsUnrestrict)), ("emojiset", ConstructorParameterDescription(self.emojiset)), ("botVerification", ConstructorParameterDescription(self.botVerification)), ("stargiftsCount", ConstructorParameterDescription(self.stargiftsCount)), ("sendPaidMessagesStars", ConstructorParameterDescription(self.sendPaidMessagesStars)), ("mainTab", ConstructorParameterDescription(self.mainTab)), ("guardBotId", ConstructorParameterDescription(self.guardBotId))])
|
||||
}
|
||||
}
|
||||
public class Cons_chatFull: TypeConstructorDescription {
|
||||
|
|
@ -1553,7 +1555,7 @@ public extension Api {
|
|||
switch self {
|
||||
case .channelFull(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-455036259)
|
||||
buffer.appendInt32(-1605464774)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.flags2, buffer: buffer, boxed: false)
|
||||
|
|
@ -1686,6 +1688,9 @@ public extension Api {
|
|||
if Int(_data.flags2) & Int(1 << 22) != 0 {
|
||||
_data.mainTab!.serialize(buffer, true)
|
||||
}
|
||||
if Int(_data.flags2) & Int(1 << 23) != 0 {
|
||||
serializeInt64(_data.guardBotId!, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .chatFull(let _data):
|
||||
if boxed {
|
||||
|
|
@ -1750,7 +1755,7 @@ public extension Api {
|
|||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
switch self {
|
||||
case .channelFull(let _data):
|
||||
return ("channelFull", [("flags", ConstructorParameterDescription(_data.flags)), ("flags2", ConstructorParameterDescription(_data.flags2)), ("id", ConstructorParameterDescription(_data.id)), ("about", ConstructorParameterDescription(_data.about)), ("participantsCount", ConstructorParameterDescription(_data.participantsCount)), ("adminsCount", ConstructorParameterDescription(_data.adminsCount)), ("kickedCount", ConstructorParameterDescription(_data.kickedCount)), ("bannedCount", ConstructorParameterDescription(_data.bannedCount)), ("onlineCount", ConstructorParameterDescription(_data.onlineCount)), ("readInboxMaxId", ConstructorParameterDescription(_data.readInboxMaxId)), ("readOutboxMaxId", ConstructorParameterDescription(_data.readOutboxMaxId)), ("unreadCount", ConstructorParameterDescription(_data.unreadCount)), ("chatPhoto", ConstructorParameterDescription(_data.chatPhoto)), ("notifySettings", ConstructorParameterDescription(_data.notifySettings)), ("exportedInvite", ConstructorParameterDescription(_data.exportedInvite)), ("botInfo", ConstructorParameterDescription(_data.botInfo)), ("migratedFromChatId", ConstructorParameterDescription(_data.migratedFromChatId)), ("migratedFromMaxId", ConstructorParameterDescription(_data.migratedFromMaxId)), ("pinnedMsgId", ConstructorParameterDescription(_data.pinnedMsgId)), ("stickerset", ConstructorParameterDescription(_data.stickerset)), ("availableMinId", ConstructorParameterDescription(_data.availableMinId)), ("folderId", ConstructorParameterDescription(_data.folderId)), ("linkedChatId", ConstructorParameterDescription(_data.linkedChatId)), ("location", ConstructorParameterDescription(_data.location)), ("slowmodeSeconds", ConstructorParameterDescription(_data.slowmodeSeconds)), ("slowmodeNextSendDate", ConstructorParameterDescription(_data.slowmodeNextSendDate)), ("statsDc", ConstructorParameterDescription(_data.statsDc)), ("pts", ConstructorParameterDescription(_data.pts)), ("call", ConstructorParameterDescription(_data.call)), ("ttlPeriod", ConstructorParameterDescription(_data.ttlPeriod)), ("pendingSuggestions", ConstructorParameterDescription(_data.pendingSuggestions)), ("groupcallDefaultJoinAs", ConstructorParameterDescription(_data.groupcallDefaultJoinAs)), ("themeEmoticon", ConstructorParameterDescription(_data.themeEmoticon)), ("requestsPending", ConstructorParameterDescription(_data.requestsPending)), ("recentRequesters", ConstructorParameterDescription(_data.recentRequesters)), ("defaultSendAs", ConstructorParameterDescription(_data.defaultSendAs)), ("availableReactions", ConstructorParameterDescription(_data.availableReactions)), ("reactionsLimit", ConstructorParameterDescription(_data.reactionsLimit)), ("stories", ConstructorParameterDescription(_data.stories)), ("wallpaper", ConstructorParameterDescription(_data.wallpaper)), ("boostsApplied", ConstructorParameterDescription(_data.boostsApplied)), ("boostsUnrestrict", ConstructorParameterDescription(_data.boostsUnrestrict)), ("emojiset", ConstructorParameterDescription(_data.emojiset)), ("botVerification", ConstructorParameterDescription(_data.botVerification)), ("stargiftsCount", ConstructorParameterDescription(_data.stargiftsCount)), ("sendPaidMessagesStars", ConstructorParameterDescription(_data.sendPaidMessagesStars)), ("mainTab", ConstructorParameterDescription(_data.mainTab))])
|
||||
return ("channelFull", [("flags", ConstructorParameterDescription(_data.flags)), ("flags2", ConstructorParameterDescription(_data.flags2)), ("id", ConstructorParameterDescription(_data.id)), ("about", ConstructorParameterDescription(_data.about)), ("participantsCount", ConstructorParameterDescription(_data.participantsCount)), ("adminsCount", ConstructorParameterDescription(_data.adminsCount)), ("kickedCount", ConstructorParameterDescription(_data.kickedCount)), ("bannedCount", ConstructorParameterDescription(_data.bannedCount)), ("onlineCount", ConstructorParameterDescription(_data.onlineCount)), ("readInboxMaxId", ConstructorParameterDescription(_data.readInboxMaxId)), ("readOutboxMaxId", ConstructorParameterDescription(_data.readOutboxMaxId)), ("unreadCount", ConstructorParameterDescription(_data.unreadCount)), ("chatPhoto", ConstructorParameterDescription(_data.chatPhoto)), ("notifySettings", ConstructorParameterDescription(_data.notifySettings)), ("exportedInvite", ConstructorParameterDescription(_data.exportedInvite)), ("botInfo", ConstructorParameterDescription(_data.botInfo)), ("migratedFromChatId", ConstructorParameterDescription(_data.migratedFromChatId)), ("migratedFromMaxId", ConstructorParameterDescription(_data.migratedFromMaxId)), ("pinnedMsgId", ConstructorParameterDescription(_data.pinnedMsgId)), ("stickerset", ConstructorParameterDescription(_data.stickerset)), ("availableMinId", ConstructorParameterDescription(_data.availableMinId)), ("folderId", ConstructorParameterDescription(_data.folderId)), ("linkedChatId", ConstructorParameterDescription(_data.linkedChatId)), ("location", ConstructorParameterDescription(_data.location)), ("slowmodeSeconds", ConstructorParameterDescription(_data.slowmodeSeconds)), ("slowmodeNextSendDate", ConstructorParameterDescription(_data.slowmodeNextSendDate)), ("statsDc", ConstructorParameterDescription(_data.statsDc)), ("pts", ConstructorParameterDescription(_data.pts)), ("call", ConstructorParameterDescription(_data.call)), ("ttlPeriod", ConstructorParameterDescription(_data.ttlPeriod)), ("pendingSuggestions", ConstructorParameterDescription(_data.pendingSuggestions)), ("groupcallDefaultJoinAs", ConstructorParameterDescription(_data.groupcallDefaultJoinAs)), ("themeEmoticon", ConstructorParameterDescription(_data.themeEmoticon)), ("requestsPending", ConstructorParameterDescription(_data.requestsPending)), ("recentRequesters", ConstructorParameterDescription(_data.recentRequesters)), ("defaultSendAs", ConstructorParameterDescription(_data.defaultSendAs)), ("availableReactions", ConstructorParameterDescription(_data.availableReactions)), ("reactionsLimit", ConstructorParameterDescription(_data.reactionsLimit)), ("stories", ConstructorParameterDescription(_data.stories)), ("wallpaper", ConstructorParameterDescription(_data.wallpaper)), ("boostsApplied", ConstructorParameterDescription(_data.boostsApplied)), ("boostsUnrestrict", ConstructorParameterDescription(_data.boostsUnrestrict)), ("emojiset", ConstructorParameterDescription(_data.emojiset)), ("botVerification", ConstructorParameterDescription(_data.botVerification)), ("stargiftsCount", ConstructorParameterDescription(_data.stargiftsCount)), ("sendPaidMessagesStars", ConstructorParameterDescription(_data.sendPaidMessagesStars)), ("mainTab", ConstructorParameterDescription(_data.mainTab)), ("guardBotId", ConstructorParameterDescription(_data.guardBotId))])
|
||||
case .chatFull(let _data):
|
||||
return ("chatFull", [("flags", ConstructorParameterDescription(_data.flags)), ("id", ConstructorParameterDescription(_data.id)), ("about", ConstructorParameterDescription(_data.about)), ("participants", ConstructorParameterDescription(_data.participants)), ("chatPhoto", ConstructorParameterDescription(_data.chatPhoto)), ("notifySettings", ConstructorParameterDescription(_data.notifySettings)), ("exportedInvite", ConstructorParameterDescription(_data.exportedInvite)), ("botInfo", ConstructorParameterDescription(_data.botInfo)), ("pinnedMsgId", ConstructorParameterDescription(_data.pinnedMsgId)), ("folderId", ConstructorParameterDescription(_data.folderId)), ("call", ConstructorParameterDescription(_data.call)), ("ttlPeriod", ConstructorParameterDescription(_data.ttlPeriod)), ("groupcallDefaultJoinAs", ConstructorParameterDescription(_data.groupcallDefaultJoinAs)), ("themeEmoticon", ConstructorParameterDescription(_data.themeEmoticon)), ("requestsPending", ConstructorParameterDescription(_data.requestsPending)), ("recentRequesters", ConstructorParameterDescription(_data.recentRequesters)), ("availableReactions", ConstructorParameterDescription(_data.availableReactions)), ("reactionsLimit", ConstructorParameterDescription(_data.reactionsLimit))])
|
||||
}
|
||||
|
|
@ -1957,6 +1962,10 @@ public extension Api {
|
|||
_47 = Api.parse(reader, signature: signature) as? Api.ProfileTab
|
||||
}
|
||||
}
|
||||
var _48: Int64?
|
||||
if Int(_2 ?? 0) & Int(1 << 23) != 0 {
|
||||
_48 = reader.readInt64()
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
|
|
@ -2004,8 +2013,9 @@ public extension Api {
|
|||
let _c45 = (Int(_2 ?? 0) & Int(1 << 18) == 0) || _45 != nil
|
||||
let _c46 = (Int(_2 ?? 0) & Int(1 << 21) == 0) || _46 != nil
|
||||
let _c47 = (Int(_2 ?? 0) & Int(1 << 22) == 0) || _47 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 && _c35 && _c36 && _c37 && _c38 && _c39 && _c40 && _c41 && _c42 && _c43 && _c44 && _c45 && _c46 && _c47 {
|
||||
return Api.ChatFull.channelFull(Cons_channelFull(flags: _1!, flags2: _2!, id: _3!, about: _4!, participantsCount: _5, adminsCount: _6, kickedCount: _7, bannedCount: _8, onlineCount: _9, readInboxMaxId: _10!, readOutboxMaxId: _11!, unreadCount: _12!, chatPhoto: _13!, notifySettings: _14!, exportedInvite: _15, botInfo: _16!, migratedFromChatId: _17, migratedFromMaxId: _18, pinnedMsgId: _19, stickerset: _20, availableMinId: _21, folderId: _22, linkedChatId: _23, location: _24, slowmodeSeconds: _25, slowmodeNextSendDate: _26, statsDc: _27, pts: _28!, call: _29, ttlPeriod: _30, pendingSuggestions: _31, groupcallDefaultJoinAs: _32, themeEmoticon: _33, requestsPending: _34, recentRequesters: _35, defaultSendAs: _36, availableReactions: _37, reactionsLimit: _38, stories: _39, wallpaper: _40, boostsApplied: _41, boostsUnrestrict: _42, emojiset: _43, botVerification: _44, stargiftsCount: _45, sendPaidMessagesStars: _46, mainTab: _47))
|
||||
let _c48 = (Int(_2 ?? 0) & Int(1 << 23) == 0) || _48 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 && _c35 && _c36 && _c37 && _c38 && _c39 && _c40 && _c41 && _c42 && _c43 && _c44 && _c45 && _c46 && _c47 && _c48 {
|
||||
return Api.ChatFull.channelFull(Cons_channelFull(flags: _1!, flags2: _2!, id: _3!, about: _4!, participantsCount: _5, adminsCount: _6, kickedCount: _7, bannedCount: _8, onlineCount: _9, readInboxMaxId: _10!, readOutboxMaxId: _11!, unreadCount: _12!, chatPhoto: _13!, notifySettings: _14!, exportedInvite: _15, botInfo: _16!, migratedFromChatId: _17, migratedFromMaxId: _18, pinnedMsgId: _19, stickerset: _20, availableMinId: _21, folderId: _22, linkedChatId: _23, location: _24, slowmodeSeconds: _25, slowmodeNextSendDate: _26, statsDc: _27, pts: _28!, call: _29, ttlPeriod: _30, pendingSuggestions: _31, groupcallDefaultJoinAs: _32, themeEmoticon: _33, requestsPending: _34, recentRequesters: _35, defaultSendAs: _36, availableReactions: _37, reactionsLimit: _38, stories: _39, wallpaper: _40, boostsApplied: _41, boostsUnrestrict: _42, emojiset: _43, botVerification: _44, stargiftsCount: _45, sendPaidMessagesStars: _46, mainTab: _47, guardBotId: _48))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
1071
submodules/TelegramApi/Sources/Api41.swift
Normal file
1071
submodules/TelegramApi/Sources/Api41.swift
Normal file
File diff suppressed because it is too large
Load diff
14093
submodules/TelegramApi/Sources/Api42.swift
Normal file
14093
submodules/TelegramApi/Sources/Api42.swift
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1094,14 +1094,20 @@ public extension Api {
|
|||
public var botId: Int64
|
||||
public var recipients: Api.BusinessBotRecipients
|
||||
public var rights: Api.BusinessBotRights
|
||||
public init(flags: Int32, botId: Int64, recipients: Api.BusinessBotRecipients, rights: Api.BusinessBotRights) {
|
||||
public var device: String?
|
||||
public var date: Int32?
|
||||
public var location: String?
|
||||
public init(flags: Int32, botId: Int64, recipients: Api.BusinessBotRecipients, rights: Api.BusinessBotRights, device: String?, date: Int32?, location: String?) {
|
||||
self.flags = flags
|
||||
self.botId = botId
|
||||
self.recipients = recipients
|
||||
self.rights = rights
|
||||
self.device = device
|
||||
self.date = date
|
||||
self.location = location
|
||||
}
|
||||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
return ("connectedBot", [("flags", ConstructorParameterDescription(self.flags)), ("botId", ConstructorParameterDescription(self.botId)), ("recipients", ConstructorParameterDescription(self.recipients)), ("rights", ConstructorParameterDescription(self.rights))])
|
||||
return ("connectedBot", [("flags", ConstructorParameterDescription(self.flags)), ("botId", ConstructorParameterDescription(self.botId)), ("recipients", ConstructorParameterDescription(self.recipients)), ("rights", ConstructorParameterDescription(self.rights)), ("device", ConstructorParameterDescription(self.device)), ("date", ConstructorParameterDescription(self.date)), ("location", ConstructorParameterDescription(self.location))])
|
||||
}
|
||||
}
|
||||
case connectedBot(Cons_connectedBot)
|
||||
|
|
@ -1110,12 +1116,21 @@ public extension Api {
|
|||
switch self {
|
||||
case .connectedBot(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-849058964)
|
||||
buffer.appendInt32(54448129)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.botId, buffer: buffer, boxed: false)
|
||||
_data.recipients.serialize(buffer, true)
|
||||
_data.rights.serialize(buffer, true)
|
||||
if Int(_data.flags) & Int(1 << 0) != 0 {
|
||||
serializeString(_data.device!, buffer: buffer, boxed: false)
|
||||
}
|
||||
if Int(_data.flags) & Int(1 << 1) != 0 {
|
||||
serializeInt32(_data.date!, buffer: buffer, boxed: false)
|
||||
}
|
||||
if Int(_data.flags) & Int(1 << 2) != 0 {
|
||||
serializeString(_data.location!, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -1123,7 +1138,7 @@ public extension Api {
|
|||
public func descriptionFields() -> (String, [(String, ConstructorParameterDescription)]) {
|
||||
switch self {
|
||||
case .connectedBot(let _data):
|
||||
return ("connectedBot", [("flags", ConstructorParameterDescription(_data.flags)), ("botId", ConstructorParameterDescription(_data.botId)), ("recipients", ConstructorParameterDescription(_data.recipients)), ("rights", ConstructorParameterDescription(_data.rights))])
|
||||
return ("connectedBot", [("flags", ConstructorParameterDescription(_data.flags)), ("botId", ConstructorParameterDescription(_data.botId)), ("recipients", ConstructorParameterDescription(_data.recipients)), ("rights", ConstructorParameterDescription(_data.rights)), ("device", ConstructorParameterDescription(_data.device)), ("date", ConstructorParameterDescription(_data.date)), ("location", ConstructorParameterDescription(_data.location))])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1140,12 +1155,27 @@ public extension Api {
|
|||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.BusinessBotRights
|
||||
}
|
||||
var _5: String?
|
||||
if Int(_1 ?? 0) & Int(1 << 0) != 0 {
|
||||
_5 = parseString(reader)
|
||||
}
|
||||
var _6: Int32?
|
||||
if Int(_1 ?? 0) & Int(1 << 1) != 0 {
|
||||
_6 = reader.readInt32()
|
||||
}
|
||||
var _7: String?
|
||||
if Int(_1 ?? 0) & Int(1 << 2) != 0 {
|
||||
_7 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.ConnectedBot.connectedBot(Cons_connectedBot(flags: _1!, botId: _2!, recipients: _3!, rights: _4!))
|
||||
let _c5 = (Int(_1 ?? 0) & Int(1 << 0) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1 ?? 0) & Int(1 << 1) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1 ?? 0) & Int(1 << 2) == 0) || _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.ConnectedBot.connectedBot(Cons_connectedBot(flags: _1!, botId: _2!, recipients: _3!, rights: _4!, device: _5, date: _6, location: _7))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ private var declaredEncodables: Void = {
|
|||
declareEncodable(InlineBotMessageAttribute.self, f: { InlineBotMessageAttribute(decoder: $0) })
|
||||
declareEncodable(InlineBusinessBotMessageAttribute.self, f: { InlineBusinessBotMessageAttribute(decoder: $0) })
|
||||
declareEncodable(TextEntitiesMessageAttribute.self, f: { TextEntitiesMessageAttribute(decoder: $0) })
|
||||
declareEncodable(RichTextMessageAttribute.self, f: { RichTextMessageAttribute(decoder: $0) })
|
||||
declareEncodable(ReplyMessageAttribute.self, f: { ReplyMessageAttribute(decoder: $0) })
|
||||
declareEncodable(QuotedReplyMessageAttribute.self, f: { QuotedReplyMessageAttribute(decoder: $0) })
|
||||
declareEncodable(ReplyStoryAttribute.self, f: { ReplyStoryAttribute(decoder: $0) })
|
||||
|
|
|
|||
|
|
@ -48,38 +48,128 @@ extension InstantPageListItem {
|
|||
self = .blocks(blocks.map({ InstantPageBlock(apiBlock: $0) }), num)
|
||||
}
|
||||
}
|
||||
|
||||
func apiInputPageListItem() -> Api.PageListItem {
|
||||
switch self {
|
||||
case let .text(value, _):
|
||||
return .pageListItemText(Api.PageListItem.Cons_pageListItemText(flags: 0, text: value.apiRichText()))
|
||||
case let .blocks(blocks, _):
|
||||
return .pageListItemBlocks(Api.PageListItem.Cons_pageListItemBlocks(flags: 0, blocks: blocks.compactMap { $0.apiInputBlock() }))
|
||||
case .unknown:
|
||||
return .pageListItemText(Api.PageListItem.Cons_pageListItemText(flags: 0, text: .textPlain(Api.RichText.Cons_textPlain(text: ""))))
|
||||
}
|
||||
}
|
||||
|
||||
func apiInputPageOrderedListItem() -> Api.InputPageListOrderedItem {
|
||||
switch self {
|
||||
case let .text(value, num):
|
||||
var flags: Int32 = 0
|
||||
|
||||
var inputNum: Int32?
|
||||
if let num, let numValue = Int32(num) {
|
||||
inputNum = numValue
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
|
||||
return .inputPageListOrderedItemText(Api.InputPageListOrderedItem.Cons_inputPageListOrderedItemText(flags: flags, text: value.apiRichText(), value: inputNum, type: nil))
|
||||
case let .blocks(blocks, num):
|
||||
var flags: Int32 = 0
|
||||
|
||||
var inputNum: Int32?
|
||||
if let num, let numValue = Int32(num) {
|
||||
inputNum = numValue
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
|
||||
return .inputPageListOrderedItemBlocks(Api.InputPageListOrderedItem.Cons_inputPageListOrderedItemBlocks(flags: flags, blocks: blocks.compactMap { $0.apiInputBlock() }, value: inputNum, type: nil))
|
||||
case .unknown:
|
||||
return .inputPageListOrderedItemText(Api.InputPageListOrderedItem.Cons_inputPageListOrderedItemText(flags: 0, text: .textPlain(Api.RichText.Cons_textPlain(text: "")), value: nil, type: nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension InstantPageTableCell {
|
||||
convenience init(apiTableCell: Api.PageTableCell) {
|
||||
switch apiTableCell {
|
||||
case let .pageTableCell(pageTableCellData):
|
||||
let (flags, text, colspan, rowspan) = (pageTableCellData.flags, pageTableCellData.text, pageTableCellData.colspan, pageTableCellData.rowspan)
|
||||
var alignment = TableHorizontalAlignment.left
|
||||
if (flags & (1 << 3)) != 0 {
|
||||
alignment = .center
|
||||
} else if (flags & (1 << 4)) != 0 {
|
||||
alignment = .right
|
||||
}
|
||||
var verticalAlignment = TableVerticalAlignment.top
|
||||
if (flags & (1 << 5)) != 0 {
|
||||
verticalAlignment = .middle
|
||||
} else if (flags & (1 << 6)) != 0 {
|
||||
verticalAlignment = .bottom
|
||||
}
|
||||
self.init(text: text != nil ? RichText(apiText: text!) : nil, header: (flags & (1 << 0)) != 0, alignment: alignment, verticalAlignment: verticalAlignment, colspan: colspan ?? 0, rowspan: rowspan ?? 0)
|
||||
case let .pageTableCell(pageTableCellData):
|
||||
let (flags, text, colspan, rowspan) = (pageTableCellData.flags, pageTableCellData.text, pageTableCellData.colspan, pageTableCellData.rowspan)
|
||||
var alignment = TableHorizontalAlignment.left
|
||||
if (flags & (1 << 3)) != 0 {
|
||||
alignment = .center
|
||||
} else if (flags & (1 << 4)) != 0 {
|
||||
alignment = .right
|
||||
}
|
||||
var verticalAlignment = TableVerticalAlignment.top
|
||||
if (flags & (1 << 5)) != 0 {
|
||||
verticalAlignment = .middle
|
||||
} else if (flags & (1 << 6)) != 0 {
|
||||
verticalAlignment = .bottom
|
||||
}
|
||||
self.init(text: text != nil ? RichText(apiText: text!) : nil, header: (flags & (1 << 0)) != 0, alignment: alignment, verticalAlignment: verticalAlignment, colspan: colspan ?? 0, rowspan: rowspan ?? 0)
|
||||
}
|
||||
}
|
||||
|
||||
func inputPageTableCell() -> Api.PageTableCell {
|
||||
var flags: Int32 = 0
|
||||
|
||||
switch self.alignment {
|
||||
case .left:
|
||||
break
|
||||
case .center:
|
||||
flags |= (1 << 3)
|
||||
case .right:
|
||||
flags |= (1 << 4)
|
||||
}
|
||||
|
||||
switch self.verticalAlignment {
|
||||
case .top:
|
||||
break
|
||||
case .middle:
|
||||
flags |= (1 << 5)
|
||||
case .bottom:
|
||||
flags |= (1 << 6)
|
||||
}
|
||||
|
||||
if self.header {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
|
||||
var inputText: Api.RichText?
|
||||
if let text = self.text {
|
||||
inputText = text.apiRichText()
|
||||
if inputText != nil {
|
||||
flags |= (1 << 7)
|
||||
}
|
||||
}
|
||||
|
||||
var inputColspan: Int32?
|
||||
if self.colspan != 0 {
|
||||
inputColspan = self.colspan
|
||||
flags |= (1 << 1)
|
||||
}
|
||||
|
||||
var inputRowspan: Int32?
|
||||
if self.rowspan != 0 {
|
||||
inputRowspan = self.rowspan
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
|
||||
return .pageTableCell(Api.PageTableCell.Cons_pageTableCell(flags: flags, text: inputText, colspan: inputColspan, rowspan: inputRowspan))
|
||||
}
|
||||
}
|
||||
|
||||
extension InstantPageTableRow {
|
||||
convenience init(apiTableRow: Api.PageTableRow) {
|
||||
switch apiTableRow {
|
||||
case let .pageTableRow(pageTableRowData):
|
||||
let cells = pageTableRowData.cells
|
||||
self.init(cells: cells.map({ InstantPageTableCell(apiTableCell: $0) }))
|
||||
case let .pageTableRow(pageTableRowData):
|
||||
let cells = pageTableRowData.cells
|
||||
self.init(cells: cells.map({ InstantPageTableCell(apiTableCell: $0) }))
|
||||
}
|
||||
}
|
||||
|
||||
func inputPageTableRow() -> Api.PageTableRow {
|
||||
return .pageTableRow(Api.PageTableRow.Cons_pageTableRow(cells: self.cells.map { $0.inputPageTableCell() }))
|
||||
}
|
||||
}
|
||||
|
||||
extension InstantPageRelatedArticle {
|
||||
|
|
@ -198,6 +288,104 @@ extension InstantPageBlock {
|
|||
default:
|
||||
self = .unsupported
|
||||
}
|
||||
case let .pageBlockHeading1(pageBlockHeading1):
|
||||
self = .heading(text: RichText(apiText: pageBlockHeading1.text), level: 1)
|
||||
case let .pageBlockHeading2(pageBlockHeading2):
|
||||
self = .heading(text: RichText(apiText: pageBlockHeading2.text), level: 2)
|
||||
case let .pageBlockHeading3(pageBlockHeading3):
|
||||
self = .heading(text: RichText(apiText: pageBlockHeading3.text), level: 3)
|
||||
case let .pageBlockHeading4(pageBlockHeading4):
|
||||
self = .heading(text: RichText(apiText: pageBlockHeading4.text), level: 4)
|
||||
case let .pageBlockHeading5(pageBlockHeading5):
|
||||
self = .heading(text: RichText(apiText: pageBlockHeading5.text), level: 5)
|
||||
case let .pageBlockHeading6(pageBlockHeading6):
|
||||
self = .heading(text: RichText(apiText: pageBlockHeading6.text), level: 6)
|
||||
case let .pageBlockMath(pageBlockMath):
|
||||
self = .formula(latex: pageBlockMath.source)
|
||||
case .inputPageBlockPhoto, .inputPageBlockVideo, .inputPageBlockAudio, .inputPageBlockMap, .inputPageBlockOrderedList:
|
||||
self = .unsupported
|
||||
}
|
||||
}
|
||||
|
||||
func apiInputBlock() -> Api.PageBlock? {
|
||||
switch self {
|
||||
case .unsupported, .title, .subtitle, .kicker, .header, .subheader, .cover, .channelBanner, .authorDate, .relatedArticles, .webEmbed, .postEmbed:
|
||||
return nil
|
||||
case let .heading(text, level):
|
||||
let block: Api.PageBlock
|
||||
switch level {
|
||||
case 0, 1:
|
||||
block = .pageBlockHeading1(Api.PageBlock.Cons_pageBlockHeading1(text: text.apiRichText()))
|
||||
case 2:
|
||||
block = .pageBlockHeading2(Api.PageBlock.Cons_pageBlockHeading2(text: text.apiRichText()))
|
||||
case 3:
|
||||
block = .pageBlockHeading3(Api.PageBlock.Cons_pageBlockHeading3(text: text.apiRichText()))
|
||||
case 4:
|
||||
block = .pageBlockHeading4(Api.PageBlock.Cons_pageBlockHeading4(text: text.apiRichText()))
|
||||
case 5:
|
||||
block = .pageBlockHeading5(Api.PageBlock.Cons_pageBlockHeading5(text: text.apiRichText()))
|
||||
default:
|
||||
block = .pageBlockHeading6(Api.PageBlock.Cons_pageBlockHeading6(text: text.apiRichText()))
|
||||
}
|
||||
return block
|
||||
case let .formula(latex):
|
||||
return .pageBlockMath(Api.PageBlock.Cons_pageBlockMath(source: latex))
|
||||
case let .paragraph(value):
|
||||
return .pageBlockParagraph(Api.PageBlock.Cons_pageBlockParagraph(text: value.apiRichText()))
|
||||
case let .preformatted(text, language):
|
||||
return .pageBlockPreformatted(Api.PageBlock.Cons_pageBlockPreformatted(text: text.apiRichText(), language: language ?? ""))
|
||||
case let .footer(value):
|
||||
return .pageBlockFooter(Api.PageBlock.Cons_pageBlockFooter(text: value.apiRichText()))
|
||||
case .divider:
|
||||
return .pageBlockDivider
|
||||
case let .anchor(value):
|
||||
return .pageBlockAnchor(Api.PageBlock.Cons_pageBlockAnchor(name: value))
|
||||
case let .list(items, ordered):
|
||||
if ordered {
|
||||
return .inputPageBlockOrderedList(Api.PageBlock.Cons_inputPageBlockOrderedList(flags: 0, items: items.map { $0.apiInputPageOrderedListItem() }, start: nil, type: nil))
|
||||
} else {
|
||||
return .pageBlockList(Api.PageBlock.Cons_pageBlockList(items: items.map { $0.apiInputPageListItem() }))
|
||||
}
|
||||
case let .blockQuote(text, caption):
|
||||
return .pageBlockBlockquote(Api.PageBlock.Cons_pageBlockBlockquote(text: text.apiRichText(), caption: caption.apiRichText()))
|
||||
case let .pullQuote(text, caption):
|
||||
return .pageBlockPullquote(Api.PageBlock.Cons_pageBlockPullquote(text: text.apiRichText(), caption: caption.apiRichText()))
|
||||
case let .image(id, caption, url, _):
|
||||
//TODO:localize
|
||||
let _ = id
|
||||
assertionFailure()
|
||||
return .inputPageBlockPhoto(Api.PageBlock.Cons_inputPageBlockPhoto(flags: 0, photo: .inputPhotoEmpty, caption: .pageCaption(Api.PageCaption.Cons_pageCaption(text: caption.text.apiRichText(), credit: caption.credit.apiRichText())), url: url))
|
||||
case let .video(id, caption, autoplay, loop):
|
||||
//TODO:localize
|
||||
let _ = autoplay
|
||||
let _ = loop
|
||||
let _ = id
|
||||
assertionFailure()
|
||||
return .inputPageBlockVideo(Api.PageBlock.Cons_inputPageBlockVideo(flags: 0, video: .inputDocumentEmpty, caption: .pageCaption(Api.PageCaption.Cons_pageCaption(text: caption.text.apiRichText(), credit: caption.credit.apiRichText()))))
|
||||
case let .audio(id, caption):
|
||||
let _ = id
|
||||
return .inputPageBlockAudio(Api.PageBlock.Cons_inputPageBlockAudio(audio: .inputDocumentEmpty, caption: .pageCaption(Api.PageCaption.Cons_pageCaption(text: caption.text.apiRichText(), credit: caption.credit.apiRichText()))))
|
||||
case let .collage(items, caption):
|
||||
return .pageBlockCollage(Api.PageBlock.Cons_pageBlockCollage(items: items.compactMap { $0.apiInputBlock() }, caption: .pageCaption(Api.PageCaption.Cons_pageCaption(text: caption.text.apiRichText(), credit: caption.credit.apiRichText()))))
|
||||
case let .slideshow(items, caption):
|
||||
return .pageBlockSlideshow(Api.PageBlock.Cons_pageBlockSlideshow(items: items.compactMap { $0.apiInputBlock() }, caption: .pageCaption(Api.PageCaption.Cons_pageCaption(text: caption.text.apiRichText(), credit: caption.credit.apiRichText()))))
|
||||
case let .table(title, rows, bordered, striped):
|
||||
var flags: Int32 = 0
|
||||
if bordered {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
if striped {
|
||||
flags |= (1 << 1)
|
||||
}
|
||||
return .pageBlockTable(Api.PageBlock.Cons_pageBlockTable(flags: flags, title: title.apiRichText(), rows: rows.map { $0.inputPageTableRow() }))
|
||||
case let .details(title, blocks, expanded):
|
||||
var flags: Int32 = 0
|
||||
if expanded {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
return .pageBlockDetails(Api.PageBlock.Cons_pageBlockDetails(flags: flags, blocks: blocks.compactMap { $0.apiInputBlock() }, title: title.apiRichText()))
|
||||
case let .map(latitude, longitude, zoom, dimensions, caption):
|
||||
return .inputPageBlockMap(Api.PageBlock.Cons_inputPageBlockMap(geo: .inputGeoPoint(Api.InputGeoPoint.Cons_inputGeoPoint(flags: 0, lat: latitude, long: longitude, accuracyRadius: nil)), zoom: zoom, w: dimensions.width, h: dimensions.height, caption: .pageCaption(Api.PageCaption.Cons_pageCaption(text: caption.text.apiRichText(), credit: caption.credit.apiRichText()))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,15 +400,15 @@ extension InstantPage {
|
|||
let url: String
|
||||
let views: Int32?
|
||||
switch apiPage {
|
||||
case let .page(pageData):
|
||||
let (flags, pageUrl, pageBlocks, pagePhotos, pageDocuments, pageViews) = (pageData.flags, pageData.url, pageData.blocks, pageData.photos, pageData.documents, pageData.views)
|
||||
url = pageUrl
|
||||
blocks = pageBlocks
|
||||
photos = pagePhotos
|
||||
files = pageDocuments
|
||||
isComplete = (flags & (1 << 0)) == 0
|
||||
rtl = (flags & (1 << 1)) != 0
|
||||
views = pageViews
|
||||
case let .page(pageData):
|
||||
let (flags, pageUrl, pageBlocks, pagePhotos, pageDocuments, pageViews) = (pageData.flags, pageData.url, pageData.blocks, pageData.photos, pageData.documents, pageData.views)
|
||||
url = pageUrl
|
||||
blocks = pageBlocks
|
||||
photos = pagePhotos
|
||||
files = pageDocuments
|
||||
isComplete = (flags & (1 << 0)) == 0
|
||||
rtl = (flags & (1 << 1)) != 0
|
||||
views = pageViews
|
||||
}
|
||||
var media: [MediaId: Media] = [:]
|
||||
for photo in photos {
|
||||
|
|
|
|||
|
|
@ -6,53 +6,102 @@ import TelegramApi
|
|||
extension RichText {
|
||||
init(apiText: Api.RichText) {
|
||||
switch apiText {
|
||||
case .textEmpty:
|
||||
self = .empty
|
||||
case let .textPlain(textPlainData):
|
||||
let text = textPlainData.text
|
||||
self = .plain(text)
|
||||
case let .textBold(textBoldData):
|
||||
let text = textBoldData.text
|
||||
self = .bold(RichText(apiText: text))
|
||||
case let .textItalic(textItalicData):
|
||||
let text = textItalicData.text
|
||||
self = .italic(RichText(apiText: text))
|
||||
case let .textUnderline(textUnderlineData):
|
||||
let text = textUnderlineData.text
|
||||
self = .underline(RichText(apiText: text))
|
||||
case let .textStrike(textStrikeData):
|
||||
let text = textStrikeData.text
|
||||
self = .strikethrough(RichText(apiText: text))
|
||||
case let .textFixed(textFixedData):
|
||||
let text = textFixedData.text
|
||||
self = .fixed(RichText(apiText: text))
|
||||
case let .textUrl(textUrlData):
|
||||
let (text, url, webpageId) = (textUrlData.text, textUrlData.url, textUrlData.webpageId)
|
||||
self = .url(text: RichText(apiText: text), url: url, webpageId: webpageId == 0 ? nil : MediaId(namespace: Namespaces.Media.CloudWebpage, id: webpageId))
|
||||
case let .textEmail(textEmailData):
|
||||
let (text, email) = (textEmailData.text, textEmailData.email)
|
||||
self = .email(text: RichText(apiText: text), email: email)
|
||||
case let .textConcat(textConcatData):
|
||||
let texts = textConcatData.texts
|
||||
self = .concat(texts.map({ RichText(apiText: $0) }))
|
||||
case let .textSubscript(textSubscriptData):
|
||||
let text = textSubscriptData.text
|
||||
self = .subscript(RichText(apiText: text))
|
||||
case let .textSuperscript(textSuperscriptData):
|
||||
let text = textSuperscriptData.text
|
||||
self = .superscript(RichText(apiText: text))
|
||||
case let .textMarked(textMarkedData):
|
||||
let text = textMarkedData.text
|
||||
self = .marked(RichText(apiText: text))
|
||||
case let .textPhone(textPhoneData):
|
||||
let (text, phone) = (textPhoneData.text, textPhoneData.phone)
|
||||
self = .phone(text: RichText(apiText: text), phone: phone)
|
||||
case let .textImage(textImageData):
|
||||
let (documentId, w, h) = (textImageData.documentId, textImageData.w, textImageData.h)
|
||||
self = .image(id: MediaId(namespace: Namespaces.Media.CloudFile, id: documentId), dimensions: PixelDimensions(width: w, height: h))
|
||||
case let .textAnchor(textAnchorData):
|
||||
let (text, name) = (textAnchorData.text, textAnchorData.name)
|
||||
self = .anchor(text: RichText(apiText: text), name: name)
|
||||
case .textEmpty:
|
||||
self = .empty
|
||||
case let .textPlain(textPlainData):
|
||||
let text = textPlainData.text
|
||||
self = .plain(text)
|
||||
case let .textBold(textBoldData):
|
||||
let text = textBoldData.text
|
||||
self = .bold(RichText(apiText: text))
|
||||
case let .textItalic(textItalicData):
|
||||
let text = textItalicData.text
|
||||
self = .italic(RichText(apiText: text))
|
||||
case let .textUnderline(textUnderlineData):
|
||||
let text = textUnderlineData.text
|
||||
self = .underline(RichText(apiText: text))
|
||||
case let .textStrike(textStrikeData):
|
||||
let text = textStrikeData.text
|
||||
self = .strikethrough(RichText(apiText: text))
|
||||
case let .textFixed(textFixedData):
|
||||
let text = textFixedData.text
|
||||
self = .fixed(RichText(apiText: text))
|
||||
case let .textUrl(textUrlData):
|
||||
let (text, url, webpageId) = (textUrlData.text, textUrlData.url, textUrlData.webpageId)
|
||||
self = .url(text: RichText(apiText: text), url: url, webpageId: webpageId == 0 ? nil : MediaId(namespace: Namespaces.Media.CloudWebpage, id: webpageId))
|
||||
case let .textEmail(textEmailData):
|
||||
let (text, email) = (textEmailData.text, textEmailData.email)
|
||||
self = .email(text: RichText(apiText: text), email: email)
|
||||
case let .textConcat(textConcatData):
|
||||
let texts = textConcatData.texts
|
||||
self = .concat(texts.map({ RichText(apiText: $0) }))
|
||||
case let .textSubscript(textSubscriptData):
|
||||
let text = textSubscriptData.text
|
||||
self = .subscript(RichText(apiText: text))
|
||||
case let .textSuperscript(textSuperscriptData):
|
||||
let text = textSuperscriptData.text
|
||||
self = .superscript(RichText(apiText: text))
|
||||
case let .textMarked(textMarkedData):
|
||||
let text = textMarkedData.text
|
||||
self = .marked(RichText(apiText: text))
|
||||
case let .textPhone(textPhoneData):
|
||||
let (text, phone) = (textPhoneData.text, textPhoneData.phone)
|
||||
self = .phone(text: RichText(apiText: text), phone: phone)
|
||||
case let .textImage(textImageData):
|
||||
let (documentId, w, h) = (textImageData.documentId, textImageData.w, textImageData.h)
|
||||
self = .image(id: MediaId(namespace: Namespaces.Media.CloudFile, id: documentId), dimensions: PixelDimensions(width: w, height: h))
|
||||
case let .textAnchor(textAnchorData):
|
||||
let (text, name) = (textAnchorData.text, textAnchorData.name)
|
||||
self = .anchor(text: RichText(apiText: text), name: name)
|
||||
case .inputTextImage:
|
||||
self = .plain("")
|
||||
case .textCustomEmoji:
|
||||
//TODO:localize
|
||||
self = .plain("")
|
||||
case let .textMath(textMath):
|
||||
self = .formula(latex: textMath.source)
|
||||
}
|
||||
}
|
||||
|
||||
func apiRichText() -> Api.RichText {
|
||||
switch self {
|
||||
case .empty:
|
||||
return .textPlain(Api.RichText.Cons_textPlain(text: ""))
|
||||
case let .plain(value):
|
||||
return .textPlain(Api.RichText.Cons_textPlain(text: value))
|
||||
case let .bold(value):
|
||||
return .textBold(Api.RichText.Cons_textBold(text: value.apiRichText()))
|
||||
case let .italic(value):
|
||||
return .textItalic(Api.RichText.Cons_textItalic(text: value.apiRichText()))
|
||||
case let .underline(value):
|
||||
return .textUnderline(Api.RichText.Cons_textUnderline(text: value.apiRichText()))
|
||||
case let .strikethrough(value):
|
||||
return .textStrike(Api.RichText.Cons_textStrike(text: value.apiRichText()))
|
||||
case let .fixed(value):
|
||||
return .textFixed(Api.RichText.Cons_textFixed(text: value.apiRichText()))
|
||||
case let .url(text, url, webpageId):
|
||||
return .textUrl(Api.RichText.Cons_textUrl(text: text.apiRichText(), url: url, webpageId: webpageId?.id ?? 0))
|
||||
case let .email(text, email):
|
||||
return .textEmail(Api.RichText.Cons_textEmail(text: text.apiRichText(), email: email))
|
||||
case let .concat(values):
|
||||
return .textConcat(Api.RichText.Cons_textConcat(texts: values.map { $0.apiRichText() }))
|
||||
case let .`subscript`(value):
|
||||
return .textSubscript(Api.RichText.Cons_textSubscript(text: value.apiRichText()))
|
||||
case let .superscript(value):
|
||||
return .textSuperscript(Api.RichText.Cons_textSuperscript(text: value.apiRichText()))
|
||||
case let .marked(value):
|
||||
return .textMarked(Api.RichText.Cons_textMarked(text: value.apiRichText()))
|
||||
case let .phone(text, phone):
|
||||
return .textPhone(Api.RichText.Cons_textPhone(text: text.apiRichText(), phone: phone))
|
||||
case let .image(id, dimensions):
|
||||
//TODO:localize
|
||||
let _ = id
|
||||
assertionFailure()
|
||||
return .inputTextImage(Api.RichText.Cons_inputTextImage(document: .inputDocumentEmpty, w: dimensions.width, h: dimensions.height))
|
||||
case let .anchor(text, name):
|
||||
return .textAnchor(Api.RichText.Cons_textAnchor(text: text.apiRichText(), name: name))
|
||||
case let .formula(latex):
|
||||
return .textMath(Api.RichText.Cons_textMath(source: latex))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -848,7 +848,7 @@ extension StoreMessage {
|
|||
convenience init?(apiMessage: Api.Message, accountPeerId: PeerId, peerIsForum: Bool, namespace: MessageId.Namespace = Namespaces.Message.Cloud) {
|
||||
switch apiMessage {
|
||||
case let .message(messageData):
|
||||
let (flags, flags2, id, fromId, boosts, rank, chatPeerId, savedPeerId, fwdFrom, viaBotId, viaBusinessBotId, guestChatViaFrom, replyTo, date, message, media, replyMarkup, entities, views, forwards, replies, editDate, postAuthor, groupingId, reactions, restrictionReason, ttlPeriod, quickReplyShortcutId, messageEffectId, factCheck, reportDeliveryUntilDate, paidMessageStars, suggestedPost, scheduledRepeatPeriod, summaryFromLanguage) = (messageData.flags, messageData.flags2, messageData.id, messageData.fromId, messageData.fromBoostsApplied, messageData.fromRank, messageData.peerId, messageData.savedPeerId, messageData.fwdFrom, messageData.viaBotId, messageData.viaBusinessBotId, messageData.guestchatViaFrom, messageData.replyTo, messageData.date, messageData.message, messageData.media, messageData.replyMarkup, messageData.entities, messageData.views, messageData.forwards, messageData.replies, messageData.editDate, messageData.postAuthor, messageData.groupedId, messageData.reactions, messageData.restrictionReason, messageData.ttlPeriod, messageData.quickReplyShortcutId, messageData.effect, messageData.factcheck, messageData.reportDeliveryUntilDate, messageData.paidMessageStars, messageData.suggestedPost, messageData.scheduleRepeatPeriod, messageData.summaryFromLanguage)
|
||||
let (flags, flags2, id, fromId, boosts, rank, chatPeerId, savedPeerId, fwdFrom, viaBotId, viaBusinessBotId, guestChatViaFrom, replyTo, date, message, media, replyMarkup, entities, views, forwards, replies, editDate, postAuthor, groupingId, reactions, restrictionReason, ttlPeriod, quickReplyShortcutId, messageEffectId, factCheck, reportDeliveryUntilDate, paidMessageStars, suggestedPost, scheduledRepeatPeriod, summaryFromLanguage) = (messageData.flags, messageData.flags2, messageData.id, messageData.fromId, messageData.fromBoostsApplied, messageData.fromRank, messageData.peerId, messageData.savedPeerId, messageData.fwdFrom, messageData.viaBotId, messageData.viaBusinessBotId, messageData.guestchatViaFrom, messageData.replyTo, messageData.date, messageData.message, messageData.media, messageData.replyMarkup, messageData.entities, messageData.views, messageData.forwards, messageData.replies, messageData.editDate, messageData.postAuthor, messageData.groupedId, messageData.reactions, messageData.restrictionReason, messageData.ttlPeriod, messageData.quickReplyShortcutId, messageData.effect, messageData.factcheck, messageData.reportDeliveryUntilDate, messageData.paidMessageStars, messageData.suggestedPost, messageData.scheduleRepeatPeriod, messageData.summaryFromLanguage)
|
||||
var attributes: [MessageAttribute] = []
|
||||
|
||||
if (flags2 & (1 << 4)) != 0 {
|
||||
|
|
@ -1133,7 +1133,7 @@ extension StoreMessage {
|
|||
}
|
||||
|
||||
var entitiesAttribute: TextEntitiesMessageAttribute?
|
||||
if let entities = entities, !entities.isEmpty {
|
||||
if let entities, !entities.isEmpty {
|
||||
let attribute = TextEntitiesMessageAttribute(entities: messageTextEntitiesFromApiEntities(entities))
|
||||
entitiesAttribute = attribute
|
||||
attributes.append(attribute)
|
||||
|
|
@ -1155,6 +1155,10 @@ extension StoreMessage {
|
|||
attributes.append(attribute)
|
||||
}
|
||||
}
|
||||
|
||||
if let richMessage = messageData.richMessage {
|
||||
attributes.append(RichTextMessageAttribute(apiRichMessage: richMessage))
|
||||
}
|
||||
|
||||
if (flags & (1 << 19)) != 0 {
|
||||
attributes.append(ContentRequiresValidationMessageAttribute())
|
||||
|
|
|
|||
|
|
@ -255,6 +255,8 @@ private func filterMessageAttributesForOutgoingMessage(_ attributes: [MessageAtt
|
|||
switch attribute {
|
||||
case _ as TextEntitiesMessageAttribute:
|
||||
return true
|
||||
case _ as RichTextMessageAttribute:
|
||||
return true
|
||||
case _ as InlineBotMessageAttribute:
|
||||
return true
|
||||
case _ as OutgoingMessageInfoAttribute:
|
||||
|
|
@ -306,6 +308,8 @@ private func filterMessageAttributesForForwardedMessage(_ attributes: [MessageAt
|
|||
switch attribute {
|
||||
case _ as TextEntitiesMessageAttribute:
|
||||
return true
|
||||
case _ as RichTextMessageAttribute:
|
||||
return true
|
||||
case _ as InlineBotMessageAttribute:
|
||||
return true
|
||||
case _ as NotificationInfoMessageAttribute:
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ private final class PendingUpdateMessageManagerImpl {
|
|||
}
|
||||
}
|
||||
|
||||
func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?, disableUrlPreview: Bool) {
|
||||
func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, richText: RichTextMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?, disableUrlPreview: Bool) {
|
||||
if let context = self.contexts[messageId] {
|
||||
self.contexts.removeValue(forKey: messageId)
|
||||
context.disposable.dispose()
|
||||
|
|
@ -75,7 +75,7 @@ private final class PendingUpdateMessageManagerImpl {
|
|||
self.contexts[messageId] = context
|
||||
|
||||
let queue = self.queue
|
||||
disposable.set((requestEditMessage(accountPeerId: self.stateManager.accountPeerId, postbox: self.postbox, network: self.network, stateManager: self.stateManager, transformOutgoingMessageMedia: self.transformOutgoingMessageMedia, messageMediaPreuploadManager: self.messageMediaPreuploadManager, mediaReferenceRevalidationContext: self.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: nil, invertMediaAttribute: invertMediaAttribute)
|
||||
disposable.set((requestEditMessage(accountPeerId: self.stateManager.accountPeerId, postbox: self.postbox, network: self.network, stateManager: self.stateManager, transformOutgoingMessageMedia: self.transformOutgoingMessageMedia, messageMediaPreuploadManager: self.messageMediaPreuploadManager, mediaReferenceRevalidationContext: self.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, richText: richText, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: nil, invertMediaAttribute: invertMediaAttribute)
|
||||
|> deliverOn(self.queue)).start(next: { [weak self, weak context] value in
|
||||
queue.async {
|
||||
guard let strongSelf = self, let initialContext = context else {
|
||||
|
|
@ -163,9 +163,9 @@ public final class PendingUpdateMessageManager {
|
|||
})
|
||||
}
|
||||
|
||||
public func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute? = nil, invertMediaAttribute: InvertMediaMessageAttribute? = nil, disableUrlPreview: Bool = false) {
|
||||
public func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, richText: RichTextMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute? = nil, invertMediaAttribute: InvertMediaMessageAttribute? = nil, disableUrlPreview: Bool = false) {
|
||||
self.impl.with { impl in
|
||||
impl.add(messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertMediaAttribute, disableUrlPreview: disableUrlPreview)
|
||||
impl.add(messageId: messageId, text: text, media: media, entities: entities, richText: richText, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertMediaAttribute, disableUrlPreview: disableUrlPreview)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,15 +27,15 @@ public enum RequestEditMessageError {
|
|||
case invalidGrouping
|
||||
}
|
||||
|
||||
func _internal_requestEditMessage(account: Account, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, disableUrlPreview: Bool, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return requestEditMessage(accountPeerId: account.peerId, postbox: account.postbox, network: account.network, stateManager: account.stateManager, transformOutgoingMessageMedia: account.transformOutgoingMessageMedia, messageMediaPreuploadManager: account.messageMediaPreuploadManager, mediaReferenceRevalidationContext: account.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: scheduleInfoAttribute, invertMediaAttribute: invertMediaAttribute)
|
||||
func _internal_requestEditMessage(account: Account, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, richText: RichTextMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, disableUrlPreview: Bool, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return requestEditMessage(accountPeerId: account.peerId, postbox: account.postbox, network: account.network, stateManager: account.stateManager, transformOutgoingMessageMedia: account.transformOutgoingMessageMedia, messageMediaPreuploadManager: account.messageMediaPreuploadManager, mediaReferenceRevalidationContext: account.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, richText: richText, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: scheduleInfoAttribute, invertMediaAttribute: invertMediaAttribute)
|
||||
}
|
||||
|
||||
func requestEditMessage(accountPeerId: PeerId, postbox: Postbox, network: Network, stateManager: AccountStateManager, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, disableUrlPreview: Bool, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return requestEditMessageInternal(accountPeerId: accountPeerId, postbox: postbox, network: network, stateManager: stateManager, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertMediaAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: scheduleInfoAttribute, forceReupload: false)
|
||||
func requestEditMessage(accountPeerId: PeerId, postbox: Postbox, network: Network, stateManager: AccountStateManager, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, richText: RichTextMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, disableUrlPreview: Bool, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return requestEditMessageInternal(accountPeerId: accountPeerId, postbox: postbox, network: network, stateManager: stateManager, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, richText: richText, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertMediaAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: scheduleInfoAttribute, forceReupload: false)
|
||||
|> `catch` { error -> Signal<RequestEditMessageResult, RequestEditMessageInternalError> in
|
||||
if case .invalidReference = error {
|
||||
return requestEditMessageInternal(accountPeerId: accountPeerId, postbox: postbox, network: network, stateManager: stateManager, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertMediaAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: scheduleInfoAttribute, forceReupload: true)
|
||||
return requestEditMessageInternal(accountPeerId: accountPeerId, postbox: postbox, network: network, stateManager: stateManager, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, richText: richText, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertMediaAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: scheduleInfoAttribute, forceReupload: true)
|
||||
} else {
|
||||
return .fail(error)
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ func requestEditMessage(accountPeerId: PeerId, postbox: Postbox, network: Networ
|
|||
}
|
||||
}
|
||||
|
||||
private func requestEditMessageInternal(accountPeerId: PeerId, postbox: Postbox, network: Network, stateManager: AccountStateManager, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?, disableUrlPreview: Bool, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute?, forceReupload: Bool) -> Signal<RequestEditMessageResult, RequestEditMessageInternalError> {
|
||||
private func requestEditMessageInternal(accountPeerId: PeerId, postbox: Postbox, network: Network, stateManager: AccountStateManager, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, richText: RichTextMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?, disableUrlPreview: Bool, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute?, forceReupload: Bool) -> Signal<RequestEditMessageResult, RequestEditMessageInternalError> {
|
||||
let uploadedMedia: Signal<PendingMessageUploadedContentResult?, NoError>
|
||||
switch media {
|
||||
case .keep:
|
||||
|
|
@ -146,15 +146,21 @@ private func requestEditMessageInternal(accountPeerId: PeerId, postbox: Postbox,
|
|||
}
|
||||
|> mapError { _ -> RequestEditMessageInternalError in }
|
||||
|> mapToSignal { peer, message, associatedPeers -> Signal<RequestEditMessageResult, RequestEditMessageInternalError> in
|
||||
if let peer = peer, let message = message, let inputPeer = apiInputPeer(peer) {
|
||||
if let peer, let message, let inputPeer = apiInputPeer(peer) {
|
||||
var flags: Int32 = 1 << 11
|
||||
|
||||
var apiEntities: [Api.MessageEntity]?
|
||||
if let entities = entities {
|
||||
if let entities {
|
||||
apiEntities = apiTextAttributeEntities(entities, associatedPeers: associatedPeers)
|
||||
flags |= Int32(1 << 3)
|
||||
}
|
||||
|
||||
var apiRichMessage: Api.InputRichMessage?
|
||||
if let richText {
|
||||
apiRichMessage = richText.apiInputRichMessage()
|
||||
flags |= Int32(1 << 23)
|
||||
}
|
||||
|
||||
if disableUrlPreview {
|
||||
flags |= Int32(1 << 1)
|
||||
}
|
||||
|
|
@ -201,7 +207,7 @@ private func requestEditMessageInternal(accountPeerId: PeerId, postbox: Postbox,
|
|||
flags |= Int32(1 << 17)
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, media: inputMedia, replyMarkup: nil, entities: apiEntities, scheduleDate: effectiveScheduleTime, scheduleRepeatPeriod: effectiveScheduleRepeatPeriod, quickReplyShortcutId: quickReplyShortcutId))
|
||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, media: inputMedia, replyMarkup: nil, entities: apiEntities, scheduleDate: effectiveScheduleTime, scheduleRepeatPeriod: effectiveScheduleRepeatPeriod, quickReplyShortcutId: quickReplyShortcutId, richMessage: apiRichMessage))
|
||||
|> map { result -> Api.Updates? in
|
||||
return result
|
||||
}
|
||||
|
|
@ -429,7 +435,7 @@ func _internal_requestEditLiveLocation(postbox: Postbox, network: Network, state
|
|||
inputMedia = .inputMediaGeoLive(.init(flags: 1 << 0, geoPoint: .inputGeoPoint(.init(flags: 0, lat: media.latitude, long: media.longitude, accuracyRadius: nil)), heading: nil, period: nil, proximityNotificationRadius: nil))
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.editMessage(flags: 1 << 14, peer: inputPeer, id: messageId.id, message: nil, media: inputMedia, replyMarkup: nil, entities: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, quickReplyShortcutId: nil))
|
||||
return network.request(Api.functions.messages.editMessage(flags: 1 << 14, peer: inputPeer, id: messageId.id, message: nil, media: inputMedia, replyMarkup: nil, entities: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, quickReplyShortcutId: nil, richMessage: nil))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
|
|
|
|||
|
|
@ -366,6 +366,7 @@ private func sendUploadedMessageContent(
|
|||
var uniqueId: Int64 = 0
|
||||
var forwardSourceInfoAttribute: ForwardSourceInfoAttribute?
|
||||
var messageEntities: [Api.MessageEntity]?
|
||||
var apiRichMessage: Api.InputRichMessage?
|
||||
var replyMessageId: Int32?
|
||||
var topMsgId: Int32?
|
||||
var monoforumPeerId: Api.InputPeer?
|
||||
|
|
@ -442,6 +443,9 @@ private func sendUploadedMessageContent(
|
|||
allowPaidStars = attribute.stars.value
|
||||
} else if let attribute = attribute as? SuggestedPostMessageAttribute {
|
||||
suggestedPost = attribute.apiSuggestedPost(fixMinTime: Int32(Date().timeIntervalSince1970 + 10))
|
||||
} else if let attribute = attribute as? RichTextMessageAttribute {
|
||||
apiRichMessage = attribute.apiInputRichMessage()
|
||||
flags |= Int32(1 << 23)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -512,7 +516,7 @@ private func sendUploadedMessageContent(
|
|||
flags |= 1 << 22
|
||||
}
|
||||
|
||||
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: allowPaidStars, suggestedPost: suggestedPost), info: .acknowledgement, tag: dependencyTag)
|
||||
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: allowPaidStars, suggestedPost: suggestedPost, richMessage: apiRichMessage), info: .acknowledgement, tag: dependencyTag)
|
||||
case let .media(inputMedia, text):
|
||||
if bubbleUpEmojiOrStickersets {
|
||||
flags |= Int32(1 << 15)
|
||||
|
|
@ -692,6 +696,7 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
|
|||
var uniqueId: Int64 = Int64.random(in: Int64.min ... Int64.max)
|
||||
//var forwardSourceInfoAttribute: ForwardSourceInfoAttribute?
|
||||
var messageEntities: [Api.MessageEntity]?
|
||||
var apiRichMessage: Api.InputRichMessage?
|
||||
var replyMessageId: Int32?
|
||||
var replyToStoryId: StoryId?
|
||||
var scheduleTime: Int32?
|
||||
|
|
@ -731,6 +736,9 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
|
|||
allowPaidStars = attribute.stars.value
|
||||
} else if let attribute = attribute as? SuggestedPostMessageAttribute {
|
||||
suggestedPost = attribute.apiSuggestedPost(fixMinTime: Int32(Date().timeIntervalSince1970 + 10))
|
||||
} else if let attribute = attribute as? RichTextMessageAttribute {
|
||||
apiRichMessage = attribute.apiInputRichMessage()
|
||||
flags |= Int32(1 << 23)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -767,7 +775,7 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
|
|||
replyTo = .inputReplyToMessage(.init(flags: flags, replyToMsgId: threadId, topMsgId: threadId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: nil, todoItemId: nil, pollOption: nil))
|
||||
}
|
||||
|
||||
sendMessageRequest = account.network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: allowPaidStars, suggestedPost: nil))
|
||||
sendMessageRequest = account.network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: nil, effect: nil, allowPaidStars: allowPaidStars, suggestedPost: nil, richMessage: apiRichMessage))
|
||||
|> `catch` { _ -> Signal<Api.Updates, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1720,6 +1720,7 @@ public final class PendingMessageManager {
|
|||
var uniqueId: Int64 = 0
|
||||
var forwardSourceInfoAttribute: ForwardSourceInfoAttribute?
|
||||
var messageEntities: [Api.MessageEntity]?
|
||||
var apiRichMessage: Api.InputRichMessage?
|
||||
var replyMessageId: Int32?
|
||||
var replyPeerId: PeerId?
|
||||
var replyQuote: EngineMessageReplyQuote?
|
||||
|
|
@ -1803,6 +1804,9 @@ public final class PendingMessageManager {
|
|||
allowPaidStars = attribute.stars.value
|
||||
} else if let attribute = attribute as? SuggestedPostMessageAttribute {
|
||||
suggestedPost = attribute.apiSuggestedPost(fixMinTime: Int32(Date().timeIntervalSince1970 + 10))
|
||||
} else if let attribute = attribute as? RichTextMessageAttribute {
|
||||
apiRichMessage = attribute.apiInputRichMessage()
|
||||
flags |= Int32(1 << 23)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1928,7 +1932,7 @@ public final class PendingMessageManager {
|
|||
flags |= 1 << 22
|
||||
}
|
||||
|
||||
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, effect: messageEffectId, allowPaidStars: allowPaidStars, suggestedPost: suggestedPost), info: .acknowledgement, tag: dependencyTag)
|
||||
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, scheduleRepeatPeriod: scheduleRepeatPeriod, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, effect: messageEffectId, allowPaidStars: allowPaidStars, suggestedPost: suggestedPost, richMessage: apiRichMessage), info: .acknowledgement, tag: dependencyTag)
|
||||
case let .media(inputMedia, text):
|
||||
if bubbleUpEmojiOrStickersets {
|
||||
flags |= Int32(1 << 15)
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ public class BoxedMessage: NSObject {
|
|||
|
||||
public class Serialization: NSObject, MTSerialization {
|
||||
public func currentLayer() -> UInt {
|
||||
return 225
|
||||
return 227
|
||||
}
|
||||
|
||||
public func parseMessage(_ data: Data!) -> Any! {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class UpdateMessageService: NSObject, MTMessageService {
|
|||
}
|
||||
case let .updateShortChatMessage(updateShortChatMessageData):
|
||||
let (flags, id, fromId, chatId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyHeader, entities, ttlPeriod) = (updateShortChatMessageData.flags, updateShortChatMessageData.id, updateShortChatMessageData.fromId, updateShortChatMessageData.chatId, updateShortChatMessageData.message, updateShortChatMessageData.pts, updateShortChatMessageData.ptsCount, updateShortChatMessageData.date, updateShortChatMessageData.fwdFrom, updateShortChatMessageData.viaBotId, updateShortChatMessageData.replyTo, updateShortChatMessageData.entities, updateShortChatMessageData.ttlPeriod)
|
||||
let generatedMessage = Api.Message.message(.init(flags: flags, flags2: 0, id: id, fromId: .peerUser(.init(userId: fromId)), fromBoostsApplied: nil, fromRank: nil, peerId: Api.Peer.peerChat(.init(chatId: chatId)), savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, viaBusinessBotId: nil, guestchatViaFrom: nil, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil, effect: nil, factcheck: nil, reportDeliveryUntilDate: nil, paidMessageStars: nil, suggestedPost: nil, scheduleRepeatPeriod: nil, summaryFromLanguage: nil))
|
||||
let generatedMessage = Api.Message.message(.init(flags: flags, flags2: 0, id: id, fromId: .peerUser(.init(userId: fromId)), fromBoostsApplied: nil, fromRank: nil, peerId: Api.Peer.peerChat(.init(chatId: chatId)), savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, viaBusinessBotId: nil, guestchatViaFrom: nil, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil, effect: nil, factcheck: nil, reportDeliveryUntilDate: nil, paidMessageStars: nil, suggestedPost: nil, scheduleRepeatPeriod: nil, summaryFromLanguage: nil, richMessage: nil))
|
||||
let update = Api.Update.updateNewMessage(.init(message: generatedMessage, pts: pts, ptsCount: ptsCount))
|
||||
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
|
||||
if groups.count != 0 {
|
||||
|
|
@ -79,7 +79,7 @@ class UpdateMessageService: NSObject, MTMessageService {
|
|||
|
||||
let generatedPeerId = Api.Peer.peerUser(.init(userId: userId))
|
||||
|
||||
let generatedMessage = Api.Message.message(.init(flags: flags, flags2: 0, id: id, fromId: generatedFromId, fromBoostsApplied: nil, fromRank: nil, peerId: generatedPeerId, savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, viaBusinessBotId: nil, guestchatViaFrom: nil, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil, effect: nil, factcheck: nil, reportDeliveryUntilDate: nil, paidMessageStars: nil, suggestedPost: nil, scheduleRepeatPeriod: nil, summaryFromLanguage: nil))
|
||||
let generatedMessage = Api.Message.message(.init(flags: flags, flags2: 0, id: id, fromId: generatedFromId, fromBoostsApplied: nil, fromRank: nil, peerId: generatedPeerId, savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, viaBusinessBotId: nil, guestchatViaFrom: nil, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil, effect: nil, factcheck: nil, reportDeliveryUntilDate: nil, paidMessageStars: nil, suggestedPost: nil, scheduleRepeatPeriod: nil, summaryFromLanguage: nil, richMessage: nil))
|
||||
let update = Api.Update.updateNewMessage(.init(message: generatedMessage, pts: pts, ptsCount: ptsCount))
|
||||
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
|
||||
if groups.count != 0 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
import TelegramApi
|
||||
|
||||
public class RichTextMessageAttribute: MessageAttribute, Equatable {
|
||||
public let instantPage: InstantPage
|
||||
|
||||
public var associatedPeerIds: [PeerId] {
|
||||
/*var result: [PeerId] = []
|
||||
for entity in entities {
|
||||
switch entity.type {
|
||||
case let .TextMention(peerId):
|
||||
result.append(peerId)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
return result*/
|
||||
return []
|
||||
}
|
||||
|
||||
public var associatedMediaIds: [MediaId] {
|
||||
/*var result: [MediaId] = []
|
||||
for entity in self.entities {
|
||||
switch entity.type {
|
||||
case let .CustomEmoji(_, fileId):
|
||||
result.append(MediaId(namespace: Namespaces.Media.CloudFile, id: fileId))
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
if result.isEmpty {
|
||||
return result
|
||||
} else {
|
||||
return Array(Set(result))
|
||||
}*/
|
||||
return []
|
||||
}
|
||||
|
||||
public init(instantPage: InstantPage) {
|
||||
self.instantPage = instantPage
|
||||
}
|
||||
|
||||
required public init(decoder: PostboxDecoder) {
|
||||
self.instantPage = decoder.decodeObjectForKey("instantPage", decoder: { InstantPage(decoder: $0) }) as! InstantPage
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeObject(self.instantPage, forKey: "instantPage")
|
||||
}
|
||||
|
||||
public static func ==(lhs: RichTextMessageAttribute, rhs: RichTextMessageAttribute) -> Bool {
|
||||
return lhs.instantPage == rhs.instantPage
|
||||
}
|
||||
}
|
||||
|
||||
extension RichTextMessageAttribute {
|
||||
convenience init(apiRichMessage: Api.RichMessage) {
|
||||
switch apiRichMessage {
|
||||
case let .richMessage(richMessage):
|
||||
var media: [MediaId: Media] = [:]
|
||||
for photo in richMessage.photos {
|
||||
if let image = telegramMediaImageFromApiPhoto(photo), let id = image.id {
|
||||
media[id] = image
|
||||
}
|
||||
}
|
||||
for file in richMessage.documents {
|
||||
if let file = telegramMediaFileFromApiDocument(file, altDocuments: []), let id = file.id {
|
||||
media[id] = file
|
||||
}
|
||||
}
|
||||
let isRtl = (richMessage.flags & (1 << 0)) != 0
|
||||
let isPartial = (richMessage.flags & (1 << 1)) != 0
|
||||
let instantPage = InstantPage(blocks: richMessage.blocks.map({ InstantPageBlock(apiBlock: $0) }), media: media, isComplete: !isPartial, rtl: isRtl, url: "", views: nil)
|
||||
self.init(instantPage: instantPage)
|
||||
}
|
||||
}
|
||||
|
||||
func apiInputRichMessage() -> Api.InputRichMessage {
|
||||
var flags: Int32 = 0
|
||||
if self.instantPage.rtl {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
|
||||
return Api.InputRichMessage.inputRichMessage(Api.InputRichMessage.Cons_inputRichMessage(
|
||||
flags: flags,
|
||||
blocks: self.instantPage.blocks.compactMap { $0.apiInputBlock() }
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
@ -72,6 +72,9 @@ public final class EngineMessage: Equatable {
|
|||
public var text: String {
|
||||
return self.impl.text
|
||||
}
|
||||
public var richText: RichTextMessageAttribute? {
|
||||
return self.impl.richText
|
||||
}
|
||||
public var attributes: [Attribute] {
|
||||
return self.impl.attributes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ func _internal_requestClosePoll(postbox: Postbox, network: Network, stateManager
|
|||
pollMediaFlags |= 1 << 1
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: .inputMediaPoll(.init(flags: pollMediaFlags, poll: .poll(.init(id: poll.pollId.id, flags: pollFlags, question: .textWithEntities(.init(text: poll.text, entities: apiEntitiesFromMessageTextEntities(poll.textEntities, associatedPeers: SimpleDictionary()))), answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: poll.deadlineDate, countriesIso2: poll.countries, hash: 0)), correctAnswers: correctAnswersIndices, attachedMedia: nil, solution: mappedSolution, solutionEntities: mappedSolutionEntities, solutionMedia: nil)), replyMarkup: nil, entities: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, quickReplyShortcutId: nil))
|
||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: .inputMediaPoll(.init(flags: pollMediaFlags, poll: .poll(.init(id: poll.pollId.id, flags: pollFlags, question: .textWithEntities(.init(text: poll.text, entities: apiEntitiesFromMessageTextEntities(poll.textEntities, associatedPeers: SimpleDictionary()))), answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: poll.deadlineDate, countriesIso2: poll.countries, hash: 0)), correctAnswers: correctAnswersIndices, attachedMedia: nil, solution: mappedSolution, solutionEntities: mappedSolutionEntities, solutionMedia: nil)), replyMarkup: nil, entities: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, quickReplyShortcutId: nil, richMessage: nil))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
|
|
|
|||
|
|
@ -202,8 +202,8 @@ public extension TelegramEngine {
|
|||
return _internal_clearAuthorHistory(account: self.account, peerId: peerId, memberId: memberId)
|
||||
}
|
||||
|
||||
public func requestEditMessage(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute? = nil, invertMediaAttribute: InvertMediaMessageAttribute? = nil, disableUrlPreview: Bool = false, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute? = nil) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return _internal_requestEditMessage(account: self.account, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: scheduleInfoAttribute, invertMediaAttribute: invertMediaAttribute)
|
||||
public func requestEditMessage(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, richText: RichTextMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute? = nil, invertMediaAttribute: InvertMediaMessageAttribute? = nil, disableUrlPreview: Bool = false, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute? = nil) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||
return _internal_requestEditMessage(account: self.account, messageId: messageId, text: text, media: media, entities: entities, richText: richText, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, disableUrlPreview: disableUrlPreview, scheduleInfoAttribute: scheduleInfoAttribute, invertMediaAttribute: invertMediaAttribute)
|
||||
}
|
||||
|
||||
public func requestEditLiveLocation(messageId: MessageId, stop: Bool, coordinate: (latitude: Double, longitude: Double, accuracyRadius: Int32?)?, heading: Int32?, proximityNotificationRadius: Int32?, extendPeriod: Int32?) -> Signal<Void, NoError> {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func _internal_toggleChannelJoinRequest(postbox: Postbox, network: Network, acco
|
|||
guard let peer = peer, let inputChannel = apiInputChannel(peer) else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
return network.request(Api.functions.channels.toggleJoinRequest(channel: inputChannel, enabled: enabled ? .boolTrue : .boolFalse))
|
||||
return network.request(Api.functions.channels.toggleJoinRequest(flags: 0, channel: inputChannel, enabled: enabled ? .boolTrue : .boolFalse, guardBot: nil))
|
||||
|> `catch` { _ -> Signal<Api.Updates, UpdateChannelJoinRequestError> in
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ func _internal_joinChannel(account: Account, peerId: PeerId, hash: String?) -> S
|
|||
|> castError(JoinChannelError.self)
|
||||
|> mapToSignal { peer -> Signal<RenderedChannelParticipant?, JoinChannelError> in
|
||||
|
||||
let request: Signal<Api.Updates, MTRpcError>
|
||||
let request: Signal<Api.messages.ChatInviteJoinResult, MTRpcError>
|
||||
if let hash = hash {
|
||||
request = account.network.request(Api.functions.messages.importChatInvite(hash: hash))
|
||||
} else if let inputChannel = apiInputChannel(peer) {
|
||||
|
|
@ -40,54 +40,57 @@ func _internal_joinChannel(account: Account, peerId: PeerId, hash: String?) -> S
|
|||
return .generic
|
||||
}
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<RenderedChannelParticipant?, JoinChannelError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
|
||||
let channels = updates.chats.compactMap { parseTelegramGroupOrChannel(chat: $0) }.compactMap(apiInputChannel)
|
||||
|
||||
if let inputChannel = channels.first {
|
||||
return account.network.request(Api.functions.channels.getParticipant(channel: inputChannel, participant: .inputPeerSelf))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.channels.ChannelParticipant?, JoinChannelError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<RenderedChannelParticipant?, JoinChannelError> in
|
||||
guard let result = result else {
|
||||
return .fail(.generic)
|
||||
|> mapToSignal { result -> Signal<RenderedChannelParticipant?, JoinChannelError> in
|
||||
switch result {
|
||||
case let .chatInviteJoinResultOk(result):
|
||||
account.stateManager.addUpdates(result.updates)
|
||||
|
||||
let channels = result.updates.chats.compactMap { parseTelegramGroupOrChannel(chat: $0) }.compactMap(apiInputChannel)
|
||||
|
||||
if let inputChannel = channels.first {
|
||||
return account.network.request(Api.functions.channels.getParticipant(channel: inputChannel, participant: .inputPeerSelf))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.channels.ChannelParticipant?, JoinChannelError> in
|
||||
return .single(nil)
|
||||
}
|
||||
return account.postbox.transaction { transaction -> RenderedChannelParticipant? in
|
||||
var peers: [EnginePeer.Id: EnginePeer] = [:]
|
||||
var presences: [PeerId: PeerPresence] = [:]
|
||||
guard let peer = transaction.getPeer(account.peerId) else {
|
||||
return nil
|
||||
|> mapToSignal { result -> Signal<RenderedChannelParticipant?, JoinChannelError> in
|
||||
guard let result = result else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
peers[account.peerId] = EnginePeer(peer)
|
||||
if let presence = transaction.getPeerPresence(peerId: account.peerId) {
|
||||
presences[account.peerId] = presence
|
||||
}
|
||||
let updatedParticipant: ChannelParticipant
|
||||
switch result {
|
||||
case let .channelParticipant(channelParticipantData):
|
||||
let participant = channelParticipantData.participant
|
||||
updatedParticipant = ChannelParticipant(apiParticipant: participant)
|
||||
}
|
||||
if case let .member(_, _, maybeAdminInfo, _, _, _) = updatedParticipant {
|
||||
if let adminInfo = maybeAdminInfo {
|
||||
if let peer = transaction.getPeer(adminInfo.promotedBy) {
|
||||
peers[peer.id] = EnginePeer(peer)
|
||||
return account.postbox.transaction { transaction -> RenderedChannelParticipant? in
|
||||
var peers: [EnginePeer.Id: EnginePeer] = [:]
|
||||
var presences: [PeerId: PeerPresence] = [:]
|
||||
guard let peer = transaction.getPeer(account.peerId) else {
|
||||
return nil
|
||||
}
|
||||
peers[account.peerId] = EnginePeer(peer)
|
||||
if let presence = transaction.getPeerPresence(peerId: account.peerId) {
|
||||
presences[account.peerId] = presence
|
||||
}
|
||||
let updatedParticipant: ChannelParticipant
|
||||
switch result {
|
||||
case let .channelParticipant(channelParticipantData):
|
||||
let participant = channelParticipantData.participant
|
||||
updatedParticipant = ChannelParticipant(apiParticipant: participant)
|
||||
}
|
||||
if case let .member(_, _, maybeAdminInfo, _, _, _) = updatedParticipant {
|
||||
if let adminInfo = maybeAdminInfo {
|
||||
if let peer = transaction.getPeer(adminInfo.promotedBy) {
|
||||
peers[peer.id] = EnginePeer(peer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RenderedChannelParticipant(participant: updatedParticipant, peer: EnginePeer(peer), peers: peers, presences: presences)
|
||||
}
|
||||
|
||||
return RenderedChannelParticipant(participant: updatedParticipant, peer: EnginePeer(peer), peers: peers, presences: presences)
|
||||
|> castError(JoinChannelError.self)
|
||||
}
|
||||
|> castError(JoinChannelError.self)
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
} else {
|
||||
case .chatInviteJoinResultWebView:
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|> afterCompleted {
|
||||
if hash == nil {
|
||||
|
|
|
|||
|
|
@ -80,21 +80,26 @@ func _internal_joinChatInteractively(with hash: String, account: Account) -> Sig
|
|||
}
|
||||
}
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<PeerId?, JoinLinkError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
if let peerId = apiUpdatesGroups(updates).first?.peerId {
|
||||
return account.postbox.multiplePeersView([peerId])
|
||||
|> castError(JoinLinkError.self)
|
||||
|> filter { view in
|
||||
return view.peers[peerId] != nil
|
||||
|> mapToSignal { result -> Signal<PeerId?, JoinLinkError> in
|
||||
switch result {
|
||||
case let .chatInviteJoinResultOk(result):
|
||||
account.stateManager.addUpdates(result.updates)
|
||||
if let peerId = apiUpdatesGroups(result.updates).first?.peerId {
|
||||
return account.postbox.multiplePeersView([peerId])
|
||||
|> castError(JoinLinkError.self)
|
||||
|> filter { view in
|
||||
return view.peers[peerId] != nil
|
||||
}
|
||||
|> take(1)
|
||||
|> map { _ in
|
||||
return peerId
|
||||
}
|
||||
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .single(nil) |> castError(JoinLinkError.self))
|
||||
}
|
||||
|> take(1)
|
||||
|> map { _ in
|
||||
return peerId
|
||||
}
|
||||
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .single(nil) |> castError(JoinLinkError.self))
|
||||
return .single(nil)
|
||||
case .chatInviteJoinResultWebView:
|
||||
return .fail(.generic)
|
||||
}
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -652,6 +652,17 @@ public extension Message {
|
|||
}
|
||||
}
|
||||
|
||||
public extension Message {
|
||||
var richText: RichTextMessageAttribute? {
|
||||
for attribute in self.attributes {
|
||||
if let attribute = attribute as? RichTextMessageAttribute {
|
||||
return attribute
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public func _internal_parseMediaAttachment(data: Data) -> Media? {
|
||||
guard let object = Api.parse(Buffer(buffer: MemoryBuffer(data: data))) else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -383,11 +383,7 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
|||
if let attribute = message.attributes.first(where: { $0 is WebpagePreviewMessageAttribute }) as? WebpagePreviewMessageAttribute, attribute.leadingPreview {
|
||||
result.insert((message, ChatMessageWebpageBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)), at: addedPriceInfo ? 1 : 0)
|
||||
} else {
|
||||
if content.instantPage != nil && item.context.sharedContext.immediateExperimentalUISettings.debugRichText {
|
||||
result.append((message, ChatMessageRichDataBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
} else {
|
||||
result.append((message, ChatMessageWebpageBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
}
|
||||
result.append((message, ChatMessageWebpageBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
}
|
||||
needReactions = false
|
||||
}
|
||||
|
|
@ -395,6 +391,18 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
|||
}
|
||||
}
|
||||
|
||||
var richText: RichTextMessageAttribute?
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? RichTextMessageAttribute {
|
||||
richText = attribute
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if richText != nil {
|
||||
result.append((message, ChatMessageRichDataBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
}
|
||||
|
||||
if message.adAttribute != nil {
|
||||
result.removeAll()
|
||||
|
||||
|
|
@ -1627,9 +1635,12 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
let chatLocationPeerId: PeerId = item.chatLocation.peerId ?? item.content.firstMessage.id.peerId
|
||||
|
||||
var isInlinePage = false
|
||||
if item.context.sharedContext.immediateExperimentalUISettings.debugRichText, let webpage = item.message.media.first(where: { $0 is TelegramMediaWebpage }) as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content, content.instantPage != nil {
|
||||
allowFullWidth = true
|
||||
isInlinePage = true
|
||||
for attribute in item.message.attributes {
|
||||
if attribute is RichTextMessageAttribute {
|
||||
allowFullWidth = true
|
||||
isInlinePage = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ public class ChatMessageRichDataBubbleContentNode: ChatMessageBubbleContentNode
|
|||
let pageView = self.ensurePageView()
|
||||
pageView.update(layout: pageLayout, theme: pageTheme, animation: animation)
|
||||
pageView.frame = CGRect(
|
||||
origin: .zero,
|
||||
origin: CGPoint(x: -1.0, y: 0.0),
|
||||
size: pageLayout.contentSize
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2292,7 +2292,7 @@ extension ChatControllerImpl {
|
|||
let currentWebpagePreviewAttribute = currentMessage.webpagePreviewAttribute ?? WebpagePreviewMessageAttribute(leadingPreview: false, forceLargeMedia: nil, isManuallyAdded: true, isSafe: false)
|
||||
|
||||
if currentMessage.text != text.string || currentEntities != entities || updatingMedia || webpagePreviewAttribute != currentWebpagePreviewAttribute || disableUrlPreview {
|
||||
strongSelf.context.account.pendingUpdateMessageManager.add(messageId: editMessage.messageId, text: text.string, media: media, entities: entitiesAttribute, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertedMediaAttribute, disableUrlPreview: disableUrlPreview)
|
||||
strongSelf.context.account.pendingUpdateMessageManager.add(messageId: editMessage.messageId, text: text.string, media: media, entities: entitiesAttribute, richText: nil, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertedMediaAttribute, disableUrlPreview: disableUrlPreview)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ extension ChatControllerImpl {
|
|||
text: "",
|
||||
media: .update(.standalone(media: updatedTodo)),
|
||||
entities: nil,
|
||||
richText: nil,
|
||||
inlineStickers: [:]
|
||||
).start()
|
||||
})))
|
||||
|
|
|
|||
|
|
@ -4175,13 +4175,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
strongSelf.presentScheduleTimePicker(selectedTime: message.timestamp, selectedRepeatPeriod: message._asMessage().scheduleRepeatPeriod, completion: { [weak self] time, repeatPeriod in
|
||||
if let strongSelf = self {
|
||||
var entities: TextEntitiesMessageAttribute?
|
||||
var richText: RichTextMessageAttribute?
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? TextEntitiesMessageAttribute {
|
||||
entities = attribute
|
||||
break
|
||||
} else if let attribute = attribute as? RichTextMessageAttribute {
|
||||
richText = attribute
|
||||
}
|
||||
}
|
||||
strongSelf.editMessageDisposable.set((strongSelf.context.engine.messages.requestEditMessage(messageId: messageId, text: message.text, media: .keep, entities: entities, inlineStickers: [:], webpagePreviewAttribute: nil, disableUrlPreview: false, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute(scheduleTime: time, repeatPeriod: repeatPeriod)) |> deliverOnMainQueue).startStrict(next: { result in
|
||||
strongSelf.editMessageDisposable.set((strongSelf.context.engine.messages.requestEditMessage(messageId: messageId, text: message.text, media: .keep, entities: entities, richText: richText, inlineStickers: [:], webpagePreviewAttribute: nil, disableUrlPreview: false, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute(scheduleTime: time, repeatPeriod: repeatPeriod)) |> deliverOnMainQueue).startStrict(next: { result in
|
||||
}, error: { error in
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -519,14 +519,16 @@ extension ChatControllerImpl {
|
|||
return
|
||||
}
|
||||
var entities: TextEntitiesMessageAttribute?
|
||||
var richText: RichTextMessageAttribute?
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? TextEntitiesMessageAttribute {
|
||||
entities = attribute
|
||||
break
|
||||
} else if let attribute = attribute as? RichTextMessageAttribute {
|
||||
richText = attribute
|
||||
}
|
||||
}
|
||||
let scheduleTime = message.timestamp + repeatAttribute.repeatPeriod
|
||||
self.editMessageDisposable.set((self.context.engine.messages.requestEditMessage(messageId: message.id, text: message.text, media: .keep, entities: entities, inlineStickers: [:], webpagePreviewAttribute: nil, disableUrlPreview: false, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute(scheduleTime: scheduleTime, repeatPeriod: repeatAttribute.repeatPeriod)) |> deliverOnMainQueue).startStrict(next: { result in
|
||||
self.editMessageDisposable.set((self.context.engine.messages.requestEditMessage(messageId: message.id, text: message.text, media: .keep, entities: entities, richText: richText, inlineStickers: [:], webpagePreviewAttribute: nil, disableUrlPreview: false, scheduleInfoAttribute: OutgoingScheduleInfoMessageAttribute(scheduleTime: scheduleTime, repeatPeriod: repeatAttribute.repeatPeriod)) |> deliverOnMainQueue).startStrict(next: { result in
|
||||
}, error: { error in
|
||||
}))
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ import PresentationDataUtils
|
|||
import TextProcessingScreen
|
||||
import Pasteboard
|
||||
import UndoUI
|
||||
import BrowserUI
|
||||
|
||||
final class VideoNavigationControllerDropContentItem: NavigationControllerDropContentItem {
|
||||
let itemNode: OverlayMediaItemNode
|
||||
|
|
@ -4856,44 +4857,51 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
for text in breakChatInputText(trimChatInputText(inputText)) {
|
||||
if text.length != 0 {
|
||||
var attributes: [MessageAttribute] = []
|
||||
let entities: [MessageTextEntity]
|
||||
if case let .customChatContents(customChatContents) = self.chatPresentationInterfaceState.subject, case .businessLinkSetup = customChatContents.kind {
|
||||
entities = generateChatInputTextEntities(text, generateLinks: false)
|
||||
} else {
|
||||
entities = generateTextEntities(text.string, enabledTypes: .all, currentEntities: generateChatInputTextEntities(text, maxAnimatedEmojisInText: 0))
|
||||
}
|
||||
if !entities.isEmpty {
|
||||
attributes.append(TextEntitiesMessageAttribute(entities: entities))
|
||||
}
|
||||
|
||||
if let urlPreview = self.chatPresentationInterfaceState.urlPreview {
|
||||
if self.chatPresentationInterfaceState.interfaceState.composeDisableUrlPreviews.contains(urlPreview.url) {
|
||||
attributes.append(OutgoingContentInfoMessageAttribute(flags: [.disableLinkPreviews]))
|
||||
if self.context.sharedContext.immediateExperimentalUISettings.debugRichText, let attribute = inputRichTextAttributeFromText(context: self.context, text: inputText.string) {
|
||||
var attributes: [MessageAttribute] = []
|
||||
attributes.append(attribute)
|
||||
messages.append(.message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: nil, threadId: self.chatLocation.threadId, replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageSubject?.subjectModel, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||
mediaReference = nil
|
||||
} else {
|
||||
for text in breakChatInputText(trimChatInputText(inputText)) {
|
||||
if text.length != 0 {
|
||||
var attributes: [MessageAttribute] = []
|
||||
let entities: [MessageTextEntity]
|
||||
if case let .customChatContents(customChatContents) = self.chatPresentationInterfaceState.subject, case .businessLinkSetup = customChatContents.kind {
|
||||
entities = generateChatInputTextEntities(text, generateLinks: false)
|
||||
} else {
|
||||
attributes.append(WebpagePreviewMessageAttribute(leadingPreview: !urlPreview.positionBelowText, forceLargeMedia: urlPreview.largeMedia, isManuallyAdded: true, isSafe: false))
|
||||
entities = generateTextEntities(text.string, enabledTypes: .all, currentEntities: generateChatInputTextEntities(text, maxAnimatedEmojisInText: 0))
|
||||
}
|
||||
}
|
||||
|
||||
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
|
||||
for entity in entities {
|
||||
if case let .CustomEmoji(_, fileId) = entity.type {
|
||||
if let packId = bubbleUpEmojiOrStickersetsById[fileId] {
|
||||
if !bubbleUpEmojiOrStickersets.contains(packId) {
|
||||
bubbleUpEmojiOrStickersets.append(packId)
|
||||
if !entities.isEmpty {
|
||||
attributes.append(TextEntitiesMessageAttribute(entities: entities))
|
||||
}
|
||||
|
||||
if let urlPreview = self.chatPresentationInterfaceState.urlPreview {
|
||||
if self.chatPresentationInterfaceState.interfaceState.composeDisableUrlPreviews.contains(urlPreview.url) {
|
||||
attributes.append(OutgoingContentInfoMessageAttribute(flags: [.disableLinkPreviews]))
|
||||
} else {
|
||||
attributes.append(WebpagePreviewMessageAttribute(leadingPreview: !urlPreview.positionBelowText, forceLargeMedia: urlPreview.largeMedia, isManuallyAdded: true, isSafe: false))
|
||||
}
|
||||
}
|
||||
|
||||
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
|
||||
for entity in entities {
|
||||
if case let .CustomEmoji(_, fileId) = entity.type {
|
||||
if let packId = bubbleUpEmojiOrStickersetsById[fileId] {
|
||||
if !bubbleUpEmojiOrStickersets.contains(packId) {
|
||||
bubbleUpEmojiOrStickersets.append(packId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if bubbleUpEmojiOrStickersets.count > 1 {
|
||||
bubbleUpEmojiOrStickersets.removeAll()
|
||||
}
|
||||
|
||||
messages.append(.message(text: text.string, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, threadId: self.chatLocation.threadId, replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageSubject?.subjectModel, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets))
|
||||
mediaReference = nil
|
||||
}
|
||||
|
||||
if bubbleUpEmojiOrStickersets.count > 1 {
|
||||
bubbleUpEmojiOrStickersets.removeAll()
|
||||
}
|
||||
|
||||
messages.append(.message(text: text.string, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, threadId: self.chatLocation.threadId, replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageSubject?.subjectModel, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets))
|
||||
mediaReference = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2257,6 +2257,7 @@ extension ChatControllerImpl {
|
|||
text: "",
|
||||
media: .update(.standalone(media: todo)),
|
||||
entities: nil,
|
||||
richText: nil,
|
||||
inlineStickers: [:]
|
||||
).start()
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue