mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-05 05:51:42 +00:00
API updates, token login support, initial data usage screen implementation
This commit is contained in:
parent
798b75dabf
commit
58f6657c6e
@ -167,10 +167,20 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
controller.loginWithNumber = { [weak self, weak controller] number, syncContacts in
|
||||
if let strongSelf = self {
|
||||
controller?.inProgress = true
|
||||
strongSelf.actionDisposable.set((sendAuthorizationCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, phoneNumber: number, apiId: strongSelf.apiId, apiHash: strongSelf.apiHash, syncContacts: syncContacts) |> deliverOnMainQueue).start(next: { [weak self] account in
|
||||
strongSelf.actionDisposable.set((sendAuthorizationCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, phoneNumber: number, apiId: strongSelf.apiId, apiHash: strongSelf.apiHash, syncContacts: syncContacts, forcedPasswordSetupNotice: { value in
|
||||
guard let entry = CodableEntry(ApplicationSpecificCounterNotice(value: value)) else {
|
||||
return nil
|
||||
}
|
||||
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||
}) |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
if let strongSelf = self {
|
||||
controller?.inProgress = false
|
||||
strongSelf.account = account
|
||||
switch result {
|
||||
case let .sentCode(account):
|
||||
controller?.inProgress = false
|
||||
strongSelf.account = account
|
||||
case .loggedIn:
|
||||
break
|
||||
}
|
||||
}
|
||||
}, error: { error in
|
||||
if let strongSelf = self, let controller = controller {
|
||||
|
||||
@ -59,6 +59,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
case sendOneLog(PresentationTheme)
|
||||
case sendShareLogs
|
||||
case sendGroupCallLogs
|
||||
case sendStorageStats
|
||||
case sendNotificationLogs(PresentationTheme)
|
||||
case sendCriticalLogs(PresentationTheme)
|
||||
case sendAllLogs
|
||||
@ -106,7 +107,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
switch self {
|
||||
case .testStickerImport:
|
||||
return DebugControllerSection.sticker.rawValue
|
||||
case .sendLogs, .sendOneLog, .sendShareLogs, .sendGroupCallLogs, .sendNotificationLogs, .sendCriticalLogs, .sendAllLogs:
|
||||
case .sendLogs, .sendOneLog, .sendShareLogs, .sendGroupCallLogs, .sendStorageStats, .sendNotificationLogs, .sendCriticalLogs, .sendAllLogs:
|
||||
return DebugControllerSection.logs.rawValue
|
||||
case .accounts:
|
||||
return DebugControllerSection.logs.rawValue
|
||||
@ -143,76 +144,78 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return 6
|
||||
case .sendAllLogs:
|
||||
return 7
|
||||
case .accounts:
|
||||
case .sendStorageStats:
|
||||
return 8
|
||||
case .logToFile:
|
||||
case .accounts:
|
||||
return 9
|
||||
case .logToConsole:
|
||||
case .logToFile:
|
||||
return 10
|
||||
case .redactSensitiveData:
|
||||
case .logToConsole:
|
||||
return 11
|
||||
case .enableRaiseToSpeak:
|
||||
case .redactSensitiveData:
|
||||
return 12
|
||||
case .keepChatNavigationStack:
|
||||
case .enableRaiseToSpeak:
|
||||
return 13
|
||||
case .skipReadHistory:
|
||||
case .keepChatNavigationStack:
|
||||
return 14
|
||||
case .crashOnSlowQueries:
|
||||
case .skipReadHistory:
|
||||
return 15
|
||||
case .clearTips:
|
||||
case .crashOnSlowQueries:
|
||||
return 16
|
||||
case .crash:
|
||||
case .clearTips:
|
||||
return 17
|
||||
case .resetData:
|
||||
case .crash:
|
||||
return 18
|
||||
case .resetDatabase:
|
||||
case .resetData:
|
||||
return 19
|
||||
case .resetDatabaseAndCache:
|
||||
case .resetDatabase:
|
||||
return 20
|
||||
case .resetHoles:
|
||||
case .resetDatabaseAndCache:
|
||||
return 21
|
||||
case .reindexUnread:
|
||||
case .resetHoles:
|
||||
return 22
|
||||
case .resetCacheIndex:
|
||||
case .reindexUnread:
|
||||
return 23
|
||||
case .reindexCache:
|
||||
case .resetCacheIndex:
|
||||
return 24
|
||||
case .resetBiometricsData:
|
||||
case .reindexCache:
|
||||
return 25
|
||||
case .resetWebViewCache:
|
||||
case .resetBiometricsData:
|
||||
return 26
|
||||
case .optimizeDatabase:
|
||||
case .resetWebViewCache:
|
||||
return 27
|
||||
case .photoPreview:
|
||||
case .optimizeDatabase:
|
||||
return 28
|
||||
case .knockoutWallpaper:
|
||||
case .photoPreview:
|
||||
return 29
|
||||
case .experimentalCompatibility:
|
||||
case .knockoutWallpaper:
|
||||
return 30
|
||||
case .enableDebugDataDisplay:
|
||||
case .experimentalCompatibility:
|
||||
return 31
|
||||
case .acceleratedStickers:
|
||||
case .enableDebugDataDisplay:
|
||||
return 32
|
||||
case .experimentalBackground:
|
||||
case .acceleratedStickers:
|
||||
return 33
|
||||
case .inlineForums:
|
||||
case .experimentalBackground:
|
||||
return 34
|
||||
case .localTranscription:
|
||||
case .inlineForums:
|
||||
return 35
|
||||
case .enableReactionOverrides:
|
||||
case .localTranscription:
|
||||
return 36
|
||||
case .restorePurchases:
|
||||
case .enableReactionOverrides:
|
||||
return 37
|
||||
case .playerEmbedding:
|
||||
case .restorePurchases:
|
||||
return 38
|
||||
case .playlistPlayback:
|
||||
case .playerEmbedding:
|
||||
return 39
|
||||
case .enableQuickReactionSwitch:
|
||||
case .playlistPlayback:
|
||||
return 40
|
||||
case .voiceConference:
|
||||
case .enableQuickReactionSwitch:
|
||||
return 41
|
||||
case .voiceConference:
|
||||
return 42
|
||||
case let .preferredVideoCodec(index, _, _, _):
|
||||
return 42 + index
|
||||
return 43 + index
|
||||
case .disableVideoAspectScaling:
|
||||
return 100
|
||||
case .enableVoipTcp:
|
||||
@ -806,6 +809,61 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
}))
|
||||
}
|
||||
|
||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])])
|
||||
arguments.presentController(actionSheet, nil)
|
||||
})
|
||||
})
|
||||
case .sendStorageStats:
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: "Send Storage Stats", label: "", sectionId: self.section, style: .blocks, action: {
|
||||
guard let context = arguments.context, context.sharedContext.applicationBindings.isMainApp else {
|
||||
return
|
||||
}
|
||||
|
||||
let allStats: Signal<Data, NoError> = Signal { subscriber in
|
||||
DispatchQueue.global().async {
|
||||
let log = collectRawStorageUsageReport(containerPath: context.sharedContext.applicationBindings.containerPath)
|
||||
subscriber.putNext(log.data(using: .utf8) ?? Data())
|
||||
}
|
||||
|
||||
return EmptyDisposable
|
||||
}
|
||||
|
||||
let _ = (allStats
|
||||
|> deliverOnMainQueue).start(next: { allStatsData in
|
||||
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
|
||||
let actionSheet = ActionSheetController(presentationData: presentationData)
|
||||
|
||||
var items: [ActionSheetButtonItem] = []
|
||||
|
||||
if let context = arguments.context, context.sharedContext.applicationBindings.isMainApp {
|
||||
items.append(ActionSheetButtonItem(title: "Via Telegram", color: .accent, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
|
||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyWriteable, .excludeDisabled]))
|
||||
controller.peerSelected = { [weak controller] peer, _ in
|
||||
let peerId = peer.id
|
||||
|
||||
if let strongController = controller {
|
||||
strongController.dismiss()
|
||||
|
||||
let id = Int64.random(in: Int64.min ... Int64.max)
|
||||
let fileResource = LocalFileMediaResource(fileId: id, size: Int64(allStatsData.count), isSecretRelated: false)
|
||||
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: allStatsData)
|
||||
|
||||
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/zip", size: Int64(allStatsData.count), attributes: [.FileName(fileName: "StorageReport.txt")])
|
||||
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
|
||||
|
||||
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
|
||||
}
|
||||
}
|
||||
arguments.pushController(controller)
|
||||
}))
|
||||
}
|
||||
|
||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
@ -1251,6 +1309,7 @@ private func debugControllerEntries(sharedContext: SharedAccountContext, present
|
||||
entries.append(.sendNotificationLogs(presentationData.theme))
|
||||
entries.append(.sendCriticalLogs(presentationData.theme))
|
||||
entries.append(.sendAllLogs)
|
||||
entries.append(.sendStorageStats)
|
||||
if isMainApp {
|
||||
entries.append(.accounts(presentationData.theme))
|
||||
}
|
||||
|
||||
@ -4395,7 +4395,15 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
if let index = strongSelf.itemIndexAtPoint(strongSelf.touchesPosition) {
|
||||
var canBeSelectedOrLongTapped = false
|
||||
for itemNode in strongSelf.itemNodes {
|
||||
if itemNode.index == index && (strongSelf.items[index].selectable && itemNode.canBeSelected) || itemNode.canBeLongTapped {
|
||||
var canBeSelected = itemNode.canBeSelected
|
||||
if canBeSelected {
|
||||
if !itemNode.isLayerBacked {
|
||||
if !itemNode.visibleForSelection(at: strongSelf.view.convert(strongSelf.touchesPosition, to: itemNode.view)) {
|
||||
canBeSelected = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if itemNode.index == index && (strongSelf.items[index].selectable && canBeSelected) || itemNode.canBeLongTapped {
|
||||
canBeSelectedOrLongTapped = true
|
||||
}
|
||||
}
|
||||
@ -4403,7 +4411,20 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
if canBeSelectedOrLongTapped {
|
||||
strongSelf.highlightedItemIndex = index
|
||||
for itemNode in strongSelf.itemNodes {
|
||||
if itemNode.index == index && itemNode.canBeSelected {
|
||||
let itemNodeFrame = itemNode.frame
|
||||
let itemNodeBounds = itemNode.bounds
|
||||
let itemPoint = strongSelf.touchesPosition.offsetBy(dx: -itemNodeFrame.minX + itemNodeBounds.minX, dy: -itemNodeFrame.minY + itemNodeBounds.minY)
|
||||
|
||||
var canBeSelected = itemNode.canBeSelected
|
||||
if canBeSelected {
|
||||
if !itemNode.isLayerBacked {
|
||||
if !itemNode.visibleForSelection(at: itemPoint) {
|
||||
canBeSelected = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if itemNode.index == index && canBeSelected {
|
||||
if true {
|
||||
if !itemNode.isLayerBacked {
|
||||
strongSelf.reorderItemNodeToFront(itemNode)
|
||||
@ -4411,10 +4432,8 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
strongSelf.reorderHeaderNodeToFront(headerNode)
|
||||
}
|
||||
}
|
||||
let itemNodeFrame = itemNode.frame
|
||||
let itemNodeBounds = itemNode.bounds
|
||||
if strongSelf.items[index].selectable {
|
||||
itemNode.setHighlighted(true, at: strongSelf.touchesPosition.offsetBy(dx: -itemNodeFrame.minX + itemNodeBounds.minX, dy: -itemNodeFrame.minY + itemNodeBounds.minY), animated: false)
|
||||
itemNode.setHighlighted(true, at: itemPoint, animated: false)
|
||||
}
|
||||
|
||||
if itemNode.canBeLongTapped {
|
||||
|
||||
@ -148,6 +148,10 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode {
|
||||
return true
|
||||
}
|
||||
|
||||
open func visibleForSelection(at point: CGPoint) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
open var canBeLongTapped: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -0,0 +1,702 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import SwitchNode
|
||||
import AppBundle
|
||||
import CheckNode
|
||||
|
||||
public enum ItemListExpandableSwitchItemNodeType {
|
||||
case regular
|
||||
case icon
|
||||
}
|
||||
|
||||
public class ItemListExpandableSwitchItem: ListViewItem, ItemListItem {
|
||||
public struct SubItem: Equatable {
|
||||
public var id: AnyHashable
|
||||
public var title: String
|
||||
public var isSelected: Bool
|
||||
|
||||
public init(
|
||||
id: AnyHashable,
|
||||
title: String,
|
||||
isSelected: Bool
|
||||
) {
|
||||
self.id = id
|
||||
self.title = title
|
||||
self.isSelected = isSelected
|
||||
}
|
||||
}
|
||||
|
||||
let presentationData: ItemListPresentationData
|
||||
let icon: UIImage?
|
||||
let title: String
|
||||
let value: Bool
|
||||
let isExpanded: Bool
|
||||
let subItems: [SubItem]
|
||||
let type: ItemListExpandableSwitchItemNodeType
|
||||
let enableInteractiveChanges: Bool
|
||||
let enabled: Bool
|
||||
let displayLocked: Bool
|
||||
let disableLeadingInset: Bool
|
||||
let maximumNumberOfLines: Int
|
||||
let noCorners: Bool
|
||||
public let sectionId: ItemListSectionId
|
||||
let style: ItemListStyle
|
||||
let updated: (Bool) -> Void
|
||||
let activatedWhileDisabled: () -> Void
|
||||
let selectAction: () -> Void
|
||||
let subAction: (SubItem) -> Void
|
||||
public let tag: ItemListItemTag?
|
||||
|
||||
public let selectable: Bool = true
|
||||
|
||||
public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, title: String, value: Bool, isExpanded: Bool, subItems: [SubItem], type: ItemListExpandableSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, displayLocked: Bool = false, disableLeadingInset: Bool = false, maximumNumberOfLines: Int = 1, noCorners: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, activatedWhileDisabled: @escaping () -> Void = {}, selectAction: @escaping () -> Void, subAction: @escaping (SubItem) -> Void, tag: ItemListItemTag? = nil) {
|
||||
self.presentationData = presentationData
|
||||
self.icon = icon
|
||||
self.title = title
|
||||
self.value = value
|
||||
self.isExpanded = isExpanded
|
||||
self.subItems = subItems
|
||||
self.type = type
|
||||
self.enableInteractiveChanges = enableInteractiveChanges
|
||||
self.enabled = enabled
|
||||
self.displayLocked = displayLocked
|
||||
self.disableLeadingInset = disableLeadingInset
|
||||
self.maximumNumberOfLines = maximumNumberOfLines
|
||||
self.noCorners = noCorners
|
||||
self.sectionId = sectionId
|
||||
self.style = style
|
||||
self.updated = updated
|
||||
self.activatedWhileDisabled = activatedWhileDisabled
|
||||
self.selectAction = selectAction
|
||||
self.subAction = subAction
|
||||
self.tag = tag
|
||||
}
|
||||
|
||||
public 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 = ItemListExpandableSwitchItemNode(type: self.type)
|
||||
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(ListViewItemUpdateAnimation.None) })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func selected(listView: ListView) {
|
||||
listView.clearHighlightAnimated(true)
|
||||
|
||||
self.selectAction()
|
||||
}
|
||||
|
||||
public 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? ItemListExpandableSwitchItemNode {
|
||||
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(animation)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class SubItemNode: HighlightTrackingButtonNode {
|
||||
private let textNode: ImmediateTextNode
|
||||
private var checkNode: CheckNode?
|
||||
private let separatorNode: ASDisplayNode
|
||||
|
||||
private var theme: PresentationTheme?
|
||||
private var item: ItemListExpandableSwitchItem.SubItem?
|
||||
private var action: ((ItemListExpandableSwitchItem.SubItem) -> Void)?
|
||||
|
||||
init() {
|
||||
self.textNode = ImmediateTextNode()
|
||||
|
||||
self.separatorNode = ASDisplayNode()
|
||||
self.separatorNode.isLayerBacked = true
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.separatorNode)
|
||||
self.addSubnode(self.textNode)
|
||||
|
||||
self.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside)
|
||||
}
|
||||
|
||||
@objc private func pressed() {
|
||||
guard let item = self.item, let action = self.action else {
|
||||
return
|
||||
}
|
||||
action(item)
|
||||
}
|
||||
|
||||
func update(presentationData: ItemListPresentationData, item: ItemListExpandableSwitchItem.SubItem, action: @escaping (ItemListExpandableSwitchItem.SubItem) -> Void, size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
let themeUpdated = self.theme !== presentationData.theme
|
||||
|
||||
self.item = item
|
||||
self.action = action
|
||||
|
||||
let leftInset: CGFloat = 60.0
|
||||
|
||||
if themeUpdated {
|
||||
self.separatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor
|
||||
}
|
||||
|
||||
let checkNode: CheckNode
|
||||
if let current = self.checkNode {
|
||||
checkNode = current
|
||||
if themeUpdated {
|
||||
checkNode.theme = CheckNodeTheme(theme: presentationData.theme, style: .plain)
|
||||
}
|
||||
} else {
|
||||
checkNode = CheckNode(theme: CheckNodeTheme(theme: presentationData.theme, style: .plain))
|
||||
self.checkNode = checkNode
|
||||
self.addSubnode(checkNode)
|
||||
}
|
||||
|
||||
let checkSize = CGSize(width: 22.0, height: 22.0)
|
||||
checkNode.frame = CGRect(origin: CGPoint(x: floor((leftInset - checkSize.width) / 2.0), y: floor((size.height - checkSize.height) / 2.0)), size: checkSize)
|
||||
|
||||
checkNode.setSelected(item.isSelected, animated: transition.isAnimated)
|
||||
|
||||
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: leftInset, y: size.height - UIScreenPixel), size: CGSize(width: size.width - leftInset, height: UIScreenPixel)))
|
||||
|
||||
self.textNode.attributedText = NSAttributedString(string: item.title, font: Font.regular(17.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
|
||||
let titleSize = self.textNode.updateLayout(CGSize(width: size.width - leftInset, height: 100.0))
|
||||
self.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: floor((size.height - titleSize.height) / 2.0)), size: titleSize)
|
||||
}
|
||||
}
|
||||
|
||||
public class ItemListExpandableSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
private let backgroundNode: ASDisplayNode
|
||||
private let topStripeNode: ASDisplayNode
|
||||
private let bottomTopStripeNode: ASDisplayNode
|
||||
private let bottomStripeNode: ASDisplayNode
|
||||
private let highlightedBackgroundNode: ASDisplayNode
|
||||
private let maskNode: ASImageNode
|
||||
|
||||
private let iconNode: ASImageNode
|
||||
private let titleNode: TextNode
|
||||
private let titleValueNode: TextNode
|
||||
private let expandArrowNode: ASImageNode
|
||||
private var switchNode: ASDisplayNode & ItemListSwitchNodeImpl
|
||||
private let switchGestureNode: ASDisplayNode
|
||||
private var disabledOverlayNode: ASDisplayNode?
|
||||
|
||||
private var lockedIconNode: ASImageNode?
|
||||
|
||||
private let subItemContainer: ASDisplayNode
|
||||
private var subItemNodes: [AnyHashable: SubItemNode] = [:]
|
||||
|
||||
private let activateArea: AccessibilityAreaNode
|
||||
|
||||
private var item: ItemListExpandableSwitchItem?
|
||||
|
||||
public var tag: ItemListItemTag? {
|
||||
return self.item?.tag
|
||||
}
|
||||
|
||||
public init(type: ItemListExpandableSwitchItemNodeType) {
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
self.backgroundNode.isLayerBacked = true
|
||||
self.backgroundNode.backgroundColor = .white
|
||||
|
||||
self.maskNode = ASImageNode()
|
||||
self.maskNode.isUserInteractionEnabled = false
|
||||
|
||||
self.topStripeNode = ASDisplayNode()
|
||||
self.topStripeNode.isLayerBacked = true
|
||||
|
||||
self.bottomTopStripeNode = ASDisplayNode()
|
||||
self.bottomTopStripeNode.isLayerBacked = true
|
||||
|
||||
self.bottomStripeNode = ASDisplayNode()
|
||||
self.bottomStripeNode.isLayerBacked = true
|
||||
|
||||
self.iconNode = ASImageNode()
|
||||
self.iconNode.isLayerBacked = true
|
||||
self.iconNode.displaysAsynchronously = false
|
||||
|
||||
self.titleNode = TextNode()
|
||||
self.titleNode.isUserInteractionEnabled = false
|
||||
switch type {
|
||||
case .regular:
|
||||
self.switchNode = SwitchNode()
|
||||
case .icon:
|
||||
self.switchNode = IconSwitchNode()
|
||||
}
|
||||
|
||||
self.titleValueNode = TextNode()
|
||||
self.titleValueNode.isUserInteractionEnabled = false
|
||||
|
||||
self.expandArrowNode = ASImageNode()
|
||||
self.expandArrowNode.displaysAsynchronously = false
|
||||
|
||||
self.highlightedBackgroundNode = ASDisplayNode()
|
||||
self.highlightedBackgroundNode.isLayerBacked = true
|
||||
|
||||
self.switchGestureNode = ASDisplayNode()
|
||||
|
||||
self.activateArea = AccessibilityAreaNode()
|
||||
|
||||
self.subItemContainer = ASDisplayNode()
|
||||
self.subItemContainer.clipsToBounds = true
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.titleValueNode)
|
||||
self.addSubnode(self.expandArrowNode)
|
||||
self.addSubnode(self.switchNode)
|
||||
self.addSubnode(self.switchGestureNode)
|
||||
self.addSubnode(self.activateArea)
|
||||
self.addSubnode(self.subItemContainer)
|
||||
|
||||
self.activateArea.activate = { [weak self] in
|
||||
guard let strongSelf = self, let item = strongSelf.item, item.enabled else {
|
||||
return false
|
||||
}
|
||||
let value = !strongSelf.switchNode.isOn
|
||||
if item.enableInteractiveChanges {
|
||||
strongSelf.switchNode.setOn(value, animated: true)
|
||||
}
|
||||
item.updated(value)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
override public func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
(self.switchNode.view as? UISwitch)?.addTarget(self, action: #selector(self.switchValueChanged(_:)), for: .valueChanged)
|
||||
self.switchGestureNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: ItemListExpandableSwitchItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation) -> Void) {
|
||||
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
||||
let makeTitleValueLayout = TextNode.asyncLayout(self.titleValueNode)
|
||||
|
||||
let currentItem = self.item
|
||||
var currentDisabledOverlayNode = self.disabledOverlayNode
|
||||
|
||||
return { item, params, neighbors in
|
||||
var contentSize: CGSize
|
||||
var insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
let itemBackgroundColor: UIColor
|
||||
let itemSeparatorColor: UIColor
|
||||
|
||||
let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize)
|
||||
|
||||
var updatedTheme: PresentationTheme?
|
||||
if currentItem?.presentationData.theme !== item.presentationData.theme {
|
||||
updatedTheme = item.presentationData.theme
|
||||
}
|
||||
|
||||
var updateIcon = false
|
||||
if currentItem?.icon != item.icon {
|
||||
updateIcon = true
|
||||
}
|
||||
|
||||
switch item.style {
|
||||
case .plain:
|
||||
itemBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemPlainSeparatorColor
|
||||
contentSize = CGSize(width: params.width, height: 44.0)
|
||||
insets = itemListNeighborsPlainInsets(neighbors)
|
||||
case .blocks:
|
||||
itemBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
contentSize = CGSize(width: params.width, height: 44.0)
|
||||
insets = itemListNeighborsGroupedInsets(neighbors, params)
|
||||
}
|
||||
|
||||
var leftInset = 16.0 + params.leftInset
|
||||
if let _ = item.icon {
|
||||
leftInset += 43.0
|
||||
}
|
||||
|
||||
if item.disableLeadingInset {
|
||||
insets.top = 0.0
|
||||
insets.bottom = 0.0
|
||||
}
|
||||
|
||||
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 - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let titleValue = "\(item.subItems.filter(\.isSelected).count)/\(item.subItems.count)"
|
||||
let (titleValueLayout, titleValueApply) = makeTitleValueLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: titleValue, font: Font.bold(14.0), textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - params.rightInset - 64.0 - titleLayout.size.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
contentSize.height = max(contentSize.height, titleLayout.size.height + 22.0)
|
||||
|
||||
let mainContentHeight = contentSize.height
|
||||
var effectiveSubItemsHeight: CGFloat = 0.0
|
||||
if item.isExpanded {
|
||||
effectiveSubItemsHeight = CGFloat(item.subItems.count) * 44.0
|
||||
}
|
||||
contentSize.height += effectiveSubItemsHeight
|
||||
|
||||
if !item.enabled {
|
||||
if currentDisabledOverlayNode == nil {
|
||||
currentDisabledOverlayNode = ASDisplayNode()
|
||||
}
|
||||
} else {
|
||||
currentDisabledOverlayNode = nil
|
||||
}
|
||||
|
||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||
let layoutSize = layout.size
|
||||
|
||||
return (ListViewItemNodeLayout(contentSize: contentSize, insets: insets), { [weak self] animation in
|
||||
if let strongSelf = self {
|
||||
strongSelf.item = item
|
||||
|
||||
strongSelf.activateArea.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 0.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: mainContentHeight))
|
||||
|
||||
strongSelf.activateArea.accessibilityLabel = item.title
|
||||
strongSelf.activateArea.accessibilityValue = item.value ? item.presentationData.strings.VoiceOver_Common_On : item.presentationData.strings.VoiceOver_Common_Off
|
||||
strongSelf.activateArea.accessibilityHint = item.presentationData.strings.VoiceOver_Common_SwitchHint
|
||||
var accessibilityTraits = UIAccessibilityTraits()
|
||||
if item.enabled {
|
||||
} else {
|
||||
accessibilityTraits.insert(.notEnabled)
|
||||
}
|
||||
strongSelf.activateArea.accessibilityTraits = accessibilityTraits
|
||||
|
||||
if let icon = item.icon {
|
||||
if strongSelf.iconNode.supernode == nil {
|
||||
strongSelf.addSubnode(strongSelf.iconNode)
|
||||
}
|
||||
if updateIcon {
|
||||
strongSelf.iconNode.image = icon
|
||||
}
|
||||
let iconY = floor((mainContentHeight - icon.size.height) / 2.0)
|
||||
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 {
|
||||
strongSelf.iconNode.image = nil
|
||||
strongSelf.iconNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
let transition: ContainedViewLayoutTransition = animation.transition
|
||||
|
||||
if let currentDisabledOverlayNode = currentDisabledOverlayNode {
|
||||
if currentDisabledOverlayNode != strongSelf.disabledOverlayNode {
|
||||
strongSelf.disabledOverlayNode = currentDisabledOverlayNode
|
||||
strongSelf.insertSubnode(currentDisabledOverlayNode, belowSubnode: strongSelf.switchGestureNode)
|
||||
currentDisabledOverlayNode.alpha = 0.0
|
||||
transition.updateAlpha(node: currentDisabledOverlayNode, alpha: 1.0)
|
||||
currentDisabledOverlayNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: layout.contentSize.width, height: mainContentHeight - separatorHeight))
|
||||
} else {
|
||||
transition.updateFrame(node: currentDisabledOverlayNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: layout.contentSize.width, height: mainContentHeight - separatorHeight)))
|
||||
}
|
||||
currentDisabledOverlayNode.backgroundColor = itemBackgroundColor.withAlphaComponent(0.6)
|
||||
} else if let disabledOverlayNode = strongSelf.disabledOverlayNode {
|
||||
transition.updateAlpha(node: disabledOverlayNode, alpha: 0.0, completion: { [weak disabledOverlayNode] _ in
|
||||
disabledOverlayNode?.removeFromSupernode()
|
||||
})
|
||||
strongSelf.disabledOverlayNode = nil
|
||||
}
|
||||
|
||||
if let _ = updatedTheme {
|
||||
strongSelf.topStripeNode.backgroundColor = itemSeparatorColor
|
||||
strongSelf.bottomTopStripeNode.backgroundColor = itemSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = itemSeparatorColor
|
||||
strongSelf.backgroundNode.backgroundColor = itemBackgroundColor
|
||||
|
||||
strongSelf.switchNode.frameColor = item.presentationData.theme.list.itemSwitchColors.frameColor
|
||||
strongSelf.switchNode.contentColor = item.presentationData.theme.list.itemSwitchColors.contentColor
|
||||
strongSelf.switchNode.handleColor = item.presentationData.theme.list.itemSwitchColors.handleColor
|
||||
strongSelf.switchNode.positiveContentColor = item.presentationData.theme.list.itemSwitchColors.positiveColor
|
||||
strongSelf.switchNode.negativeContentColor = item.presentationData.theme.list.itemSwitchColors.negativeColor
|
||||
|
||||
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor
|
||||
}
|
||||
|
||||
let _ = titleApply()
|
||||
|
||||
switch item.style {
|
||||
case .plain:
|
||||
if strongSelf.backgroundNode.supernode != nil {
|
||||
strongSelf.backgroundNode.removeFromSupernode()
|
||||
}
|
||||
if strongSelf.topStripeNode.supernode != nil {
|
||||
strongSelf.topStripeNode.removeFromSupernode()
|
||||
}
|
||||
if strongSelf.bottomStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 0)
|
||||
}
|
||||
if strongSelf.bottomTopStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.bottomTopStripeNode, at: 1)
|
||||
}
|
||||
if strongSelf.maskNode.supernode != nil {
|
||||
strongSelf.maskNode.removeFromSupernode()
|
||||
}
|
||||
strongSelf.bottomTopStripeNode.frame = CGRect(origin: CGPoint(x: leftInset, y: mainContentHeight - separatorHeight), size: CGSize(width: params.width - leftInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: leftInset, y: layout.contentSize.height - separatorHeight), size: CGSize(width: params.width - leftInset, height: separatorHeight))
|
||||
case .blocks:
|
||||
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.bottomTopStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.bottomTopStripeNode, at: 3)
|
||||
}
|
||||
if strongSelf.maskNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.maskNode, aboveSubnode: strongSelf.switchGestureNode)
|
||||
}
|
||||
|
||||
let hasCorners = itemListHasRoundedBlockLayout(params) && !item.noCorners
|
||||
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
|
||||
switch neighbors.bottom {
|
||||
case .sameSection(false):
|
||||
bottomStripeInset = leftInset
|
||||
strongSelf.bottomStripeNode.isHidden = false
|
||||
strongSelf.bottomTopStripeNode.isHidden = false
|
||||
default:
|
||||
bottomStripeInset = 0.0
|
||||
hasBottomCorners = true
|
||||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
strongSelf.bottomTopStripeNode.isHidden = false
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
|
||||
let backgroundFrame = 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)))
|
||||
animation.animator.updateFrame(layer: strongSelf.backgroundNode.layer, frame: backgroundFrame, completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.maskNode.layer, frame: backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0), completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.topStripeNode.layer, frame: CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight)), completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.bottomTopStripeNode.layer, frame: CGRect(origin: CGPoint(x: bottomStripeInset, y: mainContentHeight - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight)), completion: nil)
|
||||
animation.animator.updateFrame(layer: strongSelf.bottomStripeNode.layer, frame: CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight)), completion: nil)
|
||||
}
|
||||
|
||||
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: floorToScreenPixels((mainContentHeight - titleLayout.size.height) / 2.0)), size: titleLayout.size)
|
||||
|
||||
let _ = titleValueApply()
|
||||
strongSelf.titleValueNode.frame = CGRect(origin: CGPoint(x: strongSelf.titleNode.frame.maxX + 9.0, y: strongSelf.titleNode.frame.minY + floor((titleLayout.size.height - titleValueLayout.size.height) / 2.0)), size: titleValueLayout.size)
|
||||
|
||||
if let updatedTheme {
|
||||
strongSelf.expandArrowNode.image = generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: updatedTheme.list.itemPrimaryTextColor)
|
||||
}
|
||||
if let image = strongSelf.expandArrowNode.image {
|
||||
strongSelf.expandArrowNode.position = CGPoint(x: strongSelf.titleValueNode.frame.maxX + 9.0, y: strongSelf.titleValueNode.frame.midY)
|
||||
let scaleFactor: CGFloat = 0.8
|
||||
strongSelf.expandArrowNode.bounds = CGRect(origin: CGPoint(), size: CGSize(width: image.size.width * scaleFactor, height: image.size.height * scaleFactor))
|
||||
transition.updateTransformRotation(node: strongSelf.expandArrowNode, angle: item.isExpanded ? CGFloat.pi * 0.5 : -CGFloat.pi * 0.5)
|
||||
}
|
||||
|
||||
if let switchView = strongSelf.switchNode.view as? UISwitch {
|
||||
if strongSelf.switchNode.bounds.size.width.isZero {
|
||||
switchView.sizeToFit()
|
||||
}
|
||||
let switchSize = switchView.bounds.size
|
||||
|
||||
strongSelf.switchNode.frame = CGRect(origin: CGPoint(x: params.width - params.rightInset - switchSize.width - 15.0, y: floor((mainContentHeight - switchSize.height) / 2.0)), size: switchSize)
|
||||
strongSelf.switchGestureNode.frame = strongSelf.switchNode.frame
|
||||
if switchView.isOn != item.value {
|
||||
switchView.setOn(item.value, animated: animation.isAnimated)
|
||||
}
|
||||
switchView.isUserInteractionEnabled = item.enableInteractiveChanges
|
||||
}
|
||||
strongSelf.switchGestureNode.isHidden = item.enableInteractiveChanges && item.enabled
|
||||
|
||||
if item.displayLocked {
|
||||
var updateLockedIconImage = false
|
||||
if let _ = updatedTheme {
|
||||
updateLockedIconImage = true
|
||||
}
|
||||
|
||||
let lockedIconNode: ASImageNode
|
||||
if let current = strongSelf.lockedIconNode {
|
||||
lockedIconNode = current
|
||||
} else {
|
||||
updateLockedIconImage = true
|
||||
lockedIconNode = ASImageNode()
|
||||
strongSelf.lockedIconNode = lockedIconNode
|
||||
strongSelf.insertSubnode(lockedIconNode, aboveSubnode: strongSelf.switchNode)
|
||||
}
|
||||
|
||||
if updateLockedIconImage, let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/TextLockIcon"), color: item.presentationData.theme.list.itemSecondaryTextColor) {
|
||||
lockedIconNode.image = image
|
||||
}
|
||||
|
||||
let switchFrame = strongSelf.switchNode.frame
|
||||
|
||||
if let icon = lockedIconNode.image {
|
||||
lockedIconNode.frame = CGRect(origin: CGPoint(x: switchFrame.minX + 10.0 + UIScreenPixel, y: switchFrame.minY + 9.0), size: icon.size)
|
||||
}
|
||||
} else if let lockedIconNode = strongSelf.lockedIconNode {
|
||||
strongSelf.lockedIconNode = nil
|
||||
lockedIconNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: 44.0 + UIScreenPixel + UIScreenPixel))
|
||||
|
||||
animation.animator.updateFrame(layer: strongSelf.subItemContainer.layer, frame: CGRect(origin: CGPoint(x: 0.0, y: mainContentHeight), size: CGSize(width: params.width, height: effectiveSubItemsHeight)), completion: nil)
|
||||
|
||||
var validIds: [AnyHashable] = []
|
||||
let subItemSize = CGSize(width: params.width - params.leftInset - params.rightInset, height: 44.0)
|
||||
var nextSubItemPosition = CGPoint(x: params.leftInset, y: 0.0)
|
||||
for subItem in item.subItems {
|
||||
validIds.append(subItem.id)
|
||||
|
||||
let subItemNode: SubItemNode
|
||||
var subItemNodeTransition = transition
|
||||
if let current = strongSelf.subItemNodes[subItem.id] {
|
||||
subItemNode = current
|
||||
} else {
|
||||
subItemNodeTransition = .immediate
|
||||
subItemNode = SubItemNode()
|
||||
strongSelf.subItemNodes[subItem.id] = subItemNode
|
||||
strongSelf.subItemContainer.addSubnode(subItemNode)
|
||||
}
|
||||
let subItemFrame = CGRect(origin: nextSubItemPosition, size: subItemSize)
|
||||
subItemNode.update(presentationData: item.presentationData, item: subItem, action: item.subAction, size: subItemSize, transition: subItemNodeTransition)
|
||||
subItemNodeTransition.updateFrame(node: subItemNode, frame: subItemFrame)
|
||||
|
||||
nextSubItemPosition.y += subItemSize.height
|
||||
}
|
||||
var removeIds: [AnyHashable] = []
|
||||
for (id, itemNode) in strongSelf.subItemNodes {
|
||||
if !validIds.contains(id) {
|
||||
removeIds.append(id)
|
||||
itemNode.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
for id in removeIds {
|
||||
strongSelf.subItemNodes.removeValue(forKey: id)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override public func accessibilityActivate() -> Bool {
|
||||
guard let item = self.item else {
|
||||
return false
|
||||
}
|
||||
if !item.enabled {
|
||||
return false
|
||||
}
|
||||
if let switchNode = self.switchNode as? IconSwitchNode {
|
||||
switchNode.isOn = !switchNode.isOn
|
||||
item.updated(switchNode.isOn)
|
||||
} else if let switchNode = self.switchNode as? SwitchNode {
|
||||
switchNode.isOn = !switchNode.isOn
|
||||
item.updated(switchNode.isOn)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override public func visibleForSelection(at point: CGPoint) -> Bool {
|
||||
if !self.canBeSelected {
|
||||
return false
|
||||
}
|
||||
if point.y > self.subItemContainer.frame.minY {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override public func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) {
|
||||
var highlighted = highlighted
|
||||
if point.y > self.subItemContainer.frame.minY {
|
||||
highlighted = false
|
||||
}
|
||||
|
||||
super.setHighlighted(highlighted, at: point, animated: animated)
|
||||
|
||||
if highlighted {
|
||||
self.highlightedBackgroundNode.alpha = 1.0
|
||||
if self.highlightedBackgroundNode.supernode == nil {
|
||||
var anchorNode: ASDisplayNode?
|
||||
if self.bottomStripeNode.supernode != nil {
|
||||
anchorNode = self.bottomStripeNode
|
||||
} else if self.topStripeNode.supernode != nil {
|
||||
anchorNode = self.topStripeNode
|
||||
} else if self.backgroundNode.supernode != nil {
|
||||
anchorNode = self.backgroundNode
|
||||
}
|
||||
if let anchorNode = anchorNode {
|
||||
self.insertSubnode(self.highlightedBackgroundNode, aboveSubnode: anchorNode)
|
||||
} else {
|
||||
self.addSubnode(self.highlightedBackgroundNode)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if self.highlightedBackgroundNode.supernode != nil {
|
||||
if animated {
|
||||
self.highlightedBackgroundNode.layer.animateAlpha(from: self.highlightedBackgroundNode.alpha, to: 0.0, duration: 0.4, completion: { [weak self] completed in
|
||||
if let strongSelf = self {
|
||||
if completed {
|
||||
strongSelf.highlightedBackgroundNode.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
})
|
||||
self.highlightedBackgroundNode.alpha = 0.0
|
||||
} else {
|
||||
self.highlightedBackgroundNode.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||
self.layer.allowsGroupOpacity = true
|
||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4, completion: { [weak self] _ in
|
||||
self?.layer.allowsGroupOpacity = false
|
||||
})
|
||||
}
|
||||
|
||||
override public func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
||||
self.layer.allowsGroupOpacity = true
|
||||
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
|
||||
@objc private func switchValueChanged(_ switchView: UISwitch) {
|
||||
if let item = self.item {
|
||||
let value = switchView.isOn
|
||||
item.updated(value)
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func tapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
if let item = self.item, let switchView = self.switchNode.view as? UISwitch, case .ended = recognizer.state {
|
||||
if item.enabled {
|
||||
let value = switchView.isOn
|
||||
item.updated(!value)
|
||||
} else {
|
||||
item.activatedWhileDisabled()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,7 +87,7 @@ public class ItemListSwitchItem: ListViewItem, ItemListItem {
|
||||
}
|
||||
}
|
||||
|
||||
private protocol ItemListSwitchNodeImpl {
|
||||
protocol ItemListSwitchNodeImpl {
|
||||
var frameColor: UIColor { get set }
|
||||
var contentColor: UIColor { get set }
|
||||
var handleColor: UIColor { get set }
|
||||
|
||||
@ -14,12 +14,12 @@ public func mediaPasteboardScreen(
|
||||
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil,
|
||||
peer: EnginePeer,
|
||||
subjects: [MediaPickerScreen.Subject.Media],
|
||||
presentMediaPicker: @escaping (_ subject: MediaPickerScreen.Subject, _ saveEditedPhotos: Bool, _ bannedSendMedia: (Int32, Bool)?, _ present: @escaping (MediaPickerScreen, AttachmentMediaPickerContext?) -> Void) -> Void,
|
||||
presentMediaPicker: @escaping (_ subject: MediaPickerScreen.Subject, _ saveEditedPhotos: Bool, _ bannedSendPhotos: (Int32, Bool)?, _ bannedSendVideos: (Int32, Bool)?, _ present: @escaping (MediaPickerScreen, AttachmentMediaPickerContext?) -> Void) -> Void,
|
||||
getSourceRect: (() -> CGRect?)? = nil
|
||||
) -> ViewController {
|
||||
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: peer.id), buttons: [.standalone], initialButton: .standalone)
|
||||
controller.requestController = { _, present in
|
||||
presentMediaPicker(.media(subjects), false, nil, { mediaPicker, mediaPickerContext in
|
||||
presentMediaPicker(.media(subjects), false, nil, nil, { mediaPicker, mediaPickerContext in
|
||||
present(mediaPicker, mediaPickerContext)
|
||||
})
|
||||
}
|
||||
|
||||
@ -141,7 +141,8 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
private let peer: EnginePeer?
|
||||
private let threadTitle: String?
|
||||
private let chatLocation: ChatLocation?
|
||||
private let bannedSendMedia: (Int32, Bool)?
|
||||
private let bannedSendPhotos: (Int32, Bool)?
|
||||
private let bannedSendVideos: (Int32, Bool)?
|
||||
private let subject: Subject
|
||||
private let saveEditedPhotos: Bool
|
||||
|
||||
@ -945,7 +946,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
if cameraAccess == nil {
|
||||
cameraRect = nil
|
||||
}
|
||||
if let (untilDate, personal) = self.controller?.bannedSendMedia {
|
||||
/*if let (untilDate, personal) = self.controller?.bannedSendMedia {
|
||||
self.gridNode.isHidden = true
|
||||
|
||||
let banDescription: String
|
||||
@ -972,8 +973,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
placeholderTransition.updateFrame(node: placeholderNode, frame: innerBounds)
|
||||
|
||||
self.updateNavigation(transition: .immediate)
|
||||
} else if case .notDetermined = mediaAccess {
|
||||
|
||||
} else */if case .notDetermined = mediaAccess {
|
||||
} else {
|
||||
if case .limited = mediaAccess {
|
||||
let manageNode: MediaPickerManageNode
|
||||
@ -1099,7 +1099,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
}
|
||||
placeholderNode.update(layout: layout, theme: self.presentationData.theme, strings: self.presentationData.strings, hasCamera: cameraAccess == .authorized, transition: placeholderTransition)
|
||||
placeholderTransition.updateFrame(node: placeholderNode, frame: innerBounds)
|
||||
} else if let placeholderNode = self.placeholderNode, self.controller?.bannedSendMedia == nil {
|
||||
} else if let placeholderNode = self.placeholderNode {//, self.controller?.bannedSendMedia == nil {
|
||||
self.placeholderNode = nil
|
||||
placeholderNode.removeFromSupernode()
|
||||
}
|
||||
@ -1131,7 +1131,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
|
||||
private var isDismissing = false
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer?, threadTitle: String?, chatLocation: ChatLocation?, bannedSendMedia: (Int32, Bool)?, subject: Subject, editingContext: TGMediaEditingContext? = nil, selectionContext: TGMediaSelectionContext? = nil, saveEditedPhotos: Bool = false) {
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer?, threadTitle: String?, chatLocation: ChatLocation?, bannedSendPhotos: (Int32, Bool)?, bannedSendVideos: (Int32, Bool)?, subject: Subject, editingContext: TGMediaEditingContext? = nil, selectionContext: TGMediaSelectionContext? = nil, saveEditedPhotos: Bool = false) {
|
||||
self.context = context
|
||||
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
@ -1140,7 +1140,8 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
self.peer = peer
|
||||
self.threadTitle = threadTitle
|
||||
self.chatLocation = chatLocation
|
||||
self.bannedSendMedia = bannedSendMedia
|
||||
self.bannedSendPhotos = bannedSendPhotos
|
||||
self.bannedSendVideos = bannedSendVideos
|
||||
self.subject = subject
|
||||
self.saveEditedPhotos = saveEditedPhotos
|
||||
|
||||
@ -1495,7 +1496,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
self.requestAttachmentMenuExpansion()
|
||||
self.presentWebSearch(MediaGroupsScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, mediaAssetsContext: self.controllerNode.mediaAssetsContext, openGroup: { [weak self] collection in
|
||||
if let strongSelf = self {
|
||||
let mediaPicker = MediaPickerScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: strongSelf.peer, threadTitle: strongSelf.threadTitle, chatLocation: strongSelf.chatLocation, bannedSendMedia: strongSelf.bannedSendMedia, subject: .assets(collection), editingContext: strongSelf.interaction?.editingState, selectionContext: strongSelf.interaction?.selectionState)
|
||||
let mediaPicker = MediaPickerScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: strongSelf.peer, threadTitle: strongSelf.threadTitle, chatLocation: strongSelf.chatLocation, bannedSendPhotos: strongSelf.bannedSendPhotos, bannedSendVideos: strongSelf.bannedSendVideos, subject: .assets(collection), editingContext: strongSelf.interaction?.editingState, selectionContext: strongSelf.interaction?.selectionState)
|
||||
|
||||
mediaPicker.presentSchedulePicker = strongSelf.presentSchedulePicker
|
||||
mediaPicker.presentTimerPicker = strongSelf.presentTimerPicker
|
||||
|
||||
@ -33,8 +33,9 @@ private final class ChannelPermissionsControllerArguments {
|
||||
let presentConversionToBroadcastGroup: () -> Void
|
||||
let openChannelExample: () -> Void
|
||||
let updateSlowmode: (Int32) -> Void
|
||||
let toggleIsOptionExpanded: (TelegramChatBannedRightsFlags) -> Void
|
||||
|
||||
init(context: AccountContext, updatePermission: @escaping (TelegramChatBannedRightsFlags, Bool) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addPeer: @escaping () -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (ChannelParticipant) -> Void, openPeerInfo: @escaping (Peer) -> Void, openKicked: @escaping () -> Void, presentRestrictedPermissionAlert: @escaping (TelegramChatBannedRightsFlags) -> Void, presentConversionToBroadcastGroup: @escaping () -> Void, openChannelExample: @escaping () -> Void, updateSlowmode: @escaping (Int32) -> Void) {
|
||||
init(context: AccountContext, updatePermission: @escaping (TelegramChatBannedRightsFlags, Bool) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addPeer: @escaping () -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (ChannelParticipant) -> Void, openPeerInfo: @escaping (Peer) -> Void, openKicked: @escaping () -> Void, presentRestrictedPermissionAlert: @escaping (TelegramChatBannedRightsFlags) -> Void, presentConversionToBroadcastGroup: @escaping () -> Void, openChannelExample: @escaping () -> Void, updateSlowmode: @escaping (Int32) -> Void, toggleIsOptionExpanded: @escaping (TelegramChatBannedRightsFlags) -> Void) {
|
||||
self.context = context
|
||||
self.updatePermission = updatePermission
|
||||
self.addPeer = addPeer
|
||||
@ -47,6 +48,7 @@ private final class ChannelPermissionsControllerArguments {
|
||||
self.presentConversionToBroadcastGroup = presentConversionToBroadcastGroup
|
||||
self.openChannelExample = openChannelExample
|
||||
self.updateSlowmode = updateSlowmode
|
||||
self.toggleIsOptionExpanded = toggleIsOptionExpanded
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,9 +65,15 @@ private enum ChannelPermissionsEntryStableId: Hashable {
|
||||
case peer(PeerId)
|
||||
}
|
||||
|
||||
private struct SubPermission: Equatable {
|
||||
var title: String
|
||||
var flags: TelegramChatBannedRightsFlags
|
||||
var isSelected: Bool
|
||||
}
|
||||
|
||||
private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
||||
case permissionsHeader(PresentationTheme, String)
|
||||
case permission(PresentationTheme, Int, String, Bool, TelegramChatBannedRightsFlags, Bool?)
|
||||
case permission(PresentationTheme, Int, String, Bool, TelegramChatBannedRightsFlags, Bool?, [SubPermission], Bool)
|
||||
case slowmodeHeader(PresentationTheme, String)
|
||||
case slowmode(PresentationTheme, PresentationStrings, Int32)
|
||||
case slowmodeInfo(PresentationTheme, String)
|
||||
@ -96,7 +104,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
||||
switch self {
|
||||
case .permissionsHeader:
|
||||
return .index(0)
|
||||
case let .permission(_, index, _, _, _, _):
|
||||
case let .permission(_, index, _, _, _, _, _, _):
|
||||
return .index(1 + index)
|
||||
case .conversionHeader:
|
||||
return .index(998)
|
||||
@ -129,8 +137,8 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .permission(theme, index, title, value, rights, enabled):
|
||||
if case .permission(theme, index, title, value, rights, enabled) = rhs {
|
||||
case let .permission(theme, index, title, value, rights, enabled, subPermissions, isExpanded):
|
||||
if case .permission(theme, index, title, value, rights, enabled, subPermissions, isExpanded) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -256,16 +264,47 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
||||
switch self {
|
||||
case let .permissionsHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .permission(_, _, title, value, rights, enabled):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, type: .icon, enableInteractiveChanges: enabled != nil, enabled: enabled ?? true, sectionId: self.section, style: .blocks, updated: { value in
|
||||
if let _ = enabled {
|
||||
arguments.updatePermission(rights, value)
|
||||
} else {
|
||||
case let .permission(_, _, title, value, rights, enabled, subPermissions, isExpanded):
|
||||
if !subPermissions.isEmpty {
|
||||
return ItemListExpandableSwitchItem(presentationData: presentationData, title: title, value: value, isExpanded: isExpanded, subItems: subPermissions.map { item in
|
||||
return ItemListExpandableSwitchItem.SubItem(
|
||||
id: AnyHashable(item.flags.rawValue),
|
||||
title: item.title,
|
||||
isSelected: item.isSelected
|
||||
)
|
||||
}, type: .icon, enableInteractiveChanges: enabled != nil, enabled: enabled ?? true, sectionId: self.section, style: .blocks, updated: { value in
|
||||
if let _ = enabled {
|
||||
arguments.updatePermission(rights, value)
|
||||
} else {
|
||||
arguments.presentRestrictedPermissionAlert(rights)
|
||||
}
|
||||
}, activatedWhileDisabled: {
|
||||
arguments.presentRestrictedPermissionAlert(rights)
|
||||
}
|
||||
}, activatedWhileDisabled: {
|
||||
arguments.presentRestrictedPermissionAlert(rights)
|
||||
})
|
||||
}, selectAction: {
|
||||
arguments.toggleIsOptionExpanded(rights)
|
||||
}, subAction: { item in
|
||||
guard let value = item.id.base as? Int32 else {
|
||||
return
|
||||
}
|
||||
let subRights = TelegramChatBannedRightsFlags(rawValue: value)
|
||||
|
||||
if let _ = enabled {
|
||||
arguments.updatePermission(subRights, !item.isSelected)
|
||||
} else {
|
||||
arguments.presentRestrictedPermissionAlert(subRights)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, type: .icon, enableInteractiveChanges: enabled != nil, enabled: enabled ?? true, sectionId: self.section, style: .blocks, updated: { value in
|
||||
if let _ = enabled {
|
||||
arguments.updatePermission(rights, value)
|
||||
} else {
|
||||
arguments.presentRestrictedPermissionAlert(rights)
|
||||
}
|
||||
}, activatedWhileDisabled: {
|
||||
arguments.presentRestrictedPermissionAlert(rights)
|
||||
})
|
||||
}
|
||||
case let .slowmodeHeader(_, value):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: value, sectionId: self.section)
|
||||
case let .slowmode(theme, strings, value):
|
||||
@ -334,9 +373,11 @@ private struct ChannelPermissionsControllerState: Equatable {
|
||||
var searchingMembers: Bool = false
|
||||
var modifiedRightsFlags: TelegramChatBannedRightsFlags?
|
||||
var modifiedSlowmodeTimeout: Int32?
|
||||
var expandedPermissions = Set<TelegramChatBannedRightsFlags>()
|
||||
}
|
||||
|
||||
func stringForGroupPermission(strings: PresentationStrings, right: TelegramChatBannedRightsFlags, isForum: Bool) -> String {
|
||||
//TODO:localize
|
||||
if right.contains(.banSendMessages) {
|
||||
return strings.Channel_BanUser_PermissionSendMessages
|
||||
} else if right.contains(.banSendMedia) {
|
||||
@ -355,6 +396,20 @@ func stringForGroupPermission(strings: PresentationStrings, right: TelegramChatB
|
||||
return strings.Channel_EditAdmin_PermissionPinMessages
|
||||
} else if right.contains(.banManageTopics) {
|
||||
return strings.Channel_EditAdmin_PermissionCreateTopics
|
||||
} else if right.contains(.banSendPhotos) {
|
||||
return "Send Photos"
|
||||
} else if right.contains(.banSendVideos) {
|
||||
return "Send Videos"
|
||||
} else if right.contains(.banSendStickers) {
|
||||
return strings.Channel_BanUser_PermissionSendStickersAndGifs
|
||||
} else if right.contains(.banSendMusic) {
|
||||
return "Send Music"
|
||||
} else if right.contains(.banSendFiles) {
|
||||
return "Send Files"
|
||||
} else if right.contains(.banSendVoice) {
|
||||
return "Send Voice Messages"
|
||||
} else if right.contains(.banSendInstantVideos) {
|
||||
return "Send Video Messages"
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
@ -387,7 +442,13 @@ func compactStringForGroupPermission(strings: PresentationStrings, right: Telegr
|
||||
private let internal_allPossibleGroupPermissionList: [(TelegramChatBannedRightsFlags, TelegramChannelPermission)] = [
|
||||
(.banSendMessages, .banMembers),
|
||||
(.banSendMedia, .banMembers),
|
||||
(.banSendPhotos, .banMembers),
|
||||
(.banSendVideos, .banMembers),
|
||||
(.banSendGifs, .banMembers),
|
||||
(.banSendMusic, .banMembers),
|
||||
(.banSendFiles, .banMembers),
|
||||
(.banSendVoice, .banMembers),
|
||||
(.banSendInstantVideos, .banMembers),
|
||||
(.banEmbedLinks, .banMembers),
|
||||
(.banSendPolls, .banMembers),
|
||||
(.banAddMembers, .banMembers),
|
||||
@ -401,8 +462,6 @@ public func allGroupPermissionList(peer: EnginePeer) -> [(TelegramChatBannedRigh
|
||||
return [
|
||||
(.banSendMessages, .banMembers),
|
||||
(.banSendMedia, .banMembers),
|
||||
(.banSendGifs, .banMembers),
|
||||
(.banEmbedLinks, .banMembers),
|
||||
(.banSendPolls, .banMembers),
|
||||
(.banAddMembers, .banMembers),
|
||||
(.banPinMessages, .pinMessages),
|
||||
@ -413,8 +472,6 @@ public func allGroupPermissionList(peer: EnginePeer) -> [(TelegramChatBannedRigh
|
||||
return [
|
||||
(.banSendMessages, .banMembers),
|
||||
(.banSendMedia, .banMembers),
|
||||
(.banSendGifs, .banMembers),
|
||||
(.banEmbedLinks, .banMembers),
|
||||
(.banSendPolls, .banMembers),
|
||||
(.banAddMembers, .banMembers),
|
||||
(.banPinMessages, .pinMessages),
|
||||
@ -422,6 +479,19 @@ public func allGroupPermissionList(peer: EnginePeer) -> [(TelegramChatBannedRigh
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
public func banSendMediaSubList() -> [(TelegramChatBannedRightsFlags, TelegramChannelPermission)] {
|
||||
return [
|
||||
(.banSendPhotos, .banMembers),
|
||||
(.banSendVideos, .banMembers),
|
||||
(.banSendGifs, .banMembers),
|
||||
(.banSendMusic, .banMembers),
|
||||
(.banSendFiles, .banMembers),
|
||||
(.banSendVoice, .banMembers),
|
||||
(.banSendInstantVideos, .banMembers),
|
||||
(.banEmbedLinks, .banMembers),
|
||||
]
|
||||
}
|
||||
|
||||
let publicGroupRestrictedPermissions: TelegramChatBannedRightsFlags = [
|
||||
.banPinMessages,
|
||||
@ -429,7 +499,7 @@ let publicGroupRestrictedPermissions: TelegramChatBannedRightsFlags = [
|
||||
]
|
||||
|
||||
func groupPermissionDependencies(_ right: TelegramChatBannedRightsFlags) -> TelegramChatBannedRightsFlags {
|
||||
if right.contains(.banSendMedia) {
|
||||
if right.contains(.banSendMedia) || banSendMediaSubList().contains(where: { $0.0 == right }) {
|
||||
return [.banSendMessages]
|
||||
} else if right.contains(.banSendGifs) {
|
||||
return [.banSendMessages]
|
||||
@ -476,7 +546,18 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
|
||||
if !channel.hasPermission(correspondingAdminRight) {
|
||||
enabled = false
|
||||
}
|
||||
entries.append(.permission(presentationData.theme, rightIndex, stringForGroupPermission(strings: presentationData.strings, right: rights, isForum: channel.flags.contains(.isForum)), !effectiveRightsFlags.contains(rights), rights, enabled))
|
||||
|
||||
var isSelected = !effectiveRightsFlags.contains(rights)
|
||||
var subItems: [SubPermission] = []
|
||||
if rights == .banSendMedia {
|
||||
isSelected = banSendMediaSubList().allSatisfy({ !effectiveRightsFlags.contains($0.0) })
|
||||
|
||||
for (subRight, _) in banSendMediaSubList() {
|
||||
subItems.append(SubPermission(title: stringForGroupPermission(strings: presentationData.strings, right: subRight, isForum: channel.isForum), flags: subRight, isSelected: !effectiveRightsFlags.contains(subRight)))
|
||||
}
|
||||
}
|
||||
|
||||
entries.append(.permission(presentationData.theme, rightIndex, stringForGroupPermission(strings: presentationData.strings, right: rights, isForum: channel.flags.contains(.isForum)), isSelected, rights, enabled, subItems, state.expandedPermissions.contains(rights)))
|
||||
rightIndex += 1
|
||||
}
|
||||
|
||||
@ -513,7 +594,14 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
|
||||
entries.append(.permissionsHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_SectionTitle))
|
||||
var rightIndex: Int = 0
|
||||
for (rights, _) in allGroupPermissionList(peer: .legacyGroup(group)) {
|
||||
entries.append(.permission(presentationData.theme, rightIndex, stringForGroupPermission(strings: presentationData.strings, right: rights, isForum: false), !effectiveRightsFlags.contains(rights), rights, true))
|
||||
var subItems: [SubPermission] = []
|
||||
if rights == .banSendMedia {
|
||||
for (subRight, _) in banSendMediaSubList() {
|
||||
subItems.append(SubPermission(title: stringForGroupPermission(strings: presentationData.strings, right: subRight, isForum: false), flags: subRight, isSelected: !effectiveRightsFlags.contains(subRight)))
|
||||
}
|
||||
}
|
||||
|
||||
entries.append(.permission(presentationData.theme, rightIndex, stringForGroupPermission(strings: presentationData.strings, right: rights, isForum: false), !effectiveRightsFlags.contains(rights), rights, true, subItems, state.expandedPermissions.contains(rights)))
|
||||
rightIndex += 1
|
||||
}
|
||||
|
||||
@ -611,16 +699,47 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
||||
} else {
|
||||
effectiveRightsFlags = TelegramChatBannedRightsFlags()
|
||||
}
|
||||
if value {
|
||||
effectiveRightsFlags.remove(rights)
|
||||
effectiveRightsFlags = effectiveRightsFlags.subtracting(groupPermissionDependencies(rights))
|
||||
} else {
|
||||
effectiveRightsFlags.insert(rights)
|
||||
for (right, _) in allGroupPermissionList(peer: .channel(channel)) {
|
||||
if groupPermissionDependencies(right).contains(rights) {
|
||||
effectiveRightsFlags.insert(right)
|
||||
|
||||
if rights == .banSendMedia {
|
||||
if value {
|
||||
effectiveRightsFlags.remove(rights)
|
||||
for item in banSendMediaSubList() {
|
||||
effectiveRightsFlags.remove(item.0)
|
||||
}
|
||||
} else {
|
||||
effectiveRightsFlags.insert(rights)
|
||||
for (right, _) in allGroupPermissionList(peer: .channel(channel)) {
|
||||
if groupPermissionDependencies(right).contains(rights) {
|
||||
effectiveRightsFlags.insert(right)
|
||||
}
|
||||
}
|
||||
|
||||
for item in banSendMediaSubList() {
|
||||
effectiveRightsFlags.insert(item.0)
|
||||
for (right, _) in allGroupPermissionList(peer: .channel(channel)) {
|
||||
if groupPermissionDependencies(right).contains(item.0) {
|
||||
effectiveRightsFlags.insert(right)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if value {
|
||||
effectiveRightsFlags.remove(rights)
|
||||
effectiveRightsFlags = effectiveRightsFlags.subtracting(groupPermissionDependencies(rights))
|
||||
} else {
|
||||
effectiveRightsFlags.insert(rights)
|
||||
for (right, _) in allGroupPermissionList(peer: .channel(channel)) {
|
||||
if groupPermissionDependencies(right).contains(rights) {
|
||||
effectiveRightsFlags.insert(right)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if banSendMediaSubList().allSatisfy({ !effectiveRightsFlags.contains($0.0) }) {
|
||||
effectiveRightsFlags.remove(.banSendMedia)
|
||||
} else {
|
||||
effectiveRightsFlags.insert(.banSendMedia)
|
||||
}
|
||||
state.modifiedRightsFlags = effectiveRightsFlags
|
||||
return state
|
||||
@ -868,6 +987,16 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
||||
}))
|
||||
}
|
||||
})
|
||||
}, toggleIsOptionExpanded: { flags in
|
||||
updateState { state in
|
||||
var state = state
|
||||
if state.expandedPermissions.contains(flags) {
|
||||
state.expandedPermissions.remove(flags)
|
||||
} else {
|
||||
state.expandedPermissions.insert(flags)
|
||||
}
|
||||
return state
|
||||
}
|
||||
})
|
||||
|
||||
let previousParticipants = Atomic<[RenderedChannelParticipant]?>(value: nil)
|
||||
@ -889,6 +1018,8 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
||||
return .single((view, peers.1))
|
||||
}
|
||||
|
||||
let previousExpandedPermissionsValue = Atomic<Set<TelegramChatBannedRightsFlags>?>(value: nil)
|
||||
|
||||
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
|
||||
let signal = combineLatest(queue: .mainQueue(), presentationData, statePromise.get(), viewAndParticipants)
|
||||
|> deliverOnMainQueue
|
||||
@ -912,6 +1043,7 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
||||
}
|
||||
|
||||
let previous = previousParticipants.swap(participants)
|
||||
let previousExpandedPermissions = previousExpandedPermissionsValue.swap(state.expandedPermissions)
|
||||
|
||||
var searchItem: ItemListControllerSearch?
|
||||
if state.searchingMembers {
|
||||
@ -940,8 +1072,13 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
||||
})
|
||||
}
|
||||
|
||||
var animateChanges = previous != nil && participants != nil && previous!.count >= participants!.count
|
||||
if let previousExpandedPermissions, previousExpandedPermissions != state.expandedPermissions {
|
||||
animateChanges = true
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.GroupInfo_Permissions_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelPermissionsControllerEntries(context: context, presentationData: presentationData, view: view, state: state, participants: participants), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: previous != nil && participants != nil && previous!.count >= participants!.count)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelPermissionsControllerEntries(context: context, presentationData: presentationData, view: view, state: state, participants: participants), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: animateChanges)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
||||
@ -76,8 +76,8 @@ public enum DataAndStorageEntryTag: ItemListItemTag {
|
||||
}
|
||||
|
||||
private enum DataAndStorageEntry: ItemListNodeEntry {
|
||||
case storageUsage(PresentationTheme, String)
|
||||
case networkUsage(PresentationTheme, String)
|
||||
case storageUsage(PresentationTheme, String, String)
|
||||
case networkUsage(PresentationTheme, String, String)
|
||||
case automaticDownloadHeader(PresentationTheme, String)
|
||||
case automaticDownloadCellular(PresentationTheme, String, String)
|
||||
case automaticDownloadWifi(PresentationTheme, String, String)
|
||||
@ -170,14 +170,14 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
|
||||
|
||||
static func ==(lhs: DataAndStorageEntry, rhs: DataAndStorageEntry) -> Bool {
|
||||
switch lhs {
|
||||
case let .storageUsage(lhsTheme, lhsText):
|
||||
if case let .storageUsage(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
case let .storageUsage(lhsTheme, lhsText, lhsValue):
|
||||
if case let .storageUsage(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .networkUsage(lhsTheme, lhsText):
|
||||
if case let .networkUsage(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
case let .networkUsage(lhsTheme, lhsText, lhsValue):
|
||||
if case let .networkUsage(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -306,12 +306,12 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
|
||||
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
||||
let arguments = arguments as! DataAndStorageControllerArguments
|
||||
switch self {
|
||||
case let .storageUsage(_, text):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Settings/Menu/Storage")?.precomposed(), title: text, label: "", sectionId: self.section, style: .blocks, action: {
|
||||
case let .storageUsage(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Settings/Menu/Storage")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openStorageUsage()
|
||||
})
|
||||
case let .networkUsage(_, text):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Settings/Menu/Network")?.precomposed(), title: text, label: "", sectionId: self.section, style: .blocks, action: {
|
||||
case let .networkUsage(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: UIImage(bundleImageName: "Settings/Menu/Network")?.precomposed(), title: text, label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openNetworkUsage()
|
||||
})
|
||||
case let .automaticDownloadHeader(_, text):
|
||||
@ -478,11 +478,11 @@ private func stringForAutoDownloadSetting(strings: PresentationStrings, decimalS
|
||||
}
|
||||
}
|
||||
|
||||
private func dataAndStorageControllerEntries(state: DataAndStorageControllerState, data: DataAndStorageData, presentationData: PresentationData, defaultWebBrowser: String, contentSettingsConfiguration: ContentSettingsConfiguration?) -> [DataAndStorageEntry] {
|
||||
private func dataAndStorageControllerEntries(state: DataAndStorageControllerState, data: DataAndStorageData, presentationData: PresentationData, defaultWebBrowser: String, contentSettingsConfiguration: ContentSettingsConfiguration?, networkUsage: Int64, storageUsage: Int64) -> [DataAndStorageEntry] {
|
||||
var entries: [DataAndStorageEntry] = []
|
||||
|
||||
entries.append(.storageUsage(presentationData.theme, presentationData.strings.ChatSettings_Cache))
|
||||
entries.append(.networkUsage(presentationData.theme, presentationData.strings.NetworkUsageSettings_Title))
|
||||
entries.append(.storageUsage(presentationData.theme, presentationData.strings.ChatSettings_Cache, dataSizeString(storageUsage, formatting: DataSizeStringFormatting(presentationData: presentationData))))
|
||||
entries.append(.networkUsage(presentationData.theme, presentationData.strings.NetworkUsageSettings_Title, dataSizeString(networkUsage, formatting: DataSizeStringFormatting(presentationData: presentationData))))
|
||||
|
||||
entries.append(.automaticDownloadHeader(presentationData.theme, presentationData.strings.ChatSettings_AutoDownloadTitle.uppercased()))
|
||||
entries.append(.automaticDownloadCellular(presentationData.theme, presentationData.strings.ChatSettings_AutoDownloadUsingCellular, stringForAutoDownloadSetting(strings: presentationData.strings, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator, settings: data.automaticMediaDownloadSettings, connectionType: .cellular)))
|
||||
@ -554,6 +554,67 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da
|
||||
contentSettingsConfiguration.set(.single(nil)
|
||||
|> then(updatedContentSettingsConfiguration))
|
||||
|
||||
struct UsageData: Equatable {
|
||||
var network: Int64
|
||||
var storage: Int64
|
||||
}
|
||||
let usageSignal: Signal<UsageData, NoError> = combineLatest(
|
||||
context.account.postbox.mediaBox.storageBox.totalSize(),
|
||||
context.account.postbox.mediaBox.cacheStorageBox.totalSize(),
|
||||
accountNetworkUsageStats(account: context.account, reset: [])
|
||||
)
|
||||
|> map { disk1, disk2, networkStats -> UsageData in
|
||||
var network: Int64 = 0
|
||||
|
||||
var keys: [KeyPath<NetworkUsageStats, Int64>] = []
|
||||
|
||||
keys.append(\.generic.cellular.outgoing)
|
||||
keys.append(\.generic.cellular.incoming)
|
||||
keys.append(\.generic.wifi.incoming)
|
||||
keys.append(\.generic.wifi.outgoing)
|
||||
|
||||
keys.append(\.image.cellular.outgoing)
|
||||
keys.append(\.image.cellular.incoming)
|
||||
keys.append(\.image.wifi.incoming)
|
||||
keys.append(\.image.wifi.outgoing)
|
||||
|
||||
keys.append(\.video.cellular.outgoing)
|
||||
keys.append(\.video.cellular.incoming)
|
||||
keys.append(\.video.wifi.incoming)
|
||||
keys.append(\.video.wifi.outgoing)
|
||||
|
||||
keys.append(\.audio.cellular.outgoing)
|
||||
keys.append(\.audio.cellular.incoming)
|
||||
keys.append(\.audio.wifi.incoming)
|
||||
keys.append(\.audio.wifi.outgoing)
|
||||
|
||||
keys.append(\.file.cellular.outgoing)
|
||||
keys.append(\.file.cellular.incoming)
|
||||
keys.append(\.file.wifi.incoming)
|
||||
keys.append(\.file.wifi.outgoing)
|
||||
|
||||
keys.append(\.call.cellular.outgoing)
|
||||
keys.append(\.call.cellular.incoming)
|
||||
keys.append(\.call.wifi.incoming)
|
||||
keys.append(\.call.wifi.outgoing)
|
||||
|
||||
keys.append(\.sticker.cellular.outgoing)
|
||||
keys.append(\.sticker.cellular.incoming)
|
||||
keys.append(\.sticker.wifi.incoming)
|
||||
keys.append(\.sticker.wifi.outgoing)
|
||||
|
||||
keys.append(\.voiceMessage.cellular.outgoing)
|
||||
keys.append(\.voiceMessage.cellular.incoming)
|
||||
keys.append(\.voiceMessage.wifi.incoming)
|
||||
keys.append(\.voiceMessage.wifi.outgoing)
|
||||
|
||||
for key in keys {
|
||||
network += networkStats[keyPath: key]
|
||||
}
|
||||
|
||||
return UsageData(network: network, storage: disk1 + disk2)
|
||||
}
|
||||
|
||||
let dataAndStorageDataPromise = Promise<DataAndStorageData>()
|
||||
dataAndStorageDataPromise.set(context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.autodownloadSettings, ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings, ApplicationSpecificSharedDataKeys.generatedMediaStoreSettings, ApplicationSpecificSharedDataKeys.voiceCallSettings, SharedDataKeys.proxySettings])
|
||||
|> map { sharedData -> DataAndStorageData in
|
||||
@ -599,7 +660,13 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da
|
||||
return storageUsageExceptionsScreen(context: context, category: category)
|
||||
}))
|
||||
}, openNetworkUsage: {
|
||||
pushControllerImpl?(networkUsageStatsController(context: context))
|
||||
//pushControllerImpl?(networkUsageStatsController(context: context))
|
||||
|
||||
let _ = (accountNetworkUsageStats(account: context.account, reset: [])
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { stats in
|
||||
pushControllerImpl?(DataUsageScreen(context: context, stats: stats))
|
||||
})
|
||||
}, openProxy: {
|
||||
pushControllerImpl?(proxySettingsController(context: context))
|
||||
}, openAutomaticDownloadConnectionType: { connectionType in
|
||||
@ -679,9 +746,10 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da
|
||||
statePromise.get(),
|
||||
dataAndStorageDataPromise.get(),
|
||||
context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.webBrowserSettings]),
|
||||
contentSettingsConfiguration.get()
|
||||
contentSettingsConfiguration.get(),
|
||||
usageSignal
|
||||
)
|
||||
|> map { presentationData, state, dataAndStorageData, sharedData, contentSettingsConfiguration -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
|> map { presentationData, state, dataAndStorageData, sharedData, contentSettingsConfiguration, usageSignal -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let webBrowserSettings = sharedData.entries[ApplicationSpecificSharedDataKeys.webBrowserSettings]?.get(WebBrowserSettings.self) ?? WebBrowserSettings.defaultSettings
|
||||
let options = availableOpenInOptions(context: context, item: .url(url: "https://telegram.org"))
|
||||
let defaultWebBrowser: String
|
||||
@ -692,7 +760,7 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.ChatSettings_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: dataAndStorageControllerEntries(state: state, data: dataAndStorageData, presentationData: presentationData, defaultWebBrowser: defaultWebBrowser, contentSettingsConfiguration: contentSettingsConfiguration), style: .blocks, ensureVisibleItemTag: focusOnItemTag, emptyStateItem: nil, animateChanges: false)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: dataAndStorageControllerEntries(state: state, data: dataAndStorageData, presentationData: presentationData, defaultWebBrowser: defaultWebBrowser, contentSettingsConfiguration: contentSettingsConfiguration, networkUsage: usageSignal.network, storageUsage: usageSignal.storage), style: .blocks, ensureVisibleItemTag: focusOnItemTag, emptyStateItem: nil, animateChanges: false)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
} |> afterDisposed {
|
||||
|
||||
@ -123,7 +123,13 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
|
||||
self.animationNode = animationNode
|
||||
|
||||
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 400.0, height: 400.0))
|
||||
let fitSize: CGSize
|
||||
if item.file.isCustomEmoji {
|
||||
fitSize = CGSize(width: 200.0, height: 200.0)
|
||||
} else {
|
||||
fitSize = CGSize(width: 400.0, height: 400.0)
|
||||
}
|
||||
let fittedDimensions = dimensions.cgSize.aspectFitted(fitSize)
|
||||
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: account, resource: item.file.resource, isVideo: item.file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: isPremiumSticker ? .once : .loop, mode: .direct(cachePathPrefix: nil))
|
||||
animationNode.visibility = true
|
||||
@ -197,7 +203,9 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
|
||||
|
||||
public func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let boundingSize: CGSize
|
||||
if let _ = self.additionalAnimationNode {
|
||||
if self.item.file.isCustomEmoji {
|
||||
boundingSize = CGSize(width: 120.0, height: 120.0)
|
||||
} else if let _ = self.additionalAnimationNode {
|
||||
boundingSize = CGSize(width: 240.0, height: 240.0).fitted(size)
|
||||
} else {
|
||||
boundingSize = CGSize(width: 180.0, height: 180.0).fitted(size)
|
||||
@ -239,7 +247,11 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
|
||||
|
||||
self.textNode.frame = CGRect(origin: CGPoint(x: floor((imageFrame.size.width - textSize.width) / 2.0) - centerOffset, y: -textSize.height - textSpacing), size: textSize)
|
||||
|
||||
return CGSize(width: size.width, height: imageFrame.height + textSize.height + textSpacing)
|
||||
if self.item.file.isCustomEmoji {
|
||||
return CGSize(width: size.width, height: imageFrame.height)
|
||||
} else {
|
||||
return CGSize(width: size.width, height: imageFrame.height + textSize.height + textSpacing)
|
||||
}
|
||||
} else {
|
||||
return CGSize(width: size.width, height: 10.0)
|
||||
}
|
||||
|
||||
@ -939,7 +939,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-842824308] = { return Api.account.WallPapers.parse_wallPapers($0) }
|
||||
dict[471437699] = { return Api.account.WallPapers.parse_wallPapersNotModified($0) }
|
||||
dict[-313079300] = { return Api.account.WebAuthorizations.parse_webAuthorizations($0) }
|
||||
dict[872119224] = { return Api.auth.Authorization.parse_authorization($0) }
|
||||
dict[782418132] = { return Api.auth.Authorization.parse_authorization($0) }
|
||||
dict[1148485274] = { return Api.auth.Authorization.parse_authorizationSignUpRequired($0) }
|
||||
dict[1948046307] = { return Api.auth.CodeType.parse_codeTypeCall($0) }
|
||||
dict[577556219] = { return Api.auth.CodeType.parse_codeTypeFlashCall($0) }
|
||||
@ -953,6 +953,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[957176926] = { return Api.auth.LoginToken.parse_loginTokenSuccess($0) }
|
||||
dict[326715557] = { return Api.auth.PasswordRecovery.parse_passwordRecovery($0) }
|
||||
dict[1577067778] = { return Api.auth.SentCode.parse_sentCode($0) }
|
||||
dict[596704836] = { return Api.auth.SentCode.parse_sentCodeSuccess($0) }
|
||||
dict[1035688326] = { return Api.auth.SentCodeType.parse_sentCodeTypeApp($0) }
|
||||
dict[1398007207] = { return Api.auth.SentCodeType.parse_sentCodeTypeCall($0) }
|
||||
dict[1511364673] = { return Api.auth.SentCodeType.parse_sentCodeTypeEmailCode($0) }
|
||||
|
||||
@ -1176,18 +1176,19 @@ public extension Api.account {
|
||||
}
|
||||
public extension Api.auth {
|
||||
enum Authorization: TypeConstructorDescription {
|
||||
case authorization(flags: Int32, otherwiseReloginDays: Int32?, tmpSessions: Int32?, user: Api.User)
|
||||
case authorization(flags: Int32, otherwiseReloginDays: Int32?, tmpSessions: Int32?, futureAuthToken: Buffer?, user: Api.User)
|
||||
case authorizationSignUpRequired(flags: Int32, termsOfService: Api.help.TermsOfService?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .authorization(let flags, let otherwiseReloginDays, let tmpSessions, let user):
|
||||
case .authorization(let flags, let otherwiseReloginDays, let tmpSessions, let futureAuthToken, let user):
|
||||
if boxed {
|
||||
buffer.appendInt32(872119224)
|
||||
buffer.appendInt32(782418132)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(otherwiseReloginDays!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(tmpSessions!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeBytes(futureAuthToken!, buffer: buffer, boxed: false)}
|
||||
user.serialize(buffer, true)
|
||||
break
|
||||
case .authorizationSignUpRequired(let flags, let termsOfService):
|
||||
@ -1202,8 +1203,8 @@ public extension Api.auth {
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .authorization(let flags, let otherwiseReloginDays, let tmpSessions, let user):
|
||||
return ("authorization", [("flags", flags as Any), ("otherwiseReloginDays", otherwiseReloginDays as Any), ("tmpSessions", tmpSessions as Any), ("user", user as Any)])
|
||||
case .authorization(let flags, let otherwiseReloginDays, let tmpSessions, let futureAuthToken, let user):
|
||||
return ("authorization", [("flags", flags as Any), ("otherwiseReloginDays", otherwiseReloginDays as Any), ("tmpSessions", tmpSessions as Any), ("futureAuthToken", futureAuthToken as Any), ("user", user as Any)])
|
||||
case .authorizationSignUpRequired(let flags, let termsOfService):
|
||||
return ("authorizationSignUpRequired", [("flags", flags as Any), ("termsOfService", termsOfService as Any)])
|
||||
}
|
||||
@ -1216,16 +1217,19 @@ public extension Api.auth {
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_2 = reader.readInt32() }
|
||||
var _3: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
||||
var _4: Api.User?
|
||||
var _4: Buffer?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = parseBytes(reader) }
|
||||
var _5: Api.User?
|
||||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.User
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.User
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 1) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.auth.Authorization.authorization(flags: _1!, otherwiseReloginDays: _2, tmpSessions: _3, user: _4!)
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.auth.Authorization.authorization(flags: _1!, otherwiseReloginDays: _2, tmpSessions: _3, futureAuthToken: _4, user: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
||||
@ -279,6 +279,7 @@ public extension Api.auth {
|
||||
public extension Api.auth {
|
||||
enum SentCode: TypeConstructorDescription {
|
||||
case sentCode(flags: Int32, type: Api.auth.SentCodeType, phoneCodeHash: String, nextType: Api.auth.CodeType?, timeout: Int32?)
|
||||
case sentCodeSuccess(authorization: Api.auth.Authorization)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
@ -292,6 +293,12 @@ public extension Api.auth {
|
||||
if Int(flags) & Int(1 << 1) != 0 {nextType!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(timeout!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .sentCodeSuccess(let authorization):
|
||||
if boxed {
|
||||
buffer.appendInt32(596704836)
|
||||
}
|
||||
authorization.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,6 +306,8 @@ public extension Api.auth {
|
||||
switch self {
|
||||
case .sentCode(let flags, let type, let phoneCodeHash, let nextType, let timeout):
|
||||
return ("sentCode", [("flags", flags as Any), ("type", type as Any), ("phoneCodeHash", phoneCodeHash as Any), ("nextType", nextType as Any), ("timeout", timeout as Any)])
|
||||
case .sentCodeSuccess(let authorization):
|
||||
return ("sentCodeSuccess", [("authorization", authorization as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,6 +338,19 @@ public extension Api.auth {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_sentCodeSuccess(_ reader: BufferReader) -> SentCode? {
|
||||
var _1: Api.auth.Authorization?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.auth.Authorization
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.auth.SentCode.sentCodeSuccess(authorization: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1112,61 +1134,3 @@ public extension Api.contacts {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.contacts {
|
||||
enum ResolvedPeer: TypeConstructorDescription {
|
||||
case resolvedPeer(peer: Api.Peer, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .resolvedPeer(let peer, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(2131196633)
|
||||
}
|
||||
peer.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .resolvedPeer(let peer, let chats, let users):
|
||||
return ("resolvedPeer", [("peer", peer as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_resolvedPeer(_ reader: BufferReader) -> ResolvedPeer? {
|
||||
var _1: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
var _2: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.contacts.ResolvedPeer.resolvedPeer(peer: _1!, chats: _2!, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,61 @@
|
||||
public extension Api.contacts {
|
||||
enum ResolvedPeer: TypeConstructorDescription {
|
||||
case resolvedPeer(peer: Api.Peer, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .resolvedPeer(let peer, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(2131196633)
|
||||
}
|
||||
peer.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .resolvedPeer(let peer, let chats, let users):
|
||||
return ("resolvedPeer", [("peer", peer as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_resolvedPeer(_ reader: BufferReader) -> ResolvedPeer? {
|
||||
var _1: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
var _2: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.contacts.ResolvedPeer.resolvedPeer(peer: _1!, chats: _2!, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.contacts {
|
||||
enum TopPeers: TypeConstructorDescription {
|
||||
case topPeers(categories: [Api.TopPeerCategoryPeers], chats: [Api.Chat], users: [Api.User])
|
||||
@ -1248,61 +1306,3 @@ public extension Api.messages {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum AvailableReactions: TypeConstructorDescription {
|
||||
case availableReactions(hash: Int32, reactions: [Api.AvailableReaction])
|
||||
case availableReactionsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .availableReactions(let hash, let reactions):
|
||||
if boxed {
|
||||
buffer.appendInt32(1989032621)
|
||||
}
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(reactions.count))
|
||||
for item in reactions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .availableReactionsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1626924713)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .availableReactions(let hash, let reactions):
|
||||
return ("availableReactions", [("hash", hash as Any), ("reactions", reactions as Any)])
|
||||
case .availableReactionsNotModified:
|
||||
return ("availableReactionsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_availableReactions(_ reader: BufferReader) -> AvailableReactions? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.AvailableReaction]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.AvailableReaction.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.AvailableReactions.availableReactions(hash: _1!, reactions: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_availableReactionsNotModified(_ reader: BufferReader) -> AvailableReactions? {
|
||||
return Api.messages.AvailableReactions.availableReactionsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,61 @@
|
||||
public extension Api.messages {
|
||||
enum AvailableReactions: TypeConstructorDescription {
|
||||
case availableReactions(hash: Int32, reactions: [Api.AvailableReaction])
|
||||
case availableReactionsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .availableReactions(let hash, let reactions):
|
||||
if boxed {
|
||||
buffer.appendInt32(1989032621)
|
||||
}
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(reactions.count))
|
||||
for item in reactions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .availableReactionsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1626924713)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .availableReactions(let hash, let reactions):
|
||||
return ("availableReactions", [("hash", hash as Any), ("reactions", reactions as Any)])
|
||||
case .availableReactionsNotModified:
|
||||
return ("availableReactionsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_availableReactions(_ reader: BufferReader) -> AvailableReactions? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.AvailableReaction]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.AvailableReaction.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.AvailableReactions.availableReactions(hash: _1!, reactions: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_availableReactionsNotModified(_ reader: BufferReader) -> AvailableReactions? {
|
||||
return Api.messages.AvailableReactions.availableReactionsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum BotCallbackAnswer: TypeConstructorDescription {
|
||||
case botCallbackAnswer(flags: Int32, message: String?, url: String?, cacheTime: Int32)
|
||||
@ -1432,281 +1490,3 @@ public extension Api.messages {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum MessageViews: TypeConstructorDescription {
|
||||
case messageViews(views: [Api.MessageViews], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .messageViews(let views, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1228606141)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(views.count))
|
||||
for item in views {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .messageViews(let views, let chats, let users):
|
||||
return ("messageViews", [("views", views as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_messageViews(_ reader: BufferReader) -> MessageViews? {
|
||||
var _1: [Api.MessageViews]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageViews.self)
|
||||
}
|
||||
var _2: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.MessageViews.messageViews(views: _1!, chats: _2!, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum Messages: TypeConstructorDescription {
|
||||
case channelMessages(flags: Int32, pts: Int32, count: Int32, offsetIdOffset: Int32?, messages: [Api.Message], topics: [Api.ForumTopic], chats: [Api.Chat], users: [Api.User])
|
||||
case messages(messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
case messagesNotModified(count: Int32)
|
||||
case messagesSlice(flags: Int32, count: Int32, nextRate: Int32?, offsetIdOffset: Int32?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .channelMessages(let flags, let pts, let count, let offsetIdOffset, let messages, let topics, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-948520370)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(pts, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(topics.count))
|
||||
for item in topics {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .messages(let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1938715001)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .messagesNotModified(let count):
|
||||
if boxed {
|
||||
buffer.appendInt32(1951620897)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(978610270)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(nextRate!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .channelMessages(let flags, let pts, let count, let offsetIdOffset, let messages, let topics, let chats, let users):
|
||||
return ("channelMessages", [("flags", flags as Any), ("pts", pts as Any), ("count", count as Any), ("offsetIdOffset", offsetIdOffset as Any), ("messages", messages as Any), ("topics", topics as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
case .messages(let messages, let chats, let users):
|
||||
return ("messages", [("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
case .messagesNotModified(let count):
|
||||
return ("messagesNotModified", [("count", count as Any)])
|
||||
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let messages, let chats, let users):
|
||||
return ("messagesSlice", [("flags", flags as Any), ("count", count as Any), ("nextRate", nextRate as Any), ("offsetIdOffset", offsetIdOffset as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_channelMessages(_ reader: BufferReader) -> Messages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
var _5: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _6: [Api.ForumTopic]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ForumTopic.self)
|
||||
}
|
||||
var _7: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _8: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
||||
return Api.messages.Messages.channelMessages(flags: _1!, pts: _2!, count: _3!, offsetIdOffset: _4, messages: _5!, topics: _6!, chats: _7!, users: _8!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messages(_ reader: BufferReader) -> Messages? {
|
||||
var _1: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _2: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.Messages.messages(messages: _1!, chats: _2!, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messagesNotModified(_ reader: BufferReader) -> Messages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.Messages.messagesNotModified(count: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messagesSlice(_ reader: BufferReader) -> Messages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
var _5: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _6: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _7: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.messages.Messages.messagesSlice(flags: _1!, count: _2!, nextRate: _3, offsetIdOffset: _4, messages: _5!, chats: _6!, users: _7!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,281 @@
|
||||
public extension Api.messages {
|
||||
enum MessageViews: TypeConstructorDescription {
|
||||
case messageViews(views: [Api.MessageViews], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .messageViews(let views, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1228606141)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(views.count))
|
||||
for item in views {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .messageViews(let views, let chats, let users):
|
||||
return ("messageViews", [("views", views as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_messageViews(_ reader: BufferReader) -> MessageViews? {
|
||||
var _1: [Api.MessageViews]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageViews.self)
|
||||
}
|
||||
var _2: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.MessageViews.messageViews(views: _1!, chats: _2!, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum Messages: TypeConstructorDescription {
|
||||
case channelMessages(flags: Int32, pts: Int32, count: Int32, offsetIdOffset: Int32?, messages: [Api.Message], topics: [Api.ForumTopic], chats: [Api.Chat], users: [Api.User])
|
||||
case messages(messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
case messagesNotModified(count: Int32)
|
||||
case messagesSlice(flags: Int32, count: Int32, nextRate: Int32?, offsetIdOffset: Int32?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .channelMessages(let flags, let pts, let count, let offsetIdOffset, let messages, let topics, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-948520370)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(pts, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(topics.count))
|
||||
for item in topics {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .messages(let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1938715001)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .messagesNotModified(let count):
|
||||
if boxed {
|
||||
buffer.appendInt32(1951620897)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(978610270)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(nextRate!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .channelMessages(let flags, let pts, let count, let offsetIdOffset, let messages, let topics, let chats, let users):
|
||||
return ("channelMessages", [("flags", flags as Any), ("pts", pts as Any), ("count", count as Any), ("offsetIdOffset", offsetIdOffset as Any), ("messages", messages as Any), ("topics", topics as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
case .messages(let messages, let chats, let users):
|
||||
return ("messages", [("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
case .messagesNotModified(let count):
|
||||
return ("messagesNotModified", [("count", count as Any)])
|
||||
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let messages, let chats, let users):
|
||||
return ("messagesSlice", [("flags", flags as Any), ("count", count as Any), ("nextRate", nextRate as Any), ("offsetIdOffset", offsetIdOffset as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_channelMessages(_ reader: BufferReader) -> Messages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
var _5: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _6: [Api.ForumTopic]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ForumTopic.self)
|
||||
}
|
||||
var _7: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _8: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
||||
return Api.messages.Messages.channelMessages(flags: _1!, pts: _2!, count: _3!, offsetIdOffset: _4, messages: _5!, topics: _6!, chats: _7!, users: _8!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messages(_ reader: BufferReader) -> Messages? {
|
||||
var _1: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _2: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.Messages.messages(messages: _1!, chats: _2!, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messagesNotModified(_ reader: BufferReader) -> Messages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.Messages.messagesNotModified(count: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messagesSlice(_ reader: BufferReader) -> Messages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
var _5: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _6: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _7: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.messages.Messages.messagesSlice(flags: _1!, count: _2!, nextRate: _3, offsetIdOffset: _4, messages: _5!, chats: _6!, users: _7!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum PeerDialogs: TypeConstructorDescription {
|
||||
case peerDialogs(dialogs: [Api.Dialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User], state: Api.updates.State)
|
||||
@ -1086,327 +1364,3 @@ public extension Api.payments {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum PaymentForm: TypeConstructorDescription {
|
||||
case paymentForm(flags: Int32, formId: Int64, botId: Int64, title: String, description: String, photo: Api.WebDocument?, invoice: Api.Invoice, providerId: Int64, url: String, nativeProvider: String?, nativeParams: Api.DataJSON?, additionalMethods: [Api.PaymentFormMethod]?, savedInfo: Api.PaymentRequestedInfo?, savedCredentials: [Api.PaymentSavedCredentials]?, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .paymentForm(let flags, let formId, let botId, let title, let description, let photo, let invoice, let providerId, let url, let nativeProvider, let nativeParams, let additionalMethods, let savedInfo, let savedCredentials, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1610250415)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(formId, buffer: buffer, boxed: false)
|
||||
serializeInt64(botId, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
serializeString(description, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 5) != 0 {photo!.serialize(buffer, true)}
|
||||
invoice.serialize(buffer, true)
|
||||
serializeInt64(providerId, buffer: buffer, boxed: false)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeString(nativeProvider!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {nativeParams!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 6) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(additionalMethods!.count))
|
||||
for item in additionalMethods! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 0) != 0 {savedInfo!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(savedCredentials!.count))
|
||||
for item in savedCredentials! {
|
||||
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 .paymentForm(let flags, let formId, let botId, let title, let description, let photo, let invoice, let providerId, let url, let nativeProvider, let nativeParams, let additionalMethods, let savedInfo, let savedCredentials, let users):
|
||||
return ("paymentForm", [("flags", flags as Any), ("formId", formId as Any), ("botId", botId as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("providerId", providerId as Any), ("url", url as Any), ("nativeProvider", nativeProvider as Any), ("nativeParams", nativeParams as Any), ("additionalMethods", additionalMethods as Any), ("savedInfo", savedInfo as Any), ("savedCredentials", savedCredentials as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_paymentForm(_ reader: BufferReader) -> PaymentForm? {
|
||||
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: Api.WebDocument?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.WebDocument
|
||||
} }
|
||||
var _7: Api.Invoice?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.Invoice
|
||||
}
|
||||
var _8: Int64?
|
||||
_8 = reader.readInt64()
|
||||
var _9: String?
|
||||
_9 = parseString(reader)
|
||||
var _10: String?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_10 = parseString(reader) }
|
||||
var _11: Api.DataJSON?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
|
||||
_11 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||
} }
|
||||
var _12: [Api.PaymentFormMethod]?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {if let _ = reader.readInt32() {
|
||||
_12 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PaymentFormMethod.self)
|
||||
} }
|
||||
var _13: Api.PaymentRequestedInfo?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_13 = Api.parse(reader, signature: signature) as? Api.PaymentRequestedInfo
|
||||
} }
|
||||
var _14: [Api.PaymentSavedCredentials]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_14 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PaymentSavedCredentials.self)
|
||||
} }
|
||||
var _15: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 5) == 0) || _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = (Int(_1!) & Int(1 << 4) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 4) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 6) == 0) || _12 != nil
|
||||
let _c13 = (Int(_1!) & Int(1 << 0) == 0) || _13 != nil
|
||||
let _c14 = (Int(_1!) & Int(1 << 1) == 0) || _14 != nil
|
||||
let _c15 = _15 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 {
|
||||
return Api.payments.PaymentForm.paymentForm(flags: _1!, formId: _2!, botId: _3!, title: _4!, description: _5!, photo: _6, invoice: _7!, providerId: _8!, url: _9!, nativeProvider: _10, nativeParams: _11, additionalMethods: _12, savedInfo: _13, savedCredentials: _14, users: _15!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum PaymentReceipt: TypeConstructorDescription {
|
||||
case paymentReceipt(flags: Int32, date: Int32, botId: Int64, providerId: Int64, title: String, description: String, photo: Api.WebDocument?, invoice: Api.Invoice, info: Api.PaymentRequestedInfo?, shipping: Api.ShippingOption?, tipAmount: Int64?, currency: String, totalAmount: Int64, credentialsTitle: String, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .paymentReceipt(let flags, let date, let botId, let providerId, let title, let description, let photo, let invoice, let info, let shipping, let tipAmount, let currency, let totalAmount, let credentialsTitle, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(1891958275)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
serializeInt64(botId, buffer: buffer, boxed: false)
|
||||
serializeInt64(providerId, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
serializeString(description, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {photo!.serialize(buffer, true)}
|
||||
invoice.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 0) != 0 {info!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {shipping!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt64(tipAmount!, buffer: buffer, boxed: false)}
|
||||
serializeString(currency, buffer: buffer, boxed: false)
|
||||
serializeInt64(totalAmount, buffer: buffer, boxed: false)
|
||||
serializeString(credentialsTitle, buffer: buffer, boxed: false)
|
||||
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 .paymentReceipt(let flags, let date, let botId, let providerId, let title, let description, let photo, let invoice, let info, let shipping, let tipAmount, let currency, let totalAmount, let credentialsTitle, let users):
|
||||
return ("paymentReceipt", [("flags", flags as Any), ("date", date as Any), ("botId", botId as Any), ("providerId", providerId as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("info", info as Any), ("shipping", shipping as Any), ("tipAmount", tipAmount as Any), ("currency", currency as Any), ("totalAmount", totalAmount as Any), ("credentialsTitle", credentialsTitle as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_paymentReceipt(_ reader: BufferReader) -> PaymentReceipt? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: Int64?
|
||||
_4 = reader.readInt64()
|
||||
var _5: String?
|
||||
_5 = parseString(reader)
|
||||
var _6: String?
|
||||
_6 = parseString(reader)
|
||||
var _7: Api.WebDocument?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.WebDocument
|
||||
} }
|
||||
var _8: Api.Invoice?
|
||||
if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.Invoice
|
||||
}
|
||||
var _9: Api.PaymentRequestedInfo?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.PaymentRequestedInfo
|
||||
} }
|
||||
var _10: Api.ShippingOption?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_10 = Api.parse(reader, signature: signature) as? Api.ShippingOption
|
||||
} }
|
||||
var _11: Int64?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_11 = reader.readInt64() }
|
||||
var _12: String?
|
||||
_12 = parseString(reader)
|
||||
var _13: Int64?
|
||||
_13 = reader.readInt64()
|
||||
var _14: String?
|
||||
_14 = parseString(reader)
|
||||
var _15: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
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 = (Int(_1!) & Int(1 << 2) == 0) || _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = (Int(_1!) & Int(1 << 0) == 0) || _9 != nil
|
||||
let _c10 = (Int(_1!) & Int(1 << 1) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 3) == 0) || _11 != nil
|
||||
let _c12 = _12 != nil
|
||||
let _c13 = _13 != nil
|
||||
let _c14 = _14 != nil
|
||||
let _c15 = _15 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 {
|
||||
return Api.payments.PaymentReceipt.paymentReceipt(flags: _1!, date: _2!, botId: _3!, providerId: _4!, title: _5!, description: _6!, photo: _7, invoice: _8!, info: _9, shipping: _10, tipAmount: _11, currency: _12!, totalAmount: _13!, credentialsTitle: _14!, users: _15!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
indirect enum PaymentResult: TypeConstructorDescription {
|
||||
case paymentResult(updates: Api.Updates)
|
||||
case paymentVerificationNeeded(url: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .paymentResult(let updates):
|
||||
if boxed {
|
||||
buffer.appendInt32(1314881805)
|
||||
}
|
||||
updates.serialize(buffer, true)
|
||||
break
|
||||
case .paymentVerificationNeeded(let url):
|
||||
if boxed {
|
||||
buffer.appendInt32(-666824391)
|
||||
}
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .paymentResult(let updates):
|
||||
return ("paymentResult", [("updates", updates as Any)])
|
||||
case .paymentVerificationNeeded(let url):
|
||||
return ("paymentVerificationNeeded", [("url", url as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_paymentResult(_ reader: BufferReader) -> PaymentResult? {
|
||||
var _1: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Updates
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.payments.PaymentResult.paymentResult(updates: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_paymentVerificationNeeded(_ reader: BufferReader) -> PaymentResult? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.payments.PaymentResult.paymentVerificationNeeded(url: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum SavedInfo: TypeConstructorDescription {
|
||||
case savedInfo(flags: Int32, savedInfo: Api.PaymentRequestedInfo?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .savedInfo(let flags, let savedInfo):
|
||||
if boxed {
|
||||
buffer.appendInt32(-74456004)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {savedInfo!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .savedInfo(let flags, let savedInfo):
|
||||
return ("savedInfo", [("flags", flags as Any), ("savedInfo", savedInfo as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_savedInfo(_ reader: BufferReader) -> SavedInfo? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.PaymentRequestedInfo?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.PaymentRequestedInfo
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.payments.SavedInfo.savedInfo(flags: _1!, savedInfo: _2)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,327 @@
|
||||
public extension Api.payments {
|
||||
enum PaymentForm: TypeConstructorDescription {
|
||||
case paymentForm(flags: Int32, formId: Int64, botId: Int64, title: String, description: String, photo: Api.WebDocument?, invoice: Api.Invoice, providerId: Int64, url: String, nativeProvider: String?, nativeParams: Api.DataJSON?, additionalMethods: [Api.PaymentFormMethod]?, savedInfo: Api.PaymentRequestedInfo?, savedCredentials: [Api.PaymentSavedCredentials]?, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .paymentForm(let flags, let formId, let botId, let title, let description, let photo, let invoice, let providerId, let url, let nativeProvider, let nativeParams, let additionalMethods, let savedInfo, let savedCredentials, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1610250415)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(formId, buffer: buffer, boxed: false)
|
||||
serializeInt64(botId, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
serializeString(description, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 5) != 0 {photo!.serialize(buffer, true)}
|
||||
invoice.serialize(buffer, true)
|
||||
serializeInt64(providerId, buffer: buffer, boxed: false)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeString(nativeProvider!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {nativeParams!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 6) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(additionalMethods!.count))
|
||||
for item in additionalMethods! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 0) != 0 {savedInfo!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(savedCredentials!.count))
|
||||
for item in savedCredentials! {
|
||||
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 .paymentForm(let flags, let formId, let botId, let title, let description, let photo, let invoice, let providerId, let url, let nativeProvider, let nativeParams, let additionalMethods, let savedInfo, let savedCredentials, let users):
|
||||
return ("paymentForm", [("flags", flags as Any), ("formId", formId as Any), ("botId", botId as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("providerId", providerId as Any), ("url", url as Any), ("nativeProvider", nativeProvider as Any), ("nativeParams", nativeParams as Any), ("additionalMethods", additionalMethods as Any), ("savedInfo", savedInfo as Any), ("savedCredentials", savedCredentials as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_paymentForm(_ reader: BufferReader) -> PaymentForm? {
|
||||
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: Api.WebDocument?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.WebDocument
|
||||
} }
|
||||
var _7: Api.Invoice?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.Invoice
|
||||
}
|
||||
var _8: Int64?
|
||||
_8 = reader.readInt64()
|
||||
var _9: String?
|
||||
_9 = parseString(reader)
|
||||
var _10: String?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_10 = parseString(reader) }
|
||||
var _11: Api.DataJSON?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
|
||||
_11 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||
} }
|
||||
var _12: [Api.PaymentFormMethod]?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {if let _ = reader.readInt32() {
|
||||
_12 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PaymentFormMethod.self)
|
||||
} }
|
||||
var _13: Api.PaymentRequestedInfo?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_13 = Api.parse(reader, signature: signature) as? Api.PaymentRequestedInfo
|
||||
} }
|
||||
var _14: [Api.PaymentSavedCredentials]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_14 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PaymentSavedCredentials.self)
|
||||
} }
|
||||
var _15: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 5) == 0) || _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = (Int(_1!) & Int(1 << 4) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 4) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 6) == 0) || _12 != nil
|
||||
let _c13 = (Int(_1!) & Int(1 << 0) == 0) || _13 != nil
|
||||
let _c14 = (Int(_1!) & Int(1 << 1) == 0) || _14 != nil
|
||||
let _c15 = _15 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 {
|
||||
return Api.payments.PaymentForm.paymentForm(flags: _1!, formId: _2!, botId: _3!, title: _4!, description: _5!, photo: _6, invoice: _7!, providerId: _8!, url: _9!, nativeProvider: _10, nativeParams: _11, additionalMethods: _12, savedInfo: _13, savedCredentials: _14, users: _15!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum PaymentReceipt: TypeConstructorDescription {
|
||||
case paymentReceipt(flags: Int32, date: Int32, botId: Int64, providerId: Int64, title: String, description: String, photo: Api.WebDocument?, invoice: Api.Invoice, info: Api.PaymentRequestedInfo?, shipping: Api.ShippingOption?, tipAmount: Int64?, currency: String, totalAmount: Int64, credentialsTitle: String, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .paymentReceipt(let flags, let date, let botId, let providerId, let title, let description, let photo, let invoice, let info, let shipping, let tipAmount, let currency, let totalAmount, let credentialsTitle, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(1891958275)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
serializeInt64(botId, buffer: buffer, boxed: false)
|
||||
serializeInt64(providerId, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
serializeString(description, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {photo!.serialize(buffer, true)}
|
||||
invoice.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 0) != 0 {info!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {shipping!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt64(tipAmount!, buffer: buffer, boxed: false)}
|
||||
serializeString(currency, buffer: buffer, boxed: false)
|
||||
serializeInt64(totalAmount, buffer: buffer, boxed: false)
|
||||
serializeString(credentialsTitle, buffer: buffer, boxed: false)
|
||||
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 .paymentReceipt(let flags, let date, let botId, let providerId, let title, let description, let photo, let invoice, let info, let shipping, let tipAmount, let currency, let totalAmount, let credentialsTitle, let users):
|
||||
return ("paymentReceipt", [("flags", flags as Any), ("date", date as Any), ("botId", botId as Any), ("providerId", providerId as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("info", info as Any), ("shipping", shipping as Any), ("tipAmount", tipAmount as Any), ("currency", currency as Any), ("totalAmount", totalAmount as Any), ("credentialsTitle", credentialsTitle as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_paymentReceipt(_ reader: BufferReader) -> PaymentReceipt? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: Int64?
|
||||
_4 = reader.readInt64()
|
||||
var _5: String?
|
||||
_5 = parseString(reader)
|
||||
var _6: String?
|
||||
_6 = parseString(reader)
|
||||
var _7: Api.WebDocument?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.WebDocument
|
||||
} }
|
||||
var _8: Api.Invoice?
|
||||
if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.Invoice
|
||||
}
|
||||
var _9: Api.PaymentRequestedInfo?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.PaymentRequestedInfo
|
||||
} }
|
||||
var _10: Api.ShippingOption?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_10 = Api.parse(reader, signature: signature) as? Api.ShippingOption
|
||||
} }
|
||||
var _11: Int64?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_11 = reader.readInt64() }
|
||||
var _12: String?
|
||||
_12 = parseString(reader)
|
||||
var _13: Int64?
|
||||
_13 = reader.readInt64()
|
||||
var _14: String?
|
||||
_14 = parseString(reader)
|
||||
var _15: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
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 = (Int(_1!) & Int(1 << 2) == 0) || _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = (Int(_1!) & Int(1 << 0) == 0) || _9 != nil
|
||||
let _c10 = (Int(_1!) & Int(1 << 1) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 3) == 0) || _11 != nil
|
||||
let _c12 = _12 != nil
|
||||
let _c13 = _13 != nil
|
||||
let _c14 = _14 != nil
|
||||
let _c15 = _15 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 {
|
||||
return Api.payments.PaymentReceipt.paymentReceipt(flags: _1!, date: _2!, botId: _3!, providerId: _4!, title: _5!, description: _6!, photo: _7, invoice: _8!, info: _9, shipping: _10, tipAmount: _11, currency: _12!, totalAmount: _13!, credentialsTitle: _14!, users: _15!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
indirect enum PaymentResult: TypeConstructorDescription {
|
||||
case paymentResult(updates: Api.Updates)
|
||||
case paymentVerificationNeeded(url: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .paymentResult(let updates):
|
||||
if boxed {
|
||||
buffer.appendInt32(1314881805)
|
||||
}
|
||||
updates.serialize(buffer, true)
|
||||
break
|
||||
case .paymentVerificationNeeded(let url):
|
||||
if boxed {
|
||||
buffer.appendInt32(-666824391)
|
||||
}
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .paymentResult(let updates):
|
||||
return ("paymentResult", [("updates", updates as Any)])
|
||||
case .paymentVerificationNeeded(let url):
|
||||
return ("paymentVerificationNeeded", [("url", url as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_paymentResult(_ reader: BufferReader) -> PaymentResult? {
|
||||
var _1: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Updates
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.payments.PaymentResult.paymentResult(updates: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_paymentVerificationNeeded(_ reader: BufferReader) -> PaymentResult? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.payments.PaymentResult.paymentVerificationNeeded(url: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum SavedInfo: TypeConstructorDescription {
|
||||
case savedInfo(flags: Int32, savedInfo: Api.PaymentRequestedInfo?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .savedInfo(let flags, let savedInfo):
|
||||
if boxed {
|
||||
buffer.appendInt32(-74456004)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {savedInfo!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .savedInfo(let flags, let savedInfo):
|
||||
return ("savedInfo", [("flags", flags as Any), ("savedInfo", savedInfo as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_savedInfo(_ reader: BufferReader) -> SavedInfo? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.PaymentRequestedInfo?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.PaymentRequestedInfo
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.payments.SavedInfo.savedInfo(flags: _1!, savedInfo: _2)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum ValidatedRequestedInfo: TypeConstructorDescription {
|
||||
case validatedRequestedInfo(flags: Int32, id: String?, shippingOptions: [Api.ShippingOption]?)
|
||||
@ -1220,207 +1544,3 @@ public extension Api.updates {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.updates {
|
||||
enum Difference: TypeConstructorDescription {
|
||||
case difference(newMessages: [Api.Message], newEncryptedMessages: [Api.EncryptedMessage], otherUpdates: [Api.Update], chats: [Api.Chat], users: [Api.User], state: Api.updates.State)
|
||||
case differenceEmpty(date: Int32, seq: Int32)
|
||||
case differenceSlice(newMessages: [Api.Message], newEncryptedMessages: [Api.EncryptedMessage], otherUpdates: [Api.Update], chats: [Api.Chat], users: [Api.User], intermediateState: Api.updates.State)
|
||||
case differenceTooLong(pts: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .difference(let newMessages, let newEncryptedMessages, let otherUpdates, let chats, let users, let state):
|
||||
if boxed {
|
||||
buffer.appendInt32(16030880)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(newMessages.count))
|
||||
for item in newMessages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(newEncryptedMessages.count))
|
||||
for item in newEncryptedMessages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(otherUpdates.count))
|
||||
for item in otherUpdates {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
state.serialize(buffer, true)
|
||||
break
|
||||
case .differenceEmpty(let date, let seq):
|
||||
if boxed {
|
||||
buffer.appendInt32(1567990072)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
serializeInt32(seq, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .differenceSlice(let newMessages, let newEncryptedMessages, let otherUpdates, let chats, let users, let intermediateState):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1459938943)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(newMessages.count))
|
||||
for item in newMessages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(newEncryptedMessages.count))
|
||||
for item in newEncryptedMessages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(otherUpdates.count))
|
||||
for item in otherUpdates {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
intermediateState.serialize(buffer, true)
|
||||
break
|
||||
case .differenceTooLong(let pts):
|
||||
if boxed {
|
||||
buffer.appendInt32(1258196845)
|
||||
}
|
||||
serializeInt32(pts, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .difference(let newMessages, let newEncryptedMessages, let otherUpdates, let chats, let users, let state):
|
||||
return ("difference", [("newMessages", newMessages as Any), ("newEncryptedMessages", newEncryptedMessages as Any), ("otherUpdates", otherUpdates as Any), ("chats", chats as Any), ("users", users as Any), ("state", state as Any)])
|
||||
case .differenceEmpty(let date, let seq):
|
||||
return ("differenceEmpty", [("date", date as Any), ("seq", seq as Any)])
|
||||
case .differenceSlice(let newMessages, let newEncryptedMessages, let otherUpdates, let chats, let users, let intermediateState):
|
||||
return ("differenceSlice", [("newMessages", newMessages as Any), ("newEncryptedMessages", newEncryptedMessages as Any), ("otherUpdates", otherUpdates as Any), ("chats", chats as Any), ("users", users as Any), ("intermediateState", intermediateState as Any)])
|
||||
case .differenceTooLong(let pts):
|
||||
return ("differenceTooLong", [("pts", pts as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_difference(_ reader: BufferReader) -> Difference? {
|
||||
var _1: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _2: [Api.EncryptedMessage]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.EncryptedMessage.self)
|
||||
}
|
||||
var _3: [Api.Update]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Update.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: Api.updates.State?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.updates.State
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.updates.Difference.difference(newMessages: _1!, newEncryptedMessages: _2!, otherUpdates: _3!, chats: _4!, users: _5!, state: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_differenceEmpty(_ reader: BufferReader) -> Difference? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.updates.Difference.differenceEmpty(date: _1!, seq: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_differenceSlice(_ reader: BufferReader) -> Difference? {
|
||||
var _1: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _2: [Api.EncryptedMessage]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.EncryptedMessage.self)
|
||||
}
|
||||
var _3: [Api.Update]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Update.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: Api.updates.State?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.updates.State
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.updates.Difference.differenceSlice(newMessages: _1!, newEncryptedMessages: _2!, otherUpdates: _3!, chats: _4!, users: _5!, intermediateState: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_differenceTooLong(_ reader: BufferReader) -> Difference? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.updates.Difference.differenceTooLong(pts: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,207 @@
|
||||
public extension Api.updates {
|
||||
enum Difference: TypeConstructorDescription {
|
||||
case difference(newMessages: [Api.Message], newEncryptedMessages: [Api.EncryptedMessage], otherUpdates: [Api.Update], chats: [Api.Chat], users: [Api.User], state: Api.updates.State)
|
||||
case differenceEmpty(date: Int32, seq: Int32)
|
||||
case differenceSlice(newMessages: [Api.Message], newEncryptedMessages: [Api.EncryptedMessage], otherUpdates: [Api.Update], chats: [Api.Chat], users: [Api.User], intermediateState: Api.updates.State)
|
||||
case differenceTooLong(pts: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .difference(let newMessages, let newEncryptedMessages, let otherUpdates, let chats, let users, let state):
|
||||
if boxed {
|
||||
buffer.appendInt32(16030880)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(newMessages.count))
|
||||
for item in newMessages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(newEncryptedMessages.count))
|
||||
for item in newEncryptedMessages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(otherUpdates.count))
|
||||
for item in otherUpdates {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
state.serialize(buffer, true)
|
||||
break
|
||||
case .differenceEmpty(let date, let seq):
|
||||
if boxed {
|
||||
buffer.appendInt32(1567990072)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
serializeInt32(seq, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .differenceSlice(let newMessages, let newEncryptedMessages, let otherUpdates, let chats, let users, let intermediateState):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1459938943)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(newMessages.count))
|
||||
for item in newMessages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(newEncryptedMessages.count))
|
||||
for item in newEncryptedMessages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(otherUpdates.count))
|
||||
for item in otherUpdates {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
intermediateState.serialize(buffer, true)
|
||||
break
|
||||
case .differenceTooLong(let pts):
|
||||
if boxed {
|
||||
buffer.appendInt32(1258196845)
|
||||
}
|
||||
serializeInt32(pts, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .difference(let newMessages, let newEncryptedMessages, let otherUpdates, let chats, let users, let state):
|
||||
return ("difference", [("newMessages", newMessages as Any), ("newEncryptedMessages", newEncryptedMessages as Any), ("otherUpdates", otherUpdates as Any), ("chats", chats as Any), ("users", users as Any), ("state", state as Any)])
|
||||
case .differenceEmpty(let date, let seq):
|
||||
return ("differenceEmpty", [("date", date as Any), ("seq", seq as Any)])
|
||||
case .differenceSlice(let newMessages, let newEncryptedMessages, let otherUpdates, let chats, let users, let intermediateState):
|
||||
return ("differenceSlice", [("newMessages", newMessages as Any), ("newEncryptedMessages", newEncryptedMessages as Any), ("otherUpdates", otherUpdates as Any), ("chats", chats as Any), ("users", users as Any), ("intermediateState", intermediateState as Any)])
|
||||
case .differenceTooLong(let pts):
|
||||
return ("differenceTooLong", [("pts", pts as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_difference(_ reader: BufferReader) -> Difference? {
|
||||
var _1: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _2: [Api.EncryptedMessage]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.EncryptedMessage.self)
|
||||
}
|
||||
var _3: [Api.Update]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Update.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: Api.updates.State?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.updates.State
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.updates.Difference.difference(newMessages: _1!, newEncryptedMessages: _2!, otherUpdates: _3!, chats: _4!, users: _5!, state: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_differenceEmpty(_ reader: BufferReader) -> Difference? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.updates.Difference.differenceEmpty(date: _1!, seq: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_differenceSlice(_ reader: BufferReader) -> Difference? {
|
||||
var _1: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _2: [Api.EncryptedMessage]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.EncryptedMessage.self)
|
||||
}
|
||||
var _3: [Api.Update]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Update.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: Api.updates.State?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.updates.State
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.updates.Difference.differenceSlice(newMessages: _1!, newEncryptedMessages: _2!, otherUpdates: _3!, chats: _4!, users: _5!, intermediateState: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_differenceTooLong(_ reader: BufferReader) -> Difference? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.updates.Difference.differenceTooLong(pts: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.updates {
|
||||
enum State: TypeConstructorDescription {
|
||||
case state(pts: Int32, qts: Int32, date: Int32, seq: Int32, unreadCount: Int32)
|
||||
|
||||
@ -438,40 +438,14 @@ private func cleanupAccount(networkArguments: NetworkInitializationArguments, ac
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||
let _ = (accountManager.transaction { transaction -> Void in
|
||||
var tokens = transaction.getStoredLoginTokens()
|
||||
switch result {
|
||||
case let .loggedOut(_, futureAuthToken):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
tokens.insert(futureAuthToken.makeData(), at: 0)
|
||||
}
|
||||
default:
|
||||
break
|
||||
switch result {
|
||||
case let .loggedOut(_, futureAuthToken):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
var cloudValue: [Data] = []
|
||||
if let list = NSUbiquitousKeyValueStore.default.object(forKey: "T_SLTokens") as? [String] {
|
||||
cloudValue = list.compactMap { string -> Data? in
|
||||
guard let stringData = string.data(using: .utf8) else {
|
||||
return nil
|
||||
}
|
||||
return Data(base64Encoded: stringData)
|
||||
}
|
||||
}
|
||||
for data in cloudValue {
|
||||
if !tokens.contains(data) {
|
||||
tokens.insert(data, at: 0)
|
||||
}
|
||||
}
|
||||
if tokens.count > 20 {
|
||||
tokens.removeLast(tokens.count - 20)
|
||||
}
|
||||
|
||||
NSUbiquitousKeyValueStore.default.set(tokens.map { $0.base64EncodedString() }, forKey: "T_SLTokens")
|
||||
NSUbiquitousKeyValueStore.default.synchronize()
|
||||
|
||||
transaction.setStoredLoginTokens(tokens)
|
||||
}).start()
|
||||
default:
|
||||
break
|
||||
}
|
||||
account.shouldBeServiceTaskMaster.set(.single(.never))
|
||||
return accountManager.transaction { transaction -> Void in
|
||||
transaction.updateRecord(id, { _ in
|
||||
|
||||
@ -2,16 +2,20 @@ import Foundation
|
||||
import Postbox
|
||||
import TelegramApi
|
||||
|
||||
|
||||
extension TelegramChatBannedRights {
|
||||
init(apiBannedRights: Api.ChatBannedRights) {
|
||||
switch apiBannedRights {
|
||||
case let .chatBannedRights(flags, untilDate):
|
||||
self.init(flags: TelegramChatBannedRightsFlags(rawValue: flags), untilDate: untilDate)
|
||||
var effectiveFlags = TelegramChatBannedRightsFlags(rawValue: flags)
|
||||
effectiveFlags.remove(.banSendMedia)
|
||||
self.init(flags: effectiveFlags, untilDate: untilDate)
|
||||
}
|
||||
}
|
||||
|
||||
var apiBannedRights: Api.ChatBannedRights {
|
||||
return .chatBannedRights(flags: self.flags.rawValue, untilDate: self.untilDate)
|
||||
var effectiveFlags = self.flags
|
||||
effectiveFlags.remove(.banSendMedia)
|
||||
|
||||
return .chatBannedRights(flags: effectiveFlags.rawValue, untilDate: self.untilDate)
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +71,42 @@ private func ~=<T: RegularExpressionMatchable>(pattern: Regex, matchable: T) ->
|
||||
return matchable.match(pattern)
|
||||
}
|
||||
|
||||
public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, phoneNumber: String, apiId: Int32, apiHash: String, syncContacts: Bool) -> Signal<UnauthorizedAccount, AuthorizationCodeRequestError> {
|
||||
public enum SendAuthorizationCodeResult {
|
||||
case sentCode(UnauthorizedAccount)
|
||||
case loggedIn
|
||||
}
|
||||
|
||||
func storeFutureLoginToken(accountManager: AccountManager<TelegramAccountManagerTypes>, token: Data) {
|
||||
let _ = (accountManager.transaction { transaction -> Void in
|
||||
var tokens = transaction.getStoredLoginTokens()
|
||||
tokens.insert(token, at: 0)
|
||||
|
||||
var cloudValue: [Data] = []
|
||||
if let list = NSUbiquitousKeyValueStore.default.object(forKey: "T_SLTokens") as? [String] {
|
||||
cloudValue = list.compactMap { string -> Data? in
|
||||
guard let stringData = string.data(using: .utf8) else {
|
||||
return nil
|
||||
}
|
||||
return Data(base64Encoded: stringData)
|
||||
}
|
||||
}
|
||||
for data in cloudValue {
|
||||
if !tokens.contains(data) {
|
||||
tokens.insert(data, at: 0)
|
||||
}
|
||||
}
|
||||
if tokens.count > 20 {
|
||||
tokens.removeLast(tokens.count - 20)
|
||||
}
|
||||
|
||||
NSUbiquitousKeyValueStore.default.set(tokens.map { $0.base64EncodedString() }, forKey: "T_SLTokens")
|
||||
NSUbiquitousKeyValueStore.default.synchronize()
|
||||
|
||||
transaction.setStoredLoginTokens(tokens)
|
||||
}).start()
|
||||
}
|
||||
|
||||
public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, phoneNumber: String, apiId: Int32, apiHash: String, syncContacts: Bool, forcedPasswordSetupNotice: @escaping (Int32) -> (NoticeEntryKey, CodableEntry)?) -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> {
|
||||
var cloudValue: [Data] = []
|
||||
if let list = NSUbiquitousKeyValueStore.default.object(forKey: "T_SLTokens") as? [String] {
|
||||
cloudValue = list.compactMap { string -> Data? in
|
||||
@ -85,7 +120,7 @@ public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccount
|
||||
return transaction.getStoredLoginTokens()
|
||||
}
|
||||
|> castError(AuthorizationCodeRequestError.self)
|
||||
|> mapToSignal { localAuthTokens -> Signal<UnauthorizedAccount, AuthorizationCodeRequestError> in
|
||||
|> mapToSignal { localAuthTokens -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> in
|
||||
var authTokens = localAuthTokens
|
||||
for data in cloudValue {
|
||||
if !authTokens.contains(data) {
|
||||
@ -168,11 +203,12 @@ public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccount
|
||||
|> timeout(20.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.timeout))
|
||||
|
||||
return codeAndAccount
|
||||
|> mapToSignal { result, account -> Signal<UnauthorizedAccount, AuthorizationCodeRequestError> in
|
||||
return account.postbox.transaction { transaction -> UnauthorizedAccount in
|
||||
|> mapToSignal { result, account -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> in
|
||||
return account.postbox.transaction { transaction -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> in
|
||||
switch result {
|
||||
case let .password(hint):
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: hint ?? "", number: nil, code: nil, suggestReset: false, syncContacts: syncContacts)))
|
||||
return .single(.sentCode(account))
|
||||
case let .sentCode(sentCode):
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
@ -182,12 +218,35 @@ public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccount
|
||||
}
|
||||
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: phoneNumber, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, syncContacts: syncContacts)))
|
||||
case let .sentCodeSuccess(authorization):
|
||||
switch authorization {
|
||||
case let .authorization(_, otherwiseReloginDays, _, futureAuthToken, user):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
||||
transaction.setState(state)
|
||||
if let otherwiseReloginDays = otherwiseReloginDays, let value = forcedPasswordSetupNotice(otherwiseReloginDays) {
|
||||
transaction.setNoticeEntry(key: value.0, value: value.1)
|
||||
}
|
||||
return accountManager.transaction { transaction -> SendAuthorizationCodeResult in
|
||||
switchToAuthorizedAccount(transaction: transaction, account: account)
|
||||
return .loggedIn
|
||||
}
|
||||
|> castError(AuthorizationCodeRequestError.self)
|
||||
case .authorizationSignUpRequired:
|
||||
return .never()
|
||||
}
|
||||
}
|
||||
return .single(.sentCode(account))
|
||||
}
|
||||
return account
|
||||
}
|
||||
|> mapError { _ -> AuthorizationCodeRequestError in
|
||||
}
|
||||
|> switchToLatest
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,17 +274,18 @@ public func resendAuthorizationCode(account: UnauthorizedAccount) -> Signal<Void
|
||||
|> mapToSignal { sentCode -> Signal<Void, AuthorizationCodeRequestError> in
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: number, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, syncContacts: syncContacts)))
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: number, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, syncContacts: syncContacts)))
|
||||
case .sentCodeSuccess:
|
||||
break
|
||||
}
|
||||
} |> mapError { _ -> AuthorizationCodeRequestError in }
|
||||
} |> mapError { _ -> AuthorizationCodeRequestError in }
|
||||
}
|
||||
} else {
|
||||
return .fail(.generic(info: nil))
|
||||
@ -496,6 +556,8 @@ public func verifyLoginEmailSetup(account: UnauthorizedAccount, code: Authorizat
|
||||
}
|
||||
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: phoneNumber, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, syncContacts: syncContacts)))
|
||||
case .sentCodeSuccess:
|
||||
break
|
||||
}
|
||||
case .emailVerified:
|
||||
break
|
||||
@ -594,7 +656,11 @@ public func authorizeWithCode(accountManager: AccountManager<TelegramAccountMana
|
||||
return .single(.loggedIn)
|
||||
case let .authorization(authorization):
|
||||
switch authorization {
|
||||
case let .authorization(_, otherwiseReloginDays, _, user):
|
||||
case let .authorization(_, otherwiseReloginDays, _, futureAuthToken, user):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
||||
@ -654,7 +720,11 @@ public func authorizeWithPassword(accountManager: AccountManager<TelegramAccount
|
||||
|> mapToSignal { result -> Signal<Void, AuthorizationPasswordVerificationError> in
|
||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||
switch result {
|
||||
case let .authorization(_, _, _, user):
|
||||
case let .authorization(_, _, _, futureAuthToken, user):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
/*transaction.updatePeersInternal([user], update: { current, peer -> Peer? in
|
||||
@ -720,7 +790,11 @@ public final class RecoveredAccountData {
|
||||
public func loginWithRecoveredAccountData(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, recoveredAccountData: RecoveredAccountData, syncContacts: Bool) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||
switch recoveredAccountData.authorization {
|
||||
case let .authorization(_, _, _, user):
|
||||
case let .authorization(_, _, _, futureAuthToken, user):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
|
||||
@ -856,7 +930,11 @@ public func signUpWithName(accountManager: AccountManager<TelegramAccountManager
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, SignUpError> in
|
||||
switch result {
|
||||
case let .authorization(_, otherwiseReloginDays, _, user):
|
||||
case let .authorization(_, otherwiseReloginDays, _, futureAuthToken, user):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
let user = TelegramUser(user: user)
|
||||
let appliedState = account.postbox.transaction { transaction -> Void in
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
|
||||
@ -240,12 +240,14 @@ public struct NetworkUsageStats: Equatable {
|
||||
public let audio: NetworkUsageStatsConnectionsEntry
|
||||
public let file: NetworkUsageStatsConnectionsEntry
|
||||
public let call: NetworkUsageStatsConnectionsEntry
|
||||
public let sticker: NetworkUsageStatsConnectionsEntry
|
||||
public let voiceMessage: NetworkUsageStatsConnectionsEntry
|
||||
|
||||
public let resetWifiTimestamp: Int32
|
||||
public let resetCellularTimestamp: Int32
|
||||
|
||||
public static func ==(lhs: NetworkUsageStats, rhs: NetworkUsageStats) -> Bool {
|
||||
return lhs.generic == rhs.generic && lhs.image == rhs.image && lhs.video == rhs.video && lhs.audio == rhs.audio && lhs.file == rhs.file && lhs.call == rhs.call && lhs.resetWifiTimestamp == rhs.resetWifiTimestamp && lhs.resetCellularTimestamp == rhs.resetCellularTimestamp
|
||||
return lhs.generic == rhs.generic && lhs.image == rhs.image && lhs.video == rhs.video && lhs.audio == rhs.audio && lhs.file == rhs.file && lhs.call == rhs.call && lhs.resetWifiTimestamp == rhs.resetWifiTimestamp && lhs.resetCellularTimestamp == rhs.resetCellularTimestamp && lhs.sticker == rhs.sticker && lhs.voiceMessage == rhs.voiceMessage
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,6 +388,20 @@ func networkUsageStats(basePath: String, reset: ResetNetworkUsageStats) -> Signa
|
||||
wifi: NetworkUsageStatsDirectionsEntry(
|
||||
incoming: dict[UsageCalculationTag(connection: .wifi, direction: .incoming, category: .call).key]!,
|
||||
outgoing: dict[UsageCalculationTag(connection: .wifi, direction: .outgoing, category: .call).key]!)),
|
||||
sticker: NetworkUsageStatsConnectionsEntry(
|
||||
cellular: NetworkUsageStatsDirectionsEntry(
|
||||
incoming: 0,
|
||||
outgoing: 0),
|
||||
wifi: NetworkUsageStatsDirectionsEntry(
|
||||
incoming: 0,
|
||||
outgoing: 0)),
|
||||
voiceMessage: NetworkUsageStatsConnectionsEntry(
|
||||
cellular: NetworkUsageStatsDirectionsEntry(
|
||||
incoming: 0,
|
||||
outgoing: 0),
|
||||
wifi: NetworkUsageStatsDirectionsEntry(
|
||||
incoming: 0,
|
||||
outgoing: 0)),
|
||||
resetWifiTimestamp: Int32(dict[UsageCalculationResetKey.wifi.rawValue]!),
|
||||
resetCellularTimestamp: Int32(dict[UsageCalculationResetKey.cellular.rawValue]!)
|
||||
))
|
||||
|
||||
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
||||
|
||||
public class Serialization: NSObject, MTSerialization {
|
||||
public func currentLayer() -> UInt {
|
||||
return 151
|
||||
return 152
|
||||
}
|
||||
|
||||
public func parseMessage(_ data: Data!) -> Any! {
|
||||
|
||||
@ -24,6 +24,12 @@ public struct TelegramChatBannedRightsFlags: OptionSet, Hashable {
|
||||
public static let banAddMembers = TelegramChatBannedRightsFlags(rawValue: 1 << 15)
|
||||
public static let banPinMessages = TelegramChatBannedRightsFlags(rawValue: 1 << 17)
|
||||
public static let banManageTopics = TelegramChatBannedRightsFlags(rawValue: 1 << 18)
|
||||
public static let banSendPhotos = TelegramChatBannedRightsFlags(rawValue: 1 << 19)
|
||||
public static let banSendVideos = TelegramChatBannedRightsFlags(rawValue: 1 << 20)
|
||||
public static let banSendInstantVideos = TelegramChatBannedRightsFlags(rawValue: 1 << 21)
|
||||
public static let banSendMusic = TelegramChatBannedRightsFlags(rawValue: 1 << 22)
|
||||
public static let banSendVoice = TelegramChatBannedRightsFlags(rawValue: 1 << 23)
|
||||
public static let banSendFiles = TelegramChatBannedRightsFlags(rawValue: 1 << 24)
|
||||
}
|
||||
|
||||
public struct TelegramChatBannedRights: PostboxCoding, Equatable {
|
||||
|
||||
@ -51,14 +51,16 @@ func _internal_requestChangeAccountPhoneNumberVerification(account: Account, pho
|
||||
return .generic
|
||||
}
|
||||
}
|
||||
|> map { sentCode -> ChangeAccountPhoneNumberData in
|
||||
|> mapToSignal { sentCode -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> in
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
return ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType)
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
return .single(ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType))
|
||||
case .sentCodeSuccess:
|
||||
return .never()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,15 +78,17 @@ func _internal_requestNextChangeAccountPhoneNumberVerification(account: Account,
|
||||
return .generic
|
||||
}
|
||||
}
|
||||
|> map { sentCode -> ChangeAccountPhoneNumberData in
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
return ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType)
|
||||
|> mapToSignal { sentCode -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> in
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
return .single(ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType))
|
||||
case .sentCodeSuccess:
|
||||
return .never()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +92,11 @@ func _internal_exportAuthTransferToken(accountManager: AccountManager<TelegramAc
|
||||
switch result {
|
||||
case let .loginTokenSuccess(authorization):
|
||||
switch authorization {
|
||||
case let .authorization(_, _, _, user):
|
||||
case let .authorization(_, _, _, futureAuthToken, user):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
return updatedAccount.postbox.transaction { transaction -> Signal<ExportAuthTransferTokenResult, ExportAuthTransferTokenError> in
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: updatedAccount.testingEnvironment, masterDatacenterId: updatedAccount.masterDatacenterId, peerId: user.id, state: nil)
|
||||
@ -116,7 +120,11 @@ func _internal_exportAuthTransferToken(accountManager: AccountManager<TelegramAc
|
||||
}
|
||||
case let .loginTokenSuccess(authorization):
|
||||
switch authorization {
|
||||
case let .authorization(_, _, _, user):
|
||||
case let .authorization(_, _, _, futureAuthToken, user):
|
||||
if let futureAuthToken = futureAuthToken {
|
||||
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
|
||||
}
|
||||
|
||||
return account.postbox.transaction { transaction -> Signal<ExportAuthTransferTokenResult, ExportAuthTransferTokenError> in
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
|
||||
@ -26,14 +26,16 @@ func _internal_requestCancelAccountResetData(network: Network, hash: String) ->
|
||||
return .generic
|
||||
}
|
||||
}
|
||||
|> map { sentCode -> CancelAccountResetData in
|
||||
|> mapToSignal { sentCode -> Signal<CancelAccountResetData, RequestCancelAccountResetDataError> in
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
return CancelAccountResetData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType)
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
return .single(CancelAccountResetData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType))
|
||||
case .sentCodeSuccess:
|
||||
return .never()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,14 +49,16 @@ func _internal_requestNextCancelAccountResetOption(network: Network, phoneNumber
|
||||
return .generic
|
||||
}
|
||||
}
|
||||
|> map { sentCode -> CancelAccountResetData in
|
||||
|> mapToSignal { sentCode -> Signal<CancelAccountResetData, RequestCancelAccountResetDataError> in
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
return CancelAccountResetData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType)
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
var parsedNextType: AuthorizationCodeNextType?
|
||||
if let nextType = nextType {
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
return .single(CancelAccountResetData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType))
|
||||
case .sentCodeSuccess:
|
||||
return .never()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,6 +142,38 @@ private extension StorageUsageStats {
|
||||
}
|
||||
}
|
||||
|
||||
private func statForDirectory(path: String) -> Int64 {
|
||||
var s = darwin_dirstat()
|
||||
var result = dirstat_np(path, 1, &s, MemoryLayout<darwin_dirstat>.size)
|
||||
if result != -1 {
|
||||
return Int64(s.total_size)
|
||||
} else {
|
||||
result = dirstat_np(path, 0, &s, MemoryLayout<darwin_dirstat>.size)
|
||||
if result != -1 {
|
||||
return Int64(s.total_size)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func collectRawStorageUsageReport(containerPath: String) -> String {
|
||||
var log = ""
|
||||
|
||||
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
||||
let documentsSize = statForDirectory(path: documentsPath)
|
||||
log.append("Documents (\(documentsPath)): \(documentsSize)\n")
|
||||
|
||||
let systemCachePath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
|
||||
let systemCacheSize = statForDirectory(path: systemCachePath)
|
||||
log.append("System Cache (\(systemCachePath)): \(systemCacheSize)\n")
|
||||
|
||||
let containerSize = statForDirectory(path: containerPath)
|
||||
log.append("Container (\(containerPath)): \(containerSize)\n")
|
||||
|
||||
return log
|
||||
}
|
||||
|
||||
func _internal_collectStorageUsageStats(account: Account) -> Signal<AllStorageUsageStats, NoError> {
|
||||
/*let additionalStats = Signal<Int64, NoError> { subscriber in
|
||||
DispatchQueue.global().async {
|
||||
|
||||
@ -26,10 +26,12 @@ public func secureIdPreparePhoneVerification(network: Network, value: SecureIdPh
|
||||
}
|
||||
return .generic
|
||||
}
|
||||
|> map { sentCode -> SecureIdPreparePhoneVerificationPayload in
|
||||
|> mapToSignal { sentCode -> Signal<SecureIdPreparePhoneVerificationPayload, SecureIdPreparePhoneVerificationError> in
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
return SecureIdPreparePhoneVerificationPayload(type: SentAuthorizationCodeType(apiType: type), nextType: nextType.flatMap(AuthorizationCodeNextType.init), timeout: timeout, phone: value.phone, phoneCodeHash: phoneCodeHash)
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
return .single(SecureIdPreparePhoneVerificationPayload(type: SentAuthorizationCodeType(apiType: type), nextType: nextType.flatMap(AuthorizationCodeNextType.init), timeout: timeout, phone: value.phone, phoneCodeHash: phoneCodeHash))
|
||||
case .sentCodeSuccess:
|
||||
return .never()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ public final class ChatControllerInteraction {
|
||||
public let sendCurrentMessage: (Bool) -> Void
|
||||
public let sendMessage: (String) -> Void
|
||||
public let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool
|
||||
public let sendEmoji: (String, ChatTextInputTextCustomEmojiAttribute) -> Void
|
||||
public let sendEmoji: (String, ChatTextInputTextCustomEmojiAttribute, Bool) -> Void
|
||||
public let sendGif: (FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool
|
||||
public let sendBotContextResultAsGif: (ChatContextResultCollection, ChatContextResult, UIView, CGRect, Bool) -> Bool
|
||||
public let requestMessageActionCallback: (MessageId, MemoryBuffer?, Bool, Bool) -> Void
|
||||
@ -210,7 +210,7 @@ public final class ChatControllerInteraction {
|
||||
sendCurrentMessage: @escaping (Bool) -> Void,
|
||||
sendMessage: @escaping (String) -> Void,
|
||||
sendSticker: @escaping (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool,
|
||||
sendEmoji: @escaping (String, ChatTextInputTextCustomEmojiAttribute) -> Void,
|
||||
sendEmoji: @escaping (String, ChatTextInputTextCustomEmojiAttribute, Bool) -> Void,
|
||||
sendGif: @escaping (FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool,
|
||||
sendBotContextResultAsGif: @escaping (ChatContextResultCollection, ChatContextResult, UIView, CGRect, Bool) -> Bool,
|
||||
requestMessageActionCallback: @escaping (MessageId, MemoryBuffer?, Bool, Bool) -> Void,
|
||||
|
||||
@ -29,6 +29,7 @@ import TelegramUIPreferences
|
||||
import MultiplexedVideoNode
|
||||
import ChatControllerInteraction
|
||||
import FeaturedStickersScreen
|
||||
import Pasteboard
|
||||
|
||||
public struct ChatMediaInputPaneScrollState {
|
||||
let absoluteOffset: CGFloat?
|
||||
@ -533,6 +534,87 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
|
||||
self.externalTopPanelContainerImpl = PagerExternalTopPanelContainer()
|
||||
|
||||
var stickerPeekBehavior: EmojiContentPeekBehaviorImpl?
|
||||
if let controllerInteraction = controllerInteraction {
|
||||
let context = self.context
|
||||
|
||||
stickerPeekBehavior = EmojiContentPeekBehaviorImpl(
|
||||
context: self.context,
|
||||
interaction: EmojiContentPeekBehaviorImpl.Interaction(
|
||||
sendSticker: controllerInteraction.sendSticker,
|
||||
sendEmoji: { file in
|
||||
var text = "."
|
||||
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
|
||||
loop: for attribute in file.attributes {
|
||||
switch attribute {
|
||||
case let .CustomEmoji(_, _, displayText, stickerPackReference):
|
||||
text = displayText
|
||||
|
||||
var packId: ItemCollectionId?
|
||||
if case let .id(id, _) = stickerPackReference {
|
||||
packId = ItemCollectionId(namespace: Namespaces.ItemCollection.CloudEmojiPacks, id: id)
|
||||
}
|
||||
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: packId, fileId: file.fileId.id, file: file)
|
||||
break loop
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if let emojiAttribute {
|
||||
controllerInteraction.sendEmoji(text, emojiAttribute, true)
|
||||
}
|
||||
},
|
||||
setStatus: { [weak self] file in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.context.engine.accountData.setEmojiStatus(file: file, expirationDate: nil).start()
|
||||
|
||||
var animateInAsReplacement = false
|
||||
if let currentUndoOverlayController = strongSelf.currentUndoOverlayController {
|
||||
currentUndoOverlayController.dismissWithCommitActionAndReplacementAnimation()
|
||||
strongSelf.currentUndoOverlayController = nil
|
||||
animateInAsReplacement = true
|
||||
}
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
//TODO:localize
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: "Your emoji status has been updated.", undoText: nil, customAction: nil), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return false })
|
||||
strongSelf.currentUndoOverlayController = controller
|
||||
controllerInteraction.presentController(controller, nil)
|
||||
},
|
||||
copyEmoji: { file in
|
||||
var text = "."
|
||||
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
|
||||
loop: for attribute in file.attributes {
|
||||
switch attribute {
|
||||
case let .CustomEmoji(_, _, displayText, _):
|
||||
text = displayText
|
||||
|
||||
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file)
|
||||
break loop
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if let _ = emojiAttribute {
|
||||
storeMessageTextInPasteboard(text, entities: [MessageTextEntity(range: 0 ..< (text as NSString).length, type: .CustomEmoji(stickerPack: nil, fileId: file.fileId.id))])
|
||||
}
|
||||
},
|
||||
presentController: controllerInteraction.presentController,
|
||||
presentGlobalOverlayController: controllerInteraction.presentGlobalOverlayController,
|
||||
navigationController: controllerInteraction.navigationController
|
||||
),
|
||||
chatPeerId: chatPeerId,
|
||||
present: { c, a in
|
||||
controllerInteraction.presentGlobalOverlayController(c, a)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var premiumToastCounter = 0
|
||||
self.emojiInputInteraction = EmojiPagerContentComponent.InputInteraction(
|
||||
performItemAction: { [weak self, weak interfaceInteraction, weak controllerInteraction] groupId, item, _, _, _, _ in
|
||||
@ -879,7 +961,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
updateScrollingToItemGroup: {
|
||||
},
|
||||
chatPeerId: chatPeerId,
|
||||
peekBehavior: nil,
|
||||
peekBehavior: stickerPeekBehavior,
|
||||
customLayout: nil,
|
||||
externalBackground: nil,
|
||||
externalExpansionView: nil,
|
||||
@ -887,17 +969,6 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
hideBackground: false
|
||||
)
|
||||
|
||||
var stickerPeekBehavior: EmojiContentPeekBehaviorImpl?
|
||||
if let controllerInteraction = controllerInteraction {
|
||||
stickerPeekBehavior = EmojiContentPeekBehaviorImpl(
|
||||
context: self.context,
|
||||
interaction: EmojiContentPeekBehaviorImpl.Interaction(sendSticker: controllerInteraction.sendSticker, presentController: controllerInteraction.presentController, presentGlobalOverlayController: controllerInteraction.presentGlobalOverlayController, navigationController: controllerInteraction.navigationController),
|
||||
chatPeerId: chatPeerId,
|
||||
present: { c, a in
|
||||
controllerInteraction.presentGlobalOverlayController(c, a)
|
||||
}
|
||||
)
|
||||
}
|
||||
self.stickerInputInteraction = EmojiPagerContentComponent.InputInteraction(
|
||||
performItemAction: { [weak controllerInteraction, weak interfaceInteraction] groupId, item, view, rect, layer, _ in
|
||||
let _ = (ChatEntityKeyboardInputNode.hasPremium(context: context, chatPeerId: chatPeerId, premiumIfSavedMessages: false) |> take(1) |> deliverOnMainQueue).start(next: { hasPremium in
|
||||
@ -1988,24 +2059,40 @@ public final class EntityInputView: UIInputView, AttachmentTextInputPanelInputVi
|
||||
public final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
|
||||
public class Interaction {
|
||||
public let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool
|
||||
public let sendEmoji: (TelegramMediaFile) -> Void
|
||||
public let setStatus: (TelegramMediaFile) -> Void
|
||||
public let copyEmoji: (TelegramMediaFile) -> Void
|
||||
public let presentController: (ViewController, Any?) -> Void
|
||||
public let presentGlobalOverlayController: (ViewController, Any?) -> Void
|
||||
public let navigationController: () -> NavigationController?
|
||||
|
||||
public init(sendSticker: @escaping (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool, presentController: @escaping (ViewController, Any?) -> Void, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?) {
|
||||
public init(sendSticker: @escaping (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool, sendEmoji: @escaping (TelegramMediaFile) -> Void, setStatus: @escaping (TelegramMediaFile) -> Void, copyEmoji: @escaping (TelegramMediaFile) -> Void, presentController: @escaping (ViewController, Any?) -> Void, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?) {
|
||||
self.sendSticker = sendSticker
|
||||
self.sendEmoji = sendEmoji
|
||||
self.setStatus = setStatus
|
||||
self.copyEmoji = copyEmoji
|
||||
self.presentController = presentController
|
||||
self.presentGlobalOverlayController = presentGlobalOverlayController
|
||||
self.navigationController = navigationController
|
||||
}
|
||||
}
|
||||
|
||||
private final class ViewRecord {
|
||||
weak var view: UIView?
|
||||
let peekRecognizer: PeekControllerGestureRecognizer
|
||||
|
||||
init(view: UIView, peekRecognizer: PeekControllerGestureRecognizer) {
|
||||
self.view = view
|
||||
self.peekRecognizer = peekRecognizer
|
||||
}
|
||||
}
|
||||
|
||||
private let context: AccountContext
|
||||
private let interaction: Interaction?
|
||||
private let chatPeerId: EnginePeer.Id?
|
||||
private let present: (ViewController, Any?) -> Void
|
||||
|
||||
private var peekRecognizer: PeekControllerGestureRecognizer?
|
||||
private var viewRecords: [ViewRecord] = []
|
||||
private weak var peekController: PeekController?
|
||||
|
||||
public init(context: AccountContext, interaction: Interaction?, chatPeerId: EnginePeer.Id?, present: @escaping (ViewController, Any?) -> Void) {
|
||||
@ -2016,7 +2103,13 @@ public final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
|
||||
}
|
||||
|
||||
public func setGestureRecognizerEnabled(view: UIView, isEnabled: Bool, itemAtPoint: @escaping (CGPoint) -> (AnyHashable, EmojiPagerContentComponent.View.ItemLayer, TelegramMediaFile)?) {
|
||||
if self.peekRecognizer == nil {
|
||||
self.viewRecords = self.viewRecords.filter({ $0.view != nil })
|
||||
|
||||
let viewRecord = self.viewRecords.first(where: { $0.view === view })
|
||||
|
||||
if let viewRecord = viewRecord {
|
||||
viewRecord.peekRecognizer.isEnabled = isEnabled
|
||||
} else {
|
||||
let peekRecognizer = PeekControllerGestureRecognizer(contentAtPoint: { [weak self, weak view] point in
|
||||
guard let strongSelf = self else {
|
||||
return nil
|
||||
@ -2032,133 +2125,242 @@ public final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
|
||||
|
||||
let context = strongSelf.context
|
||||
let accountPeerId = context.account.peerId
|
||||
return combineLatest(
|
||||
context.engine.stickers.isStickerSaved(id: file.fileId),
|
||||
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: accountPeerId)) |> map { peer -> Bool in
|
||||
let chatPeerId = strongSelf.chatPeerId
|
||||
|
||||
if file.isCustomEmoji {
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: accountPeerId)) |> map { peer -> Bool in
|
||||
var hasPremium = false
|
||||
if case let .user(user) = peer, user.isPremium {
|
||||
hasPremium = true
|
||||
}
|
||||
return hasPremium
|
||||
}
|
||||
)
|
||||
|> deliverOnMainQueue
|
||||
|> map { [weak itemLayer] isStarred, hasPremium -> (UIView, CGRect, PeekControllerContent)? in
|
||||
guard let strongSelf = self, let itemLayer = itemLayer else {
|
||||
return nil
|
||||
}
|
||||
var menuItems: [ContextMenuItem] = []
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let isLocked = file.isPremiumSticker && !hasPremium
|
||||
|
||||
if let interaction = strongSelf.interaction {
|
||||
let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?) -> Void = { fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer in
|
||||
let _ = interaction.sendSticker(fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets)
|
||||
|> deliverOnMainQueue
|
||||
|> map { [weak itemLayer] hasPremium -> (UIView, CGRect, PeekControllerContent)? in
|
||||
guard let strongSelf = self, let itemLayer = itemLayer else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let chatPeerId = strongSelf.chatPeerId, !isLocked {
|
||||
if chatPeerId != strongSelf.context.account.peerId && chatPeerId.namespace != Namespaces.Peer.SecretChat {
|
||||
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_SendMessage_SendSilently, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/SilentIcon"), color: theme.actionSheet.primaryTextColor)
|
||||
|
||||
var menuItems: [ContextMenuItem] = []
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
var isLocked = false
|
||||
if !hasPremium {
|
||||
isLocked = file.isPremiumEmoji
|
||||
if isLocked && chatPeerId == context.account.peerId {
|
||||
isLocked = false
|
||||
}
|
||||
}
|
||||
|
||||
if let interaction = strongSelf.interaction {
|
||||
let sendEmoji: (TelegramMediaFile) -> Void = { file in
|
||||
interaction.sendEmoji(file)
|
||||
}
|
||||
let setStatus: (TelegramMediaFile) -> Void = { file in
|
||||
interaction.setStatus(file)
|
||||
}
|
||||
let copyEmoji: (TelegramMediaFile) -> Void = { file in
|
||||
interaction.copyEmoji(file)
|
||||
}
|
||||
|
||||
if let _ = strongSelf.chatPeerId, !isLocked {
|
||||
//TODO:localize
|
||||
menuItems.append(.action(ContextMenuActionItem(text: "Send Emoji", icon: { theme in
|
||||
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) {
|
||||
return generateImage(image.size, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
if let cgImage = image.cgImage {
|
||||
context.draw(cgImage, in: CGRect(origin: CGPoint(), size: size))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}, action: { _, f in
|
||||
sendEmoji(file)
|
||||
f(.default)
|
||||
})))
|
||||
|
||||
//TODO:localize
|
||||
menuItems.append(.action(ContextMenuActionItem(text: "Set as Status", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Smile"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
if hasPremium {
|
||||
setStatus(file)
|
||||
} else {
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
let controller = PremiumDemoScreen(context: context, subject: .animatedEmoji, action: {
|
||||
let controller = PremiumIntroScreen(context: context, source: .animatedEmoji)
|
||||
replaceImpl?(controller)
|
||||
})
|
||||
replaceImpl = { [weak controller] c in
|
||||
controller?.replace(with: c)
|
||||
}
|
||||
strongSelf.interaction?.navigationController()?.pushViewController(controller)
|
||||
}
|
||||
})))
|
||||
|
||||
//TODO:localize
|
||||
menuItems.append(.action(ContextMenuActionItem(text: "Copy Emoji", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
copyEmoji(file)
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
if menuItems.isEmpty {
|
||||
return nil
|
||||
}
|
||||
guard let view = view else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return (view, itemLayer.convert(itemLayer.bounds, to: view.layer), StickerPreviewPeekContent(account: context.account, theme: presentationData.theme, strings: presentationData.strings, item: .pack(file), isLocked: isLocked, menu: menuItems, openPremiumIntro: {
|
||||
guard let strongSelf = self, let interaction = strongSelf.interaction else {
|
||||
return
|
||||
}
|
||||
let controller = PremiumIntroScreen(context: context, source: .stickers)
|
||||
interaction.navigationController()?.pushViewController(controller)
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
return combineLatest(
|
||||
context.engine.stickers.isStickerSaved(id: file.fileId),
|
||||
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: accountPeerId)) |> map { peer -> Bool in
|
||||
var hasPremium = false
|
||||
if case let .user(user) = peer, user.isPremium {
|
||||
hasPremium = true
|
||||
}
|
||||
return hasPremium
|
||||
}
|
||||
)
|
||||
|> deliverOnMainQueue
|
||||
|> map { [weak itemLayer] isStarred, hasPremium -> (UIView, CGRect, PeekControllerContent)? in
|
||||
guard let strongSelf = self, let itemLayer = itemLayer else {
|
||||
return nil
|
||||
}
|
||||
var menuItems: [ContextMenuItem] = []
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let isLocked = file.isPremiumSticker && !hasPremium
|
||||
|
||||
if let interaction = strongSelf.interaction {
|
||||
let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?) -> Void = { fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer in
|
||||
let _ = interaction.sendSticker(fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets)
|
||||
}
|
||||
|
||||
if let chatPeerId = strongSelf.chatPeerId, !isLocked {
|
||||
if chatPeerId != strongSelf.context.account.peerId && chatPeerId.namespace != Namespaces.Peer.SecretChat {
|
||||
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_SendMessage_SendSilently, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/SilentIcon"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
if let strongSelf = self, let peekController = strongSelf.peekController {
|
||||
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
|
||||
sendSticker(.standalone(media: file), true, false, nil, false, animationNode.view, animationNode.bounds, nil)
|
||||
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
|
||||
sendSticker(.standalone(media: file), true, false, nil, false, imageNode.view, imageNode.bounds, nil)
|
||||
}
|
||||
}
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
|
||||
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_SendMessage_ScheduleMessage, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/ScheduleIcon"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
if let strongSelf = self, let peekController = strongSelf.peekController {
|
||||
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
|
||||
sendSticker(.standalone(media: file), true, false, nil, false, animationNode.view, animationNode.bounds, nil)
|
||||
let _ = sendSticker(.standalone(media: file), false, true, nil, false, animationNode.view, animationNode.bounds, nil)
|
||||
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
|
||||
sendSticker(.standalone(media: file), true, false, nil, false, imageNode.view, imageNode.bounds, nil)
|
||||
let _ = sendSticker(.standalone(media: file), false, true, nil, false, imageNode.view, imageNode.bounds, nil)
|
||||
}
|
||||
}
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
|
||||
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_SendMessage_ScheduleMessage, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/ScheduleIcon"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
if let strongSelf = self, let peekController = strongSelf.peekController {
|
||||
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
|
||||
let _ = sendSticker(.standalone(media: file), false, true, nil, false, animationNode.view, animationNode.bounds, nil)
|
||||
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
|
||||
let _ = sendSticker(.standalone(media: file), false, true, nil, false, imageNode.view, imageNode.bounds, nil)
|
||||
}
|
||||
}
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
|
||||
menuItems.append(
|
||||
.action(ContextMenuActionItem(text: isStarred ? presentationData.strings.Stickers_RemoveFromFavorites : presentationData.strings.Stickers_AddToFavorites, icon: { theme in generateTintedImage(image: isStarred ? UIImage(bundleImageName: "Chat/Context Menu/Unfave") : UIImage(bundleImageName: "Chat/Context Menu/Fave"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (context.engine.stickers.toggleStickerSaved(file: file, saved: !isStarred)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
switch result {
|
||||
case .generic:
|
||||
interaction.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: !isStarred ? presentationData.strings.Conversation_StickerAddedToFavorites : presentationData.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), nil)
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let text: String
|
||||
if limit == premiumLimit || premiumConfiguration.isPremiumDisabled {
|
||||
text = presentationData.strings.Premium_MaxFavedStickersFinalText
|
||||
} else {
|
||||
text = presentationData.strings.Premium_MaxFavedStickersText("\(premiumLimit)").string
|
||||
}
|
||||
interaction.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: presentationData.strings.Premium_MaxFavedStickersTitle("\(limit)").string, text: text, undoText: nil, customAction: nil), elevatedLayout: false, action: { action in
|
||||
if case .info = action {
|
||||
let controller = PremiumIntroScreen(context: context, source: .savedStickers)
|
||||
interaction.navigationController()?.pushViewController(controller)
|
||||
return true
|
||||
menuItems.append(
|
||||
.action(ContextMenuActionItem(text: isStarred ? presentationData.strings.Stickers_RemoveFromFavorites : presentationData.strings.Stickers_AddToFavorites, icon: { theme in generateTintedImage(image: isStarred ? UIImage(bundleImageName: "Chat/Context Menu/Unfave") : UIImage(bundleImageName: "Chat/Context Menu/Fave"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (context.engine.stickers.toggleStickerSaved(file: file, saved: !isStarred)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
switch result {
|
||||
case .generic:
|
||||
interaction.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: nil, text: !isStarred ? presentationData.strings.Conversation_StickerAddedToFavorites : presentationData.strings.Conversation_StickerRemovedFromFavorites, undoText: nil, customAction: nil), elevatedLayout: false, action: { _ in return false }), nil)
|
||||
case let .limitExceeded(limit, premiumLimit):
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
|
||||
let text: String
|
||||
if limit == premiumLimit || premiumConfiguration.isPremiumDisabled {
|
||||
text = presentationData.strings.Premium_MaxFavedStickersFinalText
|
||||
} else {
|
||||
text = presentationData.strings.Premium_MaxFavedStickersText("\(premiumLimit)").string
|
||||
}
|
||||
return false
|
||||
}), nil)
|
||||
interaction.presentGlobalOverlayController(UndoOverlayController(presentationData: presentationData, content: .sticker(context: context, file: file, title: presentationData.strings.Premium_MaxFavedStickersTitle("\(limit)").string, text: text, undoText: nil, customAction: nil), elevatedLayout: false, action: { action in
|
||||
if case .info = action {
|
||||
let controller = PremiumIntroScreen(context: context, source: .savedStickers)
|
||||
interaction.navigationController()?.pushViewController(controller)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}), nil)
|
||||
}
|
||||
})
|
||||
}))
|
||||
)
|
||||
menuItems.append(
|
||||
.action(ContextMenuActionItem(text: presentationData.strings.StickerPack_ViewPack, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Sticker"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
})
|
||||
}))
|
||||
)
|
||||
menuItems.append(
|
||||
.action(ContextMenuActionItem(text: presentationData.strings.StickerPack_ViewPack, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Sticker"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
loop: for attribute in file.attributes {
|
||||
switch attribute {
|
||||
case let .CustomEmoji(_, _, _, packReference), let .Sticker(_, packReference, _):
|
||||
if let packReference = packReference {
|
||||
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(context: context, updatedPresentationData: nil, mainStickerPack: packReference, stickerPacks: [packReference], loadedStickerPacks: [], parentNavigationController: interaction.navigationController(), sendSticker: { file, sourceView, sourceRect in
|
||||
sendSticker(file, false, false, nil, false, sourceView, sourceRect, nil)
|
||||
return true
|
||||
})
|
||||
|
||||
interaction.navigationController()?.view.window?.endEditing(true)
|
||||
interaction.presentController(controller, nil)
|
||||
|
||||
loop: for attribute in file.attributes {
|
||||
switch attribute {
|
||||
case let .CustomEmoji(_, _, _, packReference), let .Sticker(_, packReference, _):
|
||||
if let packReference = packReference {
|
||||
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(context: context, updatedPresentationData: nil, mainStickerPack: packReference, stickerPacks: [packReference], loadedStickerPacks: [], parentNavigationController: interaction.navigationController(), sendSticker: { file, sourceView, sourceRect in
|
||||
sendSticker(file, false, false, nil, false, sourceView, sourceRect, nil)
|
||||
return true
|
||||
})
|
||||
|
||||
interaction.navigationController()?.view.window?.endEditing(true)
|
||||
interaction.presentController(controller, nil)
|
||||
}
|
||||
break loop
|
||||
default:
|
||||
break
|
||||
}
|
||||
break loop
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
guard let view = view else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return (view, itemLayer.convert(itemLayer.bounds, to: view.layer), StickerPreviewPeekContent(account: context.account, theme: presentationData.theme, strings: presentationData.strings, item: .pack(file), isLocked: isLocked && !isStarred, menu: menuItems, openPremiumIntro: {
|
||||
guard let strongSelf = self, let interaction = strongSelf.interaction else {
|
||||
return
|
||||
}))
|
||||
)
|
||||
}
|
||||
let controller = PremiumIntroScreen(context: context, source: .stickers)
|
||||
interaction.navigationController()?.pushViewController(controller)
|
||||
}))
|
||||
|
||||
guard let view = view else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return (view, itemLayer.convert(itemLayer.bounds, to: view.layer), StickerPreviewPeekContent(account: context.account, theme: presentationData.theme, strings: presentationData.strings, item: .pack(file), isLocked: isLocked && !isStarred, menu: menuItems, openPremiumIntro: {
|
||||
guard let strongSelf = self, let interaction = strongSelf.interaction else {
|
||||
return
|
||||
}
|
||||
let controller = PremiumIntroScreen(context: context, source: .stickers)
|
||||
interaction.navigationController()?.pushViewController(controller)
|
||||
}))
|
||||
}
|
||||
}
|
||||
}, present: { [weak self] content, sourceView, sourceRect in
|
||||
guard let strongSelf = self else {
|
||||
@ -2184,11 +2386,9 @@ public final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
|
||||
|
||||
let _ = strongSelf
|
||||
})
|
||||
self.peekRecognizer = peekRecognizer
|
||||
self.viewRecords.append(ViewRecord(view: view, peekRecognizer: peekRecognizer))
|
||||
view.addGestureRecognizer(peekRecognizer)
|
||||
peekRecognizer.isEnabled = isEnabled
|
||||
} else {
|
||||
self.peekRecognizer?.isEnabled = isEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -672,6 +672,7 @@ final class EmojiStatusPreviewScreenComponent: Component {
|
||||
}
|
||||
))))
|
||||
}
|
||||
//TODO:localize
|
||||
menuItems.append(AnyComponentWithIdentity(id: "Other", component: AnyComponent(ContextMenuActionItem(
|
||||
title: component.strings.EmojiStatusSetup_TimerOther,
|
||||
action: { [weak self] in
|
||||
|
||||
@ -5766,7 +5766,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
component.inputInteractionHolder.inputInteraction?.peekBehavior?.setGestureRecognizerEnabled(view: self, isEnabled: component.itemLayoutType == .detailed, itemAtPoint: { [weak self] point in
|
||||
component.inputInteractionHolder.inputInteraction?.peekBehavior?.setGestureRecognizerEnabled(view: self, isEnabled: true, itemAtPoint: { [weak self] point in
|
||||
guard let strongSelf = self else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ swift_library(
|
||||
"//submodules/TelegramAnimatedStickerNode",
|
||||
"//submodules/LegacyComponents",
|
||||
"//submodules/GalleryData",
|
||||
"//submodules/SegmentedControlNode",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@ -0,0 +1,140 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import ComponentFlow
|
||||
import SwiftSignalKit
|
||||
import ViewControllerComponent
|
||||
import ComponentDisplayAdapters
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import TelegramCore
|
||||
import MultilineTextComponent
|
||||
import EmojiStatusComponent
|
||||
import Postbox
|
||||
import TelegramStringFormatting
|
||||
import CheckNode
|
||||
|
||||
final class DataButtonComponent: Component {
|
||||
let theme: PresentationTheme
|
||||
let title: String
|
||||
let action: () -> Void
|
||||
|
||||
init(
|
||||
theme: PresentationTheme,
|
||||
title: String,
|
||||
action: @escaping () -> Void
|
||||
) {
|
||||
self.theme = theme
|
||||
self.title = title
|
||||
self.action = action
|
||||
}
|
||||
|
||||
static func ==(lhs: DataButtonComponent, rhs: DataButtonComponent) -> Bool {
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.title != rhs.title {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
class View: HighlightTrackingButton {
|
||||
private let title = ComponentView<Empty>()
|
||||
|
||||
private var component: DataButtonComponent?
|
||||
|
||||
private var highlightBackgroundFrame: CGRect?
|
||||
private var highlightBackgroundLayer: SimpleLayer?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.layer.cornerRadius = 10.0
|
||||
|
||||
self.highligthedChanged = { [weak self] isHighlighted in
|
||||
guard let self, let component = self.component, let highlightBackgroundFrame = self.highlightBackgroundFrame else {
|
||||
return
|
||||
}
|
||||
|
||||
if isHighlighted {
|
||||
self.superview?.bringSubviewToFront(self)
|
||||
|
||||
let highlightBackgroundLayer: SimpleLayer
|
||||
if let current = self.highlightBackgroundLayer {
|
||||
highlightBackgroundLayer = current
|
||||
} else {
|
||||
highlightBackgroundLayer = SimpleLayer()
|
||||
self.highlightBackgroundLayer = highlightBackgroundLayer
|
||||
self.layer.insertSublayer(highlightBackgroundLayer, at: 0)
|
||||
highlightBackgroundLayer.backgroundColor = component.theme.list.itemHighlightedBackgroundColor.cgColor
|
||||
}
|
||||
highlightBackgroundLayer.frame = highlightBackgroundFrame
|
||||
highlightBackgroundLayer.opacity = 1.0
|
||||
} else {
|
||||
if let highlightBackgroundLayer = self.highlightBackgroundLayer {
|
||||
self.highlightBackgroundLayer = nil
|
||||
highlightBackgroundLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { [weak highlightBackgroundLayer] _ in
|
||||
highlightBackgroundLayer?.removeFromSuperlayer()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
self.addTarget(self, action: #selector(self.pressed), for: .touchUpInside)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func pressed() {
|
||||
guard let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.action()
|
||||
}
|
||||
|
||||
func update(component: DataButtonComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
let themeUpdated = self.component?.theme !== component.theme
|
||||
|
||||
self.component = component
|
||||
|
||||
if themeUpdated {
|
||||
self.backgroundColor = component.theme.list.itemBlocksBackgroundColor
|
||||
}
|
||||
|
||||
let titleSize = self.title.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: component.title, font: Font.regular(17.0), textColor: component.theme.list.itemDestructiveColor)))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width, height: 100.0)
|
||||
)
|
||||
|
||||
let height: CGFloat = 44.0
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) / 2.0), y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
titleView.isUserInteractionEnabled = false
|
||||
self.addSubview(titleView)
|
||||
}
|
||||
transition.setFrame(view: titleView, frame: titleFrame)
|
||||
}
|
||||
|
||||
self.highlightBackgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width, height: height))
|
||||
|
||||
return CGSize(width: availableSize.width, height: height)
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,192 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import ComponentFlow
|
||||
import SwiftSignalKit
|
||||
import ViewControllerComponent
|
||||
import ComponentDisplayAdapters
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import TelegramCore
|
||||
import MultilineTextComponent
|
||||
import EmojiStatusComponent
|
||||
import Postbox
|
||||
import CheckNode
|
||||
import SolidRoundedButtonComponent
|
||||
|
||||
final class DataCategoriesComponent: Component {
|
||||
struct CategoryData: Equatable {
|
||||
var key: DataUsageScreenComponent.Category
|
||||
var color: UIColor
|
||||
var title: String
|
||||
var size: Int64
|
||||
var sizeFraction: Double
|
||||
var incoming: Int64
|
||||
var outgoing: Int64
|
||||
var isSeparable: Bool
|
||||
var isExpanded: Bool
|
||||
|
||||
init(key: DataUsageScreenComponent.Category, color: UIColor, title: String, size: Int64, sizeFraction: Double, incoming: Int64, outgoing: Int64, isSeparable: Bool, isExpanded: Bool) {
|
||||
self.key = key
|
||||
self.title = title
|
||||
self.color = color
|
||||
self.size = size
|
||||
self.sizeFraction = sizeFraction
|
||||
self.incoming = incoming
|
||||
self.outgoing = outgoing
|
||||
self.isSeparable = isSeparable
|
||||
self.isExpanded = isExpanded
|
||||
}
|
||||
}
|
||||
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let categories: [CategoryData]
|
||||
let toggleCategoryExpanded: (DataUsageScreenComponent.Category) -> Void
|
||||
|
||||
init(
|
||||
theme: PresentationTheme,
|
||||
strings: PresentationStrings,
|
||||
categories: [CategoryData],
|
||||
toggleCategoryExpanded: @escaping (DataUsageScreenComponent.Category) -> Void
|
||||
) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.categories = categories
|
||||
self.toggleCategoryExpanded = toggleCategoryExpanded
|
||||
}
|
||||
|
||||
static func ==(lhs: DataCategoriesComponent, rhs: DataCategoriesComponent) -> Bool {
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.categories != rhs.categories {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
class View: UIView {
|
||||
private let containerView: UIView
|
||||
private var itemViews: [DataUsageScreenComponent.Category: ComponentView<Empty>] = [:]
|
||||
|
||||
private var component: DataCategoriesComponent?
|
||||
private weak var state: EmptyComponentState?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.containerView = UIView()
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.layer.cornerRadius = 10.0
|
||||
|
||||
self.addSubview(self.containerView)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(component: DataCategoriesComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
var itemsTransition = transition
|
||||
if let animationHint = transition.userData(DataUsageScreenComponent.AnimationHint.self) {
|
||||
switch animationHint.value {
|
||||
case .clearedItems, .modeChanged:
|
||||
if let copyView = self.containerView.snapshotView(afterScreenUpdates: false) {
|
||||
itemsTransition = .immediate
|
||||
|
||||
self.addSubview(copyView)
|
||||
self.containerView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.16)
|
||||
copyView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak copyView] _ in
|
||||
copyView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
|
||||
var validKeys = Set<DataUsageScreenComponent.Category>()
|
||||
for i in 0 ..< component.categories.count {
|
||||
let category = component.categories[i]
|
||||
validKeys.insert(category.key)
|
||||
|
||||
var itemTransition = itemsTransition
|
||||
let itemView: ComponentView<Empty>
|
||||
if let current = self.itemViews[category.key] {
|
||||
itemView = current
|
||||
} else {
|
||||
itemTransition = .immediate
|
||||
itemView = ComponentView()
|
||||
itemView.parentState = state
|
||||
self.itemViews[category.key] = itemView
|
||||
}
|
||||
|
||||
let itemSize = itemView.update(
|
||||
transition: itemTransition,
|
||||
component: AnyComponent(DataCategoryItemComponent(
|
||||
theme: component.theme,
|
||||
strings: component.strings,
|
||||
category: category,
|
||||
isExpanded: category.isExpanded,
|
||||
hasNext: i != component.categories.count - 1,
|
||||
action: { [weak self] key in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.toggleCategoryExpanded(key)
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width, height: 1000.0)
|
||||
)
|
||||
let itemFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: itemSize)
|
||||
if let itemComponentView = itemView.view {
|
||||
if itemComponentView.superview == nil {
|
||||
self.containerView.addSubview(itemComponentView)
|
||||
}
|
||||
itemTransition.setFrame(view: itemComponentView, frame: itemFrame)
|
||||
}
|
||||
|
||||
contentHeight += itemSize.height
|
||||
}
|
||||
|
||||
var removeKeys: [DataUsageScreenComponent.Category] = []
|
||||
for (key, itemView) in self.itemViews {
|
||||
if !validKeys.contains(key) {
|
||||
if let itemComponentView = itemView.view {
|
||||
transition.setAlpha(view: itemComponentView, alpha: 0.0, completion: { [weak itemComponentView] _ in
|
||||
itemComponentView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
removeKeys.append(key)
|
||||
}
|
||||
}
|
||||
for key in removeKeys {
|
||||
self.itemViews.removeValue(forKey: key)
|
||||
}
|
||||
|
||||
self.backgroundColor = component.theme.list.itemBlocksBackgroundColor
|
||||
|
||||
self.containerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width, height: contentHeight))
|
||||
|
||||
return CGSize(width: availableSize.width, height: contentHeight)
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,611 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import ComponentFlow
|
||||
import SwiftSignalKit
|
||||
import ViewControllerComponent
|
||||
import ComponentDisplayAdapters
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import TelegramCore
|
||||
import MultilineTextComponent
|
||||
import EmojiStatusComponent
|
||||
import Postbox
|
||||
import TelegramStringFormatting
|
||||
import CheckNode
|
||||
|
||||
private final class SubItemComponent: Component {
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let isIncoming: Bool
|
||||
let value: Int64
|
||||
let hasNext: Bool
|
||||
|
||||
init(
|
||||
theme: PresentationTheme,
|
||||
strings: PresentationStrings,
|
||||
isIncoming: Bool,
|
||||
value: Int64,
|
||||
hasNext: Bool
|
||||
) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.isIncoming = isIncoming
|
||||
self.value = value
|
||||
self.hasNext = hasNext
|
||||
}
|
||||
|
||||
static func ==(lhs: SubItemComponent, rhs: SubItemComponent) -> Bool {
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.isIncoming != rhs.isIncoming {
|
||||
return false
|
||||
}
|
||||
if lhs.value != rhs.value {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
class View: HighlightTrackingButton {
|
||||
private let iconView: UIImageView
|
||||
private let title = ComponentView<Empty>()
|
||||
private let titleValue = ComponentView<Empty>()
|
||||
private let label = ComponentView<Empty>()
|
||||
private let separatorLayer: SimpleLayer
|
||||
|
||||
private var component: SubItemComponent?
|
||||
|
||||
private var highlightBackgroundFrame: CGRect?
|
||||
private var highlightBackgroundLayer: SimpleLayer?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.iconView = UIImageView()
|
||||
self.separatorLayer = SimpleLayer()
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.layer.addSublayer(self.separatorLayer)
|
||||
|
||||
self.addSubview(self.iconView)
|
||||
|
||||
self.highligthedChanged = { [weak self] isHighlighted in
|
||||
guard let self, let component = self.component, let highlightBackgroundFrame = self.highlightBackgroundFrame else {
|
||||
return
|
||||
}
|
||||
|
||||
if isHighlighted {
|
||||
self.superview?.bringSubviewToFront(self)
|
||||
|
||||
let highlightBackgroundLayer: SimpleLayer
|
||||
if let current = self.highlightBackgroundLayer {
|
||||
highlightBackgroundLayer = current
|
||||
} else {
|
||||
highlightBackgroundLayer = SimpleLayer()
|
||||
self.highlightBackgroundLayer = highlightBackgroundLayer
|
||||
self.layer.insertSublayer(highlightBackgroundLayer, above: self.separatorLayer)
|
||||
highlightBackgroundLayer.backgroundColor = component.theme.list.itemHighlightedBackgroundColor.cgColor
|
||||
}
|
||||
highlightBackgroundLayer.frame = highlightBackgroundFrame
|
||||
highlightBackgroundLayer.opacity = 1.0
|
||||
} else {
|
||||
if let highlightBackgroundLayer = self.highlightBackgroundLayer {
|
||||
self.highlightBackgroundLayer = nil
|
||||
highlightBackgroundLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { [weak highlightBackgroundLayer] _ in
|
||||
highlightBackgroundLayer?.removeFromSuperlayer()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
self.addTarget(self, action: #selector(self.pressed), for: .touchUpInside)
|
||||
self.isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func pressed() {
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
guard let result = super.hitTest(point, with: event) else {
|
||||
return nil
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func update(component: SubItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
let themeUpdated = self.component?.theme !== component.theme || self.component?.isIncoming != component.isIncoming
|
||||
|
||||
self.component = component
|
||||
|
||||
if themeUpdated {
|
||||
self.iconView.image = generateTintedImage(image: UIImage(bundleImageName: component.isIncoming ? "Settings/Menu/DataExpandedIn" : "Settings/Menu/DataExpandedOut"), color: component.theme.list.itemPrimaryTextColor)
|
||||
}
|
||||
|
||||
var leftInset: CGFloat = 62.0
|
||||
var additionalLeftInset: CGFloat = 0.0
|
||||
|
||||
additionalLeftInset += 45.0
|
||||
leftInset += additionalLeftInset
|
||||
|
||||
let rightInset: CGFloat = 16.0
|
||||
|
||||
var availableWidth: CGFloat = availableSize.width - leftInset - rightInset
|
||||
|
||||
let fractionString: String = ""
|
||||
/*if component.category.sizeFraction != 0.0 {
|
||||
let fractionValue: Double = floor(component.category.sizeFraction * 100.0 * 10.0) / 10.0
|
||||
if fractionValue < 0.1 {
|
||||
fractionString = "<0.1%"
|
||||
} else if abs(Double(Int(fractionValue)) - fractionValue) < 0.001 {
|
||||
fractionString = "\(Int(fractionValue))%"
|
||||
} else {
|
||||
fractionString = "\(fractionValue)%"
|
||||
}
|
||||
} else {
|
||||
fractionString = ""
|
||||
}*/
|
||||
|
||||
let labelSize = self.label.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: dataSizeString(Int(component.value), formatting: DataSizeStringFormatting(strings: component.strings, decimalSeparator: ".")), font: Font.regular(17.0), textColor: component.theme.list.itemSecondaryTextColor)))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
availableWidth = max(1.0, availableWidth - labelSize.width - 1.0)
|
||||
|
||||
let titleValueSize = self.titleValue.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: fractionString, font: Font.regular(17.0), textColor: component.theme.list.itemSecondaryTextColor)))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
availableWidth = max(1.0, availableWidth - titleValueSize.width - 4.0)
|
||||
|
||||
//TODO:localize
|
||||
let titleSize = self.title.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: component.isIncoming ? "Incoming" : "Outgoing", font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor)))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
|
||||
let height: CGFloat = 44.0
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: leftInset, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
let titleValueFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: floor((height - titleValueSize.height) / 2.0)), size: titleValueSize)
|
||||
|
||||
let labelFrame = CGRect(origin: CGPoint(x: availableSize.width - rightInset - labelSize.width, y: floor((height - labelSize.height) / 2.0)), size: labelSize)
|
||||
|
||||
if let image = self.iconView.image {
|
||||
transition.setFrame(view: self.iconView, frame: CGRect(origin: CGPoint(x: leftInset - additionalLeftInset + floor((additionalLeftInset - image.size.width) * 0.5), y: floor((height - image.size.height) * 0.5)), size: image.size))
|
||||
}
|
||||
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
titleView.isUserInteractionEnabled = false
|
||||
self.addSubview(titleView)
|
||||
}
|
||||
transition.setFrame(view: titleView, frame: titleFrame)
|
||||
}
|
||||
if let titleValueView = self.titleValue.view {
|
||||
if titleValueView.superview == nil {
|
||||
titleValueView.isUserInteractionEnabled = false
|
||||
self.addSubview(titleValueView)
|
||||
}
|
||||
|
||||
if titleValueView.bounds.size != titleValueFrame.size {
|
||||
titleValueView.frame = titleValueFrame
|
||||
} else {
|
||||
transition.setFrame(view: titleValueView, frame: titleValueFrame)
|
||||
}
|
||||
}
|
||||
if let labelView = self.label.view {
|
||||
if labelView.superview == nil {
|
||||
labelView.isUserInteractionEnabled = false
|
||||
self.addSubview(labelView)
|
||||
}
|
||||
transition.setFrame(view: labelView, frame: labelFrame)
|
||||
}
|
||||
|
||||
if themeUpdated {
|
||||
self.separatorLayer.backgroundColor = component.theme.list.itemBlocksSeparatorColor.cgColor
|
||||
}
|
||||
transition.setFrame(layer: self.separatorLayer, frame: CGRect(origin: CGPoint(x: leftInset, y: height), size: CGSize(width: availableSize.width - leftInset, height: UIScreenPixel)))
|
||||
|
||||
transition.setAlpha(layer: self.separatorLayer, alpha: (component.hasNext) ? 1.0 : 0.0)
|
||||
|
||||
self.highlightBackgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width, height: height + ((component.hasNext) ? UIScreenPixel : 0.0)))
|
||||
|
||||
return CGSize(width: availableSize.width, height: height)
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
final class DataCategoryItemComponent: Component {
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let category: DataCategoriesComponent.CategoryData
|
||||
let isExpanded: Bool
|
||||
let hasNext: Bool
|
||||
let action: (DataUsageScreenComponent.Category) -> Void
|
||||
|
||||
init(
|
||||
theme: PresentationTheme,
|
||||
strings: PresentationStrings,
|
||||
category: DataCategoriesComponent.CategoryData,
|
||||
isExpanded: Bool,
|
||||
hasNext: Bool,
|
||||
action: @escaping (DataUsageScreenComponent.Category) -> Void
|
||||
) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.category = category
|
||||
self.isExpanded = isExpanded
|
||||
self.hasNext = hasNext
|
||||
self.action = action
|
||||
}
|
||||
|
||||
static func ==(lhs: DataCategoryItemComponent, rhs: DataCategoryItemComponent) -> Bool {
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.category != rhs.category {
|
||||
return false
|
||||
}
|
||||
if lhs.isExpanded != rhs.isExpanded {
|
||||
return false
|
||||
}
|
||||
if lhs.hasNext != rhs.hasNext {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
class View: HighlightTrackingButton {
|
||||
private let iconView: UIImageView
|
||||
private var expandIconView: UIImageView?
|
||||
private let title = ComponentView<Empty>()
|
||||
private let titleValue = ComponentView<Empty>()
|
||||
private let label = ComponentView<Empty>()
|
||||
private let separatorLayer: SimpleLayer
|
||||
|
||||
private let subcategoryClippingContainer: UIView
|
||||
private var itemViews: [AnyHashable: ComponentView<Empty>] = [:]
|
||||
|
||||
private var component: DataCategoryItemComponent?
|
||||
|
||||
private var highlightBackgroundFrame: CGRect?
|
||||
private var highlightBackgroundLayer: SimpleLayer?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.iconView = UIImageView()
|
||||
self.separatorLayer = SimpleLayer()
|
||||
|
||||
self.subcategoryClippingContainer = UIView()
|
||||
self.subcategoryClippingContainer.clipsToBounds = true
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.subcategoryClippingContainer)
|
||||
|
||||
self.layer.addSublayer(self.separatorLayer)
|
||||
|
||||
self.addSubview(self.iconView)
|
||||
|
||||
self.highligthedChanged = { [weak self] isHighlighted in
|
||||
guard let self, let component = self.component, let highlightBackgroundFrame = self.highlightBackgroundFrame else {
|
||||
return
|
||||
}
|
||||
|
||||
if isHighlighted {
|
||||
self.superview?.bringSubviewToFront(self)
|
||||
|
||||
let highlightBackgroundLayer: SimpleLayer
|
||||
if let current = self.highlightBackgroundLayer {
|
||||
highlightBackgroundLayer = current
|
||||
} else {
|
||||
highlightBackgroundLayer = SimpleLayer()
|
||||
self.highlightBackgroundLayer = highlightBackgroundLayer
|
||||
self.layer.insertSublayer(highlightBackgroundLayer, above: self.separatorLayer)
|
||||
highlightBackgroundLayer.backgroundColor = component.theme.list.itemHighlightedBackgroundColor.cgColor
|
||||
}
|
||||
highlightBackgroundLayer.frame = highlightBackgroundFrame
|
||||
highlightBackgroundLayer.opacity = 1.0
|
||||
} else {
|
||||
if let highlightBackgroundLayer = self.highlightBackgroundLayer {
|
||||
self.highlightBackgroundLayer = nil
|
||||
highlightBackgroundLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { [weak highlightBackgroundLayer] _ in
|
||||
highlightBackgroundLayer?.removeFromSuperlayer()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
self.addTarget(self, action: #selector(self.pressed), for: .touchUpInside)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func pressed() {
|
||||
guard let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.action(component.category.key)
|
||||
}
|
||||
|
||||
@objc private func checkPressed() {
|
||||
guard let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.action(component.category.key)
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
guard let result = super.hitTest(point, with: event) else {
|
||||
return nil
|
||||
}
|
||||
if result === self.subcategoryClippingContainer {
|
||||
return self
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func update(component: DataCategoryItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
let themeUpdated = self.component?.theme !== component.theme || self.component?.category.color != component.category.color
|
||||
|
||||
self.component = component
|
||||
|
||||
|
||||
if themeUpdated {
|
||||
let imageName: String
|
||||
switch component.category.key {
|
||||
case .photos:
|
||||
imageName = "Settings/Menu/DataPhotos"
|
||||
case .videos:
|
||||
imageName = "Settings/Menu/DataVideo"
|
||||
case .files:
|
||||
imageName = "Settings/Menu/DataFiles"
|
||||
case .music:
|
||||
imageName = "Settings/Menu/DataMusic"
|
||||
case .messages:
|
||||
imageName = "Settings/Menu/DataMessages"
|
||||
case .stickers:
|
||||
imageName = "Settings/Menu/DataStickers"
|
||||
case .voiceMessages:
|
||||
imageName = "Settings/Menu/DataVoice"
|
||||
case .calls:
|
||||
imageName = "Settings/Menu/DataCalls"
|
||||
case .totalIn:
|
||||
imageName = "Settings/Menu/DataIn"
|
||||
case .totalOut:
|
||||
imageName = "Settings/Menu/DataOut"
|
||||
}
|
||||
self.iconView.image = UIImage(bundleImageName: imageName)
|
||||
}
|
||||
|
||||
var leftInset: CGFloat = 62.0
|
||||
let additionalLeftInset: CGFloat = 0.0
|
||||
leftInset += additionalLeftInset
|
||||
|
||||
let rightInset: CGFloat = 16.0
|
||||
|
||||
var availableWidth: CGFloat = availableSize.width - leftInset - rightInset
|
||||
|
||||
if component.category.isSeparable {
|
||||
let expandIconView: UIImageView
|
||||
if let current = self.expandIconView {
|
||||
expandIconView = current
|
||||
if themeUpdated {
|
||||
expandIconView.image = PresentationResourcesItemList.disclosureArrowImage(component.theme)
|
||||
}
|
||||
} else {
|
||||
expandIconView = UIImageView()
|
||||
expandIconView.image = PresentationResourcesItemList.disclosureArrowImage(component.theme)
|
||||
self.expandIconView = expandIconView
|
||||
self.addSubview(expandIconView)
|
||||
}
|
||||
|
||||
if let image = expandIconView.image {
|
||||
availableWidth -= image.size.width + 6.0
|
||||
transition.setBounds(view: expandIconView, bounds: CGRect(origin: CGPoint(), size: image.size))
|
||||
}
|
||||
} else if let expandIconView = self.expandIconView {
|
||||
self.expandIconView = nil
|
||||
expandIconView.removeFromSuperview()
|
||||
}
|
||||
|
||||
let fractionString: String
|
||||
if component.category.sizeFraction != 0.0 {
|
||||
let fractionValue: Double = floor(component.category.sizeFraction * 100.0 * 10.0) / 10.0
|
||||
if fractionValue < 0.1 {
|
||||
fractionString = "<0.1%"
|
||||
} else if abs(Double(Int(fractionValue)) - fractionValue) < 0.001 {
|
||||
fractionString = "\(Int(fractionValue))%"
|
||||
} else {
|
||||
fractionString = "\(fractionValue)%"
|
||||
}
|
||||
} else {
|
||||
fractionString = ""
|
||||
}
|
||||
|
||||
let labelSize = self.label.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: dataSizeString(Int(component.category.size), formatting: DataSizeStringFormatting(strings: component.strings, decimalSeparator: ".")), font: Font.regular(17.0), textColor: component.theme.list.itemSecondaryTextColor)))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
availableWidth = max(1.0, availableWidth - labelSize.width - 1.0)
|
||||
|
||||
let titleValueSize = self.titleValue.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: fractionString, font: Font.regular(17.0), textColor: component.theme.list.itemSecondaryTextColor)))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
availableWidth = max(1.0, availableWidth - titleValueSize.width - 4.0)
|
||||
|
||||
let titleSize = self.title.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: component.category.title, font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor)))),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableWidth, height: 100.0)
|
||||
)
|
||||
|
||||
var height: CGFloat = 44.0
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: leftInset, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
let titleValueFrame = CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: floor((height - titleValueSize.height) / 2.0)), size: titleValueSize)
|
||||
|
||||
var labelFrame = CGRect(origin: CGPoint(x: availableSize.width - rightInset - labelSize.width, y: floor((height - labelSize.height) / 2.0)), size: labelSize)
|
||||
|
||||
if let expandIconView = self.expandIconView, let image = expandIconView.image {
|
||||
labelFrame.origin.x -= image.size.width - 6.0
|
||||
|
||||
transition.setPosition(view: expandIconView, position: CGPoint(x: availableSize.width - rightInset + 6.0 - floor(image.size.width * 0.5), y: floor(height * 0.5)))
|
||||
let angle: CGFloat = component.isExpanded ? CGFloat.pi : 0.0
|
||||
transition.setTransform(view: expandIconView, transform: CATransform3DMakeRotation(CGFloat.pi * 0.5 - angle, 0.0, 0.0, 1.0))
|
||||
}
|
||||
|
||||
if let image = self.iconView.image {
|
||||
transition.setFrame(view: self.iconView, frame: CGRect(origin: CGPoint(x: floor((leftInset - image.size.width) * 0.5), y: floor((height - image.size.height) * 0.5)), size: image.size))
|
||||
}
|
||||
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
titleView.isUserInteractionEnabled = false
|
||||
self.addSubview(titleView)
|
||||
}
|
||||
transition.setFrame(view: titleView, frame: titleFrame)
|
||||
}
|
||||
if let titleValueView = self.titleValue.view {
|
||||
if titleValueView.superview == nil {
|
||||
titleValueView.isUserInteractionEnabled = false
|
||||
self.addSubview(titleValueView)
|
||||
}
|
||||
|
||||
if titleValueView.bounds.size != titleValueFrame.size {
|
||||
titleValueView.frame = titleValueFrame
|
||||
} else {
|
||||
transition.setFrame(view: titleValueView, frame: titleValueFrame)
|
||||
}
|
||||
}
|
||||
if let labelView = self.label.view {
|
||||
if labelView.superview == nil {
|
||||
labelView.isUserInteractionEnabled = false
|
||||
self.addSubview(labelView)
|
||||
}
|
||||
transition.setFrame(view: labelView, frame: labelFrame)
|
||||
}
|
||||
|
||||
if themeUpdated {
|
||||
self.separatorLayer.backgroundColor = component.theme.list.itemBlocksSeparatorColor.cgColor
|
||||
}
|
||||
transition.setFrame(layer: self.separatorLayer, frame: CGRect(origin: CGPoint(x: leftInset, y: height), size: CGSize(width: availableSize.width - leftInset, height: UIScreenPixel)))
|
||||
|
||||
transition.setAlpha(layer: self.separatorLayer, alpha: (component.isExpanded || component.hasNext) ? 1.0 : 0.0)
|
||||
|
||||
self.highlightBackgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width, height: height + ((component.isExpanded || component.hasNext) ? UIScreenPixel : 0.0)))
|
||||
|
||||
var validKeys = Set<AnyHashable>()
|
||||
if component.isExpanded, component.category.isSeparable {
|
||||
struct SubItem {
|
||||
var id: AnyHashable
|
||||
var isIncoming: Bool
|
||||
var value: Int64
|
||||
}
|
||||
let items: [SubItem] = [
|
||||
SubItem(id: "in", isIncoming: true, value: component.category.incoming),
|
||||
SubItem(id: "out", isIncoming: false, value: component.category.outgoing)
|
||||
]
|
||||
|
||||
for i in 0 ..< items.count {
|
||||
let item = items[i]
|
||||
validKeys.insert(item.id)
|
||||
|
||||
var itemTransition = transition
|
||||
let itemView: ComponentView<Empty>
|
||||
if let current = self.itemViews[item.id] {
|
||||
itemView = current
|
||||
} else {
|
||||
itemTransition = .immediate
|
||||
itemView = ComponentView()
|
||||
self.itemViews[item.id] = itemView
|
||||
}
|
||||
|
||||
itemView.parentState = state
|
||||
let itemSize = itemView.update(
|
||||
transition: itemTransition,
|
||||
component: AnyComponent(SubItemComponent(
|
||||
theme: component.theme,
|
||||
strings: component.strings,
|
||||
isIncoming: item.isIncoming,
|
||||
value: item.value,
|
||||
hasNext: i != items.count - 1
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width, height: 1000.0)
|
||||
)
|
||||
let itemFrame = CGRect(origin: CGPoint(x: 0.0, y: height), size: itemSize)
|
||||
if let itemComponentView = itemView.view {
|
||||
if itemComponentView.superview == nil {
|
||||
self.subcategoryClippingContainer.addSubview(itemComponentView)
|
||||
if !transition.animation.isImmediate {
|
||||
itemComponentView.alpha = 0.0
|
||||
transition.setAlpha(view: itemComponentView, alpha: 1.0)
|
||||
}
|
||||
}
|
||||
itemTransition.setFrame(view: itemComponentView, frame: itemFrame)
|
||||
}
|
||||
|
||||
height += itemSize.height
|
||||
}
|
||||
}
|
||||
var removeKeys: [AnyHashable] = []
|
||||
for (key, itemView) in self.itemViews {
|
||||
if !validKeys.contains(key) {
|
||||
if let itemComponentView = itemView.view {
|
||||
transition.setAlpha(view: itemComponentView, alpha: 0.0, completion: { [weak itemComponentView] _ in
|
||||
itemComponentView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
removeKeys.append(key)
|
||||
}
|
||||
}
|
||||
for key in removeKeys {
|
||||
self.itemViews.removeValue(forKey: key)
|
||||
}
|
||||
|
||||
transition.setFrame(view: self.subcategoryClippingContainer, frame: CGRect(origin: CGPoint(), size: CGSize(width: availableSize.width, height: height)))
|
||||
|
||||
return CGSize(width: availableSize.width, height: height)
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -210,20 +210,24 @@ private final class ChartLabel: UIView {
|
||||
final class PieChartComponent: Component {
|
||||
struct ChartData: Equatable {
|
||||
struct Item: Equatable {
|
||||
var id: StorageUsageScreenComponent.Category
|
||||
var id: AnyHashable
|
||||
var displayValue: Double
|
||||
var displaySize: Int64
|
||||
var value: Double
|
||||
var color: UIColor
|
||||
var particle: String?
|
||||
var title: String
|
||||
var mergeable: Bool
|
||||
var mergeFactor: CGFloat
|
||||
|
||||
init(id: StorageUsageScreenComponent.Category, displayValue: Double, displaySize: Int64, value: Double, color: UIColor, mergeable: Bool, mergeFactor: CGFloat) {
|
||||
init(id: AnyHashable, displayValue: Double, displaySize: Int64, value: Double, color: UIColor, particle: String?, title: String, mergeable: Bool, mergeFactor: CGFloat) {
|
||||
self.id = id
|
||||
self.displayValue = displayValue
|
||||
self.displaySize = displaySize
|
||||
self.value = value
|
||||
self.color = color
|
||||
self.particle = particle
|
||||
self.title = title
|
||||
self.mergeable = mergeable
|
||||
self.mergeFactor = mergeFactor
|
||||
}
|
||||
@ -296,8 +300,10 @@ final class PieChartComponent: Component {
|
||||
}
|
||||
|
||||
private struct CalculatedSection {
|
||||
var id: StorageUsageScreenComponent.Category
|
||||
var id: AnyHashable
|
||||
var color: UIColor
|
||||
var particle: String?
|
||||
var title: String
|
||||
var innerAngle: Range<CGFloat>
|
||||
var outerAngle: Range<CGFloat>
|
||||
var innerRadius: CGFloat
|
||||
@ -305,8 +311,10 @@ final class PieChartComponent: Component {
|
||||
var label: CalculatedLabel?
|
||||
|
||||
init(
|
||||
id: StorageUsageScreenComponent.Category,
|
||||
id: AnyHashable,
|
||||
color: UIColor,
|
||||
particle: String?,
|
||||
title: String,
|
||||
innerAngle: Range<CGFloat>,
|
||||
outerAngle: Range<CGFloat>,
|
||||
innerRadius: CGFloat,
|
||||
@ -315,6 +323,8 @@ final class PieChartComponent: Component {
|
||||
) {
|
||||
self.id = id
|
||||
self.color = color
|
||||
self.particle = particle
|
||||
self.title = title
|
||||
self.innerAngle = innerAngle
|
||||
self.outerAngle = outerAngle
|
||||
self.innerRadius = innerRadius
|
||||
@ -361,6 +371,8 @@ final class PieChartComponent: Component {
|
||||
self.sections.append(CalculatedSection(
|
||||
id: right.id,
|
||||
color: left.color.interpolateTo(right.color, fraction: progress) ?? right.color,
|
||||
particle: right.particle,
|
||||
title: right.title,
|
||||
innerAngle: innerAngle,
|
||||
outerAngle: outerAngle,
|
||||
innerRadius: left.innerRadius.interpolate(to: right.innerRadius, amount: progress),
|
||||
@ -440,6 +452,8 @@ final class PieChartComponent: Component {
|
||||
self.sections.append(CalculatedSection(
|
||||
id: item.id,
|
||||
color: itemColor,
|
||||
particle: item.particle,
|
||||
title: item.title,
|
||||
innerAngle: arcInnerStartAngle ..< arcInnerEndAngle,
|
||||
outerAngle: arcOuterStartAngle ..< arcOuterEndAngle,
|
||||
innerRadius: innerDiameter * 0.5,
|
||||
@ -782,7 +796,7 @@ final class PieChartComponent: Component {
|
||||
private var particleImage: UIImage?
|
||||
private var particleLayers: [SimpleLayer] = []
|
||||
|
||||
init(category: StorageUsageScreenComponent.Category) {
|
||||
init(particle: String?) {
|
||||
self.maskLayer = SimpleShapeLayer()
|
||||
self.maskLayer.fillColor = UIColor.white.cgColor
|
||||
|
||||
@ -799,23 +813,8 @@ final class PieChartComponent: Component {
|
||||
self.addSublayer(self.gradientLayer)
|
||||
self.addSublayer(self.labelLayer)
|
||||
|
||||
switch category {
|
||||
case .photos:
|
||||
self.particleImage = UIImage(bundleImageName: "Settings/Storage/ParticlePhotos")?.precomposed()
|
||||
case .videos:
|
||||
self.particleImage = UIImage(bundleImageName: "Settings/Storage/ParticleVideos")?.precomposed()
|
||||
case .files:
|
||||
self.particleImage = UIImage(bundleImageName: "Settings/Storage/ParticleDocuments")?.precomposed()
|
||||
case .music:
|
||||
self.particleImage = UIImage(bundleImageName: "Settings/Storage/ParticleMusic")?.precomposed()
|
||||
case .other:
|
||||
self.particleImage = UIImage(bundleImageName: "Settings/Storage/ParticleOther")?.precomposed()
|
||||
case .stickers:
|
||||
self.particleImage = UIImage(bundleImageName: "Settings/Storage/ParticleStickers")?.precomposed()
|
||||
case .avatars:
|
||||
self.particleImage = UIImage(bundleImageName: "Settings/Storage/ParticleAvatars")?.precomposed()
|
||||
case .misc:
|
||||
self.particleImage = UIImage(bundleImageName: "Settings/Storage/ParticleOther")?.precomposed()
|
||||
if let particle {
|
||||
self.particleImage = UIImage(bundleImageName: particle)?.precomposed()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1069,9 +1068,9 @@ final class PieChartComponent: Component {
|
||||
return nil
|
||||
}
|
||||
|
||||
func tooltipLocation(forKey key: StorageUsageScreenComponent.Category) -> CGPoint? {
|
||||
func tooltipLocation(forKey key: AnyHashable) -> CGPoint? {
|
||||
for (id, itemLayer) in self.sectionLayers {
|
||||
if id == AnyHashable(key) {
|
||||
if id == key {
|
||||
return itemLayer.tooltipLocation()
|
||||
}
|
||||
}
|
||||
@ -1117,7 +1116,7 @@ final class PieChartComponent: Component {
|
||||
if data.items.isEmpty {
|
||||
self.currentLayout = CalculatedLayout(
|
||||
size: CGSize(width: 200.0, height: 200.0),
|
||||
items: [.init(id: .other, displayValue: 0.0, displaySize: 0, value: 1.0, color: .green, mergeable: false, mergeFactor: 1.0)],
|
||||
items: [.init(id: AnyHashable(StorageUsageScreenComponent.Category.other), displayValue: 0.0, displaySize: 0, value: 1.0, color: .green, particle: "Settings/Storage/ParticleOther", title: "", mergeable: false, mergeFactor: 1.0)],
|
||||
selectedKey: self.selectedKey,
|
||||
isEmpty: true
|
||||
)
|
||||
@ -1217,7 +1216,7 @@ final class PieChartComponent: Component {
|
||||
if let current = self.sectionLayers[section.id] {
|
||||
sectionLayer = current
|
||||
} else {
|
||||
sectionLayer = SectionLayer(category: section.id)
|
||||
sectionLayer = SectionLayer(particle: section.particle)
|
||||
self.sectionLayers[section.id] = sectionLayer
|
||||
self.layer.addSublayer(sectionLayer)
|
||||
}
|
||||
@ -1296,7 +1295,7 @@ final class PieChartComponent: Component {
|
||||
transition.setFrame(view: self.dataView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - 200.0) / 2.0), y: 0.0), size: CGSize(width: 200.0, height: 200.0)))
|
||||
self.dataView.setItems(theme: component.theme, data: component.chartData, selectedKey: self.selectedKey, animated: !transition.animation.isImmediate)
|
||||
|
||||
if let selectedKey = self.selectedKey?.base as? StorageUsageScreenComponent.Category, let item = component.chartData.items.first(where: { $0.id == selectedKey }) {
|
||||
if let selectedKey = self.selectedKey, let item = component.chartData.items.first(where: { $0.id == selectedKey }) {
|
||||
let tooltip: ComponentView<Empty>
|
||||
var tooltipTransition = transition
|
||||
var animateIn = false
|
||||
@ -1334,7 +1333,7 @@ final class PieChartComponent: Component {
|
||||
component: AnyComponent(ChartSelectionTooltip(
|
||||
theme: component.theme,
|
||||
fractionText: fractionString,
|
||||
title: selectedKey.title(strings: component.strings),
|
||||
title: item.title,
|
||||
sizeText: dataSizeString(Int(item.displaySize), formatting: DataSizeStringFormatting(strings: component.strings, decimalSeparator: "."))
|
||||
)),
|
||||
environment: {},
|
||||
|
||||
@ -0,0 +1,113 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import ComponentFlow
|
||||
import SwiftSignalKit
|
||||
import ViewControllerComponent
|
||||
import ComponentDisplayAdapters
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import TelegramCore
|
||||
import MultilineTextComponent
|
||||
import EmojiStatusComponent
|
||||
import Postbox
|
||||
import TelegramStringFormatting
|
||||
import CheckNode
|
||||
import SegmentedControlNode
|
||||
|
||||
final class SegmentControlComponent: Component {
|
||||
struct Item: Equatable {
|
||||
var id: AnyHashable
|
||||
var title: String
|
||||
}
|
||||
|
||||
let theme: PresentationTheme
|
||||
let items: [Item]
|
||||
let selectedId: AnyHashable?
|
||||
let action: (AnyHashable) -> Void
|
||||
|
||||
init(
|
||||
theme: PresentationTheme,
|
||||
items: [Item],
|
||||
selectedId: AnyHashable?,
|
||||
action: @escaping (AnyHashable) -> Void
|
||||
) {
|
||||
self.theme = theme
|
||||
self.items = items
|
||||
self.selectedId = selectedId
|
||||
self.action = action
|
||||
}
|
||||
|
||||
static func ==(lhs: SegmentControlComponent, rhs: SegmentControlComponent) -> Bool {
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.items != rhs.items {
|
||||
return false
|
||||
}
|
||||
if lhs.selectedId != rhs.selectedId {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
class View: UIView {
|
||||
private let title = ComponentView<Empty>()
|
||||
|
||||
private var component: SegmentControlComponent?
|
||||
|
||||
private var segmentedNode: SegmentedControlNode?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(component: SegmentControlComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
let themeUpdated = self.component?.theme !== component.theme
|
||||
|
||||
self.component = component
|
||||
|
||||
let segmentedNode: SegmentedControlNode
|
||||
if let current = self.segmentedNode {
|
||||
segmentedNode = current
|
||||
|
||||
if themeUpdated {
|
||||
segmentedNode.updateTheme(SegmentedControlTheme(theme: component.theme))
|
||||
}
|
||||
} else {
|
||||
let mappedItems: [SegmentedControlItem] = component.items.map { item -> SegmentedControlItem in
|
||||
return SegmentedControlItem(title: item.title)
|
||||
}
|
||||
segmentedNode = SegmentedControlNode(theme: SegmentedControlTheme(theme: component.theme), items: mappedItems, selectedIndex: component.items.firstIndex(where: { $0.id == component.selectedId }) ?? 0)
|
||||
self.segmentedNode = segmentedNode
|
||||
self.addSubnode(segmentedNode)
|
||||
|
||||
segmentedNode.selectedIndexChanged = { [weak self] index in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
self.component?.action(component.items[index].id)
|
||||
}
|
||||
}
|
||||
|
||||
let controlSize = segmentedNode.updateLayout(SegmentedControlLayout.sizeToFit(maximumWidth: availableSize.width, minimumWidth: min(availableSize.width, 296.0), height: 31.0), transition: transition.containedViewLayoutTransition)
|
||||
|
||||
transition.containedViewLayoutTransition.updateFrame(node: segmentedNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: controlSize))
|
||||
|
||||
return controlSize
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
@ -305,6 +305,27 @@ final class StorageUsageScreenComponent: Component {
|
||||
return strings.StorageManagement_SectionMiscellaneous
|
||||
}
|
||||
}
|
||||
|
||||
var particle: String? {
|
||||
switch self {
|
||||
case .photos:
|
||||
return "Settings/Storage/ParticlePhotos"
|
||||
case .videos:
|
||||
return "Settings/Storage/ParticleVideos"
|
||||
case .files:
|
||||
return "Settings/Storage/ParticleDocuments"
|
||||
case .music:
|
||||
return "Settings/Storage/ParticleMusic"
|
||||
case .other:
|
||||
return "Settings/Storage/ParticleOther"
|
||||
case .stickers:
|
||||
return "Settings/Storage/ParticleStickers"
|
||||
case .avatars:
|
||||
return "Settings/Storage/ParticleAvatars"
|
||||
case .misc:
|
||||
return "Settings/Storage/ParticleOther"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class AggregatedData {
|
||||
@ -1306,7 +1327,7 @@ final class StorageUsageScreenComponent: Component {
|
||||
if let aggregatedData = self.aggregatedData, !aggregatedData.selectedCategories.isEmpty && !aggregatedData.selectedCategories.contains(listCategory.key) {
|
||||
categoryChartFraction = 0.0
|
||||
}
|
||||
chartItems.append(PieChartComponent.ChartData.Item(id: listCategory.key, displayValue: listCategory.sizeFraction, displaySize: listCategory.size, value: categoryChartFraction, color: listCategory.color, mergeable: false, mergeFactor: 1.0))
|
||||
chartItems.append(PieChartComponent.ChartData.Item(id: listCategory.key, displayValue: listCategory.sizeFraction, displaySize: listCategory.size, value: categoryChartFraction, color: listCategory.color, particle: listCategory.key.particle, title: listCategory.key.title(strings: environment.strings), mergeable: false, mergeFactor: 1.0))
|
||||
}
|
||||
|
||||
var totalOtherSize: Int64 = 0
|
||||
@ -1339,7 +1360,7 @@ final class StorageUsageScreenComponent: Component {
|
||||
categoryChartFraction = 0.0
|
||||
}
|
||||
|
||||
var chartItem = PieChartComponent.ChartData.Item(id: listCategory.key, displayValue: listCategory.sizeFraction, displaySize: listCategory.size, value: categoryChartFraction, color: listCategory.color, mergeable: false, mergeFactor: 1.0)
|
||||
var chartItem = PieChartComponent.ChartData.Item(id: listCategory.key, displayValue: listCategory.sizeFraction, displaySize: listCategory.size, value: categoryChartFraction, color: listCategory.color, particle: listCategory.key.particle, title: listCategory.key.title(strings: environment.strings), mergeable: false, mergeFactor: 1.0)
|
||||
|
||||
if chartItem.value > 0.00001 {
|
||||
chartItem.value = max(chartItem.value, 0.01)
|
||||
@ -1355,7 +1376,7 @@ final class StorageUsageScreenComponent: Component {
|
||||
}
|
||||
|
||||
if !listCategories.isEmpty {
|
||||
chartItems.append(PieChartComponent.ChartData.Item(id: .other, displayValue: otherRealSum, displaySize: totalOtherSize, value: self.isOtherCategoryExpanded ? 0.0 : otherSum, color: Category.misc.color, mergeable: false, mergeFactor: 1.0))
|
||||
chartItems.append(PieChartComponent.ChartData.Item(id: AnyHashable(Category.other), displayValue: otherRealSum, displaySize: totalOtherSize, value: self.isOtherCategoryExpanded ? 0.0 : otherSum, color: Category.misc.color, particle: Category.misc.particle, title: Category.misc.title(strings: environment.strings), mergeable: false, mergeFactor: 1.0))
|
||||
}
|
||||
|
||||
let chartData = PieChartComponent.ChartData(items: chartItems)
|
||||
|
||||
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Smile.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Smile.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "smile_24.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
175
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Smile.imageset/smile_24.pdf
vendored
Normal file
175
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Smile.imageset/smile_24.pdf
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 3.000000 1.669922 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
17.334999 10.330078 m
|
||||
17.334999 5.726785 13.603293 1.995079 9.000000 1.995079 c
|
||||
9.000000 0.665077 l
|
||||
14.337832 0.665077 18.665001 4.992246 18.665001 10.330078 c
|
||||
17.334999 10.330078 l
|
||||
h
|
||||
9.000000 1.995079 m
|
||||
4.396707 1.995079 0.665000 5.726785 0.665000 10.330078 c
|
||||
-0.665000 10.330078 l
|
||||
-0.665000 4.992246 3.662168 0.665077 9.000000 0.665077 c
|
||||
9.000000 1.995079 l
|
||||
h
|
||||
0.665000 10.330078 m
|
||||
0.665000 14.933372 4.396707 18.665077 9.000000 18.665077 c
|
||||
9.000000 19.995079 l
|
||||
3.662168 19.995079 -0.665000 15.667911 -0.665000 10.330078 c
|
||||
0.665000 10.330078 l
|
||||
h
|
||||
9.000000 18.665077 m
|
||||
13.603293 18.665077 17.334999 14.933372 17.334999 10.330078 c
|
||||
18.665001 10.330078 l
|
||||
18.665001 15.667911 14.337832 19.995079 9.000000 19.995079 c
|
||||
9.000000 18.665077 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 7.660156 12.477661 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
2.347826 1.369570 m
|
||||
2.347826 0.613180 1.822247 0.000005 1.173913 0.000005 c
|
||||
0.525579 0.000005 0.000000 0.613180 0.000000 1.369570 c
|
||||
0.000000 2.125960 0.525579 2.739136 1.173913 2.739136 c
|
||||
1.822247 2.739136 2.347826 2.125960 2.347826 1.369570 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 14.000000 12.477661 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
2.347826 1.369570 m
|
||||
2.347826 0.613180 1.822247 0.000005 1.173913 0.000005 c
|
||||
0.525579 0.000005 0.000000 0.613180 0.000000 1.369570 c
|
||||
0.000000 2.125960 0.525579 2.739136 1.173913 2.739136 c
|
||||
1.822247 2.739136 2.347826 2.125960 2.347826 1.369570 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 8.500000 6.076050 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
7.572875 3.015941 m
|
||||
7.759379 3.332331 7.654087 3.740008 7.337697 3.926513 c
|
||||
7.021306 4.113018 6.613629 4.007725 6.427125 3.691334 c
|
||||
7.572875 3.015941 l
|
||||
h
|
||||
0.572875 3.691335 m
|
||||
0.386370 4.007725 -0.021307 4.113018 -0.337697 3.926513 c
|
||||
-0.654087 3.740008 -0.759380 3.332331 -0.572875 3.015941 c
|
||||
0.572875 3.691335 l
|
||||
h
|
||||
7.000000 3.353638 m
|
||||
6.427125 3.691334 6.427270 3.691582 6.427412 3.691822 c
|
||||
6.427454 3.691892 6.427591 3.692125 6.427674 3.692266 c
|
||||
6.427841 3.692548 6.427992 3.692801 6.428125 3.693027 c
|
||||
6.428393 3.693477 6.428595 3.693815 6.428731 3.694042 c
|
||||
6.429003 3.694496 6.429012 3.694507 6.428758 3.694089 c
|
||||
6.428248 3.693253 6.426688 3.690706 6.424076 3.686561 c
|
||||
6.418847 3.678266 6.409435 3.663620 6.395833 3.643527 c
|
||||
6.368581 3.603271 6.324809 3.541589 6.264480 3.465568 c
|
||||
6.143271 3.312833 5.958584 3.106452 5.710678 2.900174 c
|
||||
5.216724 2.489165 4.487087 2.089347 3.500000 2.089347 c
|
||||
3.500000 0.759347 l
|
||||
4.875639 0.759347 5.896002 1.324174 6.561367 1.877810 c
|
||||
6.893120 2.153855 7.140421 2.429797 7.306286 2.638804 c
|
||||
7.389494 2.743654 7.453030 2.832698 7.497203 2.897951 c
|
||||
7.519312 2.930611 7.536642 2.957415 7.549225 2.977380 c
|
||||
7.555520 2.987366 7.560634 2.995653 7.564572 3.002117 c
|
||||
7.566542 3.005350 7.568218 3.008128 7.569601 3.010437 c
|
||||
7.570293 3.011591 7.570911 3.012628 7.571457 3.013546 c
|
||||
7.571730 3.014005 7.571984 3.014434 7.572220 3.014833 c
|
||||
7.572339 3.015033 7.572502 3.015310 7.572561 3.015410 c
|
||||
7.572720 3.015679 7.572875 3.015941 7.000000 3.353638 c
|
||||
h
|
||||
3.500000 2.089347 m
|
||||
2.512913 2.089347 1.783276 2.489165 1.289322 2.900174 c
|
||||
1.041416 3.106452 0.856728 3.312833 0.735520 3.465568 c
|
||||
0.675191 3.541589 0.631418 3.603271 0.604167 3.643527 c
|
||||
0.590564 3.663620 0.581153 3.678266 0.575924 3.686562 c
|
||||
0.573312 3.690706 0.571751 3.693253 0.571242 3.694089 c
|
||||
0.570987 3.694507 0.570996 3.694496 0.571268 3.694042 c
|
||||
0.571404 3.693815 0.571606 3.693477 0.571874 3.693027 c
|
||||
0.572008 3.692801 0.572158 3.692548 0.572325 3.692266 c
|
||||
0.572408 3.692125 0.572546 3.691892 0.572588 3.691822 c
|
||||
0.572729 3.691582 0.572875 3.691335 0.000000 3.353638 c
|
||||
-0.572875 3.015941 -0.572721 3.015679 -0.572562 3.015410 c
|
||||
-0.572503 3.015310 -0.572339 3.015033 -0.572221 3.014833 c
|
||||
-0.571985 3.014434 -0.571730 3.014005 -0.571457 3.013546 c
|
||||
-0.570912 3.012628 -0.570293 3.011591 -0.569602 3.010437 c
|
||||
-0.568218 3.008128 -0.566542 3.005350 -0.564573 3.002117 c
|
||||
-0.560634 2.995653 -0.555520 2.987366 -0.549226 2.977380 c
|
||||
-0.536642 2.957415 -0.519313 2.930610 -0.497203 2.897950 c
|
||||
-0.453030 2.832698 -0.389495 2.743654 -0.306287 2.638804 c
|
||||
-0.140421 2.429797 0.106880 2.153855 0.438633 1.877810 c
|
||||
1.103997 1.324174 2.124361 0.759347 3.500000 0.759347 c
|
||||
3.500000 2.089347 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
4309
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000004399 00000 n
|
||||
0000004422 00000 n
|
||||
0000004595 00000 n
|
||||
0000004669 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
4728
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataCalls.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataCalls.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "calls.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
111
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataCalls.imageset/calls.pdf
vendored
Normal file
111
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataCalls.imageset/calls.pdf
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
1.000000 0.584314 0.000000 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 6.000000 6.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
4.868853 4.891197 m
|
||||
2.124590 7.636960 0.000000 11.022417 0.000000 13.837070 c
|
||||
0.000000 15.086933 0.413115 16.218699 1.357377 17.133953 c
|
||||
1.927869 17.694916 2.596721 18.000000 3.216393 18.000000 c
|
||||
3.747541 18.000000 4.229508 17.783487 4.573771 17.301258 c
|
||||
6.244052 14.601130 l
|
||||
6.749065 13.784742 6.700242 12.741879 6.121165 11.976244 c
|
||||
4.939975 10.414518 l
|
||||
4.831778 10.306263 4.792434 10.188166 4.792434 10.060226 c
|
||||
4.792434 9.942129 4.841614 9.814191 4.890794 9.705935 c
|
||||
5.176040 9.105606 6.031778 8.062413 7.035057 7.058586 c
|
||||
8.028500 6.054759 9.090795 5.218237 9.671123 4.913152 c
|
||||
9.779319 4.863944 9.907188 4.814737 10.044893 4.814737 c
|
||||
10.182598 4.814737 10.310467 4.854102 10.418663 4.962358 c
|
||||
11.944046 6.134850 l
|
||||
12.711500 6.724756 13.764204 6.777284 14.586570 6.266706 c
|
||||
17.340984 4.556588 l
|
||||
17.822952 4.221979 18.000000 3.769273 18.000000 3.296884 c
|
||||
18.000000 2.637506 17.626228 1.948606 17.124590 1.417168 c
|
||||
16.219671 0.442865 15.118032 0.000000 13.829508 0.000000 c
|
||||
11.016394 0.000000 7.603279 2.155275 4.868853 4.891197 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
2078
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000002168 00000 n
|
||||
0000002191 00000 n
|
||||
0000002364 00000 n
|
||||
0000002438 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
2497
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataExpandedIn.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataExpandedIn.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "down.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
159
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataExpandedIn.imageset/down.pdf
vendored
Normal file
159
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataExpandedIn.imageset/down.pdf
vendored
Normal file
@ -0,0 +1,159 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 0.000000 -1.000000 5.500061 11.394928 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
-0.470226 1.865154 m
|
||||
-0.729925 1.605455 -0.729925 1.184401 -0.470226 0.924702 c
|
||||
-0.210527 0.665003 0.210527 0.665003 0.470226 0.924702 c
|
||||
-0.470226 1.865154 l
|
||||
h
|
||||
3.500000 4.894928 m
|
||||
3.970228 5.365152 l
|
||||
3.845517 5.489864 3.676371 5.559927 3.500001 5.559928 c
|
||||
3.323632 5.559928 3.154486 5.489866 3.029774 5.365154 c
|
||||
3.500000 4.894928 l
|
||||
h
|
||||
6.529741 0.924704 m
|
||||
6.789439 0.665004 7.210494 0.665002 7.470193 0.924700 c
|
||||
7.729893 1.184397 7.729895 1.605452 7.470198 1.865152 c
|
||||
6.529741 0.924704 l
|
||||
h
|
||||
0.470226 0.924702 m
|
||||
3.970226 4.424702 l
|
||||
3.029774 5.365154 l
|
||||
-0.470226 1.865154 l
|
||||
0.470226 0.924702 l
|
||||
h
|
||||
3.029772 4.424704 m
|
||||
6.529741 0.924704 l
|
||||
7.470198 1.865152 l
|
||||
3.970228 5.365152 l
|
||||
3.029772 4.424704 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
-1.000000 -0.000000 0.000000 -1.000000 9.000031 16.825317 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
-0.665000 1.330017 m
|
||||
-0.665000 0.962748 -0.367269 0.665017 0.000000 0.665017 c
|
||||
0.367269 0.665017 0.665000 0.962748 0.665000 1.330017 c
|
||||
-0.665000 1.330017 l
|
||||
h
|
||||
0.665000 9.330017 m
|
||||
0.665000 9.697287 0.367269 9.995017 -0.000000 9.995017 c
|
||||
-0.367269 9.995017 -0.665000 9.697287 -0.665000 9.330017 c
|
||||
0.665000 9.330017 l
|
||||
h
|
||||
0.665000 1.330017 m
|
||||
0.665000 9.330017 l
|
||||
-0.665000 9.330017 l
|
||||
-0.665000 1.330017 l
|
||||
0.665000 1.330017 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 4.000000 1.665283 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.000000 1.995017 m
|
||||
-0.367269 1.995017 -0.665000 1.697286 -0.665000 1.330017 c
|
||||
-0.665000 0.962748 -0.367269 0.665017 0.000000 0.665017 c
|
||||
0.000000 1.995017 l
|
||||
h
|
||||
10.000000 0.665017 m
|
||||
10.367270 0.665017 10.665000 0.962748 10.665000 1.330017 c
|
||||
10.665000 1.697286 10.367270 1.995017 10.000000 1.995017 c
|
||||
10.000000 0.665017 l
|
||||
h
|
||||
0.000000 0.665017 m
|
||||
10.000000 0.665017 l
|
||||
10.000000 1.995017 l
|
||||
0.000000 1.995017 l
|
||||
0.000000 0.665017 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 4.000000 1.665283 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.000000 1.995017 m
|
||||
-0.367269 1.995017 -0.665000 1.697286 -0.665000 1.330017 c
|
||||
-0.665000 0.962748 -0.367269 0.665017 0.000000 0.665017 c
|
||||
0.000000 1.995017 l
|
||||
h
|
||||
10.000000 0.665017 m
|
||||
10.367270 0.665017 10.665000 0.962748 10.665000 1.330017 c
|
||||
10.665000 1.697286 10.367270 1.995017 10.000000 1.995017 c
|
||||
10.000000 0.665017 l
|
||||
h
|
||||
0.000000 0.665017 m
|
||||
10.000000 0.665017 l
|
||||
10.000000 1.995017 l
|
||||
0.000000 1.995017 l
|
||||
0.000000 0.665017 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
2383
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 18.000000 18.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000002473 00000 n
|
||||
0000002496 00000 n
|
||||
0000002669 00000 n
|
||||
0000002743 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
2802
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataExpandedOut.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataExpandedOut.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "up.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
207
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataExpandedOut.imageset/up.pdf
vendored
Normal file
207
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataExpandedOut.imageset/up.pdf
vendored
Normal file
@ -0,0 +1,207 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
-1.000000 0.000000 0.000000 1.000000 12.500031 10.598022 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
-0.470226 1.865154 m
|
||||
-0.729925 1.605455 -0.729925 1.184401 -0.470226 0.924702 c
|
||||
-0.210527 0.665003 0.210527 0.665003 0.470226 0.924702 c
|
||||
-0.470226 1.865154 l
|
||||
h
|
||||
3.500000 4.894928 m
|
||||
3.970228 5.365152 l
|
||||
3.845517 5.489864 3.676371 5.559927 3.500001 5.559928 c
|
||||
3.323632 5.559928 3.154486 5.489866 3.029774 5.365154 c
|
||||
3.500000 4.894928 l
|
||||
h
|
||||
6.529741 0.924704 m
|
||||
6.789439 0.665004 7.210494 0.665002 7.470193 0.924700 c
|
||||
7.729893 1.184397 7.729895 1.605452 7.470198 1.865152 c
|
||||
6.529741 0.924704 l
|
||||
h
|
||||
0.470226 0.924702 m
|
||||
3.970226 4.424702 l
|
||||
3.029774 5.365154 l
|
||||
-0.470226 1.865154 l
|
||||
0.470226 0.924702 l
|
||||
h
|
||||
3.029772 4.424704 m
|
||||
6.529741 0.924704 l
|
||||
7.470198 1.865152 l
|
||||
3.970228 5.365152 l
|
||||
3.029772 4.424704 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
-1.000000 -0.000000 0.000000 -1.000000 9.000031 15.822968 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
-0.665000 1.330017 m
|
||||
-0.665000 0.962748 -0.367269 0.665017 0.000000 0.665017 c
|
||||
0.367269 0.665017 0.665000 0.962748 0.665000 1.330017 c
|
||||
-0.665000 1.330017 l
|
||||
h
|
||||
0.665000 9.330017 m
|
||||
0.665000 9.697287 0.367269 9.995017 -0.000000 9.995017 c
|
||||
-0.367269 9.995017 -0.665000 9.697287 -0.665000 9.330017 c
|
||||
0.665000 9.330017 l
|
||||
h
|
||||
0.665000 1.330017 m
|
||||
0.665000 9.330017 l
|
||||
-0.665000 9.330017 l
|
||||
-0.665000 1.330017 l
|
||||
0.665000 1.330017 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 4.000000 1.662933 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.665000 3.330017 m
|
||||
0.665000 3.697286 0.367269 3.995017 0.000000 3.995017 c
|
||||
-0.367269 3.995017 -0.665000 3.697286 -0.665000 3.330017 c
|
||||
0.665000 3.330017 l
|
||||
h
|
||||
10.665000 3.330017 m
|
||||
10.665000 3.697286 10.367270 3.995017 10.000000 3.995017 c
|
||||
9.632730 3.995017 9.335000 3.697286 9.335000 3.330017 c
|
||||
10.665000 3.330017 l
|
||||
h
|
||||
1.000000 0.665017 m
|
||||
9.000000 0.665017 l
|
||||
9.000000 1.995017 l
|
||||
1.000000 1.995017 l
|
||||
1.000000 0.665017 l
|
||||
h
|
||||
0.665000 2.330017 m
|
||||
0.665000 3.330017 l
|
||||
-0.665000 3.330017 l
|
||||
-0.665000 2.330017 l
|
||||
0.665000 2.330017 l
|
||||
h
|
||||
10.665000 2.330017 m
|
||||
10.665000 3.330017 l
|
||||
9.335000 3.330017 l
|
||||
9.335000 2.330017 l
|
||||
10.665000 2.330017 l
|
||||
h
|
||||
9.000000 0.665017 m
|
||||
9.919554 0.665017 10.665000 1.410463 10.665000 2.330017 c
|
||||
9.335000 2.330017 l
|
||||
9.335000 2.145002 9.185016 1.995017 9.000000 1.995017 c
|
||||
9.000000 0.665017 l
|
||||
h
|
||||
1.000000 1.995017 m
|
||||
0.814985 1.995017 0.665000 2.145002 0.665000 2.330017 c
|
||||
-0.665000 2.330017 l
|
||||
-0.665000 1.410463 0.080446 0.665017 1.000000 0.665017 c
|
||||
1.000000 1.995017 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 4.000000 1.662933 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.665000 3.330017 m
|
||||
0.665000 3.697286 0.367269 3.995017 0.000000 3.995017 c
|
||||
-0.367269 3.995017 -0.665000 3.697286 -0.665000 3.330017 c
|
||||
0.665000 3.330017 l
|
||||
h
|
||||
10.665000 3.330017 m
|
||||
10.665000 3.697286 10.367270 3.995017 10.000000 3.995017 c
|
||||
9.632730 3.995017 9.335000 3.697286 9.335000 3.330017 c
|
||||
10.665000 3.330017 l
|
||||
h
|
||||
1.000000 0.665017 m
|
||||
9.000000 0.665017 l
|
||||
9.000000 1.995017 l
|
||||
1.000000 1.995017 l
|
||||
1.000000 0.665017 l
|
||||
h
|
||||
0.665000 2.330017 m
|
||||
0.665000 3.330017 l
|
||||
-0.665000 3.330017 l
|
||||
-0.665000 2.330017 l
|
||||
0.665000 2.330017 l
|
||||
h
|
||||
10.665000 2.330017 m
|
||||
10.665000 3.330017 l
|
||||
9.335000 3.330017 l
|
||||
9.335000 2.330017 l
|
||||
10.665000 2.330017 l
|
||||
h
|
||||
9.000000 0.665017 m
|
||||
9.919554 0.665017 10.665000 1.410463 10.665000 2.330017 c
|
||||
9.335000 2.330017 l
|
||||
9.335000 2.145002 9.185016 1.995017 9.000000 1.995017 c
|
||||
9.000000 0.665017 l
|
||||
h
|
||||
1.000000 1.995017 m
|
||||
0.814985 1.995017 0.665000 2.145002 0.665000 2.330017 c
|
||||
-0.665000 2.330017 l
|
||||
-0.665000 1.410463 0.080446 0.665017 1.000000 0.665017 c
|
||||
1.000000 1.995017 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
3492
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 18.000000 18.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000003582 00000 n
|
||||
0000003605 00000 n
|
||||
0000003778 00000 n
|
||||
0000003852 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
3911
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataFiles.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataFiles.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "files.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
143
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataFiles.imageset/files.pdf
vendored
Normal file
143
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataFiles.imageset/files.pdf
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.203922 0.780392 0.349020 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 7.000000 6.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
5.330000 18.000000 m
|
||||
5.807298 18.000000 6.123703 17.999550 6.367812 17.982895 c
|
||||
6.604466 17.966749 6.711959 17.938187 6.777740 17.910938 c
|
||||
7.064423 17.792191 7.292191 17.564423 7.410939 17.277740 c
|
||||
7.438186 17.211960 7.466748 17.104465 7.482895 16.867813 c
|
||||
7.499550 16.623703 7.500000 16.307299 7.500000 15.830000 c
|
||||
7.500000 13.530003 l
|
||||
7.500000 13.496872 l
|
||||
7.499987 12.965037 7.499976 12.516354 7.530005 12.148819 c
|
||||
7.561447 11.763987 7.629904 11.395631 7.808452 11.045210 c
|
||||
8.079773 10.512712 8.512709 10.079777 9.045207 9.808455 c
|
||||
9.395627 9.629908 9.763983 9.561451 10.148815 9.530008 c
|
||||
10.516351 9.499980 10.965034 9.499990 11.496870 9.500004 c
|
||||
11.530001 9.500004 l
|
||||
13.829997 9.500004 l
|
||||
14.307296 9.500004 14.623703 9.499555 14.867812 9.482899 c
|
||||
15.104466 9.466752 15.211960 9.438190 15.277740 9.410942 c
|
||||
15.564423 9.292194 15.792191 9.064426 15.910938 8.777744 c
|
||||
15.938186 8.711964 15.966748 8.604470 15.982895 8.367816 c
|
||||
15.999551 8.123706 16.000000 7.807300 16.000000 7.330000 c
|
||||
16.000000 4.800000 l
|
||||
16.000000 3.119843 16.000000 2.279763 15.673019 1.638029 c
|
||||
15.385400 1.073542 14.926457 0.614601 14.361972 0.326981 c
|
||||
13.720237 0.000000 12.880157 0.000000 11.200000 0.000000 c
|
||||
4.800000 0.000000 l
|
||||
3.119843 0.000000 2.279764 0.000000 1.638029 0.326981 c
|
||||
1.073542 0.614601 0.614601 1.073542 0.326980 1.638029 c
|
||||
0.000000 2.279763 0.000000 3.119843 0.000000 4.800000 c
|
||||
0.000000 13.200001 l
|
||||
0.000000 14.880157 0.000000 15.720236 0.326980 16.361971 c
|
||||
0.614601 16.926458 1.073542 17.385399 1.638029 17.673019 c
|
||||
2.279764 18.000000 3.119843 18.000000 4.800000 18.000000 c
|
||||
5.330000 18.000000 l
|
||||
h
|
||||
15.621112 11.042418 m
|
||||
15.558301 11.176268 15.488032 11.306717 15.410561 11.433140 c
|
||||
15.163194 11.836806 14.817290 12.182710 14.125484 12.874516 c
|
||||
10.874516 16.125484 l
|
||||
10.182710 16.817291 9.836806 17.163193 9.433140 17.410561 c
|
||||
9.306716 17.488033 9.176266 17.558304 9.042415 17.621115 c
|
||||
9.097363 17.412268 9.124138 17.199299 9.139045 16.980810 c
|
||||
9.160017 16.673437 9.160009 16.300030 9.160000 15.857494 c
|
||||
9.160000 15.830000 l
|
||||
9.160000 13.530003 l
|
||||
9.160000 12.956255 9.160645 12.575861 9.184492 12.283996 c
|
||||
9.207546 12.001820 9.248083 11.876238 9.287522 11.798835 c
|
||||
9.399694 11.578686 9.578682 11.399698 9.798831 11.287526 c
|
||||
9.876234 11.248087 10.001816 11.207550 10.283993 11.184496 c
|
||||
10.575858 11.160649 10.956251 11.160004 11.530001 11.160004 c
|
||||
13.829997 11.160004 l
|
||||
13.857491 11.160004 l
|
||||
14.300028 11.160013 14.673436 11.160021 14.980811 11.139048 c
|
||||
15.199297 11.124141 15.412265 11.097366 15.621112 11.042418 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
3553
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000003643 00000 n
|
||||
0000003666 00000 n
|
||||
0000003839 00000 n
|
||||
0000003913 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
3972
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataIn.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataIn.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "datain.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
148
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataIn.imageset/datain.pdf
vendored
Normal file
148
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataIn.imageset/datain.pdf
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.203922 0.780392 0.349020 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
0.000000 1.000000 -1.000000 0.000000 22.778702 10.334999 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
0.341218 6.954933 m
|
||||
-0.113739 7.409894 -0.113739 8.147528 0.341218 8.602488 c
|
||||
5.841218 14.102518 l
|
||||
6.296178 14.557480 7.033815 14.557482 7.488777 14.102523 c
|
||||
7.943739 13.647563 7.943741 12.909925 7.488781 12.454964 c
|
||||
3.977601 8.943764 l
|
||||
13.165000 8.943764 l
|
||||
13.808412 8.943764 14.330000 8.422175 14.330000 7.778764 c
|
||||
14.330000 7.135352 13.808412 6.613764 13.165000 6.613764 c
|
||||
3.977494 6.613764 l
|
||||
7.488781 3.102457 l
|
||||
7.943741 2.647495 7.943739 1.909858 7.488777 1.454898 c
|
||||
7.033815 0.999939 6.296178 0.999941 5.841218 1.454903 c
|
||||
0.341218 6.954933 l
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 8.000000 4.669998 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.000000 3.495002 m
|
||||
-0.643412 3.495002 -1.165000 2.973413 -1.165000 2.330002 c
|
||||
-1.165000 1.686590 -0.643412 1.165002 0.000000 1.165002 c
|
||||
0.000000 3.495002 l
|
||||
h
|
||||
14.000000 1.165002 m
|
||||
14.643412 1.165002 15.165000 1.686590 15.165000 2.330002 c
|
||||
15.165000 2.973413 14.643412 3.495002 14.000000 3.495002 c
|
||||
14.000000 1.165002 l
|
||||
h
|
||||
0.000000 1.165002 m
|
||||
14.000000 1.165002 l
|
||||
14.000000 3.495002 l
|
||||
0.000000 3.495002 l
|
||||
0.000000 1.165002 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 8.000000 4.669998 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
0.000000 3.495002 m
|
||||
-0.643412 3.495002 -1.165000 2.973413 -1.165000 2.330002 c
|
||||
-1.165000 1.686590 -0.643412 1.165002 0.000000 1.165002 c
|
||||
0.000000 3.495002 l
|
||||
h
|
||||
14.000000 1.165002 m
|
||||
14.643412 1.165002 15.165000 1.686590 15.165000 2.330002 c
|
||||
15.165000 2.973413 14.643412 3.495002 14.000000 3.495002 c
|
||||
14.000000 1.165002 l
|
||||
h
|
||||
0.000000 1.165002 m
|
||||
14.000000 1.165002 l
|
||||
14.000000 3.495002 l
|
||||
0.000000 3.495002 l
|
||||
0.000000 1.165002 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
2638
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000002728 00000 n
|
||||
0000002751 00000 n
|
||||
0000002924 00000 n
|
||||
0000002998 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
3057
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataMessages.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataMessages.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "messages.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
100
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataMessages.imageset/messages.pdf
vendored
Normal file
100
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataMessages.imageset/messages.pdf
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.345098 0.337255 0.839216 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 5.000000 4.484375 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
20.000000 11.044711 m
|
||||
20.000000 16.065481 15.522848 20.135620 10.000000 20.135620 c
|
||||
4.477152 20.135620 0.000000 16.065481 0.000000 11.044711 c
|
||||
0.000000 8.181209 1.337573 5.834022 3.613619 4.167677 c
|
||||
3.904685 3.954580 4.172771 2.770550 3.523984 1.775995 c
|
||||
2.875197 0.781441 2.066323 0.326941 2.471971 0.156790 c
|
||||
2.722059 0.051889 4.199766 -0.000002 5.266314 0.598131 c
|
||||
6.791368 1.453400 7.217727 2.304844 7.545889 2.229574 c
|
||||
8.331102 2.049473 9.153261 1.953802 10.000000 1.953802 c
|
||||
15.522848 1.953802 20.000000 6.023941 20.000000 11.044711 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
1584
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000001674 00000 n
|
||||
0000001697 00000 n
|
||||
0000001870 00000 n
|
||||
0000001944 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
2003
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataMusic.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataMusic.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "music.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
103
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataMusic.imageset/music.pdf
vendored
Normal file
103
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataMusic.imageset/music.pdf
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
1.000000 0.176471 0.333333 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 5.000000 5.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
10.000000 0.000000 m
|
||||
15.522847 0.000000 20.000000 4.477153 20.000000 10.000000 c
|
||||
20.000000 15.522848 15.522847 20.000000 10.000000 20.000000 c
|
||||
4.477152 20.000000 0.000000 15.522848 0.000000 10.000000 c
|
||||
0.000000 4.477153 4.477152 0.000000 10.000000 0.000000 c
|
||||
h
|
||||
14.751925 9.167950 m
|
||||
8.554701 5.036467 l
|
||||
7.890146 4.593431 7.000000 5.069821 7.000000 5.868517 c
|
||||
7.000000 14.131483 l
|
||||
7.000000 14.930179 7.890145 15.406569 8.554700 14.963533 c
|
||||
14.751925 10.832050 l
|
||||
15.345657 10.436228 15.345657 9.563771 14.751925 9.167950 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
1564
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000001654 00000 n
|
||||
0000001677 00000 n
|
||||
0000001850 00000 n
|
||||
0000001924 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
1983
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataOut.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataOut.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "dataout.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
197
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataOut.imageset/dataout.pdf
vendored
Normal file
197
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataOut.imageset/dataout.pdf
vendored
Normal file
@ -0,0 +1,197 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.000000 0.478431 1.000000 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
0.000000 -1.000000 1.000000 0.000000 7.335037 24.665001 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
0.341223 6.841220 m
|
||||
0.122742 7.059700 0.000000 7.356022 0.000000 7.665000 c
|
||||
0.000000 7.973978 0.122740 8.270301 0.341221 8.488781 c
|
||||
5.841220 13.988781 l
|
||||
6.296181 14.443742 7.033819 14.443742 7.488780 13.988781 c
|
||||
7.943740 13.533820 7.943740 12.796184 7.488780 12.341223 c
|
||||
3.977603 8.830046 l
|
||||
13.165001 8.830046 l
|
||||
13.808413 8.830046 14.330001 8.308458 14.330001 7.665046 c
|
||||
14.330001 7.021635 13.808413 6.500046 13.165001 6.500046 c
|
||||
3.977525 6.500046 l
|
||||
7.488777 2.988814 l
|
||||
7.943739 2.533854 7.943741 1.796217 7.488781 1.341255 c
|
||||
7.033822 0.886293 6.296185 0.886292 5.841223 1.341250 c
|
||||
0.341223 6.841220 l
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 8.000000 4.669998 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
1.165000 4.330002 m
|
||||
1.165000 4.973413 0.643412 5.495002 0.000000 5.495002 c
|
||||
-0.643412 5.495002 -1.165000 4.973413 -1.165000 4.330002 c
|
||||
1.165000 4.330002 l
|
||||
h
|
||||
15.165000 4.330002 m
|
||||
15.165000 4.973413 14.643412 5.495002 14.000000 5.495002 c
|
||||
13.356588 5.495002 12.835000 4.973413 12.835000 4.330002 c
|
||||
15.165000 4.330002 l
|
||||
h
|
||||
1.000000 1.165002 m
|
||||
13.000000 1.165002 l
|
||||
13.000000 3.495002 l
|
||||
1.000000 3.495002 l
|
||||
1.000000 1.165002 l
|
||||
h
|
||||
1.165000 3.330002 m
|
||||
1.165000 4.330002 l
|
||||
-1.165000 4.330002 l
|
||||
-1.165000 3.330002 l
|
||||
1.165000 3.330002 l
|
||||
h
|
||||
15.165000 3.330002 m
|
||||
15.165000 4.330002 l
|
||||
12.835000 4.330002 l
|
||||
12.835000 3.330002 l
|
||||
15.165000 3.330002 l
|
||||
h
|
||||
13.000000 1.165002 m
|
||||
14.195696 1.165002 15.165000 2.134305 15.165000 3.330002 c
|
||||
12.835000 3.330002 l
|
||||
12.835000 3.421129 12.908874 3.495002 13.000000 3.495002 c
|
||||
13.000000 1.165002 l
|
||||
h
|
||||
1.000000 3.495002 m
|
||||
1.091127 3.495002 1.165000 3.421129 1.165000 3.330002 c
|
||||
-1.165000 3.330002 l
|
||||
-1.165000 2.134305 -0.195696 1.165002 1.000000 1.165002 c
|
||||
1.000000 3.495002 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 8.000000 4.669998 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
1.165000 4.330002 m
|
||||
1.165000 4.973413 0.643412 5.495002 0.000000 5.495002 c
|
||||
-0.643412 5.495002 -1.165000 4.973413 -1.165000 4.330002 c
|
||||
1.165000 4.330002 l
|
||||
h
|
||||
15.165000 4.330002 m
|
||||
15.165000 4.973413 14.643412 5.495002 14.000000 5.495002 c
|
||||
13.356588 5.495002 12.835000 4.973413 12.835000 4.330002 c
|
||||
15.165000 4.330002 l
|
||||
h
|
||||
1.000000 1.165002 m
|
||||
13.000000 1.165002 l
|
||||
13.000000 3.495002 l
|
||||
1.000000 3.495002 l
|
||||
1.000000 1.165002 l
|
||||
h
|
||||
1.165000 3.330002 m
|
||||
1.165000 4.330002 l
|
||||
-1.165000 4.330002 l
|
||||
-1.165000 3.330002 l
|
||||
1.165000 3.330002 l
|
||||
h
|
||||
15.165000 3.330002 m
|
||||
15.165000 4.330002 l
|
||||
12.835000 4.330002 l
|
||||
12.835000 3.330002 l
|
||||
15.165000 3.330002 l
|
||||
h
|
||||
13.000000 1.165002 m
|
||||
14.195696 1.165002 15.165000 2.134305 15.165000 3.330002 c
|
||||
12.835000 3.330002 l
|
||||
12.835000 3.421129 12.908874 3.495002 13.000000 3.495002 c
|
||||
13.000000 1.165002 l
|
||||
h
|
||||
1.000000 3.495002 m
|
||||
1.091127 3.495002 1.165000 3.421129 1.165000 3.330002 c
|
||||
-1.165000 3.330002 l
|
||||
-1.165000 2.134305 -0.195696 1.165002 1.000000 1.165002 c
|
||||
1.000000 3.495002 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
3829
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000003919 00000 n
|
||||
0000003942 00000 n
|
||||
0000004115 00000 n
|
||||
0000004189 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
4248
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataPhotos.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataPhotos.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "photos.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
155
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataPhotos.imageset/photos.pdf
vendored
Normal file
155
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataPhotos.imageset/photos.pdf
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.352941 0.784314 0.980392 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 6.000000 6.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
0.326980 16.361971 m
|
||||
0.000000 15.720236 0.000000 14.880157 0.000000 13.200001 c
|
||||
0.000000 7.873625 l
|
||||
2.719312 10.802114 l
|
||||
2.739366 10.823713 l
|
||||
2.739403 10.823753 l
|
||||
2.739418 10.823770 l
|
||||
2.925786 11.024508 3.099065 11.211145 3.256842 11.354792 c
|
||||
3.426955 11.509670 3.635908 11.669102 3.908790 11.762256 c
|
||||
4.292071 11.893097 4.707929 11.893097 5.091210 11.762256 c
|
||||
5.364092 11.669102 5.573045 11.509670 5.743158 11.354791 c
|
||||
5.900949 11.211132 6.074247 11.024471 6.260634 10.823713 c
|
||||
6.280688 10.802114 l
|
||||
10.392858 6.373626 l
|
||||
11.719312 7.802115 l
|
||||
11.739367 7.823714 l
|
||||
11.925754 8.024473 12.099051 8.211132 12.256842 8.354791 c
|
||||
12.426956 8.509670 12.635908 8.669102 12.908790 8.762256 c
|
||||
13.292071 8.893097 13.707929 8.893097 14.091210 8.762256 c
|
||||
14.364092 8.669102 14.573045 8.509670 14.743158 8.354791 c
|
||||
14.900943 8.211139 15.074232 8.024488 15.260609 7.823739 c
|
||||
15.260634 7.823713 l
|
||||
15.280688 7.802114 l
|
||||
18.000000 4.873625 l
|
||||
18.000000 13.200000 l
|
||||
18.000000 14.880157 18.000000 15.720236 17.673019 16.361971 c
|
||||
17.385399 16.926458 16.926458 17.385399 16.361971 17.673019 c
|
||||
15.720237 18.000000 14.880157 18.000000 13.200001 18.000000 c
|
||||
4.800000 18.000000 l
|
||||
3.119843 18.000000 2.279764 18.000000 1.638029 17.673019 c
|
||||
1.073542 17.385399 0.614601 16.926458 0.326980 16.361971 c
|
||||
h
|
||||
16.108553 0.218262 m
|
||||
11.525509 5.153847 l
|
||||
12.935749 6.672566 l
|
||||
13.149095 6.902323 13.274549 7.036421 13.374386 7.127316 c
|
||||
13.419220 7.168135 13.445271 7.187207 13.456385 7.194696 c
|
||||
13.484964 7.202284 13.515036 7.202284 13.543615 7.194696 c
|
||||
13.554729 7.187207 13.580781 7.168135 13.625614 7.127316 c
|
||||
13.725451 7.036421 13.850905 6.902323 14.064251 6.672565 c
|
||||
17.925373 2.514434 l
|
||||
17.877884 2.167143 17.800177 1.887589 17.673019 1.638029 c
|
||||
17.385399 1.073542 16.926458 0.614601 16.361971 0.326981 c
|
||||
16.281078 0.285763 16.197035 0.249743 16.108553 0.218262 c
|
||||
h
|
||||
14.044044 0.002020 m
|
||||
5.064251 9.672565 l
|
||||
4.850905 9.902323 4.725451 10.036421 4.625614 10.127316 c
|
||||
4.580781 10.168135 4.554729 10.187207 4.543615 10.194696 c
|
||||
4.515036 10.202284 4.484964 10.202284 4.456385 10.194696 c
|
||||
4.445271 10.187207 4.419219 10.168135 4.374386 10.127316 c
|
||||
4.274549 10.036421 4.149095 9.902323 3.935749 9.672565 c
|
||||
0.000000 5.434067 l
|
||||
0.000000 4.800000 l
|
||||
0.000000 3.119843 0.000000 2.279763 0.326980 1.638029 c
|
||||
0.614601 1.073542 1.073542 0.614601 1.638029 0.326981 c
|
||||
2.279764 0.000000 3.119842 0.000000 4.800000 0.000000 c
|
||||
13.200000 0.000000 l
|
||||
13.508314 0.000000 13.788341 0.000000 14.044044 0.002020 c
|
||||
h
|
||||
13.500000 12.000000 m
|
||||
14.328427 12.000000 15.000000 12.671573 15.000000 13.500000 c
|
||||
15.000000 14.328427 14.328427 15.000000 13.500000 15.000000 c
|
||||
12.671573 15.000000 12.000000 14.328427 12.000000 13.500000 c
|
||||
12.000000 12.671573 12.671573 12.000000 13.500000 12.000000 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
3765
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000003855 00000 n
|
||||
0000003878 00000 n
|
||||
0000004051 00000 n
|
||||
0000004125 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
4184
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataStickers.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataStickers.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "stickers.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
173
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataStickers.imageset/stickers.pdf
vendored
Normal file
173
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataStickers.imageset/stickers.pdf
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
1.000000 0.800000 0.000000 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 6.000000 6.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
0.435974 15.815962 m
|
||||
0.000000 14.960315 0.000000 13.840210 0.000000 11.600000 c
|
||||
0.000000 5.538462 l
|
||||
0.000000 4.106961 0.000000 3.391212 0.181116 2.809988 c
|
||||
0.572199 1.554960 1.554961 0.572199 2.809988 0.181116 c
|
||||
3.391211 0.000000 4.106961 0.000000 5.538461 0.000000 c
|
||||
7.132836 0.000000 8.332593 0.000000 9.296358 0.049431 c
|
||||
9.392109 0.065231 9.458178 0.084789 9.510882 0.106621 c
|
||||
9.837995 0.242115 10.097885 0.502007 10.233379 0.829117 c
|
||||
10.269915 0.917324 10.300633 1.046162 10.317467 1.296604 c
|
||||
10.334650 1.552246 10.335000 1.881901 10.335000 2.365276 c
|
||||
10.335000 2.390583 l
|
||||
10.334996 3.020454 10.334994 3.541773 10.356327 3.976810 c
|
||||
9.927901 3.881188 9.474939 3.834996 8.999999 3.834996 c
|
||||
7.566772 3.834998 6.432307 4.408777 5.671366 4.962191 c
|
||||
5.289614 5.239828 4.994541 5.517408 4.793315 5.727383 c
|
||||
4.692429 5.832656 4.614337 5.921766 4.559963 5.986553 c
|
||||
4.532754 6.018972 4.511416 6.045382 4.496066 6.064772 c
|
||||
4.477521 6.088497 l
|
||||
4.471629 6.096197 l
|
||||
4.469531 6.098966 l
|
||||
4.468694 6.100076 l
|
||||
4.468329 6.100561 l
|
||||
4.468162 6.100784 4.468000 6.101000 5.000000 6.500000 c
|
||||
5.532000 6.899000 l
|
||||
5.531705 6.899393 l
|
||||
5.538846 6.890306 l
|
||||
5.546690 6.880400 5.560019 6.863840 5.578709 6.841572 c
|
||||
5.616131 6.796984 5.674759 6.729844 5.753560 6.647617 c
|
||||
5.911709 6.482592 6.147886 6.260172 6.453634 6.037808 c
|
||||
7.067693 5.591221 7.933228 5.164998 9.000001 5.164996 c
|
||||
9.630135 5.164996 10.171014 5.264124 10.633532 5.448587 c
|
||||
10.639013 5.461485 10.644600 5.474353 10.650297 5.487185 c
|
||||
11.018882 6.317377 11.682623 6.981118 12.512815 7.349703 c
|
||||
12.904016 7.523386 13.325486 7.596285 13.811561 7.631045 c
|
||||
14.286482 7.665009 14.873948 7.665005 15.609417 7.665000 c
|
||||
15.634724 7.665000 l
|
||||
16.118099 7.665000 16.447754 7.665350 16.703396 7.682533 c
|
||||
16.953838 7.699367 17.082676 7.730085 17.170883 7.766621 c
|
||||
17.497993 7.902115 17.757885 8.162005 17.893379 8.489118 c
|
||||
17.915211 8.541822 17.934769 8.607892 17.950569 8.703643 c
|
||||
18.000000 9.667408 18.000000 10.867164 18.000000 12.461538 c
|
||||
18.000000 13.893039 18.000000 14.608788 17.818884 15.190012 c
|
||||
17.427801 16.445040 16.445040 17.427801 15.190012 17.818884 c
|
||||
14.608788 18.000000 13.893039 18.000000 12.461538 18.000000 c
|
||||
6.400000 18.000000 l
|
||||
4.159790 18.000000 3.039685 18.000000 2.184038 17.564026 c
|
||||
1.431390 17.180532 0.819467 16.568611 0.435974 15.815962 c
|
||||
h
|
||||
17.652130 6.526627 m
|
||||
17.381193 6.419186 17.097967 6.376053 16.792589 6.355527 c
|
||||
16.487034 6.334990 16.112497 6.334994 15.657384 6.335000 c
|
||||
15.634724 6.335000 l
|
||||
14.868204 6.335000 14.328320 6.334603 13.906430 6.304433 c
|
||||
13.490259 6.274672 13.242615 6.218527 13.052504 6.134122 c
|
||||
12.523582 5.899294 12.100706 5.476418 11.865878 4.947496 c
|
||||
11.781473 4.757385 11.725328 4.509741 11.695567 4.093570 c
|
||||
11.665397 3.671680 11.665000 3.131796 11.665000 2.365276 c
|
||||
11.665000 2.342616 l
|
||||
11.665006 1.887503 11.665010 1.512966 11.644473 1.207411 c
|
||||
11.623947 0.902033 11.580814 0.618807 11.473373 0.347870 c
|
||||
11.542342 0.366713 11.610334 0.386574 11.677527 0.407513 c
|
||||
14.501338 1.287447 16.712553 3.498662 17.592487 6.322473 c
|
||||
17.613426 6.389666 17.633287 6.457658 17.652130 6.526627 c
|
||||
h
|
||||
5.531581 6.899558 m
|
||||
5.311111 7.192892 4.894629 7.252222 4.601000 7.032000 c
|
||||
4.307185 6.811639 4.247638 6.394815 4.468000 6.101000 c
|
||||
5.000000 6.500000 l
|
||||
5.532000 6.899000 5.531850 6.899200 5.531705 6.899393 c
|
||||
5.531581 6.899558 l
|
||||
h
|
||||
7.500000 11.187500 m
|
||||
7.500000 10.324555 6.940356 9.625000 6.250000 9.625000 c
|
||||
5.559644 9.625000 5.000000 10.324555 5.000000 11.187500 c
|
||||
5.000000 12.050446 5.559644 12.750000 6.250000 12.750000 c
|
||||
6.940356 12.750000 7.500000 12.050446 7.500000 11.187500 c
|
||||
h
|
||||
13.000000 11.187500 m
|
||||
13.000000 10.324555 12.440355 9.625000 11.750000 9.625000 c
|
||||
11.059645 9.625000 10.500000 10.324555 10.500000 11.187500 c
|
||||
10.500000 12.050446 11.059645 12.750000 11.750000 12.750000 c
|
||||
12.440355 12.750000 13.000000 12.050446 13.000000 11.187500 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
4865
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000004955 00000 n
|
||||
0000004978 00000 n
|
||||
0000005151 00000 n
|
||||
0000005225 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
5284
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataVideo.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataVideo.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "video.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
123
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataVideo.imageset/video.pdf
vendored
Normal file
123
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataVideo.imageset/video.pdf
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.000000 0.478431 1.000000 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 5.000000 8.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
0.435974 11.815962 m
|
||||
0.000000 10.960315 0.000000 9.840210 0.000000 7.599999 c
|
||||
0.000000 6.400000 l
|
||||
0.000000 4.159790 0.000000 3.039685 0.435974 2.184038 c
|
||||
0.819467 1.431390 1.431390 0.819468 2.184038 0.435974 c
|
||||
3.039685 0.000000 4.159790 0.000000 6.400001 0.000000 c
|
||||
7.600000 0.000000 l
|
||||
9.840210 0.000000 10.960316 0.000000 11.815962 0.435974 c
|
||||
12.568610 0.819468 13.180532 1.431390 13.564026 2.184038 c
|
||||
14.000000 3.039685 14.000000 4.159790 14.000000 6.400001 c
|
||||
14.000000 7.600000 l
|
||||
14.000000 9.840210 14.000000 10.960315 13.564026 11.815962 c
|
||||
13.180532 12.568610 12.568610 13.180532 11.815962 13.564026 c
|
||||
10.960316 14.000000 9.840210 14.000000 7.599999 14.000000 c
|
||||
6.400000 14.000000 l
|
||||
4.159790 14.000000 3.039685 14.000000 2.184038 13.564026 c
|
||||
1.431390 13.180532 0.819467 12.568610 0.435974 11.815962 c
|
||||
h
|
||||
20.495096 10.957284 m
|
||||
20.443178 11.542397 19.985497 12.000000 19.428572 12.000000 c
|
||||
19.196747 12.000000 18.971174 11.919026 18.785715 11.769232 c
|
||||
16.071428 9.000020 l
|
||||
15.977040 8.916782 l
|
||||
15.674964 8.626339 15.500000 8.209476 15.500000 7.769259 c
|
||||
15.500000 6.230808 l
|
||||
15.505201 6.099547 l
|
||||
15.539715 5.665031 15.744408 5.264177 16.071428 5.000048 c
|
||||
18.785715 2.230835 l
|
||||
18.871206 2.168387 l
|
||||
19.337015 1.862048 19.951559 1.981793 20.285713 2.461603 c
|
||||
20.424809 2.661328 20.500000 2.904249 20.500000 3.153906 c
|
||||
20.500000 10.846162 l
|
||||
20.495096 10.957284 l
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
2403
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000002493 00000 n
|
||||
0000002516 00000 n
|
||||
0000002689 00000 n
|
||||
0000002763 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
2822
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataVoice.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataVoice.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "voice.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
156
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataVoice.imageset/voice.pdf
vendored
Normal file
156
submodules/TelegramUI/Images.xcassets/Settings/Menu/DataVoice.imageset/voice.pdf
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||
0.686275 0.321569 0.870588 scn
|
||||
0.000000 18.799999 m
|
||||
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
|
||||
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
|
||||
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
|
||||
18.799999 30.000000 l
|
||||
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
|
||||
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
|
||||
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
|
||||
30.000000 11.200001 l
|
||||
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
|
||||
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
|
||||
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
|
||||
11.200000 0.000000 l
|
||||
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
|
||||
0.000000 18.799999 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 11.000000 12.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
0.000000 10.000000 m
|
||||
0.000000 12.209139 1.790861 14.000000 4.000000 14.000000 c
|
||||
4.000000 14.000000 l
|
||||
6.209139 14.000000 8.000000 12.209139 8.000000 10.000000 c
|
||||
8.000000 4.000000 l
|
||||
8.000000 1.790861 6.209139 0.000000 4.000000 0.000000 c
|
||||
4.000000 0.000000 l
|
||||
1.790861 0.000000 0.000000 1.790861 0.000000 4.000000 c
|
||||
0.000000 10.000000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 8.000000 7.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
1.000000 9.500000 m
|
||||
1.000000 10.052285 0.552285 10.500000 0.000000 10.500000 c
|
||||
-0.552285 10.500000 -1.000000 10.052285 -1.000000 9.500000 c
|
||||
1.000000 9.500000 l
|
||||
h
|
||||
15.000000 9.500000 m
|
||||
15.000000 10.052285 14.552285 10.500000 14.000000 10.500000 c
|
||||
13.447716 10.500000 13.000000 10.052285 13.000000 9.500000 c
|
||||
15.000000 9.500000 l
|
||||
h
|
||||
-1.000000 9.500000 m
|
||||
-1.000000 9.000000 l
|
||||
1.000000 9.000000 l
|
||||
1.000000 9.500000 l
|
||||
-1.000000 9.500000 l
|
||||
h
|
||||
15.000000 9.000000 m
|
||||
15.000000 9.500000 l
|
||||
13.000000 9.500000 l
|
||||
13.000000 9.000000 l
|
||||
15.000000 9.000000 l
|
||||
h
|
||||
7.000000 1.000000 m
|
||||
11.418278 1.000000 15.000000 4.581722 15.000000 9.000000 c
|
||||
13.000000 9.000000 l
|
||||
13.000000 5.686292 10.313708 3.000000 7.000000 3.000000 c
|
||||
7.000000 1.000000 l
|
||||
h
|
||||
-1.000000 9.000000 m
|
||||
-1.000000 4.581722 2.581722 1.000000 7.000000 1.000000 c
|
||||
7.000000 3.000000 l
|
||||
3.686292 3.000000 1.000000 5.686292 1.000000 9.000000 c
|
||||
-1.000000 9.000000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 15.000000 4.000000 cm
|
||||
1.000000 1.000000 1.000000 scn
|
||||
-1.000000 1.000000 m
|
||||
-1.000000 0.447715 -0.552285 0.000000 0.000000 0.000000 c
|
||||
0.552285 0.000000 1.000000 0.447715 1.000000 1.000000 c
|
||||
-1.000000 1.000000 l
|
||||
h
|
||||
-1.000000 5.000000 m
|
||||
-1.000000 1.000000 l
|
||||
1.000000 1.000000 l
|
||||
1.000000 5.000000 l
|
||||
-1.000000 5.000000 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
2734
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000002824 00000 n
|
||||
0000002847 00000 n
|
||||
0000003020 00000 n
|
||||
0000003094 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
3153
|
||||
%%EOF
|
||||
@ -911,7 +911,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}, sendSticker: canSendMessagesToChat(strongSelf.presentationInterfaceState) ? { fileReference, sourceNode, sourceRect in
|
||||
return self?.controllerInteraction?.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, []) ?? false
|
||||
} : nil, sendEmoji: canSendMessagesToChat(strongSelf.presentationInterfaceState) ? { text, attribute in
|
||||
self?.controllerInteraction?.sendEmoji(text, attribute)
|
||||
self?.controllerInteraction?.sendEmoji(text, attribute, false)
|
||||
} : nil, setupTemporaryHiddenMedia: { signal, centralIndex, galleryMedia in
|
||||
if let strongSelf = self {
|
||||
strongSelf.temporaryHiddenGalleryMediaDisposable.set((signal |> deliverOnMainQueue).start(next: { entry in
|
||||
@ -2032,28 +2032,43 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongSelf.sendMessages(transformedMessages)
|
||||
}
|
||||
return true
|
||||
}, sendEmoji: { [weak self] text, attribute in
|
||||
}, sendEmoji: { [weak self] text, attribute, immediately in
|
||||
if let strongSelf = self {
|
||||
strongSelf.interfaceInteraction?.insertText(NSAttributedString(string: text, attributes: [ChatTextInputAttributes.customEmoji: attribute]))
|
||||
strongSelf.updateChatPresentationInterfaceState(interactive: true, { state in
|
||||
return state.updatedInputMode({ _ in
|
||||
return .text
|
||||
})
|
||||
})
|
||||
|
||||
let _ = (ApplicationSpecificNotice.getEmojiTooltip(accountManager: strongSelf.context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).start(next: { count in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
if immediately {
|
||||
if let file = attribute.file {
|
||||
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
|
||||
for attribute in file.attributes {
|
||||
if case let .CustomEmoji(_, _, _, packReference) = attribute {
|
||||
if case let .id(id, _) = packReference {
|
||||
bubbleUpEmojiOrStickersets.append(ItemCollectionId(namespace: Namespaces.ItemCollection.CloudEmojiPacks, id: id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.sendMessages([.message(text: text, attributes: [TextEntitiesMessageAttribute(entities: [MessageTextEntity(range: 0 ..< (text as NSString).length, type: .CustomEmoji(stickerPack: nil, fileId: file.fileId.id))])], inlineStickers: [file.fileId : file], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets)], commit: false)
|
||||
}
|
||||
if count < 2 {
|
||||
let _ = ApplicationSpecificNotice.incrementEmojiTooltip(accountManager: strongSelf.context.sharedContext.accountManager).start()
|
||||
|
||||
Queue.mainQueue().after(0.5, {
|
||||
strongSelf.displayEmojiTooltip()
|
||||
} else {
|
||||
strongSelf.interfaceInteraction?.insertText(NSAttributedString(string: text, attributes: [ChatTextInputAttributes.customEmoji: attribute]))
|
||||
strongSelf.updateChatPresentationInterfaceState(interactive: true, { state in
|
||||
return state.updatedInputMode({ _ in
|
||||
return .text
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
let _ = (ApplicationSpecificNotice.getEmojiTooltip(accountManager: strongSelf.context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).start(next: { count in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if count < 2 {
|
||||
let _ = ApplicationSpecificNotice.incrementEmojiTooltip(accountManager: strongSelf.context.sharedContext.accountManager).start()
|
||||
|
||||
Queue.mainQueue().after(0.5, {
|
||||
strongSelf.displayEmojiTooltip()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}, sendGif: { [weak self] fileReference, sourceView, sourceRect, silentPosting, schedule in
|
||||
if let strongSelf = self {
|
||||
@ -10261,11 +10276,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
} else if self.presentationInterfaceState.interfaceState.mediaRecordingMode == .audio {
|
||||
var canSendMedia = false
|
||||
if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel {
|
||||
if channel.hasBannedPermission(.banSendMedia) == nil {
|
||||
if channel.hasBannedPermission(.banSendMedia) == nil && channel.hasBannedPermission(.banSendVoice) == nil {
|
||||
canSendMedia = true
|
||||
}
|
||||
} else if let group = self.presentationInterfaceState.renderedPeer?.peer as? TelegramGroup {
|
||||
if !group.hasBannedPermission(.banSendMedia) {
|
||||
if !group.hasBannedPermission(.banSendMedia) && !group.hasBannedPermission(.banSendVoice) {
|
||||
canSendMedia = true
|
||||
}
|
||||
} else {
|
||||
@ -11932,22 +11947,37 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
self.chatDisplayNode.dismissInput()
|
||||
|
||||
var bannedSendMedia: (Int32, Bool)?
|
||||
var bannedSendPhotos: (Int32, Bool)?
|
||||
var bannedSendVideos: (Int32, Bool)?
|
||||
var bannedSendFiles: (Int32, Bool)?
|
||||
|
||||
var canSendPolls = true
|
||||
if let peer = peer as? TelegramUser, peer.botInfo == nil {
|
||||
canSendPolls = false
|
||||
} else if peer is TelegramSecretChat {
|
||||
canSendPolls = false
|
||||
} else if let channel = peer as? TelegramChannel {
|
||||
if let value = channel.hasBannedPermission(.banSendMedia) {
|
||||
bannedSendMedia = value
|
||||
if let value = channel.hasBannedPermission(.banSendPhotos) {
|
||||
bannedSendPhotos = value
|
||||
}
|
||||
if let value = channel.hasBannedPermission(.banSendVideos) {
|
||||
bannedSendVideos = value
|
||||
}
|
||||
if let value = channel.hasBannedPermission(.banSendFiles) {
|
||||
bannedSendFiles = value
|
||||
}
|
||||
if channel.hasBannedPermission(.banSendPolls) != nil {
|
||||
canSendPolls = false
|
||||
}
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
if group.hasBannedPermission(.banSendMedia) {
|
||||
bannedSendMedia = (Int32.max, false)
|
||||
if group.hasBannedPermission(.banSendPhotos) {
|
||||
bannedSendPhotos = (Int32.max, false)
|
||||
}
|
||||
if group.hasBannedPermission(.banSendVideos) {
|
||||
bannedSendVideos = (Int32.max, false)
|
||||
}
|
||||
if group.hasBannedPermission(.banSendFiles) {
|
||||
bannedSendFiles = (Int32.max, false)
|
||||
}
|
||||
if group.hasBannedPermission(.banSendPolls) {
|
||||
canSendPolls = false
|
||||
@ -12097,7 +12127,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
controller.prepareForReuse()
|
||||
return
|
||||
}
|
||||
strongSelf.presentMediaPicker(saveEditedPhotos: dataSettings.storeEditedPhotos, bannedSendMedia: bannedSendMedia, present: { controller, mediaPickerContext in
|
||||
strongSelf.presentMediaPicker(saveEditedPhotos: dataSettings.storeEditedPhotos, bannedSendPhotos: bannedSendPhotos, bannedSendVideos: bannedSendVideos, present: { controller, mediaPickerContext in
|
||||
let _ = currentMediaController.swap(controller)
|
||||
if !inputText.string.isEmpty {
|
||||
mediaPickerContext?.setCaption(inputText)
|
||||
@ -12119,7 +12149,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
controller.prepareForReuse()
|
||||
return
|
||||
}
|
||||
let controller = attachmentFileController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, bannedSendMedia: bannedSendMedia, presentGallery: { [weak self, weak attachmentController] in
|
||||
let controller = attachmentFileController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, bannedSendMedia: bannedSendFiles, presentGallery: { [weak self, weak attachmentController] in
|
||||
attachmentController?.dismiss(animated: true)
|
||||
self?.presentFileGallery()
|
||||
}, presentFiles: { [weak self, weak attachmentController] in
|
||||
@ -12796,11 +12826,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.present(actionSheet, in: .window(.root))
|
||||
}
|
||||
|
||||
private func presentMediaPicker(subject: MediaPickerScreen.Subject = .assets(nil), saveEditedPhotos: Bool, bannedSendMedia: (Int32, Bool)?, present: @escaping (MediaPickerScreen, AttachmentMediaPickerContext?) -> Void, updateMediaPickerContext: @escaping (AttachmentMediaPickerContext?) -> Void, completion: @escaping ([Any], Bool, Int32?, @escaping (String) -> UIView?, @escaping () -> Void) -> Void) {
|
||||
private func presentMediaPicker(subject: MediaPickerScreen.Subject = .assets(nil), saveEditedPhotos: Bool, bannedSendPhotos: (Int32, Bool)?, bannedSendVideos: (Int32, Bool)?, present: @escaping (MediaPickerScreen, AttachmentMediaPickerContext?) -> Void, updateMediaPickerContext: @escaping (AttachmentMediaPickerContext?) -> Void, completion: @escaping ([Any], Bool, Int32?, @escaping (String) -> UIView?, @escaping () -> Void) -> Void) {
|
||||
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
|
||||
return
|
||||
}
|
||||
let controller = MediaPickerScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, peer: EnginePeer(peer), threadTitle: self.threadInfo?.title, chatLocation: self.chatLocation, bannedSendMedia: bannedSendMedia, subject: subject, saveEditedPhotos: saveEditedPhotos)
|
||||
let controller = MediaPickerScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, peer: EnginePeer(peer), threadTitle: self.threadInfo?.title, chatLocation: self.chatLocation, bannedSendPhotos: bannedSendPhotos, bannedSendVideos: bannedSendVideos, subject: subject, saveEditedPhotos: saveEditedPhotos)
|
||||
let mediaPickerContext = controller.mediaPickerContext
|
||||
controller.openCamera = { [weak self] cameraView in
|
||||
self?.openCamera(cameraView: cameraView)
|
||||
@ -13616,7 +13646,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
if let stickerPackReference = stickerPackReference {
|
||||
let _ = (self.context.engine.stickers.loadedStickerPack(reference: stickerPackReference, forceActualized: false)
|
||||
self.presentEmojiList(references: [stickerPackReference])
|
||||
|
||||
/*let _ = (self.context.engine.stickers.loadedStickerPack(reference: stickerPackReference, forceActualized: false)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] stickerPack in
|
||||
if let strongSelf = self, case let .result(info, _, _) = stickerPack {
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: file, title: nil, text: strongSelf.presentationData.strings.Stickers_EmojiPackInfoText(info.title).string, undoText: strongSelf.presentationData.strings.Stickers_PremiumPackView, customAction: nil), elevatedLayout: false, action: { [weak self] action in
|
||||
@ -13626,7 +13658,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return false
|
||||
}), in: .current)
|
||||
}
|
||||
})
|
||||
})*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -13894,9 +13926,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
updatedPresentationData: strongSelf.updatedPresentationData,
|
||||
peer: EnginePeer(peer),
|
||||
subjects: subjects,
|
||||
presentMediaPicker: { [weak self] subject, saveEditedPhotos, bannedSendMedia, present in
|
||||
presentMediaPicker: { [weak self] subject, saveEditedPhotos, bannedSendPhotos, bannedSendVideos, present in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentMediaPicker(subject: subject, saveEditedPhotos: saveEditedPhotos, bannedSendMedia: bannedSendMedia, present: present, updateMediaPickerContext: { _ in }, completion: { [weak self] signals, silentPosting, scheduleTime, getAnimatedTransitionSource, completion in
|
||||
strongSelf.presentMediaPicker(subject: subject, saveEditedPhotos: saveEditedPhotos, bannedSendPhotos: bannedSendPhotos, bannedSendVideos: bannedSendVideos, present: present, updateMediaPickerContext: { _ in }, completion: { [weak self] signals, silentPosting, scheduleTime, getAnimatedTransitionSource, completion in
|
||||
self?.enqueueMediaMessages(signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime, getAnimatedTransitionSource: getAnimatedTransitionSource, completion: completion)
|
||||
})
|
||||
}
|
||||
@ -17390,7 +17422,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let presentationData = self.presentationData
|
||||
let controller = StickerPackScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, mainStickerPack: packReference, stickerPacks: Array(references), parentNavigationController: self.effectiveNavigationController, sendEmoji: canSendMessagesToChat(self.presentationInterfaceState) ? { [weak self] text, attribute in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controllerInteraction?.sendEmoji(text, attribute)
|
||||
strongSelf.controllerInteraction?.sendEmoji(text, attribute, false)
|
||||
}
|
||||
} : nil, actionPerformed: { [weak self] actions in
|
||||
guard let strongSelf = self else {
|
||||
|
||||
@ -274,7 +274,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}, openMessageContextActions: { _, _, _, _ in
|
||||
}, navigateToMessage: { _, _ in }, navigateToMessageStandalone: { _ in
|
||||
}, navigateToThreadMessage: { _, _, _ in
|
||||
}, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { [weak self] url, _, _, _ in
|
||||
}, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { [weak self] url, _, _, _ in
|
||||
self?.openUrl(url)
|
||||
}, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { [weak self] message, associatedData in
|
||||
if let strongSelf = self, let navigationController = strongSelf.getNavigationController() {
|
||||
|
||||
@ -84,7 +84,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu
|
||||
}, sendMessage: { _ in
|
||||
}, sendSticker: { _, _, _, _, _, _, _, _, _ in
|
||||
return false
|
||||
}, sendEmoji: { _, _ in
|
||||
}, sendEmoji: { _, _, _ in
|
||||
}, sendGif: { _, _, _, _, _ in
|
||||
return false
|
||||
}, sendBotContextResultAsGif: { _, _, _, _, _ in
|
||||
|
||||
@ -1751,8 +1751,14 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
||||
if let defaultBannedRights = channel.defaultBannedRights {
|
||||
var count = 0
|
||||
for (right, _) in allGroupPermissionList(peer: .channel(channel)) {
|
||||
if !defaultBannedRights.flags.contains(right) {
|
||||
count += 1
|
||||
if right == .banSendMedia {
|
||||
if banSendMediaSubList().allSatisfy({ !defaultBannedRights.flags.contains($0.0) }) {
|
||||
count += 1
|
||||
}
|
||||
} else {
|
||||
if !defaultBannedRights.flags.contains(right) {
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
activePermissionCount = count
|
||||
@ -1868,8 +1874,14 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
||||
if let defaultBannedRights = group.defaultBannedRights {
|
||||
var count = 0
|
||||
for (right, _) in allGroupPermissionList(peer: .legacyGroup(group)) {
|
||||
if !defaultBannedRights.flags.contains(right) {
|
||||
count += 1
|
||||
if right == .banSendMedia {
|
||||
if banSendMediaSubList().allSatisfy({ !defaultBannedRights.flags.contains($0.0) }) {
|
||||
count += 1
|
||||
}
|
||||
} else {
|
||||
if !defaultBannedRights.flags.contains(right) {
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
activePermissionCount = count
|
||||
@ -2563,7 +2575,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}, sendMessage: { _ in
|
||||
}, sendSticker: { _, _, _, _, _, _, _, _, _ in
|
||||
return false
|
||||
}, sendEmoji: { _, _ in
|
||||
}, sendEmoji: { _, _, _ in
|
||||
}, sendGif: { _, _, _, _, _ in
|
||||
return false
|
||||
}, sendBotContextResultAsGif: { _, _, _, _, _ in
|
||||
|
||||
@ -1301,7 +1301,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
tapMessage?(message)
|
||||
}, clickThroughMessage: {
|
||||
clickThroughMessage?()
|
||||
}, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in
|
||||
}, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in
|
||||
return false
|
||||
}, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { _, _, _, _ in }, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { _, _ in }, openWallpaper: { _ in }, openTheme: { _ in }, openHashtag: { _, _ in }, updateInputState: { _ in }, updateInputMode: { _ in }, openMessageShareMenu: { _ in
|
||||
}, presentController: { _, _ in
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user