Power saving improvements

This commit is contained in:
Ali 2023-02-24 18:08:30 +04:00
parent 96496aabd9
commit de29a6b54b
55 changed files with 1551 additions and 411 deletions

View File

@ -740,7 +740,7 @@ private final class NotificationServiceHandler {
} else {
automaticMediaDownloadSettings = MediaAutoDownloadSettings.defaultSettings
}
let shouldSynchronizeState = automaticMediaDownloadSettings.energyUsageSettings.synchronizeInBackground
let shouldSynchronizeState = true//automaticMediaDownloadSettings.energyUsageSettings.synchronizeInBackground
if let keyId = notificationPayloadKeyId(data: payloadData) {
outer: for listRecord in records.records {

View File

@ -17,6 +17,7 @@ import MultiAnimationRenderer
import EmojiTextAttachmentView
import TextFormat
import EmojiStatusComponent
import TelegramStringFormatting
private let avatarFont = avatarPlaceholderFont(size: 16.0)
@ -349,6 +350,8 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
}
}
private static let readIconImage: UIImage? = generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Read"), color: .white)?.withRenderingMode(.alwaysTemplate)
private final class ReactionsTabNode: ASDisplayNode, UIScrollViewDelegate {
private final class ItemNode: HighlightTrackingButtonNode {
let context: AccountContext
@ -358,6 +361,8 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
let highlightBackgroundNode: ASDisplayNode
let avatarNode: AvatarNode
let titleLabelNode: ImmediateTextNode
let textLabelNode: ImmediateTextNode
let readIconView: UIImageView
var credibilityIconView: ComponentView<Empty>?
let separatorNode: ASDisplayNode
@ -389,6 +394,13 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
self.titleLabelNode.maximumNumberOfLines = 1
self.titleLabelNode.isUserInteractionEnabled = false
self.textLabelNode = ImmediateTextNode()
self.textLabelNode.isAccessibilityElement = false
self.textLabelNode.maximumNumberOfLines = 1
self.textLabelNode.isUserInteractionEnabled = false
self.readIconView = UIImageView(image: readIconImage)
self.separatorNode = ASDisplayNode()
self.separatorNode.isAccessibilityElement = false
@ -400,6 +412,8 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
self.addSubnode(self.highlightBackgroundNode)
self.addSubnode(self.avatarNode)
self.addSubnode(self.titleLabelNode)
self.addSubnode(self.textLabelNode)
self.view.addSubview(self.readIconView)
self.highligthedChanged = { [weak self] highlighted in
guard let strongSelf = self else {
@ -577,9 +591,49 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
maxTextWidth -= 32.0
}
let titleSize = self.titleLabelNode.updateLayout(CGSize(width: maxTextWidth, height: 100.0))
let titleFrame = CGRect(origin: CGPoint(x: avatarInset + avatarSize + avatarSpacing, y: floor((size.height - titleSize.height) / 2.0)), size: titleSize)
//TODO:localize
var text = "read"
if let timestamp = item.timestamp {
let dateText = humanReadableStringForTimestamp(strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, timestamp: timestamp, alwaysShowTime: false, allowYesterday: true, format: HumanReadableStringFormat(
dateFormatString: { value in
//TODO:localize
return PresentationStrings.FormattedString(string: "\(value)", ranges: [])
},
tomorrowFormatString: { value in
//TODO:localize
return PresentationStrings.FormattedString(string: "at \(value)", ranges: [])
},
todayFormatString: { value in
//TODO:localize
return PresentationStrings.FormattedString(string: "at \(value)", ranges: [])
},
yesterdayFormatString: { value in
//TODO:localize
return PresentationStrings.FormattedString(string: "yesterday", ranges: [])
}
)).string
text = "read \(dateText)"
}
self.textLabelNode.attributedText = NSAttributedString(string: text, font: Font.regular(15.0), textColor: presentationData.theme.contextMenu.secondaryColor)
let textSize = self.textLabelNode.updateLayout(CGSize(width: maxTextWidth - 18.0, height: 100.0))
let textSpacing: CGFloat = 2.0
let contentHeight = titleSize.height + textSpacing + textSize.height
let contentY = floor((size.height - contentHeight) / 2.0)
let titleFrame = CGRect(origin: CGPoint(x: avatarInset + avatarSize + avatarSpacing, y: contentY), size: titleSize)
self.titleLabelNode.frame = titleFrame
let textFrame = CGRect(origin: CGPoint(x: titleFrame.minX + 18.0, y: titleFrame.maxY + textSpacing), size: textSize)
self.textLabelNode.frame = textFrame
if let readImage = self.readIconView.image {
self.readIconView.tintColor = presentationData.theme.contextMenu.secondaryColor
let fraction: CGFloat = 0.7
let iconSize = CGSize(width: floor(readImage.size.width * fraction), height: floor(readImage.size.height * fraction))
self.readIconView.frame = CGRect(origin: CGPoint(x: titleFrame.minX, y: textFrame.minY + 2.0), size: iconSize)
}
if let credibilityIconView = self.credibilityIconView, let credibilityIconSize = credibilityIconSize {
if let credibilityIconComponentView = credibilityIconView.view {
if credibilityIconComponentView.superview == nil {
@ -623,7 +677,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
for peer in readStats.peers {
if !existingPeers.contains(peer.id) {
existingPeers.insert(peer.id)
mergedItems.append(EngineMessageReactionListContext.Item(peer: peer, reaction: nil))
mergedItems.append(EngineMessageReactionListContext.Item(peer: peer, reaction: nil, timestamp: readStats.readTimestamps[peer.id]))
}
}
}
@ -763,7 +817,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
if let size = self.currentSize {
var apparentHeight = -self.scrollNode.view.contentOffset.y + self.scrollNode.view.contentSize.height
apparentHeight = max(apparentHeight, 44.0)
apparentHeight = max(apparentHeight, 56.0)
apparentHeight = min(apparentHeight, size.height + 100.0)
if self.apparentHeight != apparentHeight {
self.apparentHeight = apparentHeight
@ -780,7 +834,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
guard let presentationData = self.presentationData else {
return
}
let itemHeight: CGFloat = 44.0
let itemHeight: CGFloat = 56.0
let visibleBounds = self.scrollNode.bounds.insetBy(dx: 0.0, dy: -180.0)
var validIds = Set<Int>()
@ -876,7 +930,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
}
func update(presentationData: PresentationData, constrainedSize: CGSize, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) -> (height: CGFloat, apparentHeight: CGFloat) {
let itemHeight: CGFloat = 44.0
let itemHeight: CGFloat = 56.0
if self.presentationData?.theme !== presentationData.theme {
let sideInset: CGFloat = 40.0

View File

@ -225,7 +225,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
let itemSeparatorColor: UIColor
let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize)
let textFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize * 14.0 / 17.0)
let textFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize * 13.0 / 17.0)
var updatedTheme: PresentationTheme?
if currentItem?.presentationData.theme !== item.presentationData.theme {
@ -250,6 +250,13 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
insets = itemListNeighborsGroupedInsets(neighbors, params)
}
let topInset: CGFloat
if item.text != nil {
topInset = 9.0
} else {
topInset = 11.0
}
var leftInset = 16.0 + params.leftInset
if let _ = item.icon {
leftInset += 43.0
@ -262,11 +269,11 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.title, font: titleFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: item.maximumNumberOfLines, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - params.rightInset - 64.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.text ?? "", font: textFont, textColor: item.presentationData.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - params.rightInset - 64.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.text ?? "", font: textFont, textColor: item.presentationData.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - params.rightInset - 84.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
contentSize.height = max(contentSize.height, titleLayout.size.height + 22.0)
contentSize.height = max(contentSize.height, titleLayout.size.height + topInset * 2.0)
if item.text != nil {
contentSize.height += 2.0 + textLayout.size.height
contentSize.height += -1.0 + textLayout.size.height
}
if !item.enabled {
@ -307,7 +314,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
if item.text == nil {
iconY = floor((layout.contentSize.height - icon.size.height) / 2.0)
} else {
iconY = max(0.0, floor(11.0 + titleLayout.size.height + 1.0 - icon.size.height * 0.5))
iconY = max(0.0, floor(topInset + titleLayout.size.height + 1.0 - icon.size.height * 0.5))
}
strongSelf.iconNode.frame = CGRect(origin: CGPoint(x: params.leftInset + floor((leftInset - params.leftInset - icon.size.width) / 2.0), y: iconY), size: icon.size)
} else if strongSelf.iconNode.supernode != nil {
@ -415,7 +422,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
}
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 11.0), size: titleLayout.size)
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: topInset), size: titleLayout.size)
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: strongSelf.titleNode.frame.maxY + 2.0), size: textLayout.size)

View File

@ -9,16 +9,15 @@ import TelegramUIPreferences
import ItemListUI
import PresentationDataUtils
import AccountContext
import UndoUI
enum ItemType: CaseIterable {
case autoplayVideo
case autoplayGif
case loopStickers
case loopEmoji
case playVideoAvatars
case fullTranslucency
case extendBackgroundWork
case synchronizeInBackground
case autodownloadInBackground
var settingsKeyPath: WritableKeyPath<EnergyUsageSettings, Bool> {
@ -31,14 +30,10 @@ enum ItemType: CaseIterable {
return \.loopStickers
case .loopEmoji:
return \.loopEmoji
case .playVideoAvatars:
return \.playVideoAvatars
case .fullTranslucency:
return \.fullTranslucency
case .extendBackgroundWork:
return \.extendBackgroundWork
case .synchronizeInBackground:
return \.synchronizeInBackground
case .autodownloadInBackground:
return \.autodownloadInBackground
}
@ -49,69 +44,59 @@ enum ItemType: CaseIterable {
switch self {
case .autoplayVideo:
return (
"Settings/Menu/Reactions",
"Settings/Power/PowerIconVideo",
"Autoplay Videos",
"Autoplay and loop videos and video messages in chats."
)
case .autoplayGif:
return (
"Settings/Menu/Reactions",
"Settings/Power/PowerIconGif",
"Autoplay GIFs",
"Autoplay and loop GIFs in chats and in the keyboard."
)
case .loopStickers:
return (
"Settings/Menu/Reactions",
"Settings/Power/PowerIconStickers",
"Sticker Animations",
"Autoplay and loop GIFs in chats and in the keyboard."
"Loop animated stickers, play full-screen premium effects."
)
case .loopEmoji:
return (
"Settings/Menu/Reactions",
"Settings/Power/PowerIconEmoji",
"Emoli Animations",
"Loop animated emoji in messages, reactions, statuses."
)
case .playVideoAvatars:
return (
"Settings/Menu/Reactions",
"Autoplay Video Avatars",
"Autoplay and loop video avatars in chats"
)
case .fullTranslucency:
return (
"Settings/Menu/Reactions",
"Settings/Power/PowerIconEffects",
"Interface Effects",
"Various effects and animations that make Telegram look amazing."
)
case .extendBackgroundWork:
return (
"Settings/Menu/Reactions",
"Settings/Power/PowerIconBackgroundTime",
"Extended Background Time",
"Extended Background Time Description"
)
case .synchronizeInBackground:
return (
"Settings/Menu/Reactions",
"Background Sync",
"Background Sync Description"
"Update chats faster when switching between apps."
)
case .autodownloadInBackground:
return (
"Settings/Menu/Reactions",
"Preload Media in Chats",
"Preload Media in Chats Description"
"Settings/Power/PowerIconMedia",
"Preload Media",
"Start loading media while in the chat list for faster access."
)
}
}
}
private final class EnergeSavingSettingsScreenArguments {
let toggleAll: (Bool) -> Void
let updateThreshold: (Int32) -> Void
let toggleItem: (ItemType) -> Void
let displayDisabledTooltip: () -> Void
init(toggleAll: @escaping (Bool) -> Void, toggleItem: @escaping (ItemType) -> Void) {
self.toggleAll = toggleAll
init(updateThreshold: @escaping (Int32) -> Void, toggleItem: @escaping (ItemType) -> Void, displayDisabledTooltip: @escaping () -> Void) {
self.updateThreshold = updateThreshold
self.toggleItem = toggleItem
self.displayDisabledTooltip = displayDisabledTooltip
}
}
@ -122,20 +107,22 @@ private enum EnergeSavingSettingsScreenSection: Int32 {
private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
enum StableId: Hashable {
case allHeader
case all
case allFooter
case itemsHeader
case item(ItemType)
}
case all(Bool)
case allFooter
case allHeader(Bool?)
case all(Int32)
case allFooter(String)
case item(index: Int, type: ItemType, value: Bool, enabled: Bool)
case itemsHeader
var section: ItemListSectionId {
switch self {
case .all, .allFooter:
case .allHeader, .all, .allFooter:
return EnergeSavingSettingsScreenSection.all.rawValue
case .item, .itemsHeader:
return EnergeSavingSettingsScreenSection.items.rawValue
@ -144,6 +131,8 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
var sortIndex: Int {
switch self {
case .allHeader:
return -4
case .all:
return -3
case .allFooter:
@ -157,6 +146,8 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
var stableId: StableId {
switch self {
case .allHeader:
return .allHeader
case .all:
return .all
case .allFooter:
@ -175,13 +166,28 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
let arguments = arguments as! EnergeSavingSettingsScreenArguments
switch self {
case let .all(value):
case let .allHeader(value):
//TODO:localize
return ItemListSwitchItem(presentationData: presentationData, title: "Power-Saving Mode", value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in
arguments.toggleAll(value)
})
case .allFooter:
return ItemListTextItem(presentationData: presentationData, text: .plain("Reduce all resource-intensive animations and background activity."), sectionId: self.section)
let text: String
if let value {
let modeValue = value ? "ON" : "OFF"
text = "POWER SAVING MODE (\(modeValue))"
} else {
text = "POWER SAVING MODE"
}
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .all(value):
return EnergyUsageBatteryLevelItem(
theme: presentationData.theme,
strings: presentationData.strings,
value: value,
sectionId: self.section,
updated: { value in
arguments.updateThreshold(value)
}
)
case let .allFooter(text):
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
case .itemsHeader:
//TODO:localize
return ItemListSectionHeaderItem(presentationData: presentationData, text: "RESOURCE-INTENSIVE PROCESSES", sectionId: self.section)
@ -189,6 +195,8 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
let (iconName, title, text) = type.title(strings: presentationData.strings)
return ItemListSwitchItem(presentationData: presentationData, icon: UIImage(bundleImageName: iconName)?.precomposed(), title: title, text: text, value: value, enableInteractiveChanges: true, enabled: enabled, sectionId: self.section, style: .blocks, updated: { value in
arguments.toggleItem(type)
}, activatedWhileDisabled: {
arguments.displayDisabledTooltip()
})
}
}
@ -200,29 +208,57 @@ private func energeSavingSettingsScreenEntries(
) -> [EnergeSavingSettingsScreenEntry] {
var entries: [EnergeSavingSettingsScreenEntry] = []
let powerSavingOn = ItemType.allCases.allSatisfy({ item in !settings.energyUsageSettings[keyPath: item.settingsKeyPath] })
entries.append(.all(powerSavingOn))
entries.append(.allFooter)
let isOn = automaticEnergyUsageShouldBeOnNow(settings: settings)
let allIsOn: Bool?
if settings.energyUsageSettings.activationThreshold == 0 || settings.energyUsageSettings.activationThreshold == 100 {
allIsOn = nil
} else {
allIsOn = isOn
}
entries.append(.allHeader(allIsOn))
entries.append(.all(settings.energyUsageSettings.activationThreshold))
let allText: String
if settings.energyUsageSettings.activationThreshold == 0 {
allText = "Dont disable all resource-intensive processes even when the battery is low."
} else if settings.energyUsageSettings.activationThreshold >= 100 {
allText = "Always disable all resource-intensive processes, regardless of the battery charge level."
} else {
allText = "Automatically disable all resource-intensive processes when your battery is below \(settings.energyUsageSettings.activationThreshold)%."
}
entries.append(.allFooter(allText))
let itemsEnabled: Bool
if settings.energyUsageSettings.activationThreshold == 0 {
itemsEnabled = false
} else if settings.energyUsageSettings.activationThreshold == 100 {
itemsEnabled = true
} else if isOn {
itemsEnabled = false
} else {
itemsEnabled = true
}
entries.append(.itemsHeader)
for type in ItemType.allCases {
entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath], enabled: !powerSavingOn))
entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath], enabled: itemsEnabled))
}
return entries
}
func energySavingSettingsScreen(context: AccountContext) -> ViewController {
public func energySavingSettingsScreen(context: AccountContext) -> ViewController {
var pushControllerImpl: ((ViewController) -> Void)?
let _ = pushControllerImpl
var displayTooltipImpl: ((UndoOverlayContent) -> Void)?
let arguments = EnergeSavingSettingsScreenArguments(
toggleAll: { value in
updateThreshold: { value in
let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
var settings = settings
for type in ItemType.allCases {
settings.energyUsageSettings[keyPath: type.settingsKeyPath] = !value
}
settings.energyUsageSettings.activationThreshold = max(0, min(100, value))
return settings
}).start()
},
@ -232,6 +268,16 @@ func energySavingSettingsScreen(context: AccountContext) -> ViewController {
settings.energyUsageSettings[keyPath: type.settingsKeyPath] = !settings.energyUsageSettings[keyPath: type.settingsKeyPath]
return settings
}).start()
},
displayDisabledTooltip: {
//TODO:localize
let text: String
if context.sharedContext.currentAutomaticMediaDownloadSettings.energyUsageSettings.activationThreshold == 100 {
text = "Turn off Power Saving Mode to change these settings."
} else {
text = "Turn off Power Saving Mode or charge your phone to change these settings."
}
displayTooltipImpl?(.info(title: nil, text: text))
}
)
@ -267,5 +313,11 @@ func energySavingSettingsScreen(context: AccountContext) -> ViewController {
(controller.navigationController as? NavigationController)?.pushViewController(c)
}
}
displayTooltipImpl = { [weak controller] c in
if let controller = controller {
let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
controller.present(UndoOverlayController(presentationData: presentationData, content: c, elevatedLayout: false, action: { _ in return false }), in: .current)
}
}
return controller
}

