Swiftgram/submodules/ContactListUI/Sources/ContactContextMenus.swift
2022-10-23 18:03:26 +04:00

153 lines
8.1 KiB
Swift

import Foundation
import UIKit
import SwiftSignalKit
import ContextUI
import AccountContext
import TelegramCore
import Display
import AlertUI
import PresentationDataUtils
import OverlayStatusController
import LocalizedPeerData
func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, contactsController: ContactsController?) -> Signal<[ContextMenuItem], NoError> {
let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings
return context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.AreVoiceCallsAvailable(id: peerId),
TelegramEngine.EngineData.Item.Peer.AreVideoCallsAvailable(id: peerId)
)
|> map { [weak contactsController] peer, areVoiceCallsAvailable, areVideoCallsAvailable -> [ContextMenuItem] in
var items: [ContextMenuItem] = []
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_SendMessage, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Message"), color: theme.contextMenu.primaryColor) }, action: { _, f in
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> deliverOnMainQueue).start(next: { peer in
guard let peer = peer else {
return
}
if let contactsController = contactsController, let navigationController = contactsController.navigationController as? NavigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), peekData: nil))
}
f(.default)
})
})))
var canStartSecretChat = true
if case let .user(user) = peer, user.flags.contains(.isSupport) {
canStartSecretChat = false
}
if canStartSecretChat {
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_StartSecretChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Timer"), color: theme.contextMenu.primaryColor) }, action: { _, f in
let _ = (context.engine.peers.mostRecentSecretChat(id: peerId)
|> deliverOnMainQueue).start(next: { currentPeerId in
if let currentPeerId = currentPeerId {
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: currentPeerId)
)
|> deliverOnMainQueue).start(next: { peer in
guard let peer = peer else {
return
}
if let contactsController = contactsController, let navigationController = (contactsController.navigationController as? NavigationController) {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), peekData: nil))
}
})
} else {
var createSignal = context.engine.peers.createSecretChat(peerId: peerId)
var cancelImpl: (() -> Void)?
let progressSignal = Signal<Never, NoError> { subscriber in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
cancelImpl?()
}))
contactsController?.present(controller, in: .window(.root))
return ActionDisposable { [weak controller] in
Queue.mainQueue().async() {
controller?.dismiss()
}
}
}
|> runOn(Queue.mainQueue())
|> delay(0.15, queue: Queue.mainQueue())
let progressDisposable = progressSignal.start()
createSignal = createSignal
|> afterDisposed {
Queue.mainQueue().async {
progressDisposable.dispose()
}
}
let createSecretChatDisposable = MetaDisposable()
cancelImpl = {
createSecretChatDisposable.set(nil)
}
createSecretChatDisposable.set((createSignal
|> deliverOnMainQueue).start(next: { peerId in
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> deliverOnMainQueue).start(next: { peer in
guard let peer = peer else {
return
}
if let navigationController = (contactsController?.navigationController as? NavigationController) {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), peekData: nil))
}
})
}, error: { error in
if let contactsController = contactsController {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let text: String
switch error {
case .limitExceeded:
text = presentationData.strings.TwoStepAuth_FloodError
default:
text = presentationData.strings.Login_UnknownError
}
contactsController.present(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}
}))
}
})
f(.default)
})))
}
var canCall = true
if case let .user(user) = peer, (user.flags.contains(.isSupport) || !areVoiceCallsAvailable) {
canCall = false
}
var canVideoCall = false
if canCall {
if areVideoCallsAvailable {
canVideoCall = true
}
}
if canCall {
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_Call, icon: { theme in
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Call"), color: theme.contextMenu.primaryColor)
}, action: { _, f in
context.requestCall(peerId: peerId, isVideo: false, completion: {})
f(.default)
})))
}
if canVideoCall {
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_VideoCall, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/VideoCall"), color: theme.contextMenu.primaryColor)
}, action: { _, f in
context.requestCall(peerId: peerId, isVideo: true, completion: {})
f(.default)
})))
}
return items
}
}