mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
1305 lines
62 KiB
Swift
1305 lines
62 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import AsyncDisplayKit
|
|
import Postbox
|
|
import TelegramCore
|
|
import TelegramPresentationData
|
|
import TelegramUIPreferences
|
|
import SwiftSignalKit
|
|
import AsyncDisplayKit
|
|
import Display
|
|
import DeviceLocationManager
|
|
import TemporaryCachedPeerDataManager
|
|
import InAppPurchaseManager
|
|
import AnimationCache
|
|
import MultiAnimationRenderer
|
|
import Photos
|
|
import TextFormat
|
|
|
|
public final class TelegramApplicationOpenUrlCompletion {
|
|
public let completion: (Bool) -> Void
|
|
|
|
public init(completion: @escaping (Bool) -> Void) {
|
|
self.completion = completion
|
|
}
|
|
}
|
|
|
|
public enum AccessType {
|
|
case notDetermined
|
|
case allowed
|
|
case denied
|
|
case restricted
|
|
case unreachable
|
|
}
|
|
|
|
public enum TelegramAppBuildType {
|
|
case `internal`
|
|
case `public`
|
|
}
|
|
|
|
public final class TelegramApplicationBindings {
|
|
public let isMainApp: Bool
|
|
public let appBundleId: String
|
|
public let appBuildType: TelegramAppBuildType
|
|
public let containerPath: String
|
|
public let appSpecificScheme: String
|
|
public let openUrl: (String) -> Void
|
|
public let openUniversalUrl: (String, TelegramApplicationOpenUrlCompletion) -> Void
|
|
public let canOpenUrl: (String) -> Bool
|
|
public let getTopWindow: () -> UIWindow?
|
|
public let displayNotification: (String) -> Void
|
|
public let applicationInForeground: Signal<Bool, NoError>
|
|
public let applicationIsActive: Signal<Bool, NoError>
|
|
public let clearMessageNotifications: ([MessageId]) -> Void
|
|
public let pushIdleTimerExtension: () -> Disposable
|
|
public let openSettings: () -> Void
|
|
public let openAppStorePage: () -> Void
|
|
public let openSubscriptions: () -> Void
|
|
public let registerForNotifications: (@escaping (Bool) -> Void) -> Void
|
|
public let requestSiriAuthorization: (@escaping (Bool) -> Void) -> Void
|
|
public let siriAuthorization: () -> AccessType
|
|
public let getWindowHost: () -> WindowHost?
|
|
public let presentNativeController: (UIViewController) -> Void
|
|
public let dismissNativeController: () -> Void
|
|
public let getAvailableAlternateIcons: () -> [PresentationAppIcon]
|
|
public let getAlternateIconName: () -> String?
|
|
public let requestSetAlternateIconName: (String?, @escaping (Bool) -> Void) -> Void
|
|
public let forceOrientation: (UIInterfaceOrientation) -> Void
|
|
|
|
public init(isMainApp: Bool, appBundleId: String, appBuildType: TelegramAppBuildType, containerPath: String, appSpecificScheme: String, openUrl: @escaping (String) -> Void, openUniversalUrl: @escaping (String, TelegramApplicationOpenUrlCompletion) -> Void, canOpenUrl: @escaping (String) -> Bool, getTopWindow: @escaping () -> UIWindow?, displayNotification: @escaping (String) -> Void, applicationInForeground: Signal<Bool, NoError>, applicationIsActive: Signal<Bool, NoError>, clearMessageNotifications: @escaping ([MessageId]) -> Void, pushIdleTimerExtension: @escaping () -> Disposable, openSettings: @escaping () -> Void, openAppStorePage: @escaping () -> Void, openSubscriptions: @escaping () -> Void, registerForNotifications: @escaping (@escaping (Bool) -> Void) -> Void, requestSiriAuthorization: @escaping (@escaping (Bool) -> Void) -> Void, siriAuthorization: @escaping () -> AccessType, getWindowHost: @escaping () -> WindowHost?, presentNativeController: @escaping (UIViewController) -> Void, dismissNativeController: @escaping () -> Void, getAvailableAlternateIcons: @escaping () -> [PresentationAppIcon], getAlternateIconName: @escaping () -> String?, requestSetAlternateIconName: @escaping (String?, @escaping (Bool) -> Void) -> Void, forceOrientation: @escaping (UIInterfaceOrientation) -> Void) {
|
|
self.isMainApp = isMainApp
|
|
self.appBundleId = appBundleId
|
|
self.appBuildType = appBuildType
|
|
self.containerPath = containerPath
|
|
self.appSpecificScheme = appSpecificScheme
|
|
self.openUrl = openUrl
|
|
self.openUniversalUrl = openUniversalUrl
|
|
self.canOpenUrl = canOpenUrl
|
|
self.getTopWindow = getTopWindow
|
|
self.displayNotification = displayNotification
|
|
self.applicationInForeground = applicationInForeground
|
|
self.applicationIsActive = applicationIsActive
|
|
self.clearMessageNotifications = clearMessageNotifications
|
|
self.pushIdleTimerExtension = pushIdleTimerExtension
|
|
self.openSettings = openSettings
|
|
self.openAppStorePage = openAppStorePage
|
|
self.openSubscriptions = openSubscriptions
|
|
self.registerForNotifications = registerForNotifications
|
|
self.requestSiriAuthorization = requestSiriAuthorization
|
|
self.siriAuthorization = siriAuthorization
|
|
self.presentNativeController = presentNativeController
|
|
self.dismissNativeController = dismissNativeController
|
|
self.getWindowHost = getWindowHost
|
|
self.getAvailableAlternateIcons = getAvailableAlternateIcons
|
|
self.getAlternateIconName = getAlternateIconName
|
|
self.requestSetAlternateIconName = requestSetAlternateIconName
|
|
self.forceOrientation = forceOrientation
|
|
}
|
|
}
|
|
|
|
public enum TextLinkItemActionType {
|
|
case tap
|
|
case longTap
|
|
}
|
|
|
|
public enum TextLinkItem: Equatable {
|
|
case url(url: String, concealed: Bool)
|
|
case mention(String)
|
|
case hashtag(String?, String)
|
|
}
|
|
|
|
public final class AccountWithInfo: Equatable {
|
|
public let account: Account
|
|
public let peer: Peer
|
|
|
|
public init(account: Account, peer: Peer) {
|
|
self.account = account
|
|
self.peer = peer
|
|
}
|
|
|
|
public static func ==(lhs: AccountWithInfo, rhs: AccountWithInfo) -> Bool {
|
|
if lhs.account !== rhs.account {
|
|
return false
|
|
}
|
|
if !arePeersEqual(lhs.peer, rhs.peer) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
|
|
public enum OpenURLContext {
|
|
case generic
|
|
case chat(peerId: PeerId, message: Message?, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?)
|
|
}
|
|
|
|
public struct ChatAvailableMessageActionOptions: OptionSet {
|
|
public var rawValue: Int32
|
|
|
|
public init(rawValue: Int32) {
|
|
self.rawValue = rawValue
|
|
}
|
|
|
|
public init() {
|
|
self.rawValue = 0
|
|
}
|
|
|
|
public static let deleteLocally = ChatAvailableMessageActionOptions(rawValue: 1 << 0)
|
|
public static let deleteGlobally = ChatAvailableMessageActionOptions(rawValue: 1 << 1)
|
|
public static let forward = ChatAvailableMessageActionOptions(rawValue: 1 << 2)
|
|
public static let report = ChatAvailableMessageActionOptions(rawValue: 1 << 3)
|
|
public static let viewStickerPack = ChatAvailableMessageActionOptions(rawValue: 1 << 4)
|
|
public static let rateCall = ChatAvailableMessageActionOptions(rawValue: 1 << 5)
|
|
public static let cancelSending = ChatAvailableMessageActionOptions(rawValue: 1 << 6)
|
|
public static let unsendPersonal = ChatAvailableMessageActionOptions(rawValue: 1 << 7)
|
|
public static let sendScheduledNow = ChatAvailableMessageActionOptions(rawValue: 1 << 8)
|
|
public static let editScheduledTime = ChatAvailableMessageActionOptions(rawValue: 1 << 9)
|
|
public static let externalShare = ChatAvailableMessageActionOptions(rawValue: 1 << 10)
|
|
}
|
|
|
|
public struct ChatAvailableMessageActions {
|
|
public var options: ChatAvailableMessageActionOptions
|
|
public var banAuthor: Peer?
|
|
public var banAuthors: [Peer]
|
|
public var disableDelete: Bool
|
|
public var isCopyProtected: Bool
|
|
public var setTag: Bool
|
|
public var editTags: Set<MessageReaction.Reaction>
|
|
|
|
public init(options: ChatAvailableMessageActionOptions, banAuthor: Peer?, banAuthors: [Peer], disableDelete: Bool, isCopyProtected: Bool, setTag: Bool, editTags: Set<MessageReaction.Reaction>) {
|
|
self.options = options
|
|
self.banAuthor = banAuthor
|
|
self.banAuthors = banAuthors
|
|
self.disableDelete = disableDelete
|
|
self.isCopyProtected = isCopyProtected
|
|
self.setTag = setTag
|
|
self.editTags = editTags
|
|
}
|
|
}
|
|
|
|
public enum WallpaperUrlParameter {
|
|
case slug(String, WallpaperPresentationOptions, [UInt32], Int32?, Int32?)
|
|
case color(UIColor)
|
|
case gradient([UInt32], Int32?)
|
|
}
|
|
|
|
public enum ResolvedUrlSettingsSection {
|
|
case theme
|
|
case devices
|
|
case autoremoveMessages
|
|
case twoStepAuth
|
|
case enableLog
|
|
}
|
|
|
|
public struct ResolvedBotChoosePeerTypes: OptionSet {
|
|
public var rawValue: UInt32
|
|
|
|
public init(rawValue: UInt32) {
|
|
self.rawValue = rawValue
|
|
}
|
|
|
|
public init() {
|
|
self.rawValue = 0
|
|
}
|
|
|
|
public static let users = ResolvedBotChoosePeerTypes(rawValue: 1)
|
|
public static let bots = ResolvedBotChoosePeerTypes(rawValue: 2)
|
|
public static let groups = ResolvedBotChoosePeerTypes(rawValue: 4)
|
|
public static let channels = ResolvedBotChoosePeerTypes(rawValue: 16)
|
|
}
|
|
|
|
public struct ResolvedBotAdminRights: OptionSet {
|
|
public var rawValue: UInt32
|
|
|
|
public init(rawValue: UInt32) {
|
|
self.rawValue = rawValue
|
|
}
|
|
|
|
public init() {
|
|
self.rawValue = 0
|
|
}
|
|
|
|
public static let changeInfo = ResolvedBotAdminRights(rawValue: 1)
|
|
public static let postMessages = ResolvedBotAdminRights(rawValue: 2)
|
|
public static let editMessages = ResolvedBotAdminRights(rawValue: 4)
|
|
public static let deleteMessages = ResolvedBotAdminRights(rawValue: 16)
|
|
public static let restrictMembers = ResolvedBotAdminRights(rawValue: 32)
|
|
public static let inviteUsers = ResolvedBotAdminRights(rawValue: 64)
|
|
public static let pinMessages = ResolvedBotAdminRights(rawValue: 128)
|
|
public static let promoteMembers = ResolvedBotAdminRights(rawValue: 256)
|
|
public static let manageVideoChats = ResolvedBotAdminRights(rawValue: 512)
|
|
public static let canBeAnonymous = ResolvedBotAdminRights(rawValue: 1024)
|
|
public static let manageChat = ResolvedBotAdminRights(rawValue: 2048)
|
|
|
|
public var chatAdminRights: TelegramChatAdminRightsFlags? {
|
|
var flags = TelegramChatAdminRightsFlags()
|
|
|
|
if self.contains(ResolvedBotAdminRights.changeInfo) {
|
|
flags.insert(.canChangeInfo)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.postMessages) {
|
|
flags.insert(.canPostMessages)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.editMessages) {
|
|
flags.insert(.canEditMessages)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.deleteMessages) {
|
|
flags.insert(.canDeleteMessages)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.restrictMembers) {
|
|
flags.insert(.canBanUsers)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.inviteUsers) {
|
|
flags.insert(.canInviteUsers)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.pinMessages) {
|
|
flags.insert(.canPinMessages)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.promoteMembers) {
|
|
flags.insert(.canAddAdmins)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.manageVideoChats) {
|
|
flags.insert(.canManageCalls)
|
|
}
|
|
if self.contains(ResolvedBotAdminRights.canBeAnonymous) {
|
|
flags.insert(.canBeAnonymous)
|
|
}
|
|
|
|
if flags.isEmpty && !self.contains(ResolvedBotAdminRights.manageChat) {
|
|
return nil
|
|
}
|
|
|
|
return flags
|
|
}
|
|
}
|
|
|
|
public enum StickerPackUrlType {
|
|
case stickers
|
|
case emoji
|
|
}
|
|
|
|
public enum ResolvedUrl {
|
|
case externalUrl(String)
|
|
case urlAuth(String)
|
|
case peer(Peer?, ChatControllerInteractionNavigateToPeer)
|
|
case inaccessiblePeer
|
|
case botStart(peer: Peer, payload: String)
|
|
case groupBotStart(peerId: PeerId, payload: String, adminRights: ResolvedBotAdminRights?)
|
|
case gameStart(peerId: PeerId, game: String)
|
|
case channelMessage(peer: Peer, messageId: MessageId, timecode: Double?)
|
|
case replyThreadMessage(replyThreadMessage: ChatReplyThreadMessage, messageId: MessageId)
|
|
case replyThread(messageId: MessageId)
|
|
case stickerPack(name: String, type: StickerPackUrlType)
|
|
case instantView(TelegramMediaWebpage, String?)
|
|
case proxy(host: String, port: Int32, username: String?, password: String?, secret: Data?)
|
|
case join(String)
|
|
case localization(String)
|
|
case confirmationCode(Int)
|
|
case cancelAccountReset(phone: String, hash: String)
|
|
case share(url: String?, text: String?, to: String?)
|
|
case wallpaper(WallpaperUrlParameter)
|
|
case theme(String)
|
|
case settings(ResolvedUrlSettingsSection)
|
|
case joinVoiceChat(PeerId, String?)
|
|
case importStickers
|
|
case startAttach(peerId: PeerId, payload: String?, choose: ResolvedBotChoosePeerTypes?)
|
|
case invoice(slug: String, invoice: TelegramMediaInvoice?)
|
|
case premiumOffer(reference: String?)
|
|
case chatFolder(slug: String)
|
|
case story(peerId: PeerId, id: Int32)
|
|
case boost(peerId: PeerId?, status: ChannelBoostStatus?, myBoostStatus: MyBoostStatus?)
|
|
case premiumGiftCode(slug: String)
|
|
case premiumMultiGift(reference: String?)
|
|
case messageLink(link: TelegramResolvedMessageLink?)
|
|
}
|
|
|
|
public enum ResolveUrlResult {
|
|
case progress
|
|
case result(ResolvedUrl)
|
|
}
|
|
|
|
public enum NavigateToChatKeepStack {
|
|
case `default`
|
|
case always
|
|
case never
|
|
}
|
|
|
|
public final class ChatPeekTimeout {
|
|
public let deadline: Int32
|
|
public let linkData: String
|
|
|
|
public init(deadline: Int32, linkData: String) {
|
|
self.deadline = deadline
|
|
self.linkData = linkData
|
|
}
|
|
}
|
|
|
|
public final class ChatPeerNearbyData: Equatable {
|
|
public static func == (lhs: ChatPeerNearbyData, rhs: ChatPeerNearbyData) -> Bool {
|
|
return lhs.distance == rhs.distance
|
|
}
|
|
|
|
public let distance: Int32
|
|
|
|
public init(distance: Int32) {
|
|
self.distance = distance
|
|
}
|
|
}
|
|
|
|
public final class ChatGreetingData: Equatable {
|
|
public static func == (lhs: ChatGreetingData, rhs: ChatGreetingData) -> Bool {
|
|
return lhs.uuid == rhs.uuid
|
|
}
|
|
|
|
public let uuid: UUID
|
|
public let sticker: Signal<TelegramMediaFile?, NoError>
|
|
|
|
public init(uuid: UUID, sticker: Signal<TelegramMediaFile?, NoError>) {
|
|
self.uuid = uuid
|
|
self.sticker = sticker
|
|
}
|
|
}
|
|
|
|
public enum ChatSearchDomain: Equatable {
|
|
case everything
|
|
case members
|
|
case member(Peer)
|
|
case tag(MessageReaction.Reaction)
|
|
|
|
public static func ==(lhs: ChatSearchDomain, rhs: ChatSearchDomain) -> Bool {
|
|
switch lhs {
|
|
case .everything:
|
|
if case .everything = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case .members:
|
|
if case .members = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .member(lhsPeer):
|
|
if case let .member(rhsPeer) = rhs, lhsPeer.isEqual(rhsPeer) {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .tag(reaction):
|
|
if case .tag(reaction) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum ChatLocation: Equatable {
|
|
case peer(id: PeerId)
|
|
case replyThread(message: ChatReplyThreadMessage)
|
|
case customChatContents
|
|
}
|
|
|
|
public extension ChatLocation {
|
|
var normalized: ChatLocation {
|
|
switch self {
|
|
case .peer, .customChatContents:
|
|
return self
|
|
case let .replyThread(message):
|
|
return .replyThread(message: message.normalized)
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum ChatControllerActivateInput {
|
|
case text
|
|
case entityInput
|
|
}
|
|
|
|
public struct ChatNavigationStackItem: Hashable {
|
|
public var peerId: EnginePeer.Id
|
|
public var threadId: Int64?
|
|
|
|
public init(peerId: EnginePeer.Id, threadId: Int64?) {
|
|
self.peerId = peerId
|
|
self.threadId = threadId
|
|
}
|
|
}
|
|
|
|
public final class NavigateToChatControllerParams {
|
|
public enum Location {
|
|
case peer(EnginePeer)
|
|
case replyThread(ChatReplyThreadMessage)
|
|
|
|
public var peerId: EnginePeer.Id {
|
|
switch self {
|
|
case let .peer(peer):
|
|
return peer.id
|
|
case let .replyThread(message):
|
|
return message.peerId
|
|
}
|
|
}
|
|
|
|
public var threadId: Int64? {
|
|
switch self {
|
|
case .peer:
|
|
return nil
|
|
case let .replyThread(message):
|
|
return message.threadId
|
|
}
|
|
}
|
|
|
|
public var asChatLocation: ChatLocation {
|
|
switch self {
|
|
case let .peer(peer):
|
|
return .peer(id: peer.id)
|
|
case let .replyThread(message):
|
|
return .replyThread(message: message)
|
|
}
|
|
}
|
|
}
|
|
|
|
public let navigationController: NavigationController
|
|
public let chatController: ChatController?
|
|
public let context: AccountContext
|
|
public let chatLocation: Location
|
|
public let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>
|
|
public let subject: ChatControllerSubject?
|
|
public let botStart: ChatControllerInitialBotStart?
|
|
public let attachBotStart: ChatControllerInitialAttachBotStart?
|
|
public let botAppStart: ChatControllerInitialBotAppStart?
|
|
public let updateTextInputState: ChatTextInputState?
|
|
public let activateInput: ChatControllerActivateInput?
|
|
public let keepStack: NavigateToChatKeepStack
|
|
public let useExisting: Bool
|
|
public let useBackAnimation: Bool
|
|
public let purposefulAction: (() -> Void)?
|
|
public let scrollToEndIfExists: Bool
|
|
public let activateMessageSearch: (ChatSearchDomain, String)?
|
|
public let peekData: ChatPeekTimeout?
|
|
public let peerNearbyData: ChatPeerNearbyData?
|
|
public let reportReason: ReportReason?
|
|
public let animated: Bool
|
|
public let options: NavigationAnimationOptions
|
|
public let parentGroupId: PeerGroupId?
|
|
public let chatListFilter: Int32?
|
|
public let chatNavigationStack: [ChatNavigationStackItem]
|
|
public let changeColors: Bool
|
|
public let setupController: (ChatController) -> Void
|
|
public let completion: (ChatController) -> Void
|
|
public let chatListCompletion: ((ChatListController) -> Void)?
|
|
public let pushController: ((ChatController, Bool, @escaping () -> Void) -> Void)?
|
|
public let forceOpenChat: Bool
|
|
public let customChatNavigationStack: [EnginePeer.Id]?
|
|
|
|
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: Location, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, attachBotStart: ChatControllerInitialAttachBotStart? = nil, botAppStart: ChatControllerInitialBotAppStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: ChatControllerActivateInput? = nil, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, useBackAnimation: Bool = false, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [ChatNavigationStackItem] = [], changeColors: Bool = false, setupController: @escaping (ChatController) -> Void = { _ in }, pushController: ((ChatController, Bool, @escaping () -> Void) -> Void)? = nil, completion: @escaping (ChatController) -> Void = { _ in }, chatListCompletion: @escaping (ChatListController) -> Void = { _ in }, forceOpenChat: Bool = false, customChatNavigationStack: [EnginePeer.Id]? = nil) {
|
|
self.navigationController = navigationController
|
|
self.chatController = chatController
|
|
self.chatLocationContextHolder = chatLocationContextHolder
|
|
self.context = context
|
|
self.chatLocation = chatLocation
|
|
self.subject = subject
|
|
self.botStart = botStart
|
|
self.attachBotStart = attachBotStart
|
|
self.botAppStart = botAppStart
|
|
self.updateTextInputState = updateTextInputState
|
|
self.activateInput = activateInput
|
|
self.keepStack = keepStack
|
|
self.useExisting = useExisting
|
|
self.useBackAnimation = useBackAnimation
|
|
self.purposefulAction = purposefulAction
|
|
self.scrollToEndIfExists = scrollToEndIfExists
|
|
self.activateMessageSearch = activateMessageSearch
|
|
self.peekData = peekData
|
|
self.peerNearbyData = peerNearbyData
|
|
self.reportReason = reportReason
|
|
self.animated = animated
|
|
self.options = options
|
|
self.parentGroupId = parentGroupId
|
|
self.chatListFilter = chatListFilter
|
|
self.chatNavigationStack = chatNavigationStack
|
|
self.changeColors = changeColors
|
|
self.setupController = setupController
|
|
self.pushController = pushController
|
|
self.completion = completion
|
|
self.chatListCompletion = chatListCompletion
|
|
self.forceOpenChat = forceOpenChat
|
|
self.customChatNavigationStack = customChatNavigationStack
|
|
}
|
|
}
|
|
|
|
public enum DeviceContactInfoSubject {
|
|
case vcard(Peer?, DeviceContactStableId?, DeviceContactExtendedData)
|
|
case filter(peer: Peer?, contactId: DeviceContactStableId?, contactData: DeviceContactExtendedData, completion: (Peer?, DeviceContactExtendedData) -> Void)
|
|
case create(peer: Peer?, contactData: DeviceContactExtendedData, isSharing: Bool, shareViaException: Bool, completion: (Peer?, DeviceContactStableId, DeviceContactExtendedData) -> Void)
|
|
|
|
public var peer: Peer? {
|
|
switch self {
|
|
case let .vcard(peer, _, _):
|
|
return peer
|
|
case let .filter(peer, _, _, _):
|
|
return peer
|
|
case .create:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public var contactData: DeviceContactExtendedData {
|
|
switch self {
|
|
case let .vcard(_, _, data):
|
|
return data
|
|
case let .filter(_, _, data, _):
|
|
return data
|
|
case let .create(_, data, _, _, _):
|
|
return data
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum PeerInfoControllerMode {
|
|
case generic
|
|
case calls(messages: [Message])
|
|
case nearbyPeer(distance: Int32)
|
|
case group(PeerId)
|
|
case reaction(MessageId)
|
|
case forumTopic(thread: ChatReplyThreadMessage)
|
|
case recommendedChannels
|
|
case myProfile
|
|
}
|
|
|
|
public enum ContactListActionItemInlineIconPosition {
|
|
case left
|
|
case right
|
|
}
|
|
|
|
public enum ContactListActionItemIcon : Equatable {
|
|
case none
|
|
case generic(UIImage)
|
|
case inline(UIImage, ContactListActionItemInlineIconPosition)
|
|
|
|
public var image: UIImage? {
|
|
switch self {
|
|
case .none:
|
|
return nil
|
|
case let .generic(image):
|
|
return image
|
|
case let .inline(image, _):
|
|
return image
|
|
}
|
|
}
|
|
|
|
public static func ==(lhs: ContactListActionItemIcon, rhs: ContactListActionItemIcon) -> Bool {
|
|
switch lhs {
|
|
case .none:
|
|
if case .none = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .generic(image):
|
|
if case .generic(image) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .inline(image, position):
|
|
if case .inline(image, position) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct ContactListAdditionalOption: Equatable {
|
|
public let title: String
|
|
public let icon: ContactListActionItemIcon
|
|
public let action: () -> Void
|
|
public let clearHighlightAutomatically: Bool
|
|
|
|
public init(title: String, icon: ContactListActionItemIcon, action: @escaping () -> Void, clearHighlightAutomatically: Bool = false) {
|
|
self.title = title
|
|
self.icon = icon
|
|
self.action = action
|
|
self.clearHighlightAutomatically = clearHighlightAutomatically
|
|
}
|
|
|
|
public static func ==(lhs: ContactListAdditionalOption, rhs: ContactListAdditionalOption) -> Bool {
|
|
return lhs.title == rhs.title && lhs.icon == rhs.icon
|
|
}
|
|
}
|
|
|
|
public enum ContactListPeerId: Hashable {
|
|
case peer(PeerId)
|
|
case deviceContact(DeviceContactStableId)
|
|
}
|
|
|
|
public enum ContactListAction: Equatable {
|
|
case generic
|
|
case voiceCall
|
|
case videoCall
|
|
case more
|
|
}
|
|
|
|
public enum ContactListPeer: Equatable {
|
|
case peer(peer: Peer, isGlobal: Bool, participantCount: Int32?)
|
|
case deviceContact(DeviceContactStableId, DeviceContactBasicData)
|
|
|
|
public var id: ContactListPeerId {
|
|
switch self {
|
|
case let .peer(peer, _, _):
|
|
return .peer(peer.id)
|
|
case let .deviceContact(id, _):
|
|
return .deviceContact(id)
|
|
}
|
|
}
|
|
|
|
public var indexName: PeerIndexNameRepresentation {
|
|
switch self {
|
|
case let .peer(peer, _, _):
|
|
return peer.indexName
|
|
case let .deviceContact(_, contact):
|
|
return .personName(first: contact.firstName, last: contact.lastName, addressNames: [], phoneNumber: "")
|
|
}
|
|
}
|
|
|
|
public static func ==(lhs: ContactListPeer, rhs: ContactListPeer) -> Bool {
|
|
switch lhs {
|
|
case let .peer(lhsPeer, lhsIsGlobal, lhsParticipantCount):
|
|
if case let .peer(rhsPeer, rhsIsGlobal, rhsParticipantCount) = rhs, lhsPeer.isEqual(rhsPeer), lhsIsGlobal == rhsIsGlobal, lhsParticipantCount == rhsParticipantCount {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .deviceContact(id, contact):
|
|
if case .deviceContact(id, contact) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public final class ContactSelectionControllerParams {
|
|
public let context: AccountContext
|
|
public let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?
|
|
public let autoDismiss: Bool
|
|
public let title: (PresentationStrings) -> String
|
|
public let options: [ContactListAdditionalOption]
|
|
public let displayDeviceContacts: Bool
|
|
public let displayCallIcons: Bool
|
|
public let multipleSelection: Bool
|
|
public let requirePhoneNumbers: Bool
|
|
public let confirmation: (ContactListPeer) -> Signal<Bool, NoError>
|
|
|
|
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, autoDismiss: Bool = true, title: @escaping (PresentationStrings) -> String, options: [ContactListAdditionalOption] = [], displayDeviceContacts: Bool = false, displayCallIcons: Bool = false, multipleSelection: Bool = false, requirePhoneNumbers: Bool = false, confirmation: @escaping (ContactListPeer) -> Signal<Bool, NoError> = { _ in .single(true) }) {
|
|
self.context = context
|
|
self.updatedPresentationData = updatedPresentationData
|
|
self.autoDismiss = autoDismiss
|
|
self.title = title
|
|
self.options = options
|
|
self.displayDeviceContacts = displayDeviceContacts
|
|
self.displayCallIcons = displayCallIcons
|
|
self.multipleSelection = multipleSelection
|
|
self.requirePhoneNumbers = requirePhoneNumbers
|
|
self.confirmation = confirmation
|
|
}
|
|
}
|
|
|
|
public enum ChatListSearchFilter: Equatable {
|
|
case chats
|
|
case topics
|
|
case channels
|
|
case media
|
|
case downloads
|
|
case links
|
|
case files
|
|
case music
|
|
case voice
|
|
case peer(PeerId, Bool, String, String)
|
|
case date(Int32?, Int32, String)
|
|
|
|
public var id: Int64 {
|
|
switch self {
|
|
case .chats:
|
|
return 0
|
|
case .topics:
|
|
return 1
|
|
case .channels:
|
|
return 2
|
|
case .media:
|
|
return 3
|
|
case .downloads:
|
|
return 4
|
|
case .links:
|
|
return 5
|
|
case .files:
|
|
return 6
|
|
case .music:
|
|
return 7
|
|
case .voice:
|
|
return 8
|
|
case let .peer(peerId, _, _, _):
|
|
return peerId.id._internalGetInt64Value()
|
|
case let .date(_, date, _):
|
|
return Int64(date)
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum InstalledStickerPacksControllerMode {
|
|
case general
|
|
case modal
|
|
case masks
|
|
case emoji
|
|
}
|
|
|
|
public let defaultContactLabel: String = "_$!<Mobile>!$_"
|
|
|
|
public enum CreateGroupMode {
|
|
case generic
|
|
case supergroup
|
|
case locatedGroup(latitude: Double, longitude: Double, address: String?)
|
|
case requestPeer(ReplyMarkupButtonRequestPeerType.Group)
|
|
}
|
|
|
|
public protocol AppLockContext: AnyObject {
|
|
var invalidAttempts: Signal<AccessChallengeAttempts?, NoError> { get }
|
|
var autolockDeadline: Signal<Int32?, NoError> { get }
|
|
|
|
func lock()
|
|
func unlock()
|
|
func failedUnlockAttempt()
|
|
}
|
|
|
|
public protocol RecentSessionsController: AnyObject {
|
|
}
|
|
|
|
public protocol AttachmentFileController: AnyObject {
|
|
}
|
|
|
|
public struct StoryCameraTransitionIn {
|
|
public weak var sourceView: UIView?
|
|
public let sourceRect: CGRect
|
|
public let sourceCornerRadius: CGFloat
|
|
|
|
public init(
|
|
sourceView: UIView,
|
|
sourceRect: CGRect,
|
|
sourceCornerRadius: CGFloat
|
|
) {
|
|
self.sourceView = sourceView
|
|
self.sourceRect = sourceRect
|
|
self.sourceCornerRadius = sourceCornerRadius
|
|
}
|
|
}
|
|
|
|
public struct StoryCameraTransitionOut {
|
|
public weak var destinationView: UIView?
|
|
public let destinationRect: CGRect
|
|
public let destinationCornerRadius: CGFloat
|
|
|
|
public init(
|
|
destinationView: UIView,
|
|
destinationRect: CGRect,
|
|
destinationCornerRadius: CGFloat
|
|
) {
|
|
self.destinationView = destinationView
|
|
self.destinationRect = destinationRect
|
|
self.destinationCornerRadius = destinationCornerRadius
|
|
}
|
|
}
|
|
|
|
public struct StoryCameraTransitionInCoordinator {
|
|
public let animateIn: () -> Void
|
|
public let updateTransitionProgress: (CGFloat) -> Void
|
|
public let completeWithTransitionProgressAndVelocity: (CGFloat, CGFloat) -> Void
|
|
|
|
public init(
|
|
animateIn: @escaping () -> Void,
|
|
updateTransitionProgress: @escaping (CGFloat) -> Void,
|
|
completeWithTransitionProgressAndVelocity: @escaping (CGFloat, CGFloat) -> Void
|
|
) {
|
|
self.animateIn = animateIn
|
|
self.updateTransitionProgress = updateTransitionProgress
|
|
self.completeWithTransitionProgressAndVelocity = completeWithTransitionProgressAndVelocity
|
|
}
|
|
}
|
|
|
|
public class MediaEditorTransitionOutExternalState {
|
|
public var storyTarget: Stories.PendingTarget?
|
|
public var isForcedTarget: Bool
|
|
public var isPeerArchived: Bool
|
|
public var transitionOut: ((Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?)?
|
|
|
|
public init(storyTarget: Stories.PendingTarget?, isForcedTarget: Bool, isPeerArchived: Bool, transitionOut: ((Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?)?) {
|
|
self.storyTarget = storyTarget
|
|
self.isForcedTarget = isForcedTarget
|
|
self.isPeerArchived = isPeerArchived
|
|
self.transitionOut = transitionOut
|
|
}
|
|
}
|
|
|
|
public protocol MediaEditorScreenResult {
|
|
|
|
}
|
|
|
|
public protocol TelegramRootControllerInterface: NavigationController {
|
|
@discardableResult
|
|
func openStoryCamera(customTarget: EnginePeer.Id?, transitionIn: StoryCameraTransitionIn?, transitionedIn: @escaping () -> Void, transitionOut: @escaping (Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?) -> StoryCameraTransitionInCoordinator?
|
|
func proceedWithStoryUpload(target: Stories.PendingTarget, result: MediaEditorScreenResult, existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void)
|
|
|
|
func getContactsController() -> ViewController?
|
|
func getChatsController() -> ViewController?
|
|
func getPrivacySettings() -> Promise<AccountPrivacySettings?>?
|
|
func openSettings()
|
|
func openBirthdaySetup()
|
|
}
|
|
|
|
public protocol QuickReplySetupScreenInitialData: AnyObject {
|
|
}
|
|
|
|
public protocol AutomaticBusinessMessageSetupScreenInitialData: AnyObject {
|
|
}
|
|
|
|
public protocol ChatbotSetupScreenInitialData: AnyObject {
|
|
}
|
|
|
|
public protocol BusinessIntroSetupScreenInitialData: AnyObject {
|
|
}
|
|
|
|
public protocol CollectibleItemInfoScreenInitialData: AnyObject {
|
|
var collectibleItemInfo: TelegramCollectibleItemInfo { get }
|
|
}
|
|
|
|
public protocol BusinessLinksSetupScreenInitialData: AnyObject {
|
|
}
|
|
|
|
public enum CollectibleItemInfoScreenSubject {
|
|
case phoneNumber(String)
|
|
case username(String)
|
|
}
|
|
|
|
public enum StorySearchControllerScope {
|
|
case query(String)
|
|
case location(coordinates: MediaArea.Coordinates, venue: MediaArea.Venue)
|
|
}
|
|
|
|
public protocol SharedAccountContext: AnyObject {
|
|
var sharedContainerPath: String { get }
|
|
var basePath: String { get }
|
|
var networkArguments: NetworkInitializationArguments { get }
|
|
var mainWindow: Window1? { get }
|
|
var accountManager: AccountManager<TelegramAccountManagerTypes> { get }
|
|
var appLockContext: AppLockContext { get }
|
|
|
|
var currentPresentationData: Atomic<PresentationData> { get }
|
|
var presentationData: Signal<PresentationData, NoError> { get }
|
|
|
|
var currentAutomaticMediaDownloadSettings: MediaAutoDownloadSettings { get }
|
|
var automaticMediaDownloadSettings: Signal<MediaAutoDownloadSettings, NoError> { get }
|
|
var currentAutodownloadSettings: Atomic<AutodownloadSettings> { get }
|
|
var immediateExperimentalUISettings: ExperimentalUISettings { get }
|
|
var currentInAppNotificationSettings: Atomic<InAppNotificationSettings> { get }
|
|
var currentMediaInputSettings: Atomic<MediaInputSettings> { get }
|
|
var currentStickerSettings: Atomic<StickerSettings> { get }
|
|
var currentMediaDisplaySettings: Atomic<MediaDisplaySettings> { get }
|
|
|
|
var energyUsageSettings: EnergyUsageSettings { get }
|
|
|
|
var applicationBindings: TelegramApplicationBindings { get }
|
|
|
|
var authorizationPushConfiguration: Signal<AuthorizationCodePushNotificationConfiguration?, NoError> { get }
|
|
var firebaseSecretStream: Signal<[String: String], NoError> { get }
|
|
|
|
var mediaManager: MediaManager { get }
|
|
var locationManager: DeviceLocationManager? { get }
|
|
var callManager: PresentationCallManager? { get }
|
|
var contactDataManager: DeviceContactDataManager? { get }
|
|
|
|
var activeAccountContexts: Signal<(primary: AccountContext?, accounts: [(AccountRecordId, AccountContext, Int32)], currentAuth: UnauthorizedAccount?), NoError> { get }
|
|
var activeAccountsWithInfo: Signal<(primary: AccountRecordId?, accounts: [AccountWithInfo]), NoError> { get }
|
|
|
|
var presentGlobalController: (ViewController, Any?) -> Void { get }
|
|
var presentCrossfadeController: () -> Void { get }
|
|
|
|
func makeTempAccountContext(account: Account) -> AccountContext
|
|
|
|
func updateNotificationTokensRegistration()
|
|
func setAccountUserInterfaceInUse(_ id: AccountRecordId) -> Disposable
|
|
func handleTextLinkAction(context: AccountContext, peerId: PeerId?, navigateDisposable: MetaDisposable, controller: ViewController, action: TextLinkItemActionType, itemLink: TextLinkItem)
|
|
func openSearch(filter: ChatListSearchFilter, query: String?)
|
|
func navigateToChat(accountId: AccountRecordId, peerId: PeerId, messageId: MessageId?)
|
|
func openChatMessage(_ params: OpenChatMessageParams) -> Bool
|
|
func messageFromPreloadedChatHistoryViewForLocation(id: MessageId, location: ChatHistoryLocationInput, context: AccountContext, chatLocation: ChatLocation, subject: ChatControllerSubject?, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tag: HistoryViewInputTag?) -> Signal<(MessageIndex?, Bool), NoError>
|
|
func makeOverlayAudioPlayerController(context: AccountContext, chatLocation: ChatLocation, type: MediaManagerPlayerType, initialMessageId: MessageId, initialOrder: MusicPlaybackSettingsOrder, playlistLocation: SharedMediaPlaylistLocation?, parentNavigationController: NavigationController?) -> ViewController & OverlayAudioPlayerController
|
|
func makePeerInfoController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: Peer, mode: PeerInfoControllerMode, avatarInitiallyExpanded: Bool, fromChat: Bool, requestsContext: PeerInvitationImportersContext?) -> ViewController?
|
|
func makeChannelAdminController(context: AccountContext, peerId: PeerId, adminId: PeerId, initialParticipant: ChannelParticipant) -> ViewController?
|
|
func makeDeviceContactInfoController(context: ShareControllerAccountContext, environment: ShareControllerEnvironment, subject: DeviceContactInfoSubject, completed: (() -> Void)?, cancelled: (() -> Void)?) -> ViewController
|
|
func makePeersNearbyController(context: AccountContext) -> ViewController
|
|
func makeComposeController(context: AccountContext) -> ViewController
|
|
func makeChatListController(context: AccountContext, location: ChatListControllerLocation, controlsHistoryPreload: Bool, hideNetworkActivityStatus: Bool, previewing: Bool, enableDebugActions: Bool) -> ChatListController
|
|
func makeChatController(context: AccountContext, chatLocation: ChatLocation, subject: ChatControllerSubject?, botStart: ChatControllerInitialBotStart?, mode: ChatControllerPresentationMode) -> ChatController
|
|
func makeChatHistoryListNode(
|
|
context: AccountContext,
|
|
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>),
|
|
chatLocation: ChatLocation,
|
|
chatLocationContextHolder: Atomic<ChatLocationContextHolder?>,
|
|
tag: HistoryViewInputTag?,
|
|
source: ChatHistoryListSource,
|
|
subject: ChatControllerSubject?,
|
|
controllerInteraction: ChatControllerInteractionProtocol,
|
|
selectedMessages: Signal<Set<MessageId>?, NoError>,
|
|
mode: ChatHistoryListMode
|
|
) -> ChatHistoryListNode
|
|
func makeChatMessagePreviewItem(context: AccountContext, messages: [Message], theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, chatBubbleCorners: PresentationChatBubbleCorners, dateTimeFormat: PresentationDateTimeFormat, nameOrder: PresentationPersonNameOrder, forcedResourceStatus: FileMediaResourceStatus?, tapMessage: ((Message) -> Void)?, clickThroughMessage: (() -> Void)?, backgroundNode: ASDisplayNode?, availableReactions: AvailableReactions?, accountPeer: Peer?, isCentered: Bool, isPreview: Bool, isStandalone: Bool) -> ListViewItem
|
|
func makeChatMessageDateHeaderItem(context: AccountContext, timestamp: Int32, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, chatBubbleCorners: PresentationChatBubbleCorners, dateTimeFormat: PresentationDateTimeFormat, nameOrder: PresentationPersonNameOrder) -> ListViewItemHeader
|
|
func makeChatMessageAvatarHeaderItem(context: AccountContext, timestamp: Int32, peer: Peer, message: Message, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, chatBubbleCorners: PresentationChatBubbleCorners, dateTimeFormat: PresentationDateTimeFormat, nameOrder: PresentationPersonNameOrder) -> ListViewItemHeader
|
|
func makePeerSharedMediaController(context: AccountContext, peerId: PeerId) -> ViewController?
|
|
func makeContactSelectionController(_ params: ContactSelectionControllerParams) -> ContactSelectionController
|
|
func makeContactMultiselectionController(_ params: ContactMultiselectionControllerParams) -> ContactMultiselectionController
|
|
func makePeerSelectionController(_ params: PeerSelectionControllerParams) -> PeerSelectionController
|
|
func makeProxySettingsController(context: AccountContext) -> ViewController
|
|
func makeLocalizationListController(context: AccountContext) -> ViewController
|
|
func makeCreateGroupController(context: AccountContext, peerIds: [PeerId], initialTitle: String?, mode: CreateGroupMode, completion: ((PeerId, @escaping () -> Void) -> Void)?) -> ViewController
|
|
func makeChatRecentActionsController(context: AccountContext, peer: Peer, adminPeerId: PeerId?) -> ViewController
|
|
func makePrivacyAndSecurityController(context: AccountContext) -> ViewController
|
|
func makeBioPrivacyController(context: AccountContext, settings: Promise<AccountPrivacySettings?>, present: @escaping (ViewController) -> Void)
|
|
func makeBirthdayPrivacyController(context: AccountContext, settings: Promise<AccountPrivacySettings?>, openedFromBirthdayScreen: Bool, present: @escaping (ViewController) -> Void)
|
|
func makeSetupTwoFactorAuthController(context: AccountContext) -> ViewController
|
|
func makeStorageManagementController(context: AccountContext) -> ViewController
|
|
func makeAttachmentFileController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, bannedSendMedia: (Int32, Bool)?, presentGallery: @escaping () -> Void, presentFiles: @escaping () -> Void, send: @escaping (AnyMediaReference) -> Void) -> AttachmentFileController
|
|
func makeGalleryCaptionPanelView(context: AccountContext, chatLocation: ChatLocation, isScheduledMessages: Bool, isFile: Bool, customEmojiAvailable: Bool, present: @escaping (ViewController) -> Void, presentInGlobalOverlay: @escaping (ViewController) -> Void) -> NSObject?
|
|
func makeHashtagSearchController(context: AccountContext, peer: EnginePeer?, query: String, all: Bool) -> ViewController
|
|
func makeStorySearchController(context: AccountContext, scope: StorySearchControllerScope, listContext: SearchStoryListContext?) -> ViewController
|
|
func makeMyStoriesController(context: AccountContext, isArchive: Bool) -> ViewController
|
|
func makeArchiveSettingsController(context: AccountContext) -> ViewController
|
|
func makeFilterSettingsController(context: AccountContext, modal: Bool, scrollToTags: Bool, dismissed: (() -> Void)?) -> ViewController
|
|
func makeBusinessSetupScreen(context: AccountContext) -> ViewController
|
|
func makeChatbotSetupScreen(context: AccountContext, initialData: ChatbotSetupScreenInitialData) -> ViewController
|
|
func makeChatbotSetupScreenInitialData(context: AccountContext) -> Signal<ChatbotSetupScreenInitialData, NoError>
|
|
func makeBusinessLocationSetupScreen(context: AccountContext, initialValue: TelegramBusinessLocation?, completion: @escaping (TelegramBusinessLocation?) -> Void) -> ViewController
|
|
func makeBusinessHoursSetupScreen(context: AccountContext, initialValue: TelegramBusinessHours?, completion: @escaping (TelegramBusinessHours?) -> Void) -> ViewController
|
|
func makeAutomaticBusinessMessageSetupScreen(context: AccountContext, initialData: AutomaticBusinessMessageSetupScreenInitialData, isAwayMode: Bool) -> ViewController
|
|
func makeAutomaticBusinessMessageSetupScreenInitialData(context: AccountContext) -> Signal<AutomaticBusinessMessageSetupScreenInitialData, NoError>
|
|
func makeQuickReplySetupScreen(context: AccountContext, initialData: QuickReplySetupScreenInitialData) -> ViewController
|
|
func makeQuickReplySetupScreenInitialData(context: AccountContext) -> Signal<QuickReplySetupScreenInitialData, NoError>
|
|
func makeBusinessIntroSetupScreen(context: AccountContext, initialData: BusinessIntroSetupScreenInitialData) -> ViewController
|
|
func makeBusinessIntroSetupScreenInitialData(context: AccountContext) -> Signal<BusinessIntroSetupScreenInitialData, NoError>
|
|
func makeBusinessLinksSetupScreen(context: AccountContext, initialData: BusinessLinksSetupScreenInitialData) -> ViewController
|
|
func makeBusinessLinksSetupScreenInitialData(context: AccountContext) -> Signal<BusinessLinksSetupScreenInitialData, NoError>
|
|
func makeCollectibleItemInfoScreen(context: AccountContext, initialData: CollectibleItemInfoScreenInitialData) -> ViewController
|
|
func makeCollectibleItemInfoScreenInitialData(context: AccountContext, peerId: EnginePeer.Id, subject: CollectibleItemInfoScreenSubject) -> Signal<CollectibleItemInfoScreenInitialData?, NoError>
|
|
func makeBotSettingsScreen(context: AccountContext, peerId: EnginePeer.Id?) -> ViewController
|
|
|
|
func navigateToChatController(_ params: NavigateToChatControllerParams)
|
|
func navigateToForumChannel(context: AccountContext, peerId: EnginePeer.Id, navigationController: NavigationController)
|
|
func navigateToForumThread(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, messageId: EngineMessage.Id?, navigationController: NavigationController, activateInput: ChatControllerActivateInput?, scrollToEndIfExists: Bool, keepStack: NavigateToChatKeepStack) -> Signal<Never, NoError>
|
|
func chatControllerForForumThread(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64) -> Signal<ChatController, NoError>
|
|
func openStorageUsage(context: AccountContext)
|
|
func openLocationScreen(context: AccountContext, messageId: MessageId, navigationController: NavigationController)
|
|
func openExternalUrl(context: AccountContext, urlContext: OpenURLContext, url: String, forceExternal: Bool, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void)
|
|
func chatAvailableMessageActions(engine: TelegramEngine, accountPeerId: EnginePeer.Id, messageIds: Set<EngineMessage.Id>, keepUpdated: Bool) -> Signal<ChatAvailableMessageActions, NoError>
|
|
func chatAvailableMessageActions(engine: TelegramEngine, accountPeerId: EnginePeer.Id, messageIds: Set<EngineMessage.Id>, messages: [EngineMessage.Id: EngineMessage], peers: [EnginePeer.Id: EnginePeer]) -> Signal<ChatAvailableMessageActions, NoError>
|
|
func resolveUrl(context: AccountContext, peerId: PeerId?, url: String, skipUrlAuth: Bool) -> Signal<ResolvedUrl, NoError>
|
|
func resolveUrlWithProgress(context: AccountContext, peerId: PeerId?, url: String, skipUrlAuth: Bool) -> Signal<ResolveUrlResult, NoError>
|
|
func openResolvedUrl(_ resolvedUrl: ResolvedUrl, context: AccountContext, urlContext: OpenURLContext, navigationController: NavigationController?, forceExternal: Bool, openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, sendEmoji: ((String, ChatTextInputTextCustomEmojiAttribute) -> Void)?, requestMessageActionUrlAuth: ((MessageActionUrlSubject) -> Void)?, joinVoiceChat: ((PeerId, String?, CachedChannelData.ActiveCall) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, contentContext: Any?, progress: Promise<Bool>?, completion: (() -> Void)?)
|
|
func openAddContact(context: AccountContext, firstName: String, lastName: String, phoneNumber: String, label: String, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void)
|
|
func openAddPersonContact(context: AccountContext, peerId: PeerId, pushController: @escaping (ViewController) -> Void, present: @escaping (ViewController, Any?) -> Void)
|
|
func presentContactsWarningSuppression(context: AccountContext, present: (ViewController, Any?) -> Void)
|
|
func openImagePicker(context: AccountContext, completion: @escaping (UIImage) -> Void, present: @escaping (ViewController) -> Void)
|
|
func openAddPeerMembers(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, parentController: ViewController, groupPeer: Peer, selectAddMemberDisposable: MetaDisposable, addMemberDisposable: MetaDisposable)
|
|
func openChatInstantPage(context: AccountContext, message: Message, sourcePeerType: MediaAutoDownloadPeerType?, navigationController: NavigationController)
|
|
func openChatWallpaper(context: AccountContext, message: Message, present: @escaping (ViewController, Any?) -> Void)
|
|
|
|
func makeRecentSessionsController(context: AccountContext, activeSessionsContext: ActiveSessionsContext) -> ViewController & RecentSessionsController
|
|
|
|
func makeChatQrCodeScreen(context: AccountContext, peer: Peer, threadId: Int64?, temporary: Bool) -> ViewController
|
|
|
|
func makePremiumIntroController(context: AccountContext, source: PremiumIntroSource, forceDark: Bool, dismissed: (() -> Void)?) -> ViewController
|
|
func makePremiumDemoController(context: AccountContext, subject: PremiumDemoSubject, forceDark: Bool, action: @escaping () -> Void, dismissed: (() -> Void)?) -> ViewController
|
|
func makePremiumLimitController(context: AccountContext, subject: PremiumLimitSubject, count: Int32, forceDark: Bool, cancel: @escaping () -> Void, action: @escaping () -> Bool) -> ViewController
|
|
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (() -> Void)?) -> ViewController
|
|
func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController
|
|
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, subject: BoostSubject, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController
|
|
|
|
func makeStickerPackScreen(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], loadedStickerPacks: [LoadedStickerPack], isEditing: Bool, expandIfNeeded: Bool, parentNavigationController: NavigationController?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, actionPerformed: ((Bool) -> Void)?) -> ViewController
|
|
|
|
func makeMediaPickerScreen(context: AccountContext, hasSearch: Bool, completion: @escaping (Any) -> Void) -> ViewController
|
|
|
|
func makeStickerEditorScreen(context: AccountContext, source: Any?, intro: Bool, transitionArguments: (UIView, CGRect, UIImage?)?, completion: @escaping (TelegramMediaFile, [String], @escaping () -> Void) -> Void, cancelled: @escaping () -> Void) -> ViewController
|
|
|
|
func makeStickerMediaPickerScreen(context: AccountContext, getSourceRect: @escaping () -> CGRect?, completion: @escaping (Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, dismissed: @escaping () -> Void) -> ViewController
|
|
func makeStoryMediaPickerScreen(context: AccountContext, getSourceRect: @escaping () -> CGRect, completion: @escaping (Any, UIView, CGRect, UIImage?, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, dismissed: @escaping () -> Void, groupsPresented: @escaping () -> Void) -> ViewController
|
|
|
|
func makeStickerPickerScreen(context: AccountContext, inputData: Promise<StickerPickerInput>, completion: @escaping (FileMediaReference) -> Void) -> ViewController
|
|
|
|
func makeProxySettingsController(sharedContext: SharedAccountContext, account: UnauthorizedAccount) -> ViewController
|
|
|
|
func makeInstalledStickerPacksController(context: AccountContext, mode: InstalledStickerPacksControllerMode, forceTheme: PresentationTheme?) -> ViewController
|
|
|
|
func makeChannelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, boosts: Bool, boostStatus: ChannelBoostStatus?) -> ViewController
|
|
func makeMessagesStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, messageId: EngineMessage.Id) -> ViewController
|
|
func makeStoryStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, storyId: Int32, storyItem: EngineStoryItem, fromStory: Bool) -> ViewController
|
|
|
|
func makeStarsTransactionsScreen(context: AccountContext, starsContext: StarsContext) -> ViewController
|
|
func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [StarsTopUpOption], peerId: EnginePeer.Id?, requiredStars: Int64?, completion: @escaping (Int64) -> Void) -> ViewController
|
|
func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController
|
|
func makeStarsTransactionScreen(context: AccountContext, transaction: StarsContext.State.Transaction) -> ViewController
|
|
func makeStarsReceiptScreen(context: AccountContext, receipt: BotPaymentReceipt) -> ViewController
|
|
func makeStarsStatisticsScreen(context: AccountContext, peerId: EnginePeer.Id, revenueContext: StarsRevenueStatsContext) -> ViewController
|
|
func makeStarsAmountScreen(context: AccountContext, completion: @escaping (Int64) -> Void) -> ViewController
|
|
|
|
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
|
|
|
|
func navigateToCurrentCall()
|
|
var hasOngoingCall: ValuePromise<Bool> { get }
|
|
var immediateHasOngoingCall: Bool { get }
|
|
|
|
var enablePreloads: Promise<Bool> { get }
|
|
var hasPreloadBlockingContent: Promise<Bool> { get }
|
|
|
|
var deviceContactPhoneNumbers: Promise<Set<String>> { get }
|
|
|
|
var hasGroupCallOnScreen: Signal<Bool, NoError> { get }
|
|
var currentGroupCallController: ViewController? { get }
|
|
|
|
func switchToAccount(id: AccountRecordId, fromSettingsController settingsController: ViewController?, withChatListController chatListController: ViewController?)
|
|
func beginNewAuth(testingEnvironment: Bool)
|
|
}
|
|
|
|
public protocol ComposeController: ViewController {
|
|
}
|
|
|
|
public protocol ChatLocationContextHolder: AnyObject {
|
|
}
|
|
|
|
public protocol AccountGroupCallContext: AnyObject {
|
|
}
|
|
|
|
public protocol AccountGroupCallContextCache: AnyObject {
|
|
}
|
|
|
|
public struct ChatSendMessageActionSheetControllerSendParameters {
|
|
public struct Effect {
|
|
public let id: Int64
|
|
|
|
public init(id: Int64) {
|
|
self.id = id
|
|
}
|
|
}
|
|
|
|
public var effect: Effect?
|
|
public var textIsAboveMedia: Bool
|
|
|
|
public init(
|
|
effect: Effect?,
|
|
textIsAboveMedia: Bool
|
|
) {
|
|
self.effect = effect
|
|
self.textIsAboveMedia = textIsAboveMedia
|
|
}
|
|
}
|
|
|
|
public enum ChatSendMessageActionSheetControllerSendMode {
|
|
case generic
|
|
case silently
|
|
case whenOnline
|
|
}
|
|
|
|
public protocol ChatSendMessageActionSheetControllerSourceSendButtonNode: ASDisplayNode {
|
|
func makeCustomContents() -> UIView?
|
|
}
|
|
|
|
public protocol ChatSendMessageActionSheetController: ViewController {
|
|
typealias SendMode = ChatSendMessageActionSheetControllerSendMode
|
|
typealias SendParameters = ChatSendMessageActionSheetControllerSendParameters
|
|
}
|
|
|
|
public protocol AccountContext: AnyObject {
|
|
var sharedContext: SharedAccountContext { get }
|
|
var account: Account { get }
|
|
var engine: TelegramEngine { get }
|
|
|
|
var liveLocationManager: LiveLocationManager? { get }
|
|
var peersNearbyManager: PeersNearbyManager? { get }
|
|
var fetchManager: FetchManager { get }
|
|
var prefetchManager: PrefetchManager? { get }
|
|
var downloadedMediaStoreManager: DownloadedMediaStoreManager { get }
|
|
var peerChannelMemberCategoriesContextsManager: PeerChannelMemberCategoriesContextsManager { get }
|
|
var wallpaperUploadManager: WallpaperUploadManager? { get }
|
|
var watchManager: WatchManager? { get }
|
|
var inAppPurchaseManager: InAppPurchaseManager? { get }
|
|
var starsContext: StarsContext? { get }
|
|
|
|
var currentLimitsConfiguration: Atomic<LimitsConfiguration> { get }
|
|
var currentContentSettings: Atomic<ContentSettings> { get }
|
|
var currentAppConfiguration: Atomic<AppConfiguration> { get }
|
|
var currentCountriesConfiguration: Atomic<CountriesConfiguration> { get }
|
|
|
|
var cachedGroupCallContexts: AccountGroupCallContextCache { get }
|
|
|
|
var animationCache: AnimationCache { get }
|
|
var animationRenderer: MultiAnimationRenderer { get }
|
|
|
|
var animatedEmojiStickers: Signal<[String: [StickerPackItem]], NoError> { get }
|
|
var animatedEmojiStickersValue: [String: [StickerPackItem]] { get }
|
|
var additionalAnimatedEmojiStickers: Signal<[String: [Int: StickerPackItem]], NoError> { get }
|
|
var availableReactions: Signal<AvailableReactions?, NoError> { get }
|
|
var availableMessageEffects: Signal<AvailableMessageEffects?, NoError> { get }
|
|
|
|
var isPremium: Bool { get }
|
|
var userLimits: EngineConfiguration.UserLimits { get }
|
|
var peerNameColors: PeerNameColors { get }
|
|
|
|
var imageCache: AnyObject? { get }
|
|
|
|
func storeSecureIdPassword(password: String)
|
|
func getStoredSecureIdPassword() -> String?
|
|
|
|
func chatLocationInput(for location: ChatLocation, contextHolder: Atomic<ChatLocationContextHolder?>) -> ChatLocationInput
|
|
func chatLocationOutgoingReadState(for location: ChatLocation, contextHolder: Atomic<ChatLocationContextHolder?>) -> Signal<MessageId?, NoError>
|
|
func chatLocationUnreadCount(for location: ChatLocation, contextHolder: Atomic<ChatLocationContextHolder?>) -> Signal<Int, NoError>
|
|
func applyMaxReadIndex(for location: ChatLocation, contextHolder: Atomic<ChatLocationContextHolder?>, messageIndex: MessageIndex)
|
|
|
|
func scheduleGroupCall(peerId: PeerId)
|
|
func joinGroupCall(peerId: PeerId, invite: String?, requestJoinAsPeerId: ((@escaping (PeerId?) -> Void) -> Void)?, activeCall: EngineGroupCallDescription)
|
|
func requestCall(peerId: PeerId, isVideo: Bool, completion: @escaping () -> Void)
|
|
}
|
|
|
|
public struct AntiSpamBotConfiguration {
|
|
public static var defaultValue: AntiSpamBotConfiguration {
|
|
return AntiSpamBotConfiguration(antiSpamBotId: nil, minimumGroupParticipants: 100)
|
|
}
|
|
|
|
public let antiSpamBotId: EnginePeer.Id?
|
|
public let minimumGroupParticipants: Int32
|
|
|
|
fileprivate init(antiSpamBotId: EnginePeer.Id?, minimumGroupParticipants: Int32) {
|
|
self.antiSpamBotId = antiSpamBotId
|
|
self.minimumGroupParticipants = minimumGroupParticipants
|
|
}
|
|
|
|
public static func with(appConfiguration: AppConfiguration) -> AntiSpamBotConfiguration {
|
|
if let data = appConfiguration.data, let botIdString = data["telegram_antispam_user_id"] as? String, let botIdValue = Int64(botIdString), let groupSize = data["telegram_antispam_group_size_min"] as? Double {
|
|
return AntiSpamBotConfiguration(antiSpamBotId: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(botIdValue)), minimumGroupParticipants: Int32(groupSize))
|
|
} else {
|
|
return .defaultValue
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct StoriesConfiguration {
|
|
public enum PostingAvailability {
|
|
case enabled
|
|
case premium
|
|
case disabled
|
|
}
|
|
|
|
public enum CaptionEntitiesAvailability {
|
|
case enabled
|
|
case premium
|
|
}
|
|
|
|
static var defaultValue: StoriesConfiguration {
|
|
return StoriesConfiguration(posting: .disabled, captionEntities: .premium, venueSearchBot: "foursquare")
|
|
}
|
|
|
|
public let posting: PostingAvailability
|
|
public let captionEntities: CaptionEntitiesAvailability
|
|
public let venueSearchBot: String
|
|
|
|
fileprivate init(posting: PostingAvailability, captionEntities: CaptionEntitiesAvailability, venueSearchBot: String) {
|
|
self.posting = posting
|
|
self.captionEntities = captionEntities
|
|
self.venueSearchBot = venueSearchBot
|
|
}
|
|
|
|
public static func with(appConfiguration: AppConfiguration) -> StoriesConfiguration {
|
|
if let data = appConfiguration.data {
|
|
let posting: PostingAvailability
|
|
let captionEntities: CaptionEntitiesAvailability
|
|
let venueSearchBot: String
|
|
if let postingString = data["stories_posting"] as? String {
|
|
switch postingString {
|
|
case "enabled":
|
|
posting = .enabled
|
|
case "premium":
|
|
posting = .premium
|
|
default:
|
|
posting = .disabled
|
|
}
|
|
} else {
|
|
posting = .disabled
|
|
}
|
|
if let entitiesString = data["stories_entities"] as? String {
|
|
switch entitiesString {
|
|
case "enabled":
|
|
captionEntities = .enabled
|
|
default:
|
|
captionEntities = .premium
|
|
}
|
|
} else {
|
|
captionEntities = .premium
|
|
}
|
|
if let venueSearchBotString = data["stories_venue_search_username"] as? String {
|
|
venueSearchBot = venueSearchBotString
|
|
} else {
|
|
venueSearchBot = "foursquare"
|
|
}
|
|
return StoriesConfiguration(posting: posting, captionEntities: captionEntities, venueSearchBot: venueSearchBot)
|
|
} else {
|
|
return .defaultValue
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct StickersSearchConfiguration {
|
|
static var defaultValue: StickersSearchConfiguration {
|
|
return StickersSearchConfiguration(disableLocalSuggestions: false)
|
|
}
|
|
|
|
public let disableLocalSuggestions: Bool
|
|
|
|
fileprivate init(disableLocalSuggestions: Bool) {
|
|
self.disableLocalSuggestions = disableLocalSuggestions
|
|
}
|
|
|
|
public static func with(appConfiguration: AppConfiguration) -> StickersSearchConfiguration {
|
|
if let data = appConfiguration.data, let suggestOnlyApi = data["stickers_emoji_suggest_only_api"] as? Bool {
|
|
return StickersSearchConfiguration(disableLocalSuggestions: suggestOnlyApi)
|
|
} else {
|
|
return .defaultValue
|
|
}
|
|
}
|
|
}
|
|
|
|
public protocol ShareControllerAccountContext: AnyObject {
|
|
var accountId: AccountRecordId { get }
|
|
var accountPeerId: EnginePeer.Id { get }
|
|
var stateManager: AccountStateManager { get }
|
|
var engineData: TelegramEngine.EngineData { get }
|
|
var animationCache: AnimationCache { get }
|
|
var animationRenderer: MultiAnimationRenderer { get }
|
|
var contentSettings: ContentSettings { get }
|
|
var appConfiguration: AppConfiguration { get }
|
|
|
|
func resolveInlineStickers(fileIds: [Int64]) -> Signal<[Int64: TelegramMediaFile], NoError>
|
|
}
|
|
|
|
public protocol ShareControllerEnvironment: AnyObject {
|
|
var presentationData: PresentationData { get }
|
|
var updatedPresentationData: Signal<PresentationData, NoError> { get }
|
|
var isMainApp: Bool { get }
|
|
var energyUsageSettings: EnergyUsageSettings { get }
|
|
|
|
var mediaManager: MediaManager? { get }
|
|
|
|
func setAccountUserInterfaceInUse(id: AccountRecordId) -> Disposable
|
|
func donateSendMessageIntent(account: ShareControllerAccountContext, peerIds: [EnginePeer.Id])
|
|
}
|