View File

@ -0,0 +1,298 @@
import Foundation
import UIKit
import Display
import AsyncDisplayKit
import SwiftSignalKit
import TelegramCore
import TelegramPresentationData
import LegacyComponents
import ItemListUI
import PresentationDataUtils
import AppBundle
class EnergyUsageBatteryLevelItem: ListViewItem, ItemListItem {
let theme: PresentationTheme
let strings: PresentationStrings
let value: Int32
let sectionId: ItemListSectionId
let updated: (Int32) -> Void
init(theme: PresentationTheme, strings: PresentationStrings, value: Int32, sectionId: ItemListSectionId, updated: @escaping (Int32) -> Void) {
self.theme = theme
self.strings = strings
self.value = value
self.sectionId = sectionId
self.updated = updated
}
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
async {
let node = EnergyUsageBatteryLevelItemNode()
let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
node.contentSize = layout.contentSize
node.insets = layout.insets
Queue.mainQueue().async {
completion(node, {
return (nil, { _ in apply() })
})
}
}
}
func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
Queue.mainQueue().async {
if let nodeValue = node() as? EnergyUsageBatteryLevelItemNode {
let makeLayout = nodeValue.asyncLayout()
async {
let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
Queue.mainQueue().async {
completion(layout, { _ in
apply()
})
}
}
}
}
}
}
class EnergyUsageBatteryLevelItemNode: ListViewItemNode {
private let backgroundNode: ASDisplayNode
private let topStripeNode: ASDisplayNode
private let bottomStripeNode: ASDisplayNode
private let maskNode: ASImageNode
private var sliderView: TGPhotoEditorSliderView?
private let leftTextNode: ImmediateTextNode
private let rightTextNode: ImmediateTextNode
private let centerTextNode: ImmediateTextNode
private let centerMeasureTextNode: ImmediateTextNode
private let batteryImage: UIImage?
private let batteryBackgroundNode: ASImageNode
private var item: EnergyUsageBatteryLevelItem?
private var layoutParams: ListViewItemLayoutParams?
init() {
self.backgroundNode = ASDisplayNode()
self.backgroundNode.isLayerBacked = true
self.topStripeNode = ASDisplayNode()
self.topStripeNode.isLayerBacked = true
self.bottomStripeNode = ASDisplayNode()
self.bottomStripeNode.isLayerBacked = true
self.maskNode = ASImageNode()
self.leftTextNode = ImmediateTextNode()
self.rightTextNode = ImmediateTextNode()
self.centerTextNode = ImmediateTextNode()
self.centerMeasureTextNode = ImmediateTextNode()
self.batteryImage = UIImage(bundleImageName: "Settings/UsageBatteryFrame")
self.batteryBackgroundNode = ASImageNode()
super.init(layerBacked: false, dynamicBounce: false)
self.addSubnode(self.leftTextNode)
self.addSubnode(self.rightTextNode)
self.addSubnode(self.centerTextNode)
self.addSubnode(self.batteryBackgroundNode)
}
override func didLoad() {
super.didLoad()
let sliderView = TGPhotoEditorSliderView()
sliderView.enablePanHandling = true
sliderView.trackCornerRadius = 1.0
sliderView.lineSize = 4.0
sliderView.minimumValue = 0.0
sliderView.startValue = 0.0
sliderView.maximumValue = 1.0
sliderView.disablesInteractiveTransitionGestureRecognizer = true
sliderView.displayEdges = true
if let item = self.item, let params = self.layoutParams {
sliderView.value = CGFloat(item.value) / 100.0
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
sliderView.backColor = item.theme.list.itemSwitchColors.frameColor
sliderView.trackColor = item.theme.list.itemAccentColor
sliderView.knobImage = PresentationResourcesItemList.knobImage(item.theme)
sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 18.0, y: 36.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 18.0 * 2.0, height: 44.0))
}
self.view.addSubview(sliderView)
sliderView.addTarget(self, action: #selector(self.sliderValueChanged), for: .valueChanged)
self.sliderView = sliderView
}
func asyncLayout() -> (_ item: EnergyUsageBatteryLevelItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
let currentItem = self.item
return { item, params, neighbors in
var themeUpdated = false
if currentItem?.theme !== item.theme {
themeUpdated = true
}
let contentSize: CGSize
let insets: UIEdgeInsets
let separatorHeight = UIScreenPixel
contentSize = CGSize(width: params.width, height: 88.0)
insets = itemListNeighborsGroupedInsets(neighbors, params)
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
let layoutSize = layout.size
return (layout, { [weak self] in
if let strongSelf = self {
strongSelf.item = item
strongSelf.layoutParams = params
strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
if strongSelf.backgroundNode.supernode == nil {
strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
}
if strongSelf.topStripeNode.supernode == nil {
strongSelf.insertSubnode(strongSelf.topStripeNode, at: 1)
}
if strongSelf.bottomStripeNode.supernode == nil {
strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 2)
}
if strongSelf.maskNode.supernode == nil {
strongSelf.insertSubnode(strongSelf.maskNode, at: 3)
}
let hasCorners = itemListHasRoundedBlockLayout(params)
var hasTopCorners = false
var hasBottomCorners = false
switch neighbors.top {
case .sameSection(false):
strongSelf.topStripeNode.isHidden = true
default:
hasTopCorners = true
strongSelf.topStripeNode.isHidden = hasCorners
}
let bottomStripeInset: CGFloat
let bottomStripeOffset: CGFloat
switch neighbors.bottom {
case .sameSection(false):
bottomStripeInset = params.leftInset + 16.0
bottomStripeOffset = -separatorHeight
strongSelf.bottomStripeNode.isHidden = false
default:
bottomStripeInset = 0.0
bottomStripeOffset = 0.0
hasBottomCorners = true
strongSelf.bottomStripeNode.isHidden = hasCorners
}
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
//TODO:localize
strongSelf.leftTextNode.attributedText = NSAttributedString(string: "Off", font: Font.regular(13.0), textColor: item.theme.list.itemSecondaryTextColor)
strongSelf.rightTextNode.attributedText = NSAttributedString(string: "On", font: Font.regular(13.0), textColor: item.theme.list.itemSecondaryTextColor)
//TODO:localize
let centralText: String
let centralMeasureText: String
if item.value <= 0 {
centralText = "Always Off"
centralMeasureText = centralText
strongSelf.batteryBackgroundNode.isHidden = true
} else if item.value >= 100 {
centralText = "Always On"
centralMeasureText = centralText
strongSelf.batteryBackgroundNode.isHidden = true
} else {
centralText = "When Below \(item.value)%"
centralMeasureText = "When Below 99%"
strongSelf.batteryBackgroundNode.isHidden = false
}
strongSelf.centerTextNode.attributedText = NSAttributedString(string: centralText, font: Font.regular(16.0), textColor: item.theme.list.itemPrimaryTextColor)
strongSelf.centerMeasureTextNode.attributedText = NSAttributedString(string: centralMeasureText, font: Font.regular(16.0), textColor: item.theme.list.itemPrimaryTextColor)
let leftTextSize = strongSelf.leftTextNode.updateLayout(CGSize(width: 100.0, height: 100.0))
let rightTextSize = strongSelf.rightTextNode.updateLayout(CGSize(width: 100.0, height: 100.0))
let centerTextSize = strongSelf.centerTextNode.updateLayout(CGSize(width: 200.0, height: 100.0))
let centerMeasureTextSize = strongSelf.centerMeasureTextNode.updateLayout(CGSize(width: 200.0, height: 100.0))
let sideInset: CGFloat = 18.0
strongSelf.leftTextNode.frame = CGRect(origin: CGPoint(x: params.leftInset + sideInset, y: 15.0), size: leftTextSize)
strongSelf.rightTextNode.frame = CGRect(origin: CGPoint(x: params.width - params.leftInset - sideInset - rightTextSize.width, y: 15.0), size: rightTextSize)
var centerFrame = CGRect(origin: CGPoint(x: floor((params.width - centerMeasureTextSize.width) / 2.0), y: 11.0), size: centerTextSize)
if !strongSelf.batteryBackgroundNode.isHidden {
centerFrame.origin.x -= 12.0
}
strongSelf.centerTextNode.frame = centerFrame
if let frameImage = strongSelf.batteryImage {
strongSelf.batteryBackgroundNode.image = generateImage(frameImage.size, rotatedContext: { size, context in
UIGraphicsPushContext(context)
context.clear(CGRect(origin: CGPoint(), size: size))
if let image = generateTintedImage(image: frameImage, color: item.theme.list.itemPrimaryTextColor.withMultipliedAlpha(0.9)) {
image.draw(in: CGRect(origin: CGPoint(), size: size))
let contentRect = CGRect(origin: CGPoint(x: 3.0, y: (size.height - 9.0) * 0.5), size: CGSize(width: 20.8, height: 9.0))
context.addPath(UIBezierPath(roundedRect: contentRect, cornerRadius: 2.0).cgPath)
context.clip()
context.setFillColor(UIColor(rgb: 0xFF3B30).cgColor)
context.addPath(UIBezierPath(roundedRect: CGRect(origin: contentRect.origin, size: CGSize(width: contentRect.width * CGFloat(item.value) / 100.0, height: contentRect.height)), cornerRadius: 1.0).cgPath)
context.fillPath()
}
UIGraphicsPopContext()
})
strongSelf.batteryBackgroundNode.frame = CGRect(origin: CGPoint(x: centerFrame.minX + centerMeasureTextSize.width + 4.0, y: floor(centerFrame.midY - frameImage.size.height * 0.5)), size: frameImage.size)
}
if let sliderView = strongSelf.sliderView {
if themeUpdated {
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
sliderView.backColor = item.theme.list.itemSecondaryTextColor
sliderView.trackColor = item.theme.list.itemAccentColor.withAlphaComponent(0.45)
sliderView.knobImage = PresentationResourcesItemList.knobImage(item.theme)
}
sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 18.0, y: 36.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 18.0 * 2.0, height: 44.0))
}
}
})
}
}
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
}
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
}
@objc func sliderValueChanged() {
guard let sliderView = self.sliderView else {
return
}
self.item?.updated(Int32(sliderView.value * 100.0))
}
}

View File

@ -142,7 +142,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
case .iconHeader, .iconItem:
return ThemeSettingsControllerSection.icon.rawValue
case .powerSaving:
return ThemeSettingsControllerSection.powerSaving.rawValue
return ThemeSettingsControllerSection.message.rawValue
case .otherHeader, .largeEmoji, .animations, .animationsInfo:
return ThemeSettingsControllerSection.other.rawValue
}
@ -168,11 +168,11 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
return 7
case .bubbleSettings:
return 8
case .iconHeader:
return 9
case .iconItem:
return 10
case .powerSaving:
return 9
case .iconHeader:
return 10
case .iconItem:
return 11
case .otherHeader:
return 12
@ -335,7 +335,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
})
case .powerSaving:
//TODO:localize
return ItemListDisclosureItem(presentationData: presentationData, icon: nil, title: "Power Saving", label: "", labelStyle: .text, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
return ItemListDisclosureItem(presentationData: presentationData, icon: nil, title: "Animations", label: "", labelStyle: .text, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
arguments.openPowerSavingSettings()
})
case let .otherHeader(_, text):
@ -396,14 +396,13 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
}
entries.append(.textSize(presentationData.theme, strings.Appearance_TextSizeSetting, textSizeValue))
entries.append(.bubbleSettings(presentationData.theme, strings.Appearance_BubbleCornersSetting, ""))
entries.append(.powerSaving)
if !availableAppIcons.isEmpty {
entries.append(.iconHeader(presentationData.theme, strings.Appearance_AppIcon.uppercased()))
entries.append(.iconItem(presentationData.theme, presentationData.strings, availableAppIcons, isPremium, currentAppIconName))
}
entries.append(.powerSaving)
entries.append(.otherHeader(presentationData.theme, strings.Appearance_Other.uppercased()))
entries.append(.largeEmoji(presentationData.theme, strings.Appearance_LargeEmoji, presentationData.largeEmoji))
entries.append(.animations(presentationData.theme, strings.Appearance_ReduceMotion, presentationData.reduceMotion))

View File

