Update API

This commit is contained in:
Ilya Laktyushin 2026-02-13 14:09:36 +04:00
parent c0f7cda4eb
commit 9616ea2ad9
10 changed files with 82 additions and 15 deletions

View file

@ -2676,7 +2676,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
var entities = entities.filter { entity in
switch entity.type {
case .Spoiler, .CustomEmoji:
case .Spoiler, .CustomEmoji, .FormattedDate:
return true
case .Strikethrough, .Underline, .Italic, .Bold:
return true
@ -2709,7 +2709,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
let messageString: NSAttributedString
if !messageText.isEmpty && entities.count > 0 {
messageString = foldLineBreaks(stringWithAppliedEntities(messageText, entities: entities, baseColor: theme.messageTextColor, linkColor: theme.messageTextColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: italicTextFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message._asMessage()))
messageString = foldLineBreaks(stringWithAppliedEntities(messageText, entities: entities, strings: item.presentationData.strings, dateTimeFormat: item.presentationData.dateTimeFormat, baseColor: theme.messageTextColor, linkColor: theme.messageTextColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: italicTextFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message._asMessage()))
} else if spoilers != nil || customEmojiRanges != nil {
let mutableString = NSMutableAttributedString(string: messageText, font: textFont, textColor: theme.messageTextColor)
if let spoilers = spoilers {

View file

@ -1244,7 +1244,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-484987010] = { return Api.Updates.parse_updatesTooLong($0) }
dict[1648005024] = { return Api.UrlAuthResult.parse_urlAuthResultAccepted($0) }
dict[-1445536993] = { return Api.UrlAuthResult.parse_urlAuthResultDefault($0) }
dict[-948574935] = { return Api.UrlAuthResult.parse_urlAuthResultRequest($0) }
dict[-117904610] = { return Api.UrlAuthResult.parse_urlAuthResultRequest($0) }
dict[829899656] = { return Api.User.parse_user($0) }
dict[-742634630] = { return Api.User.parse_userEmpty($0) }
dict[-1607745218] = { return Api.UserFull.parse_userFull($0) }

View file

@ -557,7 +557,8 @@ public extension Api {
public var ip: String?
public var region: String?
public var matchCodes: [String]?
public init(flags: Int32, bot: Api.User, domain: String, browser: String?, platform: String?, ip: String?, region: String?, matchCodes: [String]?) {
public var userIdHint: Int64?
public init(flags: Int32, bot: Api.User, domain: String, browser: String?, platform: String?, ip: String?, region: String?, matchCodes: [String]?, userIdHint: Int64?) {
self.flags = flags
self.bot = bot
self.domain = domain
@ -566,6 +567,7 @@ public extension Api {
self.ip = ip
self.region = region
self.matchCodes = matchCodes
self.userIdHint = userIdHint
}
}
case urlAuthResultAccepted(Cons_urlAuthResultAccepted)
@ -590,7 +592,7 @@ public extension Api {
break
case .urlAuthResultRequest(let _data):
if boxed {
buffer.appendInt32(-948574935)
buffer.appendInt32(-117904610)
}
serializeInt32(_data.flags, buffer: buffer, boxed: false)
_data.bot.serialize(buffer, true)
@ -614,6 +616,9 @@ public extension Api {
serializeString(item, buffer: buffer, boxed: false)
}
}
if Int(_data.flags) & Int(1 << 4) != 0 {
serializeInt64(_data.userIdHint!, buffer: buffer, boxed: false)
}
break
}
}
@ -625,7 +630,7 @@ public extension Api {
case .urlAuthResultDefault:
return ("urlAuthResultDefault", [])
case .urlAuthResultRequest(let _data):
return ("urlAuthResultRequest", [("flags", _data.flags as Any), ("bot", _data.bot as Any), ("domain", _data.domain as Any), ("browser", _data.browser as Any), ("platform", _data.platform as Any), ("ip", _data.ip as Any), ("region", _data.region as Any), ("matchCodes", _data.matchCodes as Any)])
return ("urlAuthResultRequest", [("flags", _data.flags as Any), ("bot", _data.bot as Any), ("domain", _data.domain as Any), ("browser", _data.browser as Any), ("platform", _data.platform as Any), ("ip", _data.ip as Any), ("region", _data.region as Any), ("matchCodes", _data.matchCodes as Any), ("userIdHint", _data.userIdHint as Any)])
}
}
@ -679,6 +684,10 @@ public extension Api {
_8 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
}
}
var _9: Int64?
if Int(_1!) & Int(1 << 4) != 0 {
_9 = reader.readInt64()
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -687,8 +696,9 @@ public extension Api {
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
let _c7 = (Int(_1!) & Int(1 << 2) == 0) || _7 != nil
let _c8 = (Int(_1!) & Int(1 << 3) == 0) || _8 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
return Api.UrlAuthResult.urlAuthResultRequest(Cons_urlAuthResultRequest(flags: _1!, bot: _2!, domain: _3!, browser: _4, platform: _5, ip: _6, region: _7, matchCodes: _8))
let _c9 = (Int(_1!) & Int(1 << 4) == 0) || _9 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
return Api.UrlAuthResult.urlAuthResultRequest(Cons_urlAuthResultRequest(flags: _1!, bot: _2!, domain: _3!, browser: _4, platform: _5, ip: _6, region: _7, matchCodes: _8, userIdHint: _9))
}
else {
return nil

View file

@ -5429,6 +5429,21 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func declineUrlAuth(url: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(893610940)
serializeString(url, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.declineUrlAuth", parameters: [("url", String(describing: url))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.messages {
static func deleteChat(chatId: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()

View file

@ -196,7 +196,7 @@ public enum MessageActionUrlAuthResult {
case `default`
case accepted(url: String?)
case request(domain: String, bot: Peer, clientData: ClientData?, flags: Flags)
case request(domain: String, bot: Peer, clientData: ClientData?, flags: Flags, matchCodes: [String]?, userIdHint: EnginePeer.Id?)
}
public enum MessageActionUrlAuthError {
@ -259,11 +259,19 @@ func _internal_requestMessageActionUrlAuth(account: Account, subject: MessageAct
if (apiFlags & (1 << 1)) != 0 {
flags.insert(.requestPhoneNumber)
}
return .request(domain: domain, bot: TelegramUser(user: bot), clientData: clientData, flags: flags)
return .request(domain: domain, bot: TelegramUser(user: bot), clientData: clientData, flags: flags, matchCodes: urlAuthResultRequestData.matchCodes, userIdHint: urlAuthResultRequestData.userIdHint.flatMap { EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value($0)) })
}
}
}
func _internal_declineUrlAuth(account: Account, url: String) -> Signal<Never, NoError> {
return account.network.request(Api.functions.messages.declineUrlAuth(url: url))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> ignoreValues
}
func _internal_acceptMessageActionUrlAuth(account: Account, subject: MessageActionUrlSubject, allowWriteAccess: Bool, sharePhoneNumber: Bool) -> Signal<MessageActionUrlAuthResult, MessageActionUrlAuthError> {
var flags: Int32 = 0
if allowWriteAccess {

View file

@ -102,6 +102,10 @@ public extension TelegramEngine {
public func acceptMessageActionUrlAuth(subject: MessageActionUrlSubject, allowWriteAccess: Bool, sharePhoneNumber: Bool) -> Signal<MessageActionUrlAuthResult, MessageActionUrlAuthError> {
return _internal_acceptMessageActionUrlAuth(account: self.account, subject: subject, allowWriteAccess: allowWriteAccess, sharePhoneNumber: sharePhoneNumber)
}
public func declineUrlAuth(url: String) -> Signal<Never, NoError> {
return _internal_declineUrlAuth(account: self.account, url: url)
}
public func searchMessages(location: SearchMessagesLocation, query: String, state: SearchMessagesState?, centerId: MessageId? = nil, limit: Int32 = 100) -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> {
return _internal_searchMessages(account: self.account, location: location, query: query, state: state, centerId: centerId, limit: limit)

View file

@ -79,7 +79,7 @@ private final class AuthConfirmationSheetContent: CombinedComponent {
}
func displayPhoneNumberConfirmation(commit: @escaping (Bool) -> Void) {
guard case let .request(domain, _, _, _) = self.subject else {
guard case let .request(domain, _, _, _, _, _) = self.subject else {
return
}
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
@ -182,7 +182,7 @@ private final class AuthConfirmationSheetContent: CombinedComponent {
let presentationData = context.component.context.sharedContext.currentPresentationData.with { $0 }
let _ = strings
guard case let .request(domain, bot, clientData, flags) = component.subject else {
guard case let .request(domain, bot, clientData, flags, _, _) = component.subject else {
fatalError()
}

View file

@ -2909,7 +2909,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
switch result {
case .default:
strongSelf.openUrl(defaultUrl, concealed: false, skipUrlAuth: true)
case let .request(domain, bot, _, flags):
case let .request(domain, bot, _, flags, _, _):
let controller = chatMessageActionUrlAuthController(context: strongSelf.context, defaultUrl: defaultUrl, domain: domain, bot: bot, requestWriteAccess: flags.contains(.requestWriteAccess), displayName: EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), open: { [weak self] authorize, allowWriteAccess in
if let strongSelf = self {
if authorize {

View file

@ -1841,7 +1841,7 @@ func openResolvedUrlImpl(
Queue.mainQueue().after(0.3) {
let text: String
if case let .request(domain, _, _, flags) = result {
if case let .request(domain, _, _, flags, _, _) = result {
if flags.contains(.requestPhoneNumber) && !sharePhoneNumber {
text = presentationData.strings.AuthConfirmation_LoginSuccess_TextNoNumber(domain).string
} else {
@ -1852,7 +1852,7 @@ func openResolvedUrlImpl(
}
}
}, error: { _ in
if case let .request(domain, _, _, _) = result {
if case let .request(domain, _, _, _, _, _) = result {
let controller = UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: presentationData.strings.AuthConfirmation_LoginFail_Title, text: presentationData.strings.AuthConfirmation_LoginFail_Text(domain).string, cancel: nil, destructive: false), action: { _ in return true })
(navigationController?.topViewController as? ViewController)?.present(controller, in: .window(.root))
}

View file

@ -33,7 +33,16 @@ public func stringForEntityFormattedDate(timestamp: Int32, format: MessageTextEn
case let .full(timeFormat, dateFormat, dayOfWeek):
let _ = dayOfWeek
var string = ""
if dayOfWeek {
var t: time_t = Int(timestamp)
var timeinfo = tm()
localtime_r(&t, &timeinfo);
string = stringForDayOfWeek(strings: strings, day: timeinfo.tm_wday, short: dateFormat == .short)
}
if let dateFormat {
if !string.isEmpty {
string += " "
}
switch dateFormat {
case .short:
string += stringForShortDate(timestamp: timestamp, strings: strings, dateTimeFormat: dateTimeFormat)
@ -59,6 +68,27 @@ public func stringForEntityFormattedDate(timestamp: Int32, format: MessageTextEn
}
}
private func stringForDayOfWeek(strings: PresentationStrings, day: Int32, short: Bool) -> String {
switch day {
case 0:
return short ? strings.Weekday_ShortSunday : strings.Weekday_Sunday
case 1:
return short ? strings.Weekday_ShortMonday : strings.Weekday_Monday
case 2:
return short ? strings.Weekday_ShortTuesday : strings.Weekday_Tuesday
case 3:
return short ? strings.Weekday_ShortWednesday : strings.Weekday_Wednesday
case 4:
return short ? strings.Weekday_ShortThursday : strings.Weekday_Thursday
case 5:
return short ? strings.Weekday_ShortFriday : strings.Weekday_Friday
case 6:
return short ? strings.Weekday_ShortSaturday : strings.Weekday_Saturday
default:
return ""
}
}
public func stringForShortTimestamp(hours: Int32, minutes: Int32, seconds: Int32? = nil, dateTimeFormat: PresentationDateTimeFormat, formatAsPlainText: Bool = false) -> String {
switch dateTimeFormat.timeFormat {
case .regular: