From d63d474854e805b4a0a3b79154453b57add4b09b Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Thu, 29 Feb 2024 16:08:12 +0400 Subject: [PATCH] Update API --- submodules/TelegramApi/Sources/Api0.swift | 4 +- submodules/TelegramApi/Sources/Api2.swift | 26 ++++--- submodules/TelegramApi/Sources/Api7.swift | 26 ++++--- .../Messages/QuickReplyMessages.swift | 23 +++++- .../AutomaticBusinessMessageSetupScreen.swift | 76 ++++++++++++++++++- 5 files changed, 126 insertions(+), 29 deletions(-) diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index d6ea57e18e..69621328d9 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -102,7 +102,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-944407322] = { return Api.BotMenuButton.parse_botMenuButton($0) } dict[1113113093] = { return Api.BotMenuButton.parse_botMenuButtonCommands($0) } dict[1966318984] = { return Api.BotMenuButton.parse_botMenuButtonDefault($0) } - dict[467254972] = { return Api.BusinessAwayMessage.parse_businessAwayMessage($0) } + dict[-283809188] = { return Api.BusinessAwayMessage.parse_businessAwayMessage($0) } dict[-910564679] = { return Api.BusinessAwayMessageSchedule.parse_businessAwayMessageScheduleAlways($0) } dict[-867328308] = { return Api.BusinessAwayMessageSchedule.parse_businessAwayMessageScheduleCustom($0) } dict[-1007487743] = { return Api.BusinessAwayMessageSchedule.parse_businessAwayMessageScheduleOutsideWorkHours($0) } @@ -308,7 +308,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-459324] = { return Api.InputBotInlineResult.parse_inputBotInlineResultDocument($0) } dict[1336154098] = { return Api.InputBotInlineResult.parse_inputBotInlineResultGame($0) } dict[-1462213465] = { return Api.InputBotInlineResult.parse_inputBotInlineResultPhoto($0) } - dict[-307493900] = { return Api.InputBusinessAwayMessage.parse_inputBusinessAwayMessage($0) } + dict[-2094959136] = { return Api.InputBusinessAwayMessage.parse_inputBusinessAwayMessage($0) } dict[26528571] = { return Api.InputBusinessGreetingMessage.parse_inputBusinessGreetingMessage($0) } dict[1871393450] = { return Api.InputBusinessRecipients.parse_inputBusinessRecipients($0) } dict[-212145112] = { return Api.InputChannel.parse_inputChannel($0) } diff --git a/submodules/TelegramApi/Sources/Api2.swift b/submodules/TelegramApi/Sources/Api2.swift index aaea1b49c7..9436ea5239 100644 --- a/submodules/TelegramApi/Sources/Api2.swift +++ b/submodules/TelegramApi/Sources/Api2.swift @@ -590,14 +590,15 @@ public extension Api { } public extension Api { enum BusinessAwayMessage: TypeConstructorDescription { - case businessAwayMessage(shortcutId: Int32, schedule: Api.BusinessAwayMessageSchedule, recipients: Api.BusinessRecipients) + case businessAwayMessage(flags: Int32, shortcutId: Int32, schedule: Api.BusinessAwayMessageSchedule, recipients: Api.BusinessRecipients) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .businessAwayMessage(let shortcutId, let schedule, let recipients): + case .businessAwayMessage(let flags, let shortcutId, let schedule, let recipients): if boxed { - buffer.appendInt32(467254972) + buffer.appendInt32(-283809188) } + serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(shortcutId, buffer: buffer, boxed: false) schedule.serialize(buffer, true) recipients.serialize(buffer, true) @@ -607,27 +608,30 @@ public extension Api { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .businessAwayMessage(let shortcutId, let schedule, let recipients): - return ("businessAwayMessage", [("shortcutId", shortcutId as Any), ("schedule", schedule as Any), ("recipients", recipients as Any)]) + case .businessAwayMessage(let flags, let shortcutId, let schedule, let recipients): + return ("businessAwayMessage", [("flags", flags as Any), ("shortcutId", shortcutId as Any), ("schedule", schedule as Any), ("recipients", recipients as Any)]) } } public static func parse_businessAwayMessage(_ reader: BufferReader) -> BusinessAwayMessage? { var _1: Int32? _1 = reader.readInt32() - var _2: Api.BusinessAwayMessageSchedule? + var _2: Int32? + _2 = reader.readInt32() + var _3: Api.BusinessAwayMessageSchedule? if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.BusinessAwayMessageSchedule + _3 = Api.parse(reader, signature: signature) as? Api.BusinessAwayMessageSchedule } - var _3: Api.BusinessRecipients? + var _4: Api.BusinessRecipients? if let signature = reader.readInt32() { - _3 = Api.parse(reader, signature: signature) as? Api.BusinessRecipients + _4 = Api.parse(reader, signature: signature) as? Api.BusinessRecipients } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.BusinessAwayMessage.businessAwayMessage(shortcutId: _1!, schedule: _2!, recipients: _3!) + let _c4 = _4 != nil + if _c1 && _c2 && _c3 && _c4 { + return Api.BusinessAwayMessage.businessAwayMessage(flags: _1!, shortcutId: _2!, schedule: _3!, recipients: _4!) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api7.swift b/submodules/TelegramApi/Sources/Api7.swift index 03c3e6512f..cbdf0ebf38 100644 --- a/submodules/TelegramApi/Sources/Api7.swift +++ b/submodules/TelegramApi/Sources/Api7.swift @@ -264,14 +264,15 @@ public extension Api { } public extension Api { enum InputBusinessAwayMessage: TypeConstructorDescription { - case inputBusinessAwayMessage(shortcutId: Int32, schedule: Api.BusinessAwayMessageSchedule, recipients: Api.InputBusinessRecipients) + case inputBusinessAwayMessage(flags: Int32, shortcutId: Int32, schedule: Api.BusinessAwayMessageSchedule, recipients: Api.InputBusinessRecipients) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .inputBusinessAwayMessage(let shortcutId, let schedule, let recipients): + case .inputBusinessAwayMessage(let flags, let shortcutId, let schedule, let recipients): if boxed { - buffer.appendInt32(-307493900) + buffer.appendInt32(-2094959136) } + serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(shortcutId, buffer: buffer, boxed: false) schedule.serialize(buffer, true) recipients.serialize(buffer, true) @@ -281,27 +282,30 @@ public extension Api { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .inputBusinessAwayMessage(let shortcutId, let schedule, let recipients): - return ("inputBusinessAwayMessage", [("shortcutId", shortcutId as Any), ("schedule", schedule as Any), ("recipients", recipients as Any)]) + case .inputBusinessAwayMessage(let flags, let shortcutId, let schedule, let recipients): + return ("inputBusinessAwayMessage", [("flags", flags as Any), ("shortcutId", shortcutId as Any), ("schedule", schedule as Any), ("recipients", recipients as Any)]) } } public static func parse_inputBusinessAwayMessage(_ reader: BufferReader) -> InputBusinessAwayMessage? { var _1: Int32? _1 = reader.readInt32() - var _2: Api.BusinessAwayMessageSchedule? + var _2: Int32? + _2 = reader.readInt32() + var _3: Api.BusinessAwayMessageSchedule? if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.BusinessAwayMessageSchedule + _3 = Api.parse(reader, signature: signature) as? Api.BusinessAwayMessageSchedule } - var _3: Api.InputBusinessRecipients? + var _4: Api.InputBusinessRecipients? if let signature = reader.readInt32() { - _3 = Api.parse(reader, signature: signature) as? Api.InputBusinessRecipients + _4 = Api.parse(reader, signature: signature) as? Api.InputBusinessRecipients } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.InputBusinessAwayMessage.inputBusinessAwayMessage(shortcutId: _1!, schedule: _2!, recipients: _3!) + let _c4 = _4 != nil + if _c1 && _c2 && _c3 && _c4 { + return Api.InputBusinessAwayMessage.inputBusinessAwayMessage(flags: _1!, shortcutId: _2!, schedule: _3!, recipients: _4!) } else { return nil diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/QuickReplyMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/QuickReplyMessages.swift index 81d67f73ab..294e072f0f 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/QuickReplyMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/QuickReplyMessages.swift @@ -540,16 +540,19 @@ public final class TelegramBusinessAwayMessage: Codable, Equatable { case shortcutId case recipients case schedule + case sendWhenOffline } public let shortcutId: Int32 public let recipients: TelegramBusinessRecipients public let schedule: Schedule + public let sendWhenOffline: Bool - public init(shortcutId: Int32, recipients: TelegramBusinessRecipients, schedule: Schedule) { + public init(shortcutId: Int32, recipients: TelegramBusinessRecipients, schedule: Schedule, sendWhenOffline: Bool) { self.shortcutId = shortcutId self.recipients = recipients self.schedule = schedule + self.sendWhenOffline = sendWhenOffline } public init(from decoder: Decoder) throws { @@ -558,6 +561,7 @@ public final class TelegramBusinessAwayMessage: Codable, Equatable { self.shortcutId = try container.decode(Int32.self, forKey: .shortcutId) self.recipients = try container.decode(TelegramBusinessRecipients.self, forKey: .recipients) self.schedule = try container.decode(Schedule.self, forKey: .schedule) + self.sendWhenOffline = try container.decodeIfPresent(Bool.self, forKey: .sendWhenOffline) ?? false } public func encode(to encoder: Encoder) throws { @@ -566,6 +570,7 @@ public final class TelegramBusinessAwayMessage: Codable, Equatable { try container.encode(self.shortcutId, forKey: .shortcutId) try container.encode(self.recipients, forKey: .recipients) try container.encode(self.schedule, forKey: .schedule) + try container.encode(self.sendWhenOffline, forKey: .sendWhenOffline) } public static func ==(lhs: TelegramBusinessAwayMessage, rhs: TelegramBusinessAwayMessage) -> Bool { @@ -582,6 +587,9 @@ public final class TelegramBusinessAwayMessage: Codable, Equatable { if lhs.schedule != rhs.schedule { return false } + if lhs.sendWhenOffline != rhs.sendWhenOffline { + return false + } return true } @@ -590,7 +598,7 @@ public final class TelegramBusinessAwayMessage: Codable, Equatable { extension TelegramBusinessAwayMessage { convenience init(apiAwayMessage: Api.BusinessAwayMessage) { switch apiAwayMessage { - case let .businessAwayMessage(shortcutId, schedule, recipients): + case let .businessAwayMessage(flags, shortcutId, schedule, recipients): let mappedSchedule: Schedule switch schedule { case .businessAwayMessageScheduleAlways: @@ -601,10 +609,13 @@ extension TelegramBusinessAwayMessage { mappedSchedule = .custom(beginTimestamp: startDate, endTimestamp: endDate) } + let sendWhenOffline = (flags & (1 << 0)) != 0 + self.init( shortcutId: shortcutId, recipients: TelegramBusinessRecipients(apiValue: recipients), - schedule: mappedSchedule + schedule: mappedSchedule, + sendWhenOffline: sendWhenOffline ) } } @@ -729,7 +740,13 @@ func _internal_updateBusinessAwayMessage(account: Account, awayMessage: Telegram mappedSchedule = .businessAwayMessageScheduleCustom(startDate: beginTimestamp, endDate: endTimestamp) } + var flags: Int32 = 0 + if awayMessage.sendWhenOffline { + flags |= 1 << 0 + } + mappedMessage = .inputBusinessAwayMessage( + flags: flags, shortcutId: awayMessage.shortcutId, schedule: mappedSchedule, recipients: awayMessage.recipients.apiInputValue(additionalPeers: additionalPeers) diff --git a/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/AutomaticBusinessMessageSetupScreen.swift b/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/AutomaticBusinessMessageSetupScreen.swift index de02d36ed0..6b925a68f5 100644 --- a/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/AutomaticBusinessMessageSetupScreen.swift +++ b/submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen/Sources/AutomaticBusinessMessageSetupScreen.swift @@ -120,6 +120,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component { private let messagesSection = ComponentView() private let scheduleSection = ComponentView() private let customScheduleSection = ComponentView() + private let sendWhenOfflineSection = ComponentView() private let accessSection = ComponentView() private let excludedSection = ComponentView() private let periodSection = ComponentView() @@ -140,6 +141,8 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component { private var customScheduleStart: Date? private var customScheduleEnd: Date? + private var sendWhenOffline: Bool = false + private var hasAccessToAllChatsByDefault: Bool = true private var additionalPeerList = AdditionalPeerList( categories: Set(), @@ -191,7 +194,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component { let presentationData = component.context.sharedContext.currentPresentationData.with { $0 } if self.isOn { - if self.hasAccessToAllChatsByDefault && self.additionalPeerList.categories.isEmpty && self.additionalPeerList.peers.isEmpty { + if !self.hasAccessToAllChatsByDefault && self.additionalPeerList.categories.isEmpty && self.additionalPeerList.peers.isEmpty { //TODO:localize self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: "No recipients selected. Reset?", actions: [ TextAlertAction(type: .genericAction, title: "Cancel", action: { @@ -285,7 +288,8 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component { awayMessage = TelegramBusinessAwayMessage( shortcutId: currentShortcut.id, recipients: recipients, - schedule: mappedSchedule + schedule: mappedSchedule, + sendWhenOffline: self.sendWhenOffline ) } let _ = component.context.engine.accountData.updateBusinessAwayMessage(awayMessage: awayMessage).startStandalone() @@ -601,6 +605,9 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component { if let awayMessage = component.initialData.awayMessage { self.isOn = true + + self.sendWhenOffline = awayMessage.sendWhenOffline + initialRecipients = awayMessage.recipients switch awayMessage.schedule { @@ -1110,6 +1117,71 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component { otherSectionsHeight += customScheduleSectionsHeight } } + + if case .away = component.mode { + let sendWhenOfflineSectionSize = self.sendWhenOfflineSection.update( + transition: transition, + component: AnyComponent(ListSectionComponent( + theme: environment.theme, + header: nil, + footer: AnyComponent(MultilineTextComponent( + text: .markdown( + text: "Don't send the away message if you've recently been online.", + attributes: MarkdownAttributes( + body: MarkdownAttributeSet(font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.freeTextColor), + bold: MarkdownAttributeSet(font: Font.semibold(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.freeTextColor), + link: MarkdownAttributeSet(font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.itemAccentColor), + linkAttribute: { _ in + return nil + } + ) + ), + maximumNumberOfLines: 0 + )), + items: [ + AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent( + theme: environment.theme, + title: AnyComponent(VStack([ + AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString( + string: "Only if Offline", + font: Font.regular(presentationData.listsFontSize.baseDisplaySize), + textColor: environment.theme.list.itemPrimaryTextColor + )), + maximumNumberOfLines: 1 + ))), + ], alignment: .left, spacing: 2.0)), + leftIcon: nil, + accessory: .toggle(ListActionItemComponent.Toggle( + style: .regular, + isOn: self.sendWhenOffline, + action: { [weak self] value in + guard let self else { + return + } + self.sendWhenOffline = value + self.state?.updated(transition: .spring(duration: 0.4)) + } + )), + action: nil + ))) + ] + )), + environment: {}, + containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 10000.0) + ) + let sendWhenOfflineSectionFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight + otherSectionsHeight), size: sendWhenOfflineSectionSize) + if let sendWhenOfflineSectionView = self.sendWhenOfflineSection.view { + if sendWhenOfflineSectionView.superview == nil { + sendWhenOfflineSectionView.layer.allowsGroupOpacity = true + self.scrollView.addSubview(sendWhenOfflineSectionView) + } + transition.setFrame(view: sendWhenOfflineSectionView, frame: sendWhenOfflineSectionFrame) + alphaTransition.setAlpha(view: sendWhenOfflineSectionView, alpha: self.isOn ? 1.0 : 0.0) + } + otherSectionsHeight += sendWhenOfflineSectionSize.height + otherSectionsHeight += sectionSpacing + } //TODO:localize let accessSectionSize = self.accessSection.update(