@ -43,6 +43,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[571523412] = { return $0.readDouble() }
dict[-1255641564] = { return parseString($0) }
dict[-1194283041] = { return Api.AccountDaysTTL.parse_accountDaysTTL($0) }
dict[1008422669] = { return Api.AppWebViewResult.parse_appWebViewResultUrl($0) }
dict[-928371502] = { return Api.AttachMenuBot.parse_attachMenuBot($0) }
dict[-1297663893] = { return Api.AttachMenuBotIcon.parse_attachMenuBotIcon($0) }
dict[1165423600] = { return Api.AttachMenuBotIconColor.parse_attachMenuBotIconColor($0) }
@ -67,6 +68,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1834973166] = { return Api.BaseTheme.parse_baseThemeTinted($0) }
dict[-1132882121] = { return Api.Bool.parse_boolFalse($0) }
dict[-1720552011] = { return Api.Bool.parse_boolTrue($0) }
dict[-1778593322] = { return Api.BotApp.parse_botApp($0) }
dict[1571189943] = { return Api.BotApp.parse_botAppNotModified($0) }
dict[-1032140601] = { return Api.BotCommand.parse_botCommand($0) }
dict[-1180016534] = { return Api.BotCommandScope.parse_botCommandScopeChatAdmins($0) }
dict[1877059713] = { return Api.BotCommandScope.parse_botCommandScopeChats($0) }
@ -178,7 +181,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-352570692] = { return Api.ChatReactions.parse_chatReactionsNone($0) }
dict[1713193015] = { return Api.ChatReactions.parse_chatReactionsSome($0) }
dict[-1390068360] = { return Api.CodeSettings.parse_codeSettings($0) }
dict[589653676] = { return Api.Config.parse_config($0) }
dict[-870702050] = { return Api.Config.parse_config($0) }
dict[341499403] = { return Api.Contact.parse_contact($0) }
dict[383348795] = { return Api.ContactStatus.parse_contactStatus($0) }
dict[2104790276] = { return Api.DataJSON.parse_dataJSON($0) }
@ -251,12 +254,15 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1940093419] = { return Api.HighScore.parse_highScore($0) }
dict[-1052885936] = { return Api.ImportedContact.parse_importedContact($0) }
dict[1008755359] = { return Api.InlineBotSwitchPM.parse_inlineBotSwitchPM($0) }
dict[-1250781739] = { return Api.InlineBotWebView.parse_inlineBotWebView($0) }
dict[1664413338] = { return Api.InlineQueryPeerType.parse_inlineQueryPeerTypeBroadcast($0) }
dict[-681130742] = { return Api.InlineQueryPeerType.parse_inlineQueryPeerTypeChat($0) }
dict[1589952067] = { return Api.InlineQueryPeerType.parse_inlineQueryPeerTypeMegagroup($0) }
dict[-2093215828] = { return Api.InlineQueryPeerType.parse_inlineQueryPeerTypePM($0) }
dict[813821341] = { return Api.InlineQueryPeerType.parse_inlineQueryPeerTypeSameBotPM($0) }
dict[488313413] = { return Api.InputAppEvent.parse_inputAppEvent($0) }
dict[-1457472134] = { return Api.InputBotApp.parse_inputBotAppID($0) }
dict[-1869872121] = { return Api.InputBotApp.parse_inputBotAppShortName($0) }
dict[1262639204] = { return Api.InputBotInlineMessage.parse_inputBotInlineMessageGame($0) }
dict[864077702] = { return Api.InputBotInlineMessage.parse_inputBotInlineMessageMediaAuto($0) }
dict[-1494368259] = { return Api.InputBotInlineMessage.parse_inputBotInlineMessageMediaContact($0) }
@ -433,8 +439,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[940666592] = { return Api.Message.parse_message($0) }
dict[-1868117372] = { return Api.Message.parse_messageEmpty($0) }
dict[721967202] = { return Api.Message.parse_messageService($0) }
dict[-404267113] = { return Api.MessageAction.parse_messageActionAttachMenuBotAllowed($0) }
dict[-1410748418] = { return Api.MessageAction.parse_messageActionBotAllowed($0) }
dict[-988359047] = { return Api.MessageAction.parse_messageActionBotAllowed($0) }
dict[-1781355374] = { return Api.MessageAction.parse_messageActionChannelCreate($0) }
dict[-365344535] = { return Api.MessageAction.parse_messageActionChannelMigrateFrom($0) }
dict[365886720] = { return Api.MessageAction.parse_messageActionChatAddUser($0) }
@ -647,6 +652,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[455247544] = { return Api.Reaction.parse_reactionEmoji($0) }
dict[2046153753] = { return Api.Reaction.parse_reactionEmpty($0) }
dict[-1546531968] = { return Api.ReactionCount.parse_reactionCount($0) }
dict[1246753138] = { return Api.ReadParticipantDate.parse_readParticipantDate($0) }
dict[-1551583367] = { return Api.ReceivedNotifyMessage.parse_receivedNotifyMessage($0) }
dict[-1294306862] = { return Api.RecentMeUrl.parse_recentMeUrlChat($0) }
dict[-347535331] = { return Api.RecentMeUrl.parse_recentMeUrlChatInvite($0) }
@ -1025,8 +1031,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1338747336] = { return Api.messages.ArchivedStickers.parse_archivedStickers($0) }
dict[1989032621] = { return Api.messages.AvailableReactions.parse_availableReactions($0) }
dict[-1626924713] = { return Api.messages.AvailableReactions.parse_availableReactionsNotModified($0) }
dict[-347034123] = { return Api.messages.BotApp.parse_botApp($0) }
dict[911761060] = { return Api.messages.BotCallbackAnswer.parse_botCallbackAnswer($0) }
dict[-1803769784] = { return Api.messages.BotResults.parse_botResults($0) }
dict[-534646026] = { return Api.messages.BotResults.parse_botResults($0) }
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) }
@ -1193,6 +1200,8 @@ public extension Api {
switch object {
case let _1 as Api.AccountDaysTTL:
_1.serialize(buffer, boxed)
case let _1 as Api.AppWebViewResult:
_1.serialize(buffer, boxed)
case let _1 as Api.AttachMenuBot:
_1.serialize(buffer, boxed)
case let _1 as Api.AttachMenuBotIcon:
@ -1221,6 +1230,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.Bool:
_1.serialize(buffer, boxed)
case let _1 as Api.BotApp:
_1.serialize(buffer, boxed)
case let _1 as Api.BotCommand:
_1.serialize(buffer, boxed)
case let _1 as Api.BotCommandScope:
@ -1363,10 +1374,14 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.InlineBotSwitchPM:
_1.serialize(buffer, boxed)
case let _1 as Api.InlineBotWebView:
_1.serialize(buffer, boxed)
case let _1 as Api.InlineQueryPeerType:
_1.serialize(buffer, boxed)
case let _1 as Api.InputAppEvent:
_1.serialize(buffer, boxed)
case let _1 as Api.InputBotApp:
_1.serialize(buffer, boxed)
case let _1 as Api.InputBotInlineMessage:
_1.serialize(buffer, boxed)
case let _1 as Api.InputBotInlineMessageID:
@ -1579,6 +1594,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.ReactionCount:
_1.serialize(buffer, boxed)
case let _1 as Api.ReadParticipantDate:
_1.serialize(buffer, boxed)
case let _1 as Api.ReceivedNotifyMessage:
_1.serialize(buffer, boxed)
case let _1 as Api.RecentMeUrl:
@ -1821,6 +1838,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.messages.AvailableReactions:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.BotApp:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.BotCallbackAnswer:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.BotResults:

View File

@ -34,6 +34,42 @@ public extension Api {
}
}
public extension Api {
enum AppWebViewResult: TypeConstructorDescription {
case appWebViewResultUrl(url: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .appWebViewResultUrl(let url):
if boxed {
buffer.appendInt32(1008422669)
}
serializeString(url, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .appWebViewResultUrl(let url):
return ("appWebViewResultUrl", [("url", url as Any)])
}
}
public static func parse_appWebViewResultUrl(_ reader: BufferReader) -> AppWebViewResult? {
var _1: String?
_1 = parseString(reader)
let _c1 = _1 != nil
if _c1 {
return Api.AppWebViewResult.appWebViewResultUrl(url: _1!)
}
else {
return nil
}
}
}
}
public extension Api {
enum AttachMenuBot: TypeConstructorDescription {
case attachMenuBot(flags: Int32, botId: Int64, shortName: String, peerTypes: [Api.AttachMenuPeerType], icons: [Api.AttachMenuBotIcon])
@ -848,6 +884,90 @@ public extension Api {
}
}
public extension Api {
enum BotApp: TypeConstructorDescription {
case botApp(flags: Int32, id: Int64, accessHash: Int64, shortName: String, title: String, description: String, photo: Api.Photo, document: Api.Document?, hash: Int64)
case botAppNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .botApp(let flags, let id, let accessHash, let shortName, let title, let description, let photo, let document, let hash):
if boxed {
buffer.appendInt32(-1778593322)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
serializeString(shortName, buffer: buffer, boxed: false)
serializeString(title, buffer: buffer, boxed: false)
serializeString(description, buffer: buffer, boxed: false)
photo.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {document!.serialize(buffer, true)}
serializeInt64(hash, buffer: buffer, boxed: false)
break
case .botAppNotModified:
if boxed {
buffer.appendInt32(1571189943)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .botApp(let flags, let id, let accessHash, let shortName, let title, let description, let photo, let document, let hash):
return ("botApp", [("flags", flags as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("shortName", shortName as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("document", document as Any), ("hash", hash as Any)])
case .botAppNotModified:
return ("botAppNotModified", [])
}
}
public static func parse_botApp(_ reader: BufferReader) -> BotApp? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: Int64?
_3 = reader.readInt64()
var _4: String?
_4 = parseString(reader)
var _5: String?
_5 = parseString(reader)
var _6: String?
_6 = parseString(reader)
var _7: Api.Photo?
if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.Photo
}
var _8: Api.Document?
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
_8 = Api.parse(reader, signature: signature) as? Api.Document
} }
var _9: Int64?
_9 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = (Int(_1!) & Int(1 << 0) == 0) || _8 != nil
let _c9 = _9 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
return Api.BotApp.botApp(flags: _1!, id: _2!, accessHash: _3!, shortName: _4!, title: _5!, description: _6!, photo: _7!, document: _8, hash: _9!)
}
else {
return nil
}
}
public static func parse_botAppNotModified(_ reader: BufferReader) -> BotApp? {
return Api.BotApp.botAppNotModified
}
}
}
public extension Api {
enum BotCommand: TypeConstructorDescription {
case botCommand(command: String, description: String)

View File

@ -230,8 +230,7 @@ public extension Api {
}
public extension Api {
enum MessageAction: TypeConstructorDescription {
case messageActionAttachMenuBotAllowed
case messageActionBotAllowed(domain: String)
case messageActionBotAllowed(flags: Int32, domain: String?, app: Api.BotApp?)
case messageActionChannelCreate(title: String)
case messageActionChannelMigrateFrom(title: String, chatId: Int64)
case messageActionChatAddUser(users: [Int64])
@ -271,17 +270,13 @@ public extension Api {
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .messageActionAttachMenuBotAllowed:
case .messageActionBotAllowed(let flags, let domain, let app):
if boxed {
buffer.appendInt32(-404267113)
buffer.appendInt32(-988359047)
}
break
case .messageActionBotAllowed(let domain):
if boxed {
buffer.appendInt32(-1410748418)
}
serializeString(domain, buffer: buffer, boxed: false)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(domain!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {app!.serialize(buffer, true)}
break
case .messageActionChannelCreate(let title):
if boxed {
@ -559,10 +554,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .messageActionAttachMenuBotAllowed:
return ("messageActionAttachMenuBotAllowed", [])
case .messageActionBotAllowed(let domain):
return ("messageActionBotAllowed", [("domain", domain as Any)])
case .messageActionBotAllowed(let flags, let domain, let app):
return ("messageActionBotAllowed", [("flags", flags as Any), ("domain", domain as Any), ("app", app as Any)])
case .messageActionChannelCreate(let title):
return ("messageActionChannelCreate", [("title", title as Any)])
case .messageActionChannelMigrateFrom(let title, let chatId):
@ -638,15 +631,20 @@ public extension Api {
}
}
public static func parse_messageActionAttachMenuBotAllowed(_ reader: BufferReader) -> MessageAction? {
return Api.MessageAction.messageActionAttachMenuBotAllowed
}
public static func parse_messageActionBotAllowed(_ reader: BufferReader) -> MessageAction? {
var _1: String?
_1 = parseString(reader)
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) }
var _3: Api.BotApp?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.BotApp
} }
let _c1 = _1 != nil
if _c1 {
return Api.MessageAction.messageActionBotAllowed(domain: _1!)
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _3 != nil
if _c1 && _c2 && _c3 {
return Api.MessageAction.messageActionBotAllowed(flags: _1!, domain: _2, app: _3)
}
else {
return nil

View File

@ -116,6 +116,46 @@ public extension Api {
}
}
public extension Api {
enum ReadParticipantDate: TypeConstructorDescription {
case readParticipantDate(userId: Int64, date: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .readParticipantDate(let userId, let date):
if boxed {
buffer.appendInt32(1246753138)
}
serializeInt64(userId, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .readParticipantDate(let userId, let date):
return ("readParticipantDate", [("userId", userId as Any), ("date", date as Any)])
}
}
public static func parse_readParticipantDate(_ reader: BufferReader) -> ReadParticipantDate? {
var _1: Int64?
_1 = reader.readInt64()
var _2: Int32?
_2 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.ReadParticipantDate.readParticipantDate(userId: _1!, date: _2!)
}
else {
return nil
}
}
}
}
public extension Api {
enum ReceivedNotifyMessage: TypeConstructorDescription {
case receivedNotifyMessage(id: Int32, flags: Int32)

View File

@ -160,6 +160,48 @@ public extension Api.messages {
}
}
public extension Api.messages {
enum BotApp: TypeConstructorDescription {
case botApp(flags: Int32, app: Api.BotApp)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .botApp(let flags, let app):
if boxed {
buffer.appendInt32(-347034123)
}
serializeInt32(flags, buffer: buffer, boxed: false)
app.serialize(buffer, true)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .botApp(let flags, let app):
return ("botApp", [("flags", flags as Any), ("app", app as Any)])
}
}
public static func parse_botApp(_ reader: BufferReader) -> BotApp? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.BotApp?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.BotApp
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.messages.BotApp.botApp(flags: _1!, app: _2!)
}
else {
return nil
}
}
}
}
public extension Api.messages {
enum BotCallbackAnswer: TypeConstructorDescription {
case botCallbackAnswer(flags: Int32, message: String?, url: String?, cacheTime: Int32)
@ -210,18 +252,19 @@ public extension Api.messages {
}
public extension Api.messages {
enum BotResults: TypeConstructorDescription {
case botResults(flags: Int32, queryId: Int64, nextOffset: String?, switchPm: Api.InlineBotSwitchPM?, results: [Api.BotInlineResult], cacheTime: Int32, users: [Api.User])
case botResults(flags: Int32, queryId: Int64, nextOffset: String?, switchPm: Api.InlineBotSwitchPM?, switchWebview: Api.InlineBotWebView?, results: [Api.BotInlineResult], cacheTime: Int32, users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .botResults(let flags, let queryId, let nextOffset, let switchPm, let results, let cacheTime, let users):
case .botResults(let flags, let queryId, let nextOffset, let switchPm, let switchWebview, let results, let cacheTime, let users):
if boxed {
buffer.appendInt32(-1803769784)
buffer.appendInt32(-534646026)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(queryId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 1) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {switchPm!.serialize(buffer, true)}
if Int(flags) & Int(1 << 3) != 0 {switchWebview!.serialize(buffer, true)}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(results.count))
for item in results {
@ -239,8 +282,8 @@ public extension Api.messages {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .botResults(let flags, let queryId, let nextOffset, let switchPm, let results, let cacheTime, let users):
return ("botResults", [("flags", flags as Any), ("queryId", queryId as Any), ("nextOffset", nextOffset as Any), ("switchPm", switchPm as Any), ("results", results as Any), ("cacheTime", cacheTime as Any), ("users", users as Any)])
case .botResults(let flags, let queryId, let nextOffset, let switchPm, let switchWebview, let results, let cacheTime, let users):
return ("botResults", [("flags", flags as Any), ("queryId", queryId as Any), ("nextOffset", nextOffset as Any), ("switchPm", switchPm as Any), ("switchWebview", switchWebview as Any), ("results", results as Any), ("cacheTime", cacheTime as Any), ("users", users as Any)])
}
}
@ -255,25 +298,30 @@ public extension Api.messages {
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.InlineBotSwitchPM
} }
var _5: [Api.BotInlineResult]?
var _5: Api.InlineBotWebView?
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.InlineBotWebView
} }
var _6: [Api.BotInlineResult]?
if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BotInlineResult.self)
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BotInlineResult.self)
}
var _6: Int32?
_6 = reader.readInt32()
var _7: [Api.User]?
var _7: Int32?
_7 = reader.readInt32()
var _8: [Api.User]?
if let _ = reader.readInt32() {
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
let _c5 = _5 != nil
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.messages.BotResults.botResults(flags: _1!, queryId: _2!, nextOffset: _3, switchPm: _4, results: _5!, cacheTime: _6!, users: _7!)
let _c8 = _8 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
return Api.messages.BotResults.botResults(flags: _1!, queryId: _2!, nextOffset: _3, switchPm: _4, switchWebview: _5, results: _6!, cacheTime: _7!, users: _8!)
}
else {
return nil
@ -1352,55 +1400,3 @@ public extension Api.messages {
}
}
public extension Api.messages {
enum HighScores: TypeConstructorDescription {
case highScores(scores: [Api.HighScore], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .highScores(let scores, let users):
if boxed {
buffer.appendInt32(-1707344487)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(scores.count))
for item in scores {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .highScores(let scores, let users):
return ("highScores", [("scores", scores as Any), ("users", users as Any)])
}
}
public static func parse_highScores(_ reader: BufferReader) -> HighScores? {
var _1: [Api.HighScore]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.HighScore.self)
}
var _2: [Api.User]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.messages.HighScores.highScores(scores: _1!, users: _2!)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,55 @@
public extension Api.messages {
enum HighScores: TypeConstructorDescription {
case highScores(scores: [Api.HighScore], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .highScores(let scores, let users):
if boxed {
buffer.appendInt32(-1707344487)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(scores.count))
for item in scores {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .highScores(let scores, let users):
return ("highScores", [("scores", scores as Any), ("users", users as Any)])
}
}
public static func parse_highScores(_ reader: BufferReader) -> HighScores? {
var _1: [Api.HighScore]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.HighScore.self)
}
var _2: [Api.User]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.messages.HighScores.highScores(scores: _1!, users: _2!)
}
else {
return nil
}
}
}
}
public extension Api.messages {
enum HistoryImport: TypeConstructorDescription {
case historyImport(id: Int64)
@ -1374,47 +1426,3 @@ public extension Api.messages {
}
}
public extension Api.messages {
enum TranscribedAudio: TypeConstructorDescription {
case transcribedAudio(flags: Int32, transcriptionId: Int64, text: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .transcribedAudio(let flags, let transcriptionId, let text):
if boxed {
buffer.appendInt32(-1821037486)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(transcriptionId, buffer: buffer, boxed: false)
serializeString(text, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .transcribedAudio(let flags, let transcriptionId, let text):
return ("transcribedAudio", [("flags", flags as Any), ("transcriptionId", transcriptionId as Any), ("text", text as Any)])
}
}
public static func parse_transcribedAudio(_ reader: BufferReader) -> TranscribedAudio? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: String?
_3 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.messages.TranscribedAudio.transcribedAudio(flags: _1!, transcriptionId: _2!, text: _3!)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,47 @@
public extension Api.messages {
enum TranscribedAudio: TypeConstructorDescription {
case transcribedAudio(flags: Int32, transcriptionId: Int64, text: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .transcribedAudio(let flags, let transcriptionId, let text):
if boxed {
buffer.appendInt32(-1821037486)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(transcriptionId, buffer: buffer, boxed: false)
serializeString(text, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .transcribedAudio(let flags, let transcriptionId, let text):
return ("transcribedAudio", [("flags", flags as Any), ("transcriptionId", transcriptionId as Any), ("text", text as Any)])
}
}
public static func parse_transcribedAudio(_ reader: BufferReader) -> TranscribedAudio? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: String?
_3 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.messages.TranscribedAudio.transcribedAudio(flags: _1!, transcriptionId: _2!, text: _3!)
}
else {
return nil
}
}
}
}
public extension Api.messages {
enum TranslatedText: TypeConstructorDescription {
case translateResult(result: [Api.TextWithEntities])

View File

@ -1802,6 +1802,21 @@ public extension Api.functions.bots {
})
}
}
public extension Api.functions.bots {
static func getBotInfo(langCode: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[String]>) {
let buffer = Buffer()
buffer.appendInt32(1978405606)
serializeString(langCode, buffer: buffer, boxed: false)
return (FunctionDescription(name: "bots.getBotInfo", parameters: [("langCode", String(describing: langCode))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> [String]? in
let reader = BufferReader(buffer)
var result: [String]?
if let _ = reader.readInt32() {
result = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
}
return result
})
}
}
public extension Api.functions.bots {
static func getBotMenuButton(userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.BotMenuButton>) {
let buffer = Buffer()
@ -1900,6 +1915,24 @@ public extension Api.functions.bots {
})
}
}
public extension Api.functions.bots {
static func setBotInfo(flags: Int32, langCode: String, about: String?, description: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-1553604742)
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(langCode, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(about!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {serializeString(description!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "bots.setBotInfo", parameters: [("flags", String(describing: flags)), ("langCode", String(describing: langCode)), ("about", String(describing: about)), ("description", String(describing: description))]), 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.bots {
static func setBotMenuButton(userId: Api.InputUser, button: Api.BotMenuButton) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
@ -4401,6 +4434,22 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func getBotApp(app: Api.InputBotApp, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.BotApp>) {
let buffer = Buffer()
buffer.appendInt32(889046467)
app.serialize(buffer, true)
serializeInt64(hash, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.getBotApp", parameters: [("app", String(describing: app)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.BotApp? in
let reader = BufferReader(buffer)
var result: Api.messages.BotApp?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.BotApp
}
return result
})
}
}
public extension Api.functions.messages {
static func getBotCallbackAnswer(flags: Int32, peer: Api.InputPeer, msgId: Int32, data: Buffer?, password: Api.InputCheckPasswordSRP?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.BotCallbackAnswer>) {
let buffer = Buffer()
@ -4979,16 +5028,16 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func getMessageReadParticipants(peer: Api.InputPeer, msgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Int64]>) {
static func getMessageReadParticipants(peer: Api.InputPeer, msgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.ReadParticipantDate]>) {
let buffer = Buffer()
buffer.appendInt32(745510839)
buffer.appendInt32(834782287)
peer.serialize(buffer, true)
serializeInt32(msgId, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.getMessageReadParticipants", parameters: [("peer", String(describing: peer)), ("msgId", String(describing: msgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> [Int64]? in
return (FunctionDescription(name: "messages.getMessageReadParticipants", parameters: [("peer", String(describing: peer)), ("msgId", String(describing: msgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> [Api.ReadParticipantDate]? in
let reader = BufferReader(buffer)
var result: [Int64]?
var result: [Api.ReadParticipantDate]?
if let _ = reader.readInt32() {
result = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
result = Api.parseVector(reader, elementSignature: 0, elementType: Api.ReadParticipantDate.self)
}
return result
})
@ -5939,6 +5988,26 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func requestAppWebView(flags: Int32, peer: Api.InputPeer, app: Api.InputBotApp, startParam: String?, themeParams: Api.DataJSON?, platform: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.AppWebViewResult>) {
let buffer = Buffer()
buffer.appendInt32(-1940243652)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
app.serialize(buffer, true)
if Int(flags) & Int(1 << 1) != 0 {serializeString(startParam!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {themeParams!.serialize(buffer, true)}
serializeString(platform, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.requestAppWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("app", String(describing: app)), ("startParam", String(describing: startParam)), ("themeParams", String(describing: themeParams)), ("platform", String(describing: platform))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.AppWebViewResult? in
let reader = BufferReader(buffer)
var result: Api.AppWebViewResult?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.AppWebViewResult
}
return result
})
}
}
public extension Api.functions.messages {
static func requestEncryption(userId: Api.InputUser, randomId: Int32, gA: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.EncryptedChat>) {
let buffer = Buffer()
@ -6656,9 +6725,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func setInlineBotResults(flags: Int32, queryId: Int64, results: [Api.InputBotInlineResult], cacheTime: Int32, nextOffset: String?, switchPm: Api.InlineBotSwitchPM?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
static func setInlineBotResults(flags: Int32, queryId: Int64, results: [Api.InputBotInlineResult], cacheTime: Int32, nextOffset: String?, switchPm: Api.InlineBotSwitchPM?, switchWebview: Api.InlineBotWebView?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-346119674)
buffer.appendInt32(-1156406247)
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(queryId, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
@ -6669,7 +6738,8 @@ public extension Api.functions.messages {
serializeInt32(cacheTime, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 2) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 3) != 0 {switchPm!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.setInlineBotResults", parameters: [("flags", String(describing: flags)), ("queryId", String(describing: queryId)), ("results", String(describing: results)), ("cacheTime", String(describing: cacheTime)), ("nextOffset", String(describing: nextOffset)), ("switchPm", String(describing: switchPm))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
if Int(flags) & Int(1 << 4) != 0 {switchWebview!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.setInlineBotResults", parameters: [("flags", String(describing: flags)), ("queryId", String(describing: queryId)), ("results", String(describing: results)), ("cacheTime", String(describing: cacheTime)), ("nextOffset", String(describing: nextOffset)), ("switchPm", String(describing: switchPm)), ("switchWebview", String(describing: switchWebview))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
@ -7994,6 +8064,21 @@ public extension Api.functions.stickers {
})
}
}
public extension Api.functions.stickers {
static func deleteStickerSet(stickerset: Api.InputStickerSet) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-2022685804)
stickerset.serialize(buffer, true)
return (FunctionDescription(name: "stickers.deleteStickerSet", parameters: [("stickerset", String(describing: stickerset))]), 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.stickers {
static func removeStickerFromSet(sticker: Api.InputDocument) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.StickerSet>) {
let buffer = Buffer()

View File

@ -450,13 +450,13 @@ public extension Api {
}
public extension Api {
enum Config: TypeConstructorDescription {
case config(flags: Int32, date: Int32, expires: Int32, testMode: Api.Bool, thisDc: Int32, dcOptions: [Api.DcOption], dcTxtDomainName: String, chatSizeMax: Int32, megagroupSizeMax: Int32, forwardedCountMax: Int32, onlineUpdatePeriodMs: Int32, offlineBlurTimeoutMs: Int32, offlineIdleTimeoutMs: Int32, onlineCloudTimeoutMs: Int32, notifyCloudDelayMs: Int32, notifyDefaultDelayMs: Int32, pushChatPeriodMs: Int32, pushChatLimit: Int32, savedGifsLimit: Int32, editTimeLimit: Int32, revokeTimeLimit: Int32, revokePmTimeLimit: Int32, ratingEDecay: Int32, stickersRecentLimit: Int32, stickersFavedLimit: Int32, channelsReadMediaPeriod: Int32, tmpSessions: Int32?, pinnedDialogsCountMax: Int32, pinnedInfolderCountMax: Int32, callReceiveTimeoutMs: Int32, callRingTimeoutMs: Int32, callConnectTimeoutMs: Int32, callPacketTimeoutMs: Int32, meUrlPrefix: String, autoupdateUrlPrefix: String?, gifSearchUsername: String?, venueSearchUsername: String?, imgSearchUsername: String?, staticMapsProvider: String?, captionLengthMax: Int32, messageLengthMax: Int32, webfileDcId: Int32, suggestedLangCode: String?, langPackVersion: Int32?, baseLangPackVersion: Int32?, reactionsDefault: Api.Reaction?)
case config(flags: Int32, date: Int32, expires: Int32, testMode: Api.Bool, thisDc: Int32, dcOptions: [Api.DcOption], dcTxtDomainName: String, chatSizeMax: Int32, megagroupSizeMax: Int32, forwardedCountMax: Int32, onlineUpdatePeriodMs: Int32, offlineBlurTimeoutMs: Int32, offlineIdleTimeoutMs: Int32, onlineCloudTimeoutMs: Int32, notifyCloudDelayMs: Int32, notifyDefaultDelayMs: Int32, pushChatPeriodMs: Int32, pushChatLimit: Int32, editTimeLimit: Int32, revokeTimeLimit: Int32, revokePmTimeLimit: Int32, ratingEDecay: Int32, stickersRecentLimit: Int32, channelsReadMediaPeriod: Int32, tmpSessions: Int32?, callReceiveTimeoutMs: Int32, callRingTimeoutMs: Int32, callConnectTimeoutMs: Int32, callPacketTimeoutMs: Int32, meUrlPrefix: String, autoupdateUrlPrefix: String?, gifSearchUsername: String?, venueSearchUsername: String?, imgSearchUsername: String?, staticMapsProvider: String?, captionLengthMax: Int32, messageLengthMax: Int32, webfileDcId: Int32, suggestedLangCode: String?, langPackVersion: Int32?, baseLangPackVersion: Int32?, reactionsDefault: Api.Reaction?, autologinToken: String?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let dcTxtDomainName, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let revokeTimeLimit, let revokePmTimeLimit, let ratingEDecay, let stickersRecentLimit, let stickersFavedLimit, let channelsReadMediaPeriod, let tmpSessions, let pinnedDialogsCountMax, let pinnedInfolderCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let autoupdateUrlPrefix, let gifSearchUsername, let venueSearchUsername, let imgSearchUsername, let staticMapsProvider, let captionLengthMax, let messageLengthMax, let webfileDcId, let suggestedLangCode, let langPackVersion, let baseLangPackVersion, let reactionsDefault):
case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let dcTxtDomainName, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let pushChatPeriodMs, let pushChatLimit, let editTimeLimit, let revokeTimeLimit, let revokePmTimeLimit, let ratingEDecay, let stickersRecentLimit, let channelsReadMediaPeriod, let tmpSessions, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let autoupdateUrlPrefix, let gifSearchUsername, let venueSearchUsername, let imgSearchUsername, let staticMapsProvider, let captionLengthMax, let messageLengthMax, let webfileDcId, let suggestedLangCode, let langPackVersion, let baseLangPackVersion, let reactionsDefault, let autologinToken):
if boxed {
buffer.appendInt32(589653676)
buffer.appendInt32(-870702050)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
@ -480,17 +480,13 @@ public extension Api {
serializeInt32(notifyDefaultDelayMs, buffer: buffer, boxed: false)
serializeInt32(pushChatPeriodMs, buffer: buffer, boxed: false)
serializeInt32(pushChatLimit, buffer: buffer, boxed: false)
serializeInt32(savedGifsLimit, buffer: buffer, boxed: false)
serializeInt32(editTimeLimit, buffer: buffer, boxed: false)
serializeInt32(revokeTimeLimit, buffer: buffer, boxed: false)
serializeInt32(revokePmTimeLimit, buffer: buffer, boxed: false)
serializeInt32(ratingEDecay, buffer: buffer, boxed: false)
serializeInt32(stickersRecentLimit, buffer: buffer, boxed: false)
serializeInt32(stickersFavedLimit, buffer: buffer, boxed: false)
serializeInt32(channelsReadMediaPeriod, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(tmpSessions!, buffer: buffer, boxed: false)}
serializeInt32(pinnedDialogsCountMax, buffer: buffer, boxed: false)
serializeInt32(pinnedInfolderCountMax, buffer: buffer, boxed: false)
serializeInt32(callReceiveTimeoutMs, buffer: buffer, boxed: false)
serializeInt32(callRingTimeoutMs, buffer: buffer, boxed: false)
serializeInt32(callConnectTimeoutMs, buffer: buffer, boxed: false)
@ -508,14 +504,15 @@ public extension Api {
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(langPackVersion!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(baseLangPackVersion!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 15) != 0 {reactionsDefault!.serialize(buffer, true)}
if Int(flags) & Int(1 << 16) != 0 {serializeString(autologinToken!, buffer: buffer, boxed: false)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let dcTxtDomainName, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let revokeTimeLimit, let revokePmTimeLimit, let ratingEDecay, let stickersRecentLimit, let stickersFavedLimit, let channelsReadMediaPeriod, let tmpSessions, let pinnedDialogsCountMax, let pinnedInfolderCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let autoupdateUrlPrefix, let gifSearchUsername, let venueSearchUsername, let imgSearchUsername, let staticMapsProvider, let captionLengthMax, let messageLengthMax, let webfileDcId, let suggestedLangCode, let langPackVersion, let baseLangPackVersion, let reactionsDefault):
return ("config", [("flags", flags as Any), ("date", date as Any), ("expires", expires as Any), ("testMode", testMode as Any), ("thisDc", thisDc as Any), ("dcOptions", dcOptions as Any), ("dcTxtDomainName", dcTxtDomainName as Any), ("chatSizeMax", chatSizeMax as Any), ("megagroupSizeMax", megagroupSizeMax as Any), ("forwardedCountMax", forwardedCountMax as Any), ("onlineUpdatePeriodMs", onlineUpdatePeriodMs as Any), ("offlineBlurTimeoutMs", offlineBlurTimeoutMs as Any), ("offlineIdleTimeoutMs", offlineIdleTimeoutMs as Any), ("onlineCloudTimeoutMs", onlineCloudTimeoutMs as Any), ("notifyCloudDelayMs", notifyCloudDelayMs as Any), ("notifyDefaultDelayMs", notifyDefaultDelayMs as Any), ("pushChatPeriodMs", pushChatPeriodMs as Any), ("pushChatLimit", pushChatLimit as Any), ("savedGifsLimit", savedGifsLimit as Any), ("editTimeLimit", editTimeLimit as Any), ("revokeTimeLimit", revokeTimeLimit as Any), ("revokePmTimeLimit", revokePmTimeLimit as Any), ("ratingEDecay", ratingEDecay as Any), ("stickersRecentLimit", stickersRecentLimit as Any), ("stickersFavedLimit", stickersFavedLimit as Any), ("channelsReadMediaPeriod", channelsReadMediaPeriod as Any), ("tmpSessions", tmpSessions as Any), ("pinnedDialogsCountMax", pinnedDialogsCountMax as Any), ("pinnedInfolderCountMax", pinnedInfolderCountMax as Any), ("callReceiveTimeoutMs", callReceiveTimeoutMs as Any), ("callRingTimeoutMs", callRingTimeoutMs as Any), ("callConnectTimeoutMs", callConnectTimeoutMs as Any), ("callPacketTimeoutMs", callPacketTimeoutMs as Any), ("meUrlPrefix", meUrlPrefix as Any), ("autoupdateUrlPrefix", autoupdateUrlPrefix as Any), ("gifSearchUsername", gifSearchUsername as Any), ("venueSearchUsername", venueSearchUsername as Any), ("imgSearchUsername", imgSearchUsername as Any), ("staticMapsProvider", staticMapsProvider as Any), ("captionLengthMax", captionLengthMax as Any), ("messageLengthMax", messageLengthMax as Any), ("webfileDcId", webfileDcId as Any), ("suggestedLangCode", suggestedLangCode as Any), ("langPackVersion", langPackVersion as Any), ("baseLangPackVersion", baseLangPackVersion as Any), ("reactionsDefault", reactionsDefault as Any)])
case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let dcTxtDomainName, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let pushChatPeriodMs, let pushChatLimit, let editTimeLimit, let revokeTimeLimit, let revokePmTimeLimit, let ratingEDecay, let stickersRecentLimit, let channelsReadMediaPeriod, let tmpSessions, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let autoupdateUrlPrefix, let gifSearchUsername, let venueSearchUsername, let imgSearchUsername, let staticMapsProvider, let captionLengthMax, let messageLengthMax, let webfileDcId, let suggestedLangCode, let langPackVersion, let baseLangPackVersion, let reactionsDefault, let autologinToken):
return ("config", [("flags", flags as Any), ("date", date as Any), ("expires", expires as Any), ("testMode", testMode as Any), ("thisDc", thisDc as Any), ("dcOptions", dcOptions as Any), ("dcTxtDomainName", dcTxtDomainName as Any), ("chatSizeMax", chatSizeMax as Any), ("megagroupSizeMax", megagroupSizeMax as Any), ("forwardedCountMax", forwardedCountMax as Any), ("onlineUpdatePeriodMs", onlineUpdatePeriodMs as Any), ("offlineBlurTimeoutMs", offlineBlurTimeoutMs as Any), ("offlineIdleTimeoutMs", offlineIdleTimeoutMs as Any), ("onlineCloudTimeoutMs", onlineCloudTimeoutMs as Any), ("notifyCloudDelayMs", notifyCloudDelayMs as Any), ("notifyDefaultDelayMs", notifyDefaultDelayMs as Any), ("pushChatPeriodMs", pushChatPeriodMs as Any), ("pushChatLimit", pushChatLimit as Any), ("editTimeLimit", editTimeLimit as Any), ("revokeTimeLimit", revokeTimeLimit as Any), ("revokePmTimeLimit", revokePmTimeLimit as Any), ("ratingEDecay", ratingEDecay as Any), ("stickersRecentLimit", stickersRecentLimit as Any), ("channelsReadMediaPeriod", channelsReadMediaPeriod as Any), ("tmpSessions", tmpSessions as Any), ("callReceiveTimeoutMs", callReceiveTimeoutMs as Any), ("callRingTimeoutMs", callRingTimeoutMs as Any), ("callConnectTimeoutMs", callConnectTimeoutMs as Any), ("callPacketTimeoutMs", callPacketTimeoutMs as Any), ("meUrlPrefix", meUrlPrefix as Any), ("autoupdateUrlPrefix", autoupdateUrlPrefix as Any), ("gifSearchUsername", gifSearchUsername as Any), ("venueSearchUsername", venueSearchUsername as Any), ("imgSearchUsername", imgSearchUsername as Any), ("staticMapsProvider", staticMapsProvider as Any), ("captionLengthMax", captionLengthMax as Any), ("messageLengthMax", messageLengthMax as Any), ("webfileDcId", webfileDcId as Any), ("suggestedLangCode", suggestedLangCode as Any), ("langPackVersion", langPackVersion as Any), ("baseLangPackVersion", baseLangPackVersion as Any), ("reactionsDefault", reactionsDefault as Any), ("autologinToken", autologinToken as Any)])
}
}
@ -573,51 +570,45 @@ public extension Api {
var _24: Int32?
_24 = reader.readInt32()
var _25: Int32?
_25 = reader.readInt32()
if Int(_1!) & Int(1 << 0) != 0 {_25 = reader.readInt32() }
var _26: Int32?
_26 = reader.readInt32()
var _27: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_27 = reader.readInt32() }
_27 = reader.readInt32()
var _28: Int32?
_28 = reader.readInt32()
var _29: Int32?
_29 = reader.readInt32()
var _30: Int32?
_30 = reader.readInt32()
var _31: Int32?
_31 = reader.readInt32()
var _32: Int32?
_32 = reader.readInt32()
var _33: Int32?
_33 = reader.readInt32()
var _30: String?
_30 = parseString(reader)
var _31: String?
if Int(_1!) & Int(1 << 7) != 0 {_31 = parseString(reader) }
var _32: String?
if Int(_1!) & Int(1 << 9) != 0 {_32 = parseString(reader) }
var _33: String?
if Int(_1!) & Int(1 << 10) != 0 {_33 = parseString(reader) }
var _34: String?
_34 = parseString(reader)
if Int(_1!) & Int(1 << 11) != 0 {_34 = parseString(reader) }
var _35: String?
if Int(_1!) & Int(1 << 7) != 0 {_35 = parseString(reader) }
var _36: String?
if Int(_1!) & Int(1 << 9) != 0 {_36 = parseString(reader) }
var _37: String?
if Int(_1!) & Int(1 << 10) != 0 {_37 = parseString(reader) }
var _38: String?
if Int(_1!) & Int(1 << 11) != 0 {_38 = parseString(reader) }
if Int(_1!) & Int(1 << 12) != 0 {_35 = parseString(reader) }
var _36: Int32?
_36 = reader.readInt32()
var _37: Int32?
_37 = reader.readInt32()
var _38: Int32?
_38 = reader.readInt32()
var _39: String?
if Int(_1!) & Int(1 << 12) != 0 {_39 = parseString(reader) }
if Int(_1!) & Int(1 << 2) != 0 {_39 = parseString(reader) }
var _40: Int32?
_40 = reader.readInt32()
if Int(_1!) & Int(1 << 2) != 0 {_40 = reader.readInt32() }
var _41: Int32?
_41 = reader.readInt32()
var _42: Int32?
_42 = reader.readInt32()
var _43: String?
if Int(_1!) & Int(1 << 2) != 0 {_43 = parseString(reader) }
var _44: Int32?
if Int(_1!) & Int(1 << 2) != 0 {_44 = reader.readInt32() }
var _45: Int32?
if Int(_1!) & Int(1 << 2) != 0 {_45 = reader.readInt32() }
var _46: Api.Reaction?
if Int(_1!) & Int(1 << 2) != 0 {_41 = reader.readInt32() }
var _42: Api.Reaction?
if Int(_1!) & Int(1 << 15) != 0 {if let signature = reader.readInt32() {
_46 = Api.parse(reader, signature: signature) as? Api.Reaction
_42 = Api.parse(reader, signature: signature) as? Api.Reaction
} }
var _43: String?
if Int(_1!) & Int(1 << 16) != 0 {_43 = parseString(reader) }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -642,30 +633,27 @@ public extension Api {
let _c22 = _22 != nil
let _c23 = _23 != nil
let _c24 = _24 != nil
let _c25 = _25 != nil
let _c25 = (Int(_1!) & Int(1 << 0) == 0) || _25 != nil
let _c26 = _26 != nil
let _c27 = (Int(_1!) & Int(1 << 0) == 0) || _27 != nil
let _c27 = _27 != nil
let _c28 = _28 != nil
let _c29 = _29 != nil
let _c30 = _30 != nil
let _c31 = _31 != nil
let _c32 = _32 != nil
let _c33 = _33 != nil
let _c34 = _34 != nil
let _c35 = (Int(_1!) & Int(1 << 7) == 0) || _35 != nil
let _c36 = (Int(_1!) & Int(1 << 9) == 0) || _36 != nil
let _c37 = (Int(_1!) & Int(1 << 10) == 0) || _37 != nil
let _c38 = (Int(_1!) & Int(1 << 11) == 0) || _38 != nil
let _c39 = (Int(_1!) & Int(1 << 12) == 0) || _39 != nil
let _c40 = _40 != nil
let _c41 = _41 != nil
let _c42 = _42 != nil
let _c43 = (Int(_1!) & Int(1 << 2) == 0) || _43 != nil
let _c44 = (Int(_1!) & Int(1 << 2) == 0) || _44 != nil
let _c45 = (Int(_1!) & Int(1 << 2) == 0) || _45 != nil
let _c46 = (Int(_1!) & Int(1 << 15) == 0) || _46 != 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 {
return Api.Config.config(flags: _1!, date: _2!, expires: _3!, testMode: _4!, thisDc: _5!, dcOptions: _6!, dcTxtDomainName: _7!, chatSizeMax: _8!, megagroupSizeMax: _9!, forwardedCountMax: _10!, onlineUpdatePeriodMs: _11!, offlineBlurTimeoutMs: _12!, offlineIdleTimeoutMs: _13!, onlineCloudTimeoutMs: _14!, notifyCloudDelayMs: _15!, notifyDefaultDelayMs: _16!, pushChatPeriodMs: _17!, pushChatLimit: _18!, savedGifsLimit: _19!, editTimeLimit: _20!, revokeTimeLimit: _21!, revokePmTimeLimit: _22!, ratingEDecay: _23!, stickersRecentLimit: _24!, stickersFavedLimit: _25!, channelsReadMediaPeriod: _26!, tmpSessions: _27, pinnedDialogsCountMax: _28!, pinnedInfolderCountMax: _29!, callReceiveTimeoutMs: _30!, callRingTimeoutMs: _31!, callConnectTimeoutMs: _32!, callPacketTimeoutMs: _33!, meUrlPrefix: _34!, autoupdateUrlPrefix: _35, gifSearchUsername: _36, venueSearchUsername: _37, imgSearchUsername: _38, staticMapsProvider: _39, captionLengthMax: _40!, messageLengthMax: _41!, webfileDcId: _42!, suggestedLangCode: _43, langPackVersion: _44, baseLangPackVersion: _45, reactionsDefault: _46)
let _c31 = (Int(_1!) & Int(1 << 7) == 0) || _31 != nil
let _c32 = (Int(_1!) & Int(1 << 9) == 0) || _32 != nil
let _c33 = (Int(_1!) & Int(1 << 10) == 0) || _33 != nil
let _c34 = (Int(_1!) & Int(1 << 11) == 0) || _34 != nil
let _c35 = (Int(_1!) & Int(1 << 12) == 0) || _35 != nil
let _c36 = _36 != nil
let _c37 = _37 != nil
let _c38 = _38 != nil
let _c39 = (Int(_1!) & Int(1 << 2) == 0) || _39 != nil
let _c40 = (Int(_1!) & Int(1 << 2) == 0) || _40 != nil
let _c41 = (Int(_1!) & Int(1 << 2) == 0) || _41 != nil
let _c42 = (Int(_1!) & Int(1 << 15) == 0) || _42 != nil
let _c43 = (Int(_1!) & Int(1 << 16) == 0) || _43 != 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 {
return Api.Config.config(flags: _1!, date: _2!, expires: _3!, testMode: _4!, thisDc: _5!, dcOptions: _6!, dcTxtDomainName: _7!, chatSizeMax: _8!, megagroupSizeMax: _9!, forwardedCountMax: _10!, onlineUpdatePeriodMs: _11!, offlineBlurTimeoutMs: _12!, offlineIdleTimeoutMs: _13!, onlineCloudTimeoutMs: _14!, notifyCloudDelayMs: _15!, notifyDefaultDelayMs: _16!, pushChatPeriodMs: _17!, pushChatLimit: _18!, editTimeLimit: _19!, revokeTimeLimit: _20!, revokePmTimeLimit: _21!, ratingEDecay: _22!, stickersRecentLimit: _23!, channelsReadMediaPeriod: _24!, tmpSessions: _25, callReceiveTimeoutMs: _26!, callRingTimeoutMs: _27!, callConnectTimeoutMs: _28!, callPacketTimeoutMs: _29!, meUrlPrefix: _30!, autoupdateUrlPrefix: _31, gifSearchUsername: _32, venueSearchUsername: _33, imgSearchUsername: _34, staticMapsProvider: _35, captionLengthMax: _36!, messageLengthMax: _37!, webfileDcId: _38!, suggestedLangCode: _39, langPackVersion: _40, baseLangPackVersion: _41, reactionsDefault: _42, autologinToken: _43)
}
else {
return nil

View File

@ -876,6 +876,46 @@ public extension Api {
}
}
public extension Api {
enum InlineBotWebView: TypeConstructorDescription {
case inlineBotWebView(text: String, url: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .inlineBotWebView(let text, let url):
if boxed {
buffer.appendInt32(-1250781739)
}
serializeString(text, buffer: buffer, boxed: false)
serializeString(url, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .inlineBotWebView(let text, let url):
return ("inlineBotWebView", [("text", text as Any), ("url", url as Any)])
}
}
public static func parse_inlineBotWebView(_ reader: BufferReader) -> InlineBotWebView? {
var _1: String?
_1 = parseString(reader)
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.InlineBotWebView.inlineBotWebView(text: _1!, url: _2!)
}
else {
return nil
}
}
}
}
public extension Api {
enum InlineQueryPeerType: TypeConstructorDescription {
case inlineQueryPeerTypeBroadcast
@ -1002,6 +1042,72 @@ public extension Api {
}
}
public extension Api {
indirect enum InputBotApp: TypeConstructorDescription {
case inputBotAppID(id: Int64, accessHash: Int64)
case inputBotAppShortName(botId: Api.InputUser, shortName: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .inputBotAppID(let id, let accessHash):
if boxed {
buffer.appendInt32(-1457472134)
}
serializeInt64(id, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
break
case .inputBotAppShortName(let botId, let shortName):
if boxed {
buffer.appendInt32(-1869872121)
}
botId.serialize(buffer, true)
serializeString(shortName, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .inputBotAppID(let id, let accessHash):
return ("inputBotAppID", [("id", id as Any), ("accessHash", accessHash as Any)])
case .inputBotAppShortName(let botId, let shortName):
return ("inputBotAppShortName", [("botId", botId as Any), ("shortName", shortName as Any)])
}
}
public static func parse_inputBotAppID(_ reader: BufferReader) -> InputBotApp? {
var _1: Int64?
_1 = reader.readInt64()
var _2: Int64?
_2 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.InputBotApp.inputBotAppID(id: _1!, accessHash: _2!)
}
else {
return nil
}
}
public static func parse_inputBotAppShortName(_ reader: BufferReader) -> InputBotApp? {
var _1: Api.InputUser?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.InputUser
}
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.InputBotApp.inputBotAppShortName(botId: _1!, shortName: _2!)
}
else {
return nil
}
}
}
}
public extension Api {
enum InputBotInlineMessage: TypeConstructorDescription {
case inputBotInlineMessageGame(flags: Int32, replyMarkup: Api.ReplyMarkup?)
@ -1322,79 +1428,3 @@ public extension Api {
}
}
public extension Api {
enum InputBotInlineMessageID: TypeConstructorDescription {
case inputBotInlineMessageID(dcId: Int32, id: Int64, accessHash: Int64)
case inputBotInlineMessageID64(dcId: Int32, ownerId: Int64, id: Int32, accessHash: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .inputBotInlineMessageID(let dcId, let id, let accessHash):
if boxed {
buffer.appendInt32(-1995686519)
}
serializeInt32(dcId, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
break
case .inputBotInlineMessageID64(let dcId, let ownerId, let id, let accessHash):
if boxed {
buffer.appendInt32(-1227287081)
}
serializeInt32(dcId, buffer: buffer, boxed: false)
serializeInt64(ownerId, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .inputBotInlineMessageID(let dcId, let id, let accessHash):
return ("inputBotInlineMessageID", [("dcId", dcId as Any), ("id", id as Any), ("accessHash", accessHash as Any)])
case .inputBotInlineMessageID64(let dcId, let ownerId, let id, let accessHash):
return ("inputBotInlineMessageID64", [("dcId", dcId as Any), ("ownerId", ownerId as Any), ("id", id as Any), ("accessHash", accessHash as Any)])
}
}
public static func parse_inputBotInlineMessageID(_ reader: BufferReader) -> InputBotInlineMessageID? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: Int64?
_3 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.InputBotInlineMessageID.inputBotInlineMessageID(dcId: _1!, id: _2!, accessHash: _3!)
}
else {
return nil
}
}
public static func parse_inputBotInlineMessageID64(_ reader: BufferReader) -> InputBotInlineMessageID? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int64?
_4 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.InputBotInlineMessageID.inputBotInlineMessageID64(dcId: _1!, ownerId: _2!, id: _3!, accessHash: _4!)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,79 @@
public extension Api {
enum InputBotInlineMessageID: TypeConstructorDescription {
case inputBotInlineMessageID(dcId: Int32, id: Int64, accessHash: Int64)
case inputBotInlineMessageID64(dcId: Int32, ownerId: Int64, id: Int32, accessHash: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .inputBotInlineMessageID(let dcId, let id, let accessHash):
if boxed {
buffer.appendInt32(-1995686519)
}
serializeInt32(dcId, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
break
case .inputBotInlineMessageID64(let dcId, let ownerId, let id, let accessHash):
if boxed {
buffer.appendInt32(-1227287081)
}
serializeInt32(dcId, buffer: buffer, boxed: false)
serializeInt64(ownerId, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .inputBotInlineMessageID(let dcId, let id, let accessHash):
return ("inputBotInlineMessageID", [("dcId", dcId as Any), ("id", id as Any), ("accessHash", accessHash as Any)])
case .inputBotInlineMessageID64(let dcId, let ownerId, let id, let accessHash):
return ("inputBotInlineMessageID64", [("dcId", dcId as Any), ("ownerId", ownerId as Any), ("id", id as Any), ("accessHash", accessHash as Any)])
}
}
public static func parse_inputBotInlineMessageID(_ reader: BufferReader) -> InputBotInlineMessageID? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: Int64?
_3 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.InputBotInlineMessageID.inputBotInlineMessageID(dcId: _1!, id: _2!, accessHash: _3!)
}
else {
return nil
}
}
public static func parse_inputBotInlineMessageID64(_ reader: BufferReader) -> InputBotInlineMessageID? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int64?
_4 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.InputBotInlineMessageID.inputBotInlineMessageID64(dcId: _1!, ownerId: _2!, id: _3!, accessHash: _4!)
}
else {
return nil
}
}
}
}
public extension Api {
enum InputBotInlineResult: TypeConstructorDescription {
case inputBotInlineResult(flags: Int32, id: String, type: String, title: String?, description: String?, url: String?, thumb: Api.InputWebDocument?, content: Api.InputWebDocument?, sendMessage: Api.InputBotInlineMessage)

View File

@ -514,7 +514,7 @@ extension ChatContextResultSwitchPeer {
extension ChatContextResultCollection {
convenience init(apiResults: Api.messages.BotResults, botId: PeerId, peerId: PeerId, query: String, geoPoint: (Double, Double)?) {
switch apiResults {
case let .botResults(flags, queryId, nextOffset, switchPm, results, cacheTime, _):
case let .botResults(flags, queryId, nextOffset, switchPm, _, results, cacheTime, _):
var switchPeer: ChatContextResultSwitchPeer?
if let switchPm = switchPm {
switchPeer = ChatContextResultSwitchPeer(apiSwitchPeer: switchPm)

View File

@ -205,7 +205,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
}
switch action {
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionAttachMenuBotAllowed:
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto:
break
case let .messageActionChannelMigrateFrom(_, chatId):
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId)))

View File

@ -50,8 +50,8 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
return TelegramMediaAction(action: .historyScreenshot)
case let .messageActionCustomAction(message):
return TelegramMediaAction(action: .customText(text: message, entities: []))
case let .messageActionBotAllowed(domain):
return TelegramMediaAction(action: .botDomainAccessGranted(domain: domain))
case let .messageActionBotAllowed(_, domain, _):
return TelegramMediaAction(action: .botDomainAccessGranted(domain: domain ?? ""))
case .messageActionSecureValuesSentMe:
return nil
case let .messageActionSecureValuesSent(types):
@ -106,8 +106,6 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
return TelegramMediaAction(action: .topicEdited(components: components))
case let.messageActionSuggestProfilePhoto(photo):
return TelegramMediaAction(action: .suggestedProfilePhoto(image: telegramMediaImageFromApiPhoto(photo)))
case .messageActionAttachMenuBotAllowed:
return TelegramMediaAction(action: .attachMenuBotAllowed)
case let .messageActionRequestedPeer(buttonId, peer):
return TelegramMediaAction(action: .requestedPeer(buttonId: buttonId, peerId: peer.peerId))
}

View File

@ -1,3 +1,4 @@
import Foundation
import Postbox
import TelegramApi

View File

@ -14,7 +14,8 @@ func managedConfigurationUpdates(accountManager: AccountManager<TelegramAccountM
|> mapToSignal { result, defaultHistoryTtl -> Signal<Void, NoError> in
return postbox.transaction { transaction -> Signal<Void, NoError> in
switch result {
case let .config(flags, _, _, _, _, dcOptions, _, chatSizeMax, megagroupSizeMax, forwardedCountMax, _, _, _, _, _, _, _, _, savedGifsLimit, editTimeLimit, revokeTimeLimit, revokePmTimeLimit, _, stickersRecentLimit, stickersFavedLimit, _, _, pinnedDialogsCountMax, pinnedInfolderCountMax, _, _, _, _, _, autoupdateUrlPrefix, gifSearchUsername, venueSearchUsername, imgSearchUsername, _, captionLengthMax, _, webfileDcId, suggestedLangCode, langPackVersion, baseLangPackVersion, defaultReaction):
case let .config(flags, _, _, _, _, dcOptions, _, chatSizeMax, megagroupSizeMax, forwardedCountMax, _, _, _, _, _, _, _, _, editTimeLimit, revokeTimeLimit, revokePmTimeLimit, _, stickersRecentLimit, _, _, _, _, _, _, _, autoupdateUrlPrefix, gifSearchUsername, venueSearchUsername, imgSearchUsername, _, captionLengthMax, _, webfileDcId, suggestedLangCode, langPackVersion, baseLangPackVersion, reactionsDefault, autologinToken):
let _ = autologinToken
var addressList: [Int: [MTDatacenterAddress]] = [:]
for option in dcOptions {
switch option {
@ -61,11 +62,11 @@ func managedConfigurationUpdates(accountManager: AccountManager<TelegramAccountM
return entry
})
updateLimitsConfiguration(transaction: transaction, configuration: LimitsConfiguration(maxPinnedChatCount: pinnedDialogsCountMax, maxArchivedPinnedChatCount: pinnedInfolderCountMax, maxGroupMemberCount: chatSizeMax, maxSupergroupMemberCount: megagroupSizeMax, maxMessageForwardBatchSize: forwardedCountMax, maxSavedGifCount: savedGifsLimit, maxRecentStickerCount: stickersRecentLimit, maxFavedStickerCount: stickersFavedLimit, maxMessageEditingInterval: editTimeLimit, maxMediaCaptionLength: captionLengthMax, canRemoveIncomingMessagesInPrivateChats: (flags & (1 << 6)) != 0, maxMessageRevokeInterval: revokeTimeLimit, maxMessageRevokeIntervalInPrivateChats: revokePmTimeLimit))
updateLimitsConfiguration(transaction: transaction, configuration: LimitsConfiguration(maxPinnedChatCount: 5, maxArchivedPinnedChatCount: 5, maxGroupMemberCount: chatSizeMax, maxSupergroupMemberCount: megagroupSizeMax, maxMessageForwardBatchSize: forwardedCountMax, maxSavedGifCount: 10, maxRecentStickerCount: stickersRecentLimit, maxFavedStickerCount: 10, maxMessageEditingInterval: editTimeLimit, maxMediaCaptionLength: captionLengthMax, canRemoveIncomingMessagesInPrivateChats: (flags & (1 << 6)) != 0, maxMessageRevokeInterval: revokeTimeLimit, maxMessageRevokeIntervalInPrivateChats: revokePmTimeLimit))
updateSearchBotsConfiguration(transaction: transaction, configuration: SearchBotsConfiguration(imageBotUsername: imgSearchUsername, gifBotUsername: gifSearchUsername, venueBotUsername: venueSearchUsername))
if let defaultReaction = defaultReaction, let reaction = MessageReaction.Reaction(apiReaction: defaultReaction) {
if let defaultReaction = reactionsDefault, let reaction = MessageReaction.Reaction(apiReaction: defaultReaction) {
updateReactionSettings(transaction: transaction, { settings in
var settings = settings
settings.quickReaction = reaction

View File

@ -338,7 +338,7 @@ public extension EngineMessageReactionListContext.State {
for recentPeer in reactionsAttribute.recentPeers {
if let peer = message.peers[recentPeer.peerId] {
if reaction == nil || recentPeer.value == reaction {
items.append(EngineMessageReactionListContext.Item(peer: EnginePeer(peer), reaction: recentPeer.value))
items.append(EngineMessageReactionListContext.Item(peer: EnginePeer(peer), reaction: recentPeer.value, timestamp: nil))
}
}
}
@ -359,13 +359,16 @@ public final class EngineMessageReactionListContext {
public final class Item: Equatable {
public let peer: EnginePeer
public let reaction: MessageReaction.Reaction?
public let timestamp: Int32?
public init(
peer: EnginePeer,
reaction: MessageReaction.Reaction?
reaction: MessageReaction.Reaction?,
timestamp: Int32?
) {
self.peer = peer
self.reaction = reaction
self.timestamp = timestamp
}
public static func ==(lhs: Item, rhs: Item) -> Bool {
@ -375,6 +378,9 @@ public final class EngineMessageReactionListContext {
if lhs.reaction != rhs.reaction {
return false
}
if lhs.timestamp != rhs.timestamp {
return false
}
return true
}
}
@ -503,7 +509,7 @@ public final class EngineMessageReactionListContext {
switch reaction {
case let .messagePeerReaction(_, peer, reaction):
if let peer = transaction.getPeer(peer.peerId), let reaction = MessageReaction.Reaction(apiReaction: reaction) {
items.append(EngineMessageReactionListContext.Item(peer: EnginePeer(peer), reaction: reaction))
items.append(EngineMessageReactionListContext.Item(peer: EnginePeer(peer), reaction: reaction, timestamp: nil))
}
}
}

View File

@ -33,6 +33,7 @@ func _internal_resetAccountState(postbox: Postbox, network: Network, accountPeer
}
}
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, _ in nil })
transaction.setPeerThreadCombinedState(peerId: peerId, state: nil)
}
}

View File

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 153
return 154
}
public func parseMessage(_ data: Data!) -> Any! {
@ -246,7 +246,7 @@ public class Serialization: NSObject, MTSerialization {
return { response -> MTDatacenterAddressListData? in
if let config = parser.parse(Buffer(data: response)) {
switch config {
case let .config(_, _, _, _, _, dcOptions, _, _, _, _, _, _,_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .config(_, _, _, _, _, dcOptions, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
var addressDict: [NSNumber: [Any]] = [:]
for option in dcOptions {
switch option {

View File

@ -3,20 +3,19 @@ import Postbox
import TelegramApi
import SwiftSignalKit
func _internal_currentlySuggestedLocalization(network: Network, extractKeys: [String]) -> Signal<SuggestedLocalizationInfo?, NoError> {
return network.request(Api.functions.help.getConfig())
|> retryRequest
|> mapToSignal { result -> Signal<SuggestedLocalizationInfo?, NoError> in
switch result {
case let .config(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, suggestedLangCode, _, _, _):
if let suggestedLangCode = suggestedLangCode {
return _internal_suggestedLocalizationInfo(network: network, languageCode: suggestedLangCode, extractKeys: extractKeys) |> map(Optional.init)
} else {
return .single(nil)
}
|> retryRequest
|> mapToSignal { result -> Signal<SuggestedLocalizationInfo?, NoError> in
switch result {
case let .config(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, suggestedLangCode, _, _, _, _):
if let suggestedLangCode = suggestedLangCode {
return _internal_suggestedLocalizationInfo(network: network, languageCode: suggestedLangCode, extractKeys: extractKeys) |> map(Optional.init)
} else {
return .single(nil)
}
}
}
}
func _internal_suggestedLocalizationInfo(network: Network, languageCode: String, extractKeys: [String]) -> Signal<SuggestedLocalizationInfo, NoError> {

View File

@ -5,10 +5,12 @@ import TelegramApi
public final class MessageReadStats {
public let reactionCount: Int
public let peers: [EnginePeer]
public let readTimestamps: [EnginePeer.Id: Int32]
public init(reactionCount: Int, peers: [EnginePeer]) {
public init(reactionCount: Int, peers: [EnginePeer], readTimestamps: [EnginePeer.Id: Int32]) {
self.reactionCount = reactionCount
self.peers = peers
self.readTimestamps = readTimestamps
}
}
@ -24,9 +26,18 @@ func _internal_messageReadStats(account: Account, id: MessageId) -> Signal<Messa
return .single(nil)
}
let readPeers: Signal<[Int64]?, NoError> = account.network.request(Api.functions.messages.getMessageReadParticipants(peer: inputPeer, msgId: id.id))
|> map(Optional.init)
|> `catch` { _ -> Signal<[Int64]?, NoError> in
let readPeers: Signal<[(Int64, Int32)]?, NoError> = account.network.request(Api.functions.messages.getMessageReadParticipants(peer: inputPeer, msgId: id.id))
|> map { result -> [(Int64, Int32)]? in
var items: [(Int64, Int32)] = []
for item in result {
switch item {
case let .readParticipantDate(userId, date):
items.append((userId, date))
}
}
return items
}
|> `catch` { _ -> Signal<[(Int64, Int32)]?, NoError> in
return .single(nil)
}
@ -43,15 +54,17 @@ func _internal_messageReadStats(account: Account, id: MessageId) -> Signal<Messa
return combineLatest(readPeers, reactionCount)
|> mapToSignal { result, reactionCount -> Signal<MessageReadStats?, NoError> in
return account.postbox.transaction { transaction -> (peerIds: [PeerId], missingPeerIds: [PeerId]) in
return account.postbox.transaction { transaction -> (peerIds: [PeerId], readTimestamps: [PeerId: Int32], missingPeerIds: [PeerId]) in
var peerIds: [PeerId] = []
var readTimestamps: [PeerId: Int32] = [:]
var missingPeerIds: [PeerId] = []
let authorId = transaction.getMessage(id)?.author?.id
if let result = result {
for id in result {
for (id, timestamp) in result {
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id))
readTimestamps[peerId] = timestamp
if peerId == account.peerId {
continue
}
@ -65,14 +78,14 @@ func _internal_messageReadStats(account: Account, id: MessageId) -> Signal<Messa
}
}
return (peerIds: peerIds, missingPeerIds: missingPeerIds)
return (peerIds: peerIds, readTimestamps: readTimestamps, missingPeerIds: missingPeerIds)
}
|> mapToSignal { peerIds, missingPeerIds -> Signal<MessageReadStats?, NoError> in
|> mapToSignal { peerIds, readTimestamps, missingPeerIds -> Signal<MessageReadStats?, NoError> in
if missingPeerIds.isEmpty || id.peerId.namespace != Namespaces.Peer.CloudChannel {
return account.postbox.transaction { transaction -> MessageReadStats? in
return MessageReadStats(reactionCount: reactionCount, peers: peerIds.compactMap { peerId -> EnginePeer? in
return transaction.getPeer(peerId).flatMap(EnginePeer.init)
})
}, readTimestamps: readTimestamps)
}
} else {
return _internal_channelMembers(postbox: account.postbox, network: account.network, accountPeerId: account.peerId, peerId: id.peerId, category: .recent(.all), offset: 0, limit: 50, hash: 0)
@ -80,7 +93,7 @@ func _internal_messageReadStats(account: Account, id: MessageId) -> Signal<Messa
return account.postbox.transaction { transaction -> MessageReadStats? in
return MessageReadStats(reactionCount: reactionCount, peers: peerIds.compactMap { peerId -> EnginePeer? in
return transaction.getPeer(peerId).flatMap(EnginePeer.init)
})
}, readTimestamps: readTimestamps)
}
}
}

View File

@ -491,6 +491,44 @@ private func automaticThemeShouldSwitch(_ settings: AutomaticThemeSwitchSetting,
}
}
public func automaticEnergyUsageShouldBeOnNow(settings: MediaAutoDownloadSettings) -> Bool {
if settings.energyUsageSettings.activationThreshold == 0 {
return false
} else if settings.energyUsageSettings.activationThreshold >= 100 {
return true
} else {
let batteryLevel = UIDevice.current.batteryLevel
if batteryLevel < 0.0 {
return false
} else {
return batteryLevel <= Float(settings.energyUsageSettings.activationThreshold) / 100.0
}
}
}
public func automaticEnergyUsageShouldBeOn(settings: MediaAutoDownloadSettings) -> Signal<Bool, NoError> {
if settings.energyUsageSettings.activationThreshold == 0 {
return .single(false)
} else if settings.energyUsageSettings.activationThreshold >= 100 {
return .single(true)
} else {
return Signal { subscriber in
subscriber.putNext(automaticEnergyUsageShouldBeOnNow(settings: settings))
let timer = SwiftSignalKit.Timer(timeout: 1.0, repeat: true, completion: {
subscriber.putNext(automaticEnergyUsageShouldBeOnNow(settings: settings))
}, queue: Queue.mainQueue())
timer.start()
return ActionDisposable {
timer.invalidate()
}
}
|> runOn(Queue.mainQueue())
|> distinctUntilChanged
}
}
private func serviceColor(for data: Signal<MediaResourceData, NoError>) -> Signal<UIColor, NoError> {
return data
|> mapToSignal { data -> Signal<UIColor, NoError> in

View File

@ -38,6 +38,8 @@ public struct PresentationResourcesSettings {
public static let deleteAccount = renderIcon(name: "Chat/Info/GroupRemovedIcon")
public static let powerSaving = renderIcon(name: "Settings/Menu/PowerSaving")
public static let premium = generateImage(CGSize(width: 29.0, height: 29.0), contextGenerator: { size, context in
let bounds = CGRect(origin: CGPoint(), size: size)
context.clear(bounds)

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "IconPowersaving.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,13 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1001_6956)">
<rect width="30" height="30" rx="7" fill="#FF9500"/>
<rect x="5" y="10" width="18" height="10" rx="3" stroke="white" stroke-width="1.66"/>
<path d="M24.5 12.5V17.5C25.5059 17.0765 26.16 16.0914 26.16 15C26.16 13.9086 25.5059 12.9235 24.5 12.5Z" fill="white"/>
<path d="M7 13.6C7 13.0399 7 12.7599 7.10899 12.546C7.20487 12.3578 7.35785 12.2049 7.54601 12.109C7.75992 12 8.03995 12 8.6 12H9.4C9.96005 12 10.2401 12 10.454 12.109C10.6422 12.2049 10.7951 12.3578 10.891 12.546C11 12.7599 11 13.0399 11 13.6V16.4C11 16.9601 11 17.2401 10.891 17.454C10.7951 17.6422 10.6422 17.7951 10.454 17.891C10.2401 18 9.96005 18 9.4 18H8.6C8.03995 18 7.75992 18 7.54601 17.891C7.35785 17.7951 7.20487 17.6422 7.10899 17.454C7 17.2401 7 16.9601 7 16.4V13.6Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1001_6956">
<rect width="30" height="30" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1006 B

View File

@ -0,0 +1,9 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"provides-namespace" : true
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "PowerIconBackgroundTime.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1001_3249)">
<rect width="30" height="30" rx="7" fill="#AF52DE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 24C19.9706 24 24 19.9706 24 15C24 10.0294 19.9706 6 15 6C10.0294 6 6 10.0294 6 15C6 19.9706 10.0294 24 15 24ZM15.83 9.5C15.83 9.0416 15.4584 8.67 15 8.67C14.5416 8.67 14.17 9.0416 14.17 9.5V15C14.17 15.2201 14.2574 15.4312 14.4131 15.5868L17.9131 19.0869C18.2372 19.411 18.7628 19.411 19.0869 19.0869C19.411 18.7628 19.411 18.2372 19.0869 17.9131L15.83 14.6562V9.5Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1001_3249">
<rect width="30" height="30" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 737 B

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "PowerIconEffects.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,15 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1001_6334)">
<rect width="30" height="30" rx="7" fill="#32ADE6"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.83 4.99998C15.83 4.54159 15.4584 4.16998 15 4.16998C14.5416 4.16998 14.17 4.54159 14.17 4.99998V7.99998C14.17 8.45838 14.5416 8.82998 15 8.82998C15.4584 8.82998 15.83 8.45838 15.83 7.99998V4.99998ZM15.83 22C15.83 21.5416 15.4584 21.17 15 21.17C14.5416 21.17 14.17 21.5416 14.17 22V25C14.17 25.4584 14.5416 25.83 15 25.83C15.4584 25.83 15.83 25.4584 15.83 25V22Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.00001 14.17C4.54162 14.17 4.17001 14.5416 4.17001 15C4.17001 15.4584 4.54162 15.83 5.00001 15.83H8.00001C8.45841 15.83 8.83001 15.4584 8.83001 15C8.83001 14.5416 8.45841 14.17 8.00001 14.17H5.00001ZM22 14.17C21.5416 14.17 21.17 14.5416 21.17 15C21.17 15.4584 21.5416 15.83 22 15.83H25C25.4584 15.83 25.83 15.4584 25.83 15C25.83 14.5416 25.4584 14.17 25 14.17H22Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.658 8.51582C22.9821 8.19169 22.9821 7.66616 22.658 7.34203C22.3338 7.01789 21.8083 7.01789 21.4842 7.34203L19.3629 9.46335C19.0387 9.78748 19.0387 10.313 19.3629 10.6371C19.687 10.9613 20.2125 10.9613 20.5367 10.6371L22.658 8.51582ZM10.6372 20.5366C10.9613 20.2125 10.9613 19.687 10.6372 19.3628C10.313 19.0387 9.7875 19.0387 9.46336 19.3628L7.34204 21.4842C7.01791 21.8083 7.01791 22.3338 7.34204 22.658C7.66618 22.9821 8.1917 22.9821 8.51584 22.658L10.6372 20.5366Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.51585 7.34206C8.19172 7.01792 7.66619 7.01792 7.34206 7.34206C7.01792 7.66619 7.01792 8.19172 7.34206 8.51585L9.46338 10.6372C9.78751 10.9613 10.313 10.9613 10.6372 10.6372C10.9613 10.313 10.9613 9.78751 10.6372 9.46338L8.51585 7.34206ZM20.5367 19.3629C20.2125 19.0387 19.687 19.0387 19.3629 19.3629C19.0387 19.687 19.0387 20.2125 19.3629 20.5367L21.4842 22.658C21.8083 22.9821 22.3339 22.9821 22.658 22.658C22.9821 22.3339 22.9821 21.8083 22.658 21.4842L20.5367 19.3629Z" fill="white"/>
<path d="M14.9498 14.9498L22.0711 22.0711" stroke="white" stroke-width="2" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_1001_6334">
<rect width="30" height="30" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "PowerIconEmoji.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1001_6305)">
<rect width="30" height="30" rx="7" fill="#00C7BE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 15C5 19.6672 8.1974 23.5877 12.5212 24.6904C12.1923 24.209 12 23.627 12 23V21.8869C10.2129 21.0612 9.29757 19.5789 8.85926 18.5679C8.68659 18.1697 9.1181 17.8198 9.52066 17.9822C10.6079 18.4208 12.5143 19 15 19C17.4857 19 19.3921 18.4208 20.4793 17.9822C20.8819 17.8198 21.3134 18.1697 21.1407 18.568C20.7024 19.5789 19.7871 21.0612 18 21.8869V23C18 23.627 17.8077 24.209 17.4788 24.6904C21.8026 23.5877 25 19.6672 25 15C25 9.47715 20.5228 5 15 5C9.47715 5 5 9.47715 5 15ZM19 15.75C20.2426 15.75 21.25 14.7426 21.25 13.5C21.25 12.2574 20.2426 11.25 19 11.25C17.7574 11.25 16.75 12.2574 16.75 13.5C16.75 14.7426 17.7574 15.75 19 15.75ZM19 16.75C20.7949 16.75 22.25 15.2949 22.25 13.5C22.25 11.7051 20.7949 10.25 19 10.25C17.2051 10.25 15.75 11.7051 15.75 13.5C15.75 15.2949 17.2051 16.75 19 16.75ZM20 13.5C20 14.0523 19.5523 14.5 19 14.5C18.4477 14.5 18 14.0523 18 13.5C18 12.9477 18.4477 12.5 19 12.5C19.5523 12.5 20 12.9477 20 13.5ZM13.9826 14.5529C13.5523 14.0359 12.7941 13.5 11.5 13.5C10.2059 13.5 9.44774 14.0359 9.01739 14.5529C8.74409 14.8812 9.10359 15.2328 9.51 15.1012C10.0636 14.9219 10.7818 14.75 11.5 14.75C12.2182 14.75 12.9364 14.9219 13.49 15.1012C13.8964 15.2328 14.2559 14.8812 13.9826 14.5529ZM14 20C13.4477 20 13 20.4477 13 21V23C13 24.1046 13.8954 25 15 25C16.1046 25 17 24.1046 17 23V21C17 20.4477 16.5523 20 16 20C15.7144 20 15.4734 20.2127 15.438 20.4961L15.137 22.9036C15.1169 23.0649 14.8831 23.0649 14.863 22.9036L14.562 20.4961C14.5266 20.2127 14.2856 20 14 20Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1001_6305">
<rect width="30" height="30" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "PowerIconGif.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1001_6263)">
<rect width="30" height="30" rx="7" fill="#FF9500"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.32698 7.63803C5 8.27976 5 9.11984 5 10.8V19.2C5 20.8802 5 21.7202 5.32698 22.362C5.6146 22.9265 6.07354 23.3854 6.63803 23.673C7.27976 24 8.11984 24 9.8 24H20.2C21.8802 24 22.7202 24 23.362 23.673C23.9265 23.3854 24.3854 22.9265 24.673 22.362C25 21.7202 25 20.8802 25 19.2V10.8C25 9.11984 25 8.27976 24.673 7.63803C24.3854 7.07354 23.9265 6.6146 23.362 6.32698C22.7202 6 21.8802 6 20.2 6H9.8C8.11984 6 7.27976 6 6.63803 6.32698C6.07354 6.6146 5.6146 7.07354 5.32698 7.63803ZM20.0287 11.6688L20.05 11.6688H21.75C22.2091 11.6688 22.5813 12.0409 22.5813 12.5C22.5813 12.9591 22.2091 13.3313 21.75 13.3313H20.0813V14.1688H21.75C22.2091 14.1688 22.5813 14.5409 22.5813 15C22.5813 15.4591 22.2091 15.8313 21.75 15.8313H20.0813V17.5C20.0813 17.9591 19.7091 18.3313 19.25 18.3313C18.7909 18.3313 18.4188 17.9591 18.4188 17.5V15V13.3L18.4188 13.2787C18.4187 13.1576 18.4187 13.022 18.4283 12.9039C18.4393 12.7691 18.467 12.5858 18.5639 12.3956C18.6915 12.1451 18.8951 11.9415 19.1456 11.8139C19.3358 11.7169 19.5191 11.6893 19.6539 11.6783C19.772 11.6687 19.9076 11.6687 20.0287 11.6688ZM16.8293 12.5C16.8293 12.0409 16.4571 11.6688 15.9981 11.6688C15.539 11.6688 15.1668 12.0409 15.1668 12.5V17.5C15.1668 17.9591 15.539 18.3313 15.9981 18.3313C16.4571 18.3313 16.8293 17.9591 16.8293 17.5V12.5ZM7.41876 15C7.41876 13.1602 8.91021 11.6688 10.75 11.6688C11.3028 11.6688 11.8264 11.804 12.2871 12.044C12.6943 12.2561 12.8525 12.7581 12.6404 13.1652C12.4284 13.5724 11.9264 13.7306 11.5192 13.5185C11.2899 13.3991 11.0291 13.3313 10.75 13.3313C9.82839 13.3313 9.08126 14.0784 9.08126 15C9.08126 15.9216 9.82839 16.6688 10.75 16.6688C11.3069 16.6688 11.8393 16.367 12.0753 15.8313H11.75C11.2909 15.8313 10.9188 15.4591 10.9188 15C10.9188 14.5409 11.2909 14.1688 11.75 14.1688H12.722C13.3865 14.1688 13.9079 14.7388 13.8488 15.4007L13.8183 15.7415L13.8147 15.7823L13.807 15.8227C13.4977 17.4503 12.0907 18.3313 10.75 18.3313C8.91021 18.3313 7.41876 16.8398 7.41876 15Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1001_6263">
<rect width="30" height="30" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "PowerIconMedia.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1001_6126)">
<rect width="30" height="30" rx="7" fill="#007AFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.32698 7.63803C6 8.27976 6 9.11984 6 10.8V16.1264L8.71931 13.1979L8.73937 13.1763L8.7394 13.1762L8.73942 13.1762C8.92579 12.9755 9.09907 12.7889 9.25684 12.6452C9.42696 12.4903 9.63591 12.3309 9.90879 12.2377C10.2921 12.1069 10.7079 12.1069 11.0912 12.2377C11.3641 12.3309 11.573 12.4903 11.7432 12.6452C11.9009 12.7889 12.0742 12.9755 12.2606 13.1763L12.2807 13.1979L16.3929 17.6264L17.7193 16.1979L17.7394 16.1763C17.9258 15.9755 18.0991 15.7889 18.2568 15.6452C18.427 15.4903 18.6359 15.3309 18.9088 15.2377C19.2921 15.1069 19.7079 15.1069 20.0912 15.2377C20.3641 15.3309 20.573 15.4903 20.7432 15.6452C20.9009 15.7889 21.0742 15.9755 21.2606 16.1763L21.2606 16.1763L21.2807 16.1979L24 19.1264V10.8C24 9.11984 24 8.27976 23.673 7.63803C23.3854 7.07354 22.9265 6.6146 22.362 6.32698C21.7202 6 20.8802 6 19.2 6H10.8C9.11984 6 8.27976 6 7.63803 6.32698C7.07354 6.6146 6.6146 7.07354 6.32698 7.63803ZM22.1086 23.7817L17.5255 18.8462L18.9357 17.3274C19.1491 17.0977 19.2745 16.9636 19.3744 16.8727C19.4192 16.8319 19.4453 16.8128 19.4564 16.8053C19.485 16.7977 19.515 16.7977 19.5436 16.8053C19.5547 16.8128 19.5808 16.8319 19.6256 16.8727C19.7255 16.9636 19.8509 17.0977 20.0643 17.3274L23.9254 21.4856C23.8779 21.8329 23.8002 22.1124 23.673 22.362C23.3854 22.9265 22.9265 23.3854 22.362 23.673C22.2811 23.7142 22.197 23.7503 22.1086 23.7817ZM20.044 23.998L11.0643 14.3274C10.8509 14.0977 10.7255 13.9636 10.6256 13.8727C10.5808 13.8319 10.5547 13.8128 10.5436 13.8053C10.515 13.7977 10.485 13.7977 10.4564 13.8053C10.4453 13.8128 10.4192 13.8319 10.3744 13.8727C10.2745 13.9636 10.1491 14.0977 9.93575 14.3274L6 18.5659V19.2C6 20.8802 6 21.7202 6.32698 22.362C6.6146 22.9265 7.07354 23.3854 7.63803 23.673C8.27976 24 9.11984 24 10.8 24H19.2C19.5083 24 19.7883 24 20.044 23.998ZM19.5 12C20.3284 12 21 11.3284 21 10.5C21 9.67157 20.3284 9 19.5 9C18.6716 9 18 9.67157 18 10.5C18 11.3284 18.6716 12 19.5 12Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1001_6126">
<rect width="30" height="30" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "PowerIconStickers.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1001_6284)">
<rect width="30" height="30" rx="7" fill="#34C759"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.43597 8.18404C6 9.03969 6 10.1598 6 12.4V18.4615C6 19.893 6 20.6088 6.18112 21.19C6.5722 22.445 7.55496 23.4278 8.80999 23.8189C9.39121 24 10.107 24 11.5385 24C13.1328 24 14.3326 24 15.2964 23.9506C15.3921 23.9348 15.4582 23.9152 15.5109 23.8934C15.838 23.7579 16.0979 23.498 16.2334 23.1709C16.2699 23.0827 16.3006 22.9538 16.3175 22.7034C16.3347 22.4478 16.335 22.1181 16.335 21.6347V21.6094C16.335 20.9795 16.335 20.4582 16.3563 20.0232C15.9279 20.1188 15.4749 20.165 15 20.165C13.5668 20.165 12.4323 19.5912 11.6714 19.0378C11.2896 18.7602 10.9945 18.4826 10.7933 18.2726C10.6924 18.1673 10.6143 18.0782 10.56 18.0134C10.5328 17.981 10.5114 17.9546 10.4961 17.9352L10.4775 17.9115L10.4716 17.9038L10.4695 17.901L10.4687 17.8999L10.4683 17.8994C10.4682 17.8992 10.468 17.899 11 17.5L11.532 17.101L11.5317 17.1006L11.5388 17.1097C11.5467 17.1196 11.56 17.1362 11.5787 17.1584C11.6161 17.203 11.6748 17.2702 11.7536 17.3524C11.9117 17.5174 12.1479 17.7398 12.4536 17.9622C13.0677 18.4088 13.9332 18.835 15 18.835C15.6301 18.835 16.171 18.7359 16.6335 18.5514C16.639 18.5385 16.6446 18.5256 16.6503 18.5128C17.0189 17.6826 17.6826 17.0189 18.5128 16.6503C18.904 16.4766 19.3255 16.4037 19.8116 16.369C20.2865 16.335 20.8739 16.335 21.6094 16.335H21.6347C22.1181 16.335 22.4478 16.3347 22.7034 16.3175C22.9538 16.3006 23.0827 16.2699 23.1709 16.2334C23.498 16.0979 23.7579 15.838 23.8934 15.5109C23.9152 15.4582 23.9348 15.3921 23.9506 15.2964C24 14.3326 24 13.1328 24 11.5385C24 10.107 24 9.39121 23.8189 8.80999C23.4278 7.55496 22.445 6.5722 21.19 6.18112C20.6088 6 19.893 6 18.4615 6H12.4C10.1598 6 9.03969 6 8.18404 6.43597C7.43139 6.81947 6.81947 7.43139 6.43597 8.18404ZM23.6521 17.4734C23.3812 17.5808 23.098 17.6239 22.7926 17.6445C22.487 17.665 22.1125 17.665 21.6574 17.665H21.6347C20.8682 17.665 20.3283 17.6654 19.9064 17.6956C19.4903 17.7253 19.2426 17.7815 19.0525 17.8659C18.5236 18.1007 18.1007 18.5236 17.8659 19.0525C17.7815 19.2426 17.7253 19.4903 17.6956 19.9064C17.6654 20.3283 17.665 20.8682 17.665 21.6347V21.6574C17.665 22.1125 17.665 22.487 17.6445 22.7926C17.6239 23.098 17.5808 23.3812 17.4734 23.6521C17.5423 23.6333 17.6103 23.6134 17.6775 23.5925C20.5013 22.7126 22.7126 20.5013 23.5925 17.6775C23.6134 17.6103 23.6333 17.5423 23.6521 17.4734ZM11.5316 17.1004C11.3111 16.8071 10.8946 16.7478 10.601 16.968C10.3072 17.1884 10.2476 17.6052 10.468 17.899L11 17.5C11.532 17.101 11.5318 17.1008 11.5317 17.1006L11.5316 17.1004ZM13.5 12.8125C13.5 13.6754 12.9404 14.375 12.25 14.375C11.5596 14.375 11 13.6754 11 12.8125C11 11.9496 11.5596 11.25 12.25 11.25C12.9404 11.25 13.5 11.9496 13.5 12.8125ZM19 12.8125C19 13.6754 18.4404 14.375 17.75 14.375C17.0596 14.375 16.5 13.6754 16.5 12.8125C16.5 11.9496 17.0596 11.25 17.75 11.25C18.4404 11.25 19 11.9496 19 12.8125Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1001_6284">
<rect width="30" height="30" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "PowerIconVideo.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1001_6246)">
<rect width="30" height="30" rx="7" fill="#FF2D55"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.43597 10.184C5 11.0397 5 12.1598 5 14.4V15.6C5 17.8402 5 18.9603 5.43597 19.816C5.81947 20.5686 6.43139 21.1805 7.18404 21.564C8.03969 22 9.15979 22 11.4 22H12.6C14.8402 22 15.9603 22 16.816 21.564C17.5686 21.1805 18.1805 20.5686 18.564 19.816C19 18.9603 19 17.8402 19 15.6V14.4C19 12.1598 19 11.0397 18.564 10.184C18.1805 9.43139 17.5686 8.81947 16.816 8.43597C15.9603 8 14.8402 8 12.6 8H11.4C9.15979 8 8.03969 8 7.18404 8.43597C6.43139 8.81947 5.81947 9.43139 5.43597 10.184ZM25.4951 11.0427C25.4432 10.4576 24.9855 10 24.4286 10C24.1967 10 23.9712 10.081 23.7857 10.2308L21.0714 13L20.977 13.0832C20.675 13.3737 20.5 13.7905 20.5 14.2307V15.7692L20.5052 15.9005C20.5397 16.335 20.7444 16.7358 21.0714 17L23.7857 19.7692L23.8712 19.8316C24.337 20.138 24.9516 20.0182 25.2857 19.5384C25.4248 19.3387 25.5 19.0958 25.5 18.8461V11.1538L25.4951 11.0427Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1001_6246">
<rect width="30" height="30" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,4 @@
<svg width="29" height="13" viewBox="0 0 29 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect opacity="0.35" x="1.33598" y="0.5" width="24" height="12" rx="4" stroke="black"/>
<path opacity="0.4" d="M26.836 4.66666V8.66666C27.6407 8.32788 28.164 7.53979 28.164 6.66666C28.164 5.79352 27.6407 5.00543 26.836 4.66666Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 347 B

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "Battery.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1009,6 +1009,21 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
Logger.shared.logToConsole = loggingSettings.logToConsole
Logger.shared.redactSensitiveData = loggingSettings.redactSensitiveData
Queue.mainQueue().async {
var previousValue: Bool?
let _ = (sharedApplicationContext.sharedContext.automaticMediaDownloadSettings
|> mapToSignal { settings -> Signal<Bool, NoError> in
return automaticEnergyUsageShouldBeOn(settings: settings)
}
|> distinctUntilChanged).start(next: { isPowerSavingEnabled in
let previousValueValue = previousValue
previousValue = isPowerSavingEnabled
if isPowerSavingEnabled != previousValueValue && previousValueValue != nil {
}
})
}
return .single(sharedApplicationContext)
})

View File

@ -1706,7 +1706,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
}
actions.insert(.custom(ChatReadReportContextItem(context: context, message: message, hasReadReports: hasReadReports, stats: readStats, action: { c, f, stats, customReactionEmojiPacks, firstCustomEmojiReaction in
if reactionCount == 0, let stats = stats, stats.peers.count == 1 {
if reactionCount == 0, let stats = stats, stats.peers.count == 1, !"".isEmpty {
c.dismiss(completion: {
controllerInteraction.openPeer(stats.peers[0], .default, nil, .default)
})

View File

@ -526,7 +526,7 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
}
self.avatarNode.setPeer(context: context, theme: theme, peer: EnginePeer(peer), authorOfMessage: authorOfMessage, overrideImage: overrideImage, emptyColor: emptyColor, synchronousLoad: synchronousLoad, displayDimensions: CGSize(width: 38.0, height: 38.0))
if peer.isPremium && context.sharedContext.energyUsageSettings.playVideoAvatars {
if peer.isPremium && context.sharedContext.energyUsageSettings.autoplayVideo {
self.cachedDataDisposable.set((context.account.postbox.peerView(id: peer.id)
|> deliverOnMainQueue).start(next: { [weak self] peerView in
guard let strongSelf = self else {

View File

@ -197,6 +197,7 @@ final class PeerInfoScreenData {
let requestsContext: PeerInvitationImportersContext?
let threadData: MessageHistoryThreadData?
let appConfiguration: AppConfiguration?
let isPowerSavingEnabled: Bool?
init(
peer: Peer?,
@ -216,7 +217,8 @@ final class PeerInfoScreenData {
requests: PeerInvitationImportersState?,
requestsContext: PeerInvitationImportersContext?,
threadData: MessageHistoryThreadData?,
appConfiguration: AppConfiguration?
appConfiguration: AppConfiguration?,
isPowerSavingEnabled: Bool?
) {
self.peer = peer
self.chatPeer = chatPeer
@ -236,6 +238,7 @@ final class PeerInfoScreenData {
self.requestsContext = requestsContext
self.threadData = threadData
self.appConfiguration = appConfiguration
self.isPowerSavingEnabled = isPowerSavingEnabled
}
}
@ -450,9 +453,14 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false),
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
),
hasPassword
hasPassword,
context.sharedContext.automaticMediaDownloadSettings
|> mapToSignal { settings -> Signal<Bool, NoError> in
return automaticEnergyUsageShouldBeOn(settings: settings)
}
|> distinctUntilChanged
)
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, hasWatchApp, accountPreferences, suggestions, limits, hasPassword -> PeerInfoScreenData in
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, hasWatchApp, accountPreferences, suggestions, limits, hasPassword, isPowerSavingEnabled -> PeerInfoScreenData in
let (notificationExceptions, notificationsAuthorizationStatus, notificationsWarningSuppressed) = notifications
let (featuredStickerPacks, archivedStickerPacks) = stickerPacks
@ -514,7 +522,8 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
requests: nil,
requestsContext: nil,
threadData: nil,
appConfiguration: appConfiguration
appConfiguration: appConfiguration,
isPowerSavingEnabled: isPowerSavingEnabled
)
}
}
@ -542,7 +551,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
requests: nil,
requestsContext: nil,
threadData: nil,
appConfiguration: nil
appConfiguration: nil,
isPowerSavingEnabled: nil
))
case let .user(userPeerId, secretChatId, kind):
let groupsInCommon: GroupsInCommonContext?
@ -674,7 +684,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
requests: nil,
requestsContext: nil,
threadData: nil,
appConfiguration: nil
appConfiguration: nil,
isPowerSavingEnabled: nil
)
}
case .channel:
@ -751,7 +762,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
requests: requests,
requestsContext: currentRequestsContext,
threadData: nil,
appConfiguration: nil
appConfiguration: nil,
isPowerSavingEnabled: nil
)
}
case let .group(groupId):
@ -951,7 +963,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
requests: requests,
requestsContext: currentRequestsContext,
threadData: threadData,
appConfiguration: appConfiguration
appConfiguration: appConfiguration,
isPowerSavingEnabled: nil
)
}
}

View File

@ -475,6 +475,7 @@ private enum PeerInfoSettingsSection {
case logout
case rememberPassword
case emojiStatus
case powerSaving
}
private enum PeerInfoReportType {
@ -818,6 +819,11 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
interaction.openSettings(.appearance)
}))
//TODO:localize
items[.advanced]!.append(PeerInfoScreenDisclosureItem(id: 6, label: .text(data.isPowerSavingEnabled == true ? "On" : "Off"), text: "Power Saving", icon: PresentationResourcesSettings.powerSaving, action: {
interaction.openSettings(.powerSaving)
}))
let languageName = presentationData.strings.primaryComponent.localizedName
items[.advanced]!.append(PeerInfoScreenDisclosureItem(id: 4, label: .text(languageName.isEmpty ? presentationData.strings.Localization_LanguageName : languageName), text: presentationData.strings.Settings_AppLanguage, icon: PresentationResourcesSettings.language, action: {
interaction.openSettings(.language)
@ -7718,6 +7724,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
push(controller)
case .emojiStatus:
self.headerNode.invokeDisplayPremiumIntro()
case .powerSaving:
self.controller?.push(energySavingSettingsScreen(context: self.context))
}
}

View File

@ -152,9 +152,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return self._automaticMediaDownloadSettings.get()
}
public var energyUsageSettings: EnergyUsageSettings {
return self.currentAutomaticMediaDownloadSettings.energyUsageSettings
}
public private(set) var energyUsageSettings: EnergyUsageSettings
public let currentAutodownloadSettings: Atomic<AutodownloadSettings>
private let _autodownloadSettings = Promise<AutodownloadSettings>()
@ -183,6 +181,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
private var invalidatedApsToken: Data?
private let energyUsageAutomaticDisposable = MetaDisposable()
init(mainWindow: Window1?, sharedContainerPath: String, basePath: String, encryptionParameters: ValueBoxEncryptionParameters, accountManager: AccountManager<TelegramAccountManagerTypes>, appLockContext: AppLockContext, applicationBindings: TelegramApplicationBindings, initialPresentationDataAndSettings: InitialPresentationDataAndSettings, networkArguments: NetworkInitializationArguments, hasInAppPurchases: Bool, rootPath: String, legacyBasePath: String?, apsNotificationToken: Signal<Data?, NoError>, voipNotificationToken: Signal<Data?, NoError>, firebaseSecretStream: Signal<[String: String], NoError>, setNotificationCall: @escaping (PresentationCall?) -> Void, navigateToChat: @escaping (AccountRecordId, PeerId, MessageId?) -> Void, displayUpgradeProgress: @escaping (Float?) -> Void = { _ in }, appDelegate: AppDelegate?) {
assert(Queue.mainQueue().isCurrent())
@ -239,6 +239,12 @@ public final class SharedAccountContextImpl: SharedAccountContext {
self.currentMediaInputSettings = Atomic(value: initialPresentationDataAndSettings.mediaInputSettings)
self.currentInAppNotificationSettings = Atomic(value: initialPresentationDataAndSettings.inAppNotificationSettings)
if automaticEnergyUsageShouldBeOnNow(settings: self.currentAutomaticMediaDownloadSettings) {
self.energyUsageSettings = self.currentAutomaticMediaDownloadSettings.energyUsageSettings
} else {
self.energyUsageSettings = EnergyUsageSettings.default
}
let presentationData: Signal<PresentationData, NoError> = .single(initialPresentationDataAndSettings.presentationData)
|> then(
updatedPresentationData(accountManager: self.accountManager, applicationInForeground: self.applicationBindings.applicationInForeground, systemUserInterfaceStyle: mainWindow?.systemUserInterfaceStyle ?? .single(.light))
@ -368,6 +374,22 @@ public final class SharedAccountContextImpl: SharedAccountContext {
self.automaticMediaDownloadSettingsDisposable.set(self._automaticMediaDownloadSettings.get().start(next: { [weak self] next in
if let strongSelf = self {
strongSelf.currentAutomaticMediaDownloadSettings = next
if automaticEnergyUsageShouldBeOnNow(settings: next) {
strongSelf.energyUsageSettings = next.energyUsageSettings
} else {
strongSelf.energyUsageSettings = EnergyUsageSettings.default
}
strongSelf.energyUsageAutomaticDisposable.set((automaticEnergyUsageShouldBeOn(settings: next)
|> deliverOnMainQueue).start(next: { value in
if let strongSelf = self {
if value {
strongSelf.energyUsageSettings = next.energyUsageSettings
} else {
strongSelf.energyUsageSettings = EnergyUsageSettings.default
}
}
}))
}
}))

View File

@ -260,88 +260,82 @@ public struct MediaAutoSaveSettings: Codable, Equatable {
public struct EnergyUsageSettings: Codable, Equatable {
private enum CodingKeys: CodingKey {
case activationThreshold
case autoplayVideo
case autoplayGif
case loopStickers
case loopEmoji
case playVideoAvatars
case fullTranslucency
case extendBackgroundWork
case synchronizeInBackground
case autodownloadInBackground
}
public static var `default`: EnergyUsageSettings {
return EnergyUsageSettings(
activationThreshold: 20,
autoplayVideo: true,
autoplayGif: true,
loopStickers: true,
loopEmoji: true,
playVideoAvatars: true,
fullTranslucency: true,
extendBackgroundWork: true,
synchronizeInBackground: true,
autodownloadInBackground: true
)
}
public var activationThreshold: Int32
public var autoplayVideo: Bool
public var autoplayGif: Bool
public var loopStickers: Bool
public var loopEmoji: Bool
public var playVideoAvatars: Bool
public var fullTranslucency: Bool
public var extendBackgroundWork: Bool
public var synchronizeInBackground: Bool
public var autodownloadInBackground: Bool
public init(
activationThreshold: Int32,
autoplayVideo: Bool,
autoplayGif: Bool,
loopStickers: Bool,
loopEmoji: Bool,
playVideoAvatars: Bool,
fullTranslucency: Bool,
extendBackgroundWork: Bool,
synchronizeInBackground: Bool,
autodownloadInBackground: Bool
) {
self.activationThreshold = activationThreshold
self.autoplayVideo = autoplayVideo
self.autoplayGif = autoplayGif
self.loopStickers = loopStickers
self.loopEmoji = loopEmoji
self.playVideoAvatars = playVideoAvatars
self.fullTranslucency = fullTranslucency
self.extendBackgroundWork = extendBackgroundWork
self.synchronizeInBackground = synchronizeInBackground
self.autodownloadInBackground = autodownloadInBackground
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.activationThreshold = try container.decodeIfPresent(Int32.self, forKey: .activationThreshold) ?? EnergyUsageSettings.default.activationThreshold
self.autoplayVideo = try container.decodeIfPresent(Bool.self, forKey: .autoplayVideo) ?? EnergyUsageSettings.default.autoplayVideo
self.autoplayGif = try container.decodeIfPresent(Bool.self, forKey: .autoplayGif) ?? EnergyUsageSettings.default.autoplayGif
self.loopStickers = try container.decodeIfPresent(Bool.self, forKey: .loopStickers) ?? EnergyUsageSettings.default.loopStickers
self.loopEmoji = try container.decodeIfPresent(Bool.self, forKey: .loopEmoji) ?? EnergyUsageSettings.default.loopEmoji
self.playVideoAvatars = try container.decodeIfPresent(Bool.self, forKey: .playVideoAvatars) ?? EnergyUsageSettings.default.playVideoAvatars
self.fullTranslucency = try container.decodeIfPresent(Bool.self, forKey: .fullTranslucency) ?? EnergyUsageSettings.default.fullTranslucency
self.extendBackgroundWork = try container.decodeIfPresent(Bool.self, forKey: .extendBackgroundWork) ?? EnergyUsageSettings.default.extendBackgroundWork
self.synchronizeInBackground = try container.decodeIfPresent(Bool.self, forKey: .synchronizeInBackground) ?? EnergyUsageSettings.default.synchronizeInBackground
self.autodownloadInBackground = try container.decodeIfPresent(Bool.self, forKey: .autodownloadInBackground) ?? EnergyUsageSettings.default.autodownloadInBackground
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.activationThreshold, forKey: .activationThreshold)
try container.encode(self.autoplayVideo, forKey: .autoplayVideo)
try container.encode(self.autoplayGif, forKey: .autoplayGif)
try container.encode(self.loopEmoji, forKey: .loopEmoji)
try container.encode(self.loopStickers, forKey: .loopStickers)
try container.encode(self.playVideoAvatars, forKey: .playVideoAvatars)
try container.encode(self.fullTranslucency, forKey: .fullTranslucency)
try container.encode(self.extendBackgroundWork, forKey: .extendBackgroundWork)
try container.encode(self.synchronizeInBackground, forKey: .synchronizeInBackground)
try container.encode(self.autodownloadInBackground, forKey: .autodownloadInBackground)
}
}