mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Refactoring
This commit is contained in:
parent
9973b37e97
commit
9134bae908
@ -322,7 +322,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
|||||||
isMuted = true
|
isMuted = true
|
||||||
}
|
}
|
||||||
items.append(.action(ContextMenuActionItem(text: isMuted ? strings.ChatList_Context_Unmute : strings.ChatList_Context_Mute, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
items.append(.action(ContextMenuActionItem(text: isMuted ? strings.ChatList_Context_Unmute : strings.ChatList_Context_Mute, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||||
let _ = (togglePeerMuted(account: context.account, peerId: peerId)
|
let _ = (context.engine.peers.togglePeerMuted(peerId: peerId)
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
f(.default)
|
f(.default)
|
||||||
})
|
})
|
||||||
@ -332,7 +332,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
|||||||
if case .search = source {
|
if case .search = source {
|
||||||
if let _ = peer as? TelegramChannel {
|
if let _ = peer as? TelegramChannel {
|
||||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_JoinChannel, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Add"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_JoinChannel, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Add"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||||
var createSignal = context.peerChannelMemberCategoriesContextsManager.join(account: context.account, peerId: peerId, hash: nil)
|
var createSignal = context.peerChannelMemberCategoriesContextsManager.join(engine: context.engine, peerId: peerId, hash: nil)
|
||||||
var cancelImpl: (() -> Void)?
|
var cancelImpl: (() -> Void)?
|
||||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
@ -688,7 +688,7 @@ public final class ChatListNode: ListView {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.setCurrentRemovingPeerId(peerId)
|
strongSelf.setCurrentRemovingPeerId(peerId)
|
||||||
let _ = (togglePeerMuted(account: context.account, peerId: peerId)
|
let _ = (context.engine.peers.togglePeerMuted(peerId: peerId)
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
self?.updateState { state in
|
self?.updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
|
@ -365,7 +365,7 @@ final class InviteContactsControllerNode: ASDisplayNode {
|
|||||||
return DeviceContactNormalizedPhoneNumber(rawValue: formatPhoneNumber(phoneNumber.value))
|
return DeviceContactNormalizedPhoneNumber(rawValue: formatPhoneNumber(phoneNumber.value))
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
return deviceContactsImportedByCount(postbox: context.account.postbox, contacts: mappedContacts)
|
return context.engine.contacts.deviceContactsImportedByCount(contacts: mappedContacts)
|
||||||
|> map { counts -> [(DeviceContactStableId, DeviceContactBasicData, Int32)]? in
|
|> map { counts -> [(DeviceContactStableId, DeviceContactBasicData, Int32)]? in
|
||||||
var result: [(DeviceContactStableId, DeviceContactBasicData, Int32)] = []
|
var result: [(DeviceContactStableId, DeviceContactBasicData, Int32)] = []
|
||||||
var contactValues: [DeviceContactStableId: DeviceContactBasicData] = [:]
|
var contactValues: [DeviceContactStableId: DeviceContactBasicData] = [:]
|
||||||
|
@ -310,7 +310,7 @@ final class InstantPagePeerReferenceNode: ASDisplayNode, InstantPageNode {
|
|||||||
@objc func joinPressed() {
|
@objc func joinPressed() {
|
||||||
if let peer = self.peer, case .notJoined = self.joinState {
|
if let peer = self.peer, case .notJoined = self.joinState {
|
||||||
self.updateJoinState(.inProgress)
|
self.updateJoinState(.inProgress)
|
||||||
self.joinDisposable.set((joinChannel(account: self.context.account, peerId: peer.id, hash: nil) |> deliverOnMainQueue).start(error: { [weak self] _ in
|
self.joinDisposable.set((self.context.engine.peers.joinChannel(peerId: peer.id, hash: nil) |> deliverOnMainQueue).start(error: { [weak self] _ in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
if case .inProgress = strongSelf.joinState {
|
if case .inProgress = strongSelf.joinState {
|
||||||
strongSelf.updateJoinState(.notJoined)
|
strongSelf.updateJoinState(.notJoined)
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
|
||||||
|
|
||||||
swift_library(
|
|
||||||
name = "MessageReactionListUI",
|
|
||||||
module_name = "MessageReactionListUI",
|
|
||||||
srcs = glob([
|
|
||||||
"Sources/**/*.swift",
|
|
||||||
]),
|
|
||||||
deps = [
|
|
||||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
|
||||||
"//submodules/TelegramCore:TelegramCore",
|
|
||||||
"//submodules/SyncCore:SyncCore",
|
|
||||||
"//submodules/Postbox:Postbox",
|
|
||||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
|
||||||
"//submodules/Display:Display",
|
|
||||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
|
||||||
"//submodules/AccountContext:AccountContext",
|
|
||||||
"//submodules/MergeLists:MergeLists",
|
|
||||||
"//submodules/ItemListPeerItem:ItemListPeerItem",
|
|
||||||
],
|
|
||||||
visibility = [
|
|
||||||
"//visibility:public",
|
|
||||||
],
|
|
||||||
)
|
|
@ -1,104 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import AsyncDisplayKit
|
|
||||||
import Display
|
|
||||||
import TelegramPresentationData
|
|
||||||
import TelegramCore
|
|
||||||
import SyncCore
|
|
||||||
|
|
||||||
final class MessageReactionCategoryNode: ASDisplayNode {
|
|
||||||
let category: MessageReactionListCategory
|
|
||||||
private let action: () -> Void
|
|
||||||
|
|
||||||
private let buttonNode: HighlightableButtonNode
|
|
||||||
private let highlightedBackgroundNode: ASImageNode
|
|
||||||
private let iconNode: ASImageNode
|
|
||||||
private let emojiNode: ImmediateTextNode
|
|
||||||
private let countNode: ImmediateTextNode
|
|
||||||
|
|
||||||
var isSelected = false {
|
|
||||||
didSet {
|
|
||||||
self.highlightedBackgroundNode.alpha = self.isSelected ? 1.0 : 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init(theme: PresentationTheme, category: MessageReactionListCategory, count: Int, action: @escaping () -> Void) {
|
|
||||||
self.category = category
|
|
||||||
self.action = action
|
|
||||||
|
|
||||||
self.buttonNode = HighlightableButtonNode()
|
|
||||||
|
|
||||||
self.highlightedBackgroundNode = ASImageNode()
|
|
||||||
self.highlightedBackgroundNode.displaysAsynchronously = false
|
|
||||||
self.highlightedBackgroundNode.displayWithoutProcessing = true
|
|
||||||
self.highlightedBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 18.0, color: UIColor(rgb: 0xe6e6e8))
|
|
||||||
self.highlightedBackgroundNode.alpha = 1.0
|
|
||||||
|
|
||||||
self.iconNode = ASImageNode()
|
|
||||||
|
|
||||||
self.emojiNode = ImmediateTextNode()
|
|
||||||
self.emojiNode.displaysAsynchronously = false
|
|
||||||
let emojiText: String
|
|
||||||
switch category {
|
|
||||||
case .all:
|
|
||||||
emojiText = ""
|
|
||||||
self.iconNode.image = PresentationResourcesChat.chatInputTextFieldTimerImage(theme)
|
|
||||||
case let .reaction(value):
|
|
||||||
emojiText = value
|
|
||||||
}
|
|
||||||
self.emojiNode.attributedText = NSAttributedString(string: emojiText, font: Font.regular(18.0), textColor: .black)
|
|
||||||
|
|
||||||
self.countNode = ImmediateTextNode()
|
|
||||||
self.countNode.displaysAsynchronously = false
|
|
||||||
self.countNode.attributedText = NSAttributedString(string: "\(count)", font: Font.regular(16.0), textColor: .black)
|
|
||||||
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
self.addSubnode(self.highlightedBackgroundNode)
|
|
||||||
self.addSubnode(self.iconNode)
|
|
||||||
self.addSubnode(self.emojiNode)
|
|
||||||
self.addSubnode(self.countNode)
|
|
||||||
self.addSubnode(self.buttonNode)
|
|
||||||
|
|
||||||
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateLayout() -> CGSize {
|
|
||||||
let sideInset: CGFloat = 6.0
|
|
||||||
let spacing: CGFloat = 2.0
|
|
||||||
let emojiSize = self.emojiNode.updateLayout(CGSize(width: 100.0, height: 100.0))
|
|
||||||
let iconSize = self.iconNode.image?.size ?? CGSize()
|
|
||||||
let countSize = self.countNode.updateLayout(CGSize(width: 100.0, height: 100.0))
|
|
||||||
|
|
||||||
let height: CGFloat = 60.0
|
|
||||||
let backgroundHeight: CGFloat = 36.0
|
|
||||||
|
|
||||||
self.emojiNode.frame = CGRect(origin: CGPoint(x: sideInset, y: floor((height - emojiSize.height) / 2.0)), size: emojiSize)
|
|
||||||
self.iconNode.frame = CGRect(origin: CGPoint(x: sideInset, y: floor((height - iconSize.height) / 2.0)), size: iconSize)
|
|
||||||
|
|
||||||
let iconFrame: CGRect
|
|
||||||
if self.iconNode.image != nil {
|
|
||||||
iconFrame = self.iconNode.frame
|
|
||||||
} else {
|
|
||||||
iconFrame = self.emojiNode.frame
|
|
||||||
}
|
|
||||||
|
|
||||||
self.countNode.frame = CGRect(origin: CGPoint(x: iconFrame.maxX + spacing, y: floor((height - countSize.height) / 2.0)), size: countSize)
|
|
||||||
let contentWidth = sideInset * 2.0 + spacing + iconFrame.width + countSize.width
|
|
||||||
self.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: floor((height - backgroundHeight) / 2.0)), size: CGSize(width: contentWidth, height: backgroundHeight))
|
|
||||||
|
|
||||||
let size = CGSize(width: contentWidth, height: height)
|
|
||||||
self.buttonNode.frame = CGRect(origin: CGPoint(), size: size)
|
|
||||||
return size
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc private func buttonPressed() {
|
|
||||||
self.action()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
||||||
if self.buttonNode.frame.contains(point) {
|
|
||||||
return self.buttonNode.view
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,447 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
import AsyncDisplayKit
|
|
||||||
import Display
|
|
||||||
import AccountContext
|
|
||||||
import TelegramPresentationData
|
|
||||||
import Postbox
|
|
||||||
import TelegramCore
|
|
||||||
import SyncCore
|
|
||||||
import SwiftSignalKit
|
|
||||||
import MergeLists
|
|
||||||
import ItemListPeerItem
|
|
||||||
import ItemListUI
|
|
||||||
|
|
||||||
public final class MessageReactionListController: ViewController {
|
|
||||||
private let context: AccountContext
|
|
||||||
private let messageId: MessageId
|
|
||||||
private let presentationData: PresentationData
|
|
||||||
private let initialReactions: [MessageReaction]
|
|
||||||
|
|
||||||
private var controllerNode: MessageReactionListControllerNode {
|
|
||||||
return self.displayNode as! MessageReactionListControllerNode
|
|
||||||
}
|
|
||||||
|
|
||||||
private var animatedIn: Bool = false
|
|
||||||
|
|
||||||
private let _ready = Promise<Bool>()
|
|
||||||
override public var ready: Promise<Bool> {
|
|
||||||
return self._ready
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(context: AccountContext, messageId: MessageId, initialReactions: [MessageReaction]) {
|
|
||||||
self.context = context
|
|
||||||
self.messageId = messageId
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
||||||
self.initialReactions = initialReactions
|
|
||||||
|
|
||||||
super.init(navigationBarPresentationData: nil)
|
|
||||||
|
|
||||||
self.statusBar.statusBarStyle = .Ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
required public init(coder aDecoder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func loadDisplayNode() {
|
|
||||||
self.displayNode = MessageReactionListControllerNode(context: self.context, presentationData: self.presentationData, messageId: messageId, initialReactions: initialReactions, dismiss: { [weak self] in
|
|
||||||
self?.dismiss()
|
|
||||||
})
|
|
||||||
|
|
||||||
super.displayNodeDidLoad()
|
|
||||||
|
|
||||||
self._ready.set(self.controllerNode.isReady.get())
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
|
||||||
super.containerLayoutUpdated(layout, transition: transition)
|
|
||||||
|
|
||||||
self.controllerNode.containerLayoutUpdated(layout: layout, transition: transition)
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func viewDidAppear(_ animated: Bool) {
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
if !self.animatedIn {
|
|
||||||
self.animatedIn = true
|
|
||||||
self.controllerNode.animateIn()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func dismiss(completion: (() -> Void)? = nil) {
|
|
||||||
self.controllerNode.animateOut(completion: { [weak self] in
|
|
||||||
self?.presentingViewController?.dismiss(animated: false, completion: nil)
|
|
||||||
completion?()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct MessageReactionListTransaction {
|
|
||||||
let deletions: [ListViewDeleteItem]
|
|
||||||
let insertions: [ListViewInsertItem]
|
|
||||||
let updates: [ListViewUpdateItem]
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct MessageReactionListEntry: Comparable, Identifiable {
|
|
||||||
let index: Int
|
|
||||||
let item: MessageReactionListCategoryItem
|
|
||||||
|
|
||||||
var stableId: PeerId {
|
|
||||||
return self.item.peer.id
|
|
||||||
}
|
|
||||||
|
|
||||||
static func <(lhs: MessageReactionListEntry, rhs: MessageReactionListEntry) -> Bool {
|
|
||||||
return lhs.index < rhs.index
|
|
||||||
}
|
|
||||||
|
|
||||||
func item(context: AccountContext, presentationData: PresentationData) -> ListViewItem {
|
|
||||||
return ItemListPeerItem(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, context: context, peer: self.item.peer, height: .peerList, nameStyle: .distinctBold, presence: nil, text: .none, label: .text(self.item.reaction, .custom(Font.regular(19.0))), editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: false, sectionId: 0, action: {
|
|
||||||
|
|
||||||
}, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, noInsets: true, tag: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func preparedTransition(from fromEntries: [MessageReactionListEntry], to toEntries: [MessageReactionListEntry], context: AccountContext, presentationData: PresentationData) -> MessageReactionListTransaction {
|
|
||||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
|
||||||
|
|
||||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
|
||||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData), directionHint: nil) }
|
|
||||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData), directionHint: nil) }
|
|
||||||
|
|
||||||
return MessageReactionListTransaction(deletions: deletions, insertions: insertions, updates: updates)
|
|
||||||
}
|
|
||||||
|
|
||||||
private let headerHeight: CGFloat = 60.0
|
|
||||||
private let itemHeight: CGFloat = 50.0
|
|
||||||
|
|
||||||
private func topInsetForLayout(layout: ContainerViewLayout, itemCount: Int) -> CGFloat {
|
|
||||||
let contentHeight = CGFloat(itemCount) * itemHeight
|
|
||||||
let minimumItemHeights: CGFloat = max(contentHeight, itemHeight * 5.0)
|
|
||||||
|
|
||||||
return max(layout.size.height - layout.intrinsicInsets.bottom - minimumItemHeights, headerHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class MessageReactionListControllerNode: ViewControllerTracingNode {
|
|
||||||
private let context: AccountContext
|
|
||||||
private let presentationData: PresentationData
|
|
||||||
private let dismiss: () -> Void
|
|
||||||
|
|
||||||
private let listContext: MessageReactionListContext
|
|
||||||
|
|
||||||
private let dimNode: ASDisplayNode
|
|
||||||
private let backgroundNode: ASDisplayNode
|
|
||||||
private let contentHeaderContainerNode: ASDisplayNode
|
|
||||||
private let contentHeaderContainerBackgroundNode: ASImageNode
|
|
||||||
private let contentHeaderContainerSeparatorNode: ASDisplayNode
|
|
||||||
private var categoryItemNodes: [MessageReactionCategoryNode] = []
|
|
||||||
private let categoryScrollNode: ASScrollNode
|
|
||||||
private let listNode: ListView
|
|
||||||
private var placeholderNode: MessageReactionListLoadingPlaceholder?
|
|
||||||
private var placeholderNodeIsAnimatingOut = false
|
|
||||||
|
|
||||||
private var validLayout: ContainerViewLayout?
|
|
||||||
|
|
||||||
private var currentCategory: MessageReactionListCategory = .all
|
|
||||||
private var currentState: MessageReactionListState?
|
|
||||||
|
|
||||||
private var enqueuedTransactions: [MessageReactionListTransaction] = []
|
|
||||||
|
|
||||||
private let disposable = MetaDisposable()
|
|
||||||
|
|
||||||
let isReady = Promise<Bool>()
|
|
||||||
|
|
||||||
private var forceHeaderTransition: ContainedViewLayoutTransition?
|
|
||||||
|
|
||||||
init(context: AccountContext, presentationData: PresentationData, messageId: MessageId, initialReactions: [MessageReaction], dismiss: @escaping () -> Void) {
|
|
||||||
self.context = context
|
|
||||||
self.presentationData = presentationData
|
|
||||||
self.dismiss = dismiss
|
|
||||||
|
|
||||||
self.dimNode = ASDisplayNode()
|
|
||||||
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
|
|
||||||
|
|
||||||
self.backgroundNode = ASDisplayNode()
|
|
||||||
self.backgroundNode.backgroundColor = self.presentationData.theme.actionSheet.opaqueItemBackgroundColor
|
|
||||||
|
|
||||||
self.contentHeaderContainerNode = ASDisplayNode()
|
|
||||||
self.contentHeaderContainerBackgroundNode = ASImageNode()
|
|
||||||
self.contentHeaderContainerBackgroundNode.displaysAsynchronously = false
|
|
||||||
|
|
||||||
self.contentHeaderContainerSeparatorNode = ASDisplayNode()
|
|
||||||
self.contentHeaderContainerSeparatorNode.backgroundColor = self.presentationData.theme.list.itemPlainSeparatorColor
|
|
||||||
|
|
||||||
self.categoryScrollNode = ASScrollNode()
|
|
||||||
self.contentHeaderContainerBackgroundNode.displayWithoutProcessing = true
|
|
||||||
self.contentHeaderContainerBackgroundNode.image = generateImage(CGSize(width: 10.0, height: 10.0), rotatedContext: { size, context in
|
|
||||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
||||||
context.setFillColor(presentationData.theme.rootController.navigationBar.opaqueBackgroundColor.cgColor)
|
|
||||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
|
||||||
context.fill(CGRect(origin: CGPoint(x: 0.0, y: size.height / 2.0), size: CGSize(width: size.width, height: size.height / 2.0)))
|
|
||||||
})?.stretchableImage(withLeftCapWidth: 5, topCapHeight: 5)
|
|
||||||
|
|
||||||
self.listNode = ListView()
|
|
||||||
self.listNode.limitHitTestToNodes = true
|
|
||||||
self.listNode.accessibilityPageScrolledString = { row, count in
|
|
||||||
return presentationData.strings.VoiceOver_ScrollStatus(row, count).0
|
|
||||||
}
|
|
||||||
|
|
||||||
self.placeholderNode = MessageReactionListLoadingPlaceholder(theme: presentationData.theme, itemHeight: itemHeight)
|
|
||||||
self.placeholderNode?.isUserInteractionEnabled = false
|
|
||||||
|
|
||||||
self.listContext = MessageReactionListContext(postbox: self.context.account.postbox, network: self.context.account.network, messageId: messageId, initialReactions: initialReactions)
|
|
||||||
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
self.addSubnode(self.dimNode)
|
|
||||||
self.addSubnode(self.backgroundNode)
|
|
||||||
|
|
||||||
self.listNode.stackFromBottom = false
|
|
||||||
self.addSubnode(self.listNode)
|
|
||||||
self.placeholderNode.flatMap(self.addSubnode)
|
|
||||||
|
|
||||||
self.addSubnode(self.contentHeaderContainerNode)
|
|
||||||
self.contentHeaderContainerNode.addSubnode(self.contentHeaderContainerBackgroundNode)
|
|
||||||
self.contentHeaderContainerNode.addSubnode(self.contentHeaderContainerSeparatorNode)
|
|
||||||
self.contentHeaderContainerNode.addSubnode(self.categoryScrollNode)
|
|
||||||
|
|
||||||
self.listNode.updateFloatingHeaderOffset = { [weak self] offset, listTransition in
|
|
||||||
guard let strongSelf = self, let layout = strongSelf.validLayout else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let transition = strongSelf.forceHeaderTransition ?? listTransition
|
|
||||||
strongSelf.forceHeaderTransition = nil
|
|
||||||
|
|
||||||
let topOffset = offset
|
|
||||||
transition.updateFrame(node: strongSelf.contentHeaderContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: topOffset - headerHeight), size: CGSize(width: layout.size.width, height: headerHeight)))
|
|
||||||
transition.updateFrame(node: strongSelf.contentHeaderContainerBackgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: headerHeight)))
|
|
||||||
transition.updateFrame(node: strongSelf.contentHeaderContainerSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: headerHeight), size: CGSize(width: layout.size.width, height: UIScreenPixel)))
|
|
||||||
if let placeholderNode = strongSelf.placeholderNode {
|
|
||||||
transition.updateFrame(node: placeholderNode, frame: CGRect(origin: CGPoint(x: 0.0, y: topOffset), size: placeholderNode.bounds.size))
|
|
||||||
}
|
|
||||||
transition.updateFrame(node: strongSelf.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: topOffset - headerHeight / 2.0), size: CGSize(width: layout.size.width, height: layout.size.height + 300.0)))
|
|
||||||
}
|
|
||||||
|
|
||||||
self.disposable.set((self.listContext.state
|
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] state in
|
|
||||||
self?.updateState(state)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
self.disposable.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func didLoad() {
|
|
||||||
super.didLoad()
|
|
||||||
|
|
||||||
self.dimNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dimNodeTapGesture)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func containerLayoutUpdated(layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
|
||||||
let isFirstLayout = self.validLayout == nil
|
|
||||||
self.validLayout = layout
|
|
||||||
|
|
||||||
transition.updateFrame(node: self.dimNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
|
||||||
|
|
||||||
transition.updateBounds(node: self.listNode, bounds: CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: layout.size.height))
|
|
||||||
transition.updatePosition(node: self.listNode, position: CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0))
|
|
||||||
|
|
||||||
var currentCategoryItemCount = 0
|
|
||||||
if let currentState = self.currentState {
|
|
||||||
for (category, categoryState) in currentState.states {
|
|
||||||
if category == self.currentCategory {
|
|
||||||
currentCategoryItemCount = categoryState.count
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var insets = UIEdgeInsets()
|
|
||||||
insets.top = topInsetForLayout(layout: layout, itemCount: currentCategoryItemCount)
|
|
||||||
insets.bottom = layout.intrinsicInsets.bottom
|
|
||||||
|
|
||||||
if let placeholderNode = self.placeholderNode, !self.placeholderNodeIsAnimatingOut {
|
|
||||||
let placeholderHeight = min(CGFloat(currentCategoryItemCount) * itemHeight, layout.size.height) + UIScreenPixel
|
|
||||||
placeholderNode.frame = CGRect(origin: placeholderNode.frame.origin, size: CGSize(width: layout.size.width, height: placeholderHeight))
|
|
||||||
placeholderNode.updateLayout(size: CGSize(width: layout.size.width, height: placeholderHeight))
|
|
||||||
}
|
|
||||||
|
|
||||||
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
|
|
||||||
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: insets, duration: duration, curve: curve), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
|
||||||
|
|
||||||
let sideInset: CGFloat = 12.0
|
|
||||||
let spacing: CGFloat = 6.0
|
|
||||||
var leftX = sideInset
|
|
||||||
for itemNode in self.categoryItemNodes {
|
|
||||||
let itemSize = itemNode.updateLayout()
|
|
||||||
itemNode.frame = CGRect(origin: CGPoint(x: leftX, y: 0.0), size: itemSize)
|
|
||||||
leftX += spacing + itemSize.width
|
|
||||||
}
|
|
||||||
leftX += sideInset
|
|
||||||
self.categoryScrollNode.view.contentSize = CGSize(width: leftX, height: 60.0)
|
|
||||||
self.categoryScrollNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: 60.0))
|
|
||||||
|
|
||||||
if isFirstLayout {
|
|
||||||
while !self.enqueuedTransactions.isEmpty {
|
|
||||||
self.dequeueTransaction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func animateIn() {
|
|
||||||
self.dimNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
|
|
||||||
self.dimNode.layer.animatePosition(from: CGPoint(x: self.dimNode.position.x, y: self.dimNode.position.y - self.layer.bounds.size.height), to: self.layer.position, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, completion: { _ in
|
|
||||||
})
|
|
||||||
self.layer.animatePosition(from: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), to: self.layer.position, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, completion: { _ in
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func animateOut(completion: @escaping () -> Void) {
|
|
||||||
self.dimNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
|
|
||||||
self.dimNode.layer.animatePosition(from: self.dimNode.position, to: CGPoint(x: self.dimNode.position.x, y: self.dimNode.position.y - self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false)
|
|
||||||
self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in
|
|
||||||
completion()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateState(_ state: MessageReactionListState) {
|
|
||||||
if self.currentState != state {
|
|
||||||
self.currentState = state
|
|
||||||
|
|
||||||
self.updateItems()
|
|
||||||
|
|
||||||
if let validLayout = self.validLayout {
|
|
||||||
self.containerLayoutUpdated(layout: validLayout, transition: .immediate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var currentEntries: [MessageReactionListEntry]?
|
|
||||||
private func updateItems() {
|
|
||||||
var entries: [MessageReactionListEntry] = []
|
|
||||||
|
|
||||||
var index = 0
|
|
||||||
let states = self.currentState?.states ?? []
|
|
||||||
for (category, categoryState) in states {
|
|
||||||
if self.categoryItemNodes.count <= index {
|
|
||||||
let itemNode = MessageReactionCategoryNode(theme: self.presentationData.theme, category: category, count: categoryState.count, action: { [weak self] in
|
|
||||||
self?.setCategory(category)
|
|
||||||
})
|
|
||||||
self.categoryItemNodes.append(itemNode)
|
|
||||||
self.categoryScrollNode.addSubnode(itemNode)
|
|
||||||
if category == self.currentCategory {
|
|
||||||
itemNode.isSelected = true
|
|
||||||
} else {
|
|
||||||
itemNode.isSelected = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if category == self.currentCategory {
|
|
||||||
for item in categoryState.items {
|
|
||||||
entries.append(MessageReactionListEntry(index: entries.count, item: item))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index += 1
|
|
||||||
}
|
|
||||||
let transaction = preparedTransition(from: self.currentEntries ?? [], to: entries, context: self.context, presentationData: self.presentationData)
|
|
||||||
let previousWasEmpty = self.currentEntries == nil || self.currentEntries?.count == 0
|
|
||||||
let isEmpty = entries.isEmpty
|
|
||||||
self.currentEntries = entries
|
|
||||||
|
|
||||||
self.enqueuedTransactions.append(transaction)
|
|
||||||
self.dequeueTransaction()
|
|
||||||
|
|
||||||
if previousWasEmpty && !isEmpty {
|
|
||||||
if let placeholderNode = self.placeholderNode {
|
|
||||||
self.placeholderNodeIsAnimatingOut = true
|
|
||||||
placeholderNode.allowsGroupOpacity = true
|
|
||||||
placeholderNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.18, removeOnCompletion: false, completion: { [weak self] _ in
|
|
||||||
guard let strongSelf = self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongSelf.placeholderNode?.removeFromSupernode()
|
|
||||||
strongSelf.placeholderNode = nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
self.listNode.forEachItemNode({ itemNode in
|
|
||||||
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.18)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setCategory(_ category: MessageReactionListCategory) {
|
|
||||||
if self.currentCategory != category {
|
|
||||||
self.currentCategory = category
|
|
||||||
|
|
||||||
for itemNode in self.categoryItemNodes {
|
|
||||||
itemNode.isSelected = category == itemNode.category
|
|
||||||
}
|
|
||||||
|
|
||||||
//self.forceHeaderTransition = .animated(duration: 0.3, curve: .spring)
|
|
||||||
if let validLayout = self.validLayout {
|
|
||||||
self.containerLayoutUpdated(layout: validLayout, transition: .animated(duration: 0.3, curve: .spring))
|
|
||||||
}
|
|
||||||
|
|
||||||
self.updateItems()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func dequeueTransaction() {
|
|
||||||
guard let layout = self.validLayout, let transaction = self.enqueuedTransactions.first else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.enqueuedTransactions.remove(at: 0)
|
|
||||||
|
|
||||||
var options = ListViewDeleteAndInsertOptions()
|
|
||||||
options.insert(.Synchronous)
|
|
||||||
options.insert(.PreferSynchronousResourceLoading)
|
|
||||||
options.insert(.PreferSynchronousDrawing)
|
|
||||||
|
|
||||||
var currentCategoryItemCount = 0
|
|
||||||
if let currentState = self.currentState {
|
|
||||||
for (category, categoryState) in currentState.states {
|
|
||||||
if category == self.currentCategory {
|
|
||||||
currentCategoryItemCount = categoryState.count
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var insets = UIEdgeInsets()
|
|
||||||
insets.top = topInsetForLayout(layout: layout, itemCount: currentCategoryItemCount)
|
|
||||||
insets.bottom = layout.intrinsicInsets.bottom
|
|
||||||
|
|
||||||
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: self.listNode.bounds.size, insets: insets, duration: 0.3, curve: .Default(duration: 0.3))
|
|
||||||
|
|
||||||
self.listNode.transaction(deleteIndices: transaction.deletions, insertIndicesAndItems: transaction.insertions, updateIndicesAndItems: transaction.updates, options: options, updateSizeAndInsets: updateSizeAndInsets, updateOpaqueState: nil, completion: { [weak self] _ in
|
|
||||||
self?.isReady.set(.single(true))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc private func dimNodeTapGesture(_ recognizer: UITapGestureRecognizer) {
|
|
||||||
if case .ended = recognizer.state {
|
|
||||||
self.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
||||||
for itemNode in self.categoryItemNodes {
|
|
||||||
if let result = itemNode.hitTest(self.view.convert(point, to: itemNode.view), with: event) {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let result = self.listNode.hitTest(self.view.convert(point, to: self.listNode.view), with: event) {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
if point.y >= self.contentHeaderContainerNode.frame.minY && point.y < self.bounds.height {
|
|
||||||
return self.listNode.view
|
|
||||||
}
|
|
||||||
if point.y >= 0 && point.y < self.contentHeaderContainerNode.frame.minY {
|
|
||||||
return self.dimNode.view
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import AsyncDisplayKit
|
|
||||||
import Display
|
|
||||||
import TelegramPresentationData
|
|
||||||
import TelegramCore
|
|
||||||
import SyncCore
|
|
||||||
|
|
||||||
final class MessageReactionListLoadingPlaceholder: ASDisplayNode {
|
|
||||||
private let theme: PresentationTheme
|
|
||||||
private let itemHeight: CGFloat
|
|
||||||
private let itemImage: UIImage?
|
|
||||||
|
|
||||||
private let backgroundNode: ASDisplayNode
|
|
||||||
private let separatorNode: ASDisplayNode
|
|
||||||
private let highlightNode: ASImageNode
|
|
||||||
private var itemNodes: [ASImageNode] = []
|
|
||||||
|
|
||||||
init(theme: PresentationTheme, itemHeight: CGFloat) {
|
|
||||||
self.theme = theme
|
|
||||||
self.itemHeight = itemHeight
|
|
||||||
|
|
||||||
self.backgroundNode = ASDisplayNode()
|
|
||||||
self.backgroundNode.backgroundColor = UIColor(white: 0.92, alpha: 1.0)
|
|
||||||
|
|
||||||
self.separatorNode = ASDisplayNode()
|
|
||||||
self.separatorNode.backgroundColor = theme.list.itemPlainSeparatorColor
|
|
||||||
|
|
||||||
self.highlightNode = ASImageNode()
|
|
||||||
self.highlightNode.displaysAsynchronously = false
|
|
||||||
self.highlightNode.displayWithoutProcessing = true
|
|
||||||
|
|
||||||
let leftInset: CGFloat = 15.0
|
|
||||||
let avatarSize: CGFloat = 40.0
|
|
||||||
let avatarSpacing: CGFloat = 11.0
|
|
||||||
let contentWidth: CGFloat = 4.0
|
|
||||||
let contentHeight: CGFloat = 14.0
|
|
||||||
let rightInset: CGFloat = 54.0
|
|
||||||
self.itemImage = generateImage(CGSize(width: leftInset + avatarSize + avatarSpacing + contentWidth + rightInset, height: itemHeight), rotatedContext: { size, context in
|
|
||||||
context.setFillColor(theme.actionSheet.opaqueItemBackgroundColor.cgColor)
|
|
||||||
context.fill(CGRect(origin: CGPoint(), size: size))
|
|
||||||
context.setFillColor(theme.list.itemPlainSeparatorColor.cgColor)
|
|
||||||
context.fill(CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: UIScreenPixel)))
|
|
||||||
context.setBlendMode(.copy)
|
|
||||||
context.setFillColor(UIColor.clear.cgColor)
|
|
||||||
context.fillEllipse(in: CGRect(origin: CGPoint(x: leftInset, y: floor((itemHeight - avatarSize) / 2.0)), size: CGSize(width: avatarSize, height: avatarSize)))
|
|
||||||
let contentOrigin = leftInset + avatarSize + avatarSpacing
|
|
||||||
context.fill(CGRect(origin: CGPoint(x: contentOrigin, y: floor((size.height - contentHeight) / 2.0)), size: CGSize(width: size.width - contentOrigin - rightInset, height: contentHeight)))
|
|
||||||
})?.stretchableImage(withLeftCapWidth: Int(leftInset + avatarSize + avatarSpacing + 1), topCapHeight: 0)
|
|
||||||
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
self.addSubnode(self.backgroundNode)
|
|
||||||
self.addSubnode(self.highlightNode)
|
|
||||||
self.addSubnode(self.separatorNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateLayout(size: CGSize) {
|
|
||||||
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size)
|
|
||||||
|
|
||||||
var verticalOffset: CGFloat = 0.0
|
|
||||||
var index = 0
|
|
||||||
while verticalOffset < size.height - 1.0 {
|
|
||||||
if self.itemNodes.count >= index {
|
|
||||||
let itemNode = ASImageNode()
|
|
||||||
itemNode.image = self.itemImage
|
|
||||||
self.itemNodes.append(itemNode)
|
|
||||||
self.addSubnode(itemNode)
|
|
||||||
}
|
|
||||||
self.itemNodes[index].frame = CGRect(origin: CGPoint(x: 0.0, y: verticalOffset), size: CGSize(width: size.width, height: self.itemHeight))
|
|
||||||
verticalOffset += self.itemHeight
|
|
||||||
index += 1
|
|
||||||
}
|
|
||||||
self.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: verticalOffset), size: CGSize(width: size.width, height: UIScreenPixel))
|
|
||||||
if index < self.itemNodes.count {
|
|
||||||
for i in index ..< self.itemNodes.count {
|
|
||||||
self.itemNodes[i].removeFromSupernode()
|
|
||||||
}
|
|
||||||
self.itemNodes.removeLast(self.itemNodes.count - index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -36,7 +36,7 @@ public func peerInfoProfilePhotos(context: AccountContext, peerId: PeerId) -> Si
|
|||||||
if let firstEntry = entries.first {
|
if let firstEntry = entries.first {
|
||||||
return context.account.postbox.loadedPeerWithId(peerId)
|
return context.account.postbox.loadedPeerWithId(peerId)
|
||||||
|> mapToSignal { peer -> Signal<(Bool, [AvatarGalleryEntry])?, NoError>in
|
|> mapToSignal { peer -> Signal<(Bool, [AvatarGalleryEntry])?, NoError>in
|
||||||
return fetchedAvatarGalleryEntries(account: context.account, peer: peer, firstEntry: firstEntry)
|
return fetchedAvatarGalleryEntries(engine: context.engine, account: context.account, peer: peer, firstEntry: firstEntry)
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -210,7 +210,7 @@ public func initialAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchedAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<[AvatarGalleryEntry], NoError> {
|
public func fetchedAvatarGalleryEntries(engine: TelegramEngine, account: Account, peer: Peer) -> Signal<[AvatarGalleryEntry], NoError> {
|
||||||
return initialAvatarGalleryEntries(account: account, peer: peer)
|
return initialAvatarGalleryEntries(account: account, peer: peer)
|
||||||
|> map { entries -> [AvatarGalleryEntry] in
|
|> map { entries -> [AvatarGalleryEntry] in
|
||||||
return entries ?? []
|
return entries ?? []
|
||||||
@ -218,7 +218,7 @@ public func fetchedAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<
|
|||||||
|> mapToSignal { initialEntries in
|
|> mapToSignal { initialEntries in
|
||||||
return .single(initialEntries)
|
return .single(initialEntries)
|
||||||
|> then(
|
|> then(
|
||||||
requestPeerPhotos(postbox: account.postbox, network: account.network, peerId: peer.id)
|
engine.peers.requestPeerPhotos(peerId: peer.id)
|
||||||
|> map { photos -> [AvatarGalleryEntry] in
|
|> map { photos -> [AvatarGalleryEntry] in
|
||||||
var result: [AvatarGalleryEntry] = []
|
var result: [AvatarGalleryEntry] = []
|
||||||
if photos.isEmpty {
|
if photos.isEmpty {
|
||||||
@ -269,11 +269,11 @@ public func fetchedAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchedAvatarGalleryEntries(account: Account, peer: Peer, firstEntry: AvatarGalleryEntry) -> Signal<(Bool, [AvatarGalleryEntry]), NoError> {
|
public func fetchedAvatarGalleryEntries(engine: TelegramEngine, account: Account, peer: Peer, firstEntry: AvatarGalleryEntry) -> Signal<(Bool, [AvatarGalleryEntry]), NoError> {
|
||||||
let initialEntries = [firstEntry]
|
let initialEntries = [firstEntry]
|
||||||
return Signal<(Bool, [AvatarGalleryEntry]), NoError>.single((false, initialEntries))
|
return Signal<(Bool, [AvatarGalleryEntry]), NoError>.single((false, initialEntries))
|
||||||
|> then(
|
|> then(
|
||||||
requestPeerPhotos(postbox: account.postbox, network: account.network, peerId: peer.id)
|
engine.peers.requestPeerPhotos(peerId: peer.id)
|
||||||
|> map { photos -> (Bool, [AvatarGalleryEntry]) in
|
|> map { photos -> (Bool, [AvatarGalleryEntry]) in
|
||||||
var result: [AvatarGalleryEntry] = []
|
var result: [AvatarGalleryEntry] = []
|
||||||
let initialEntries = [firstEntry]
|
let initialEntries = [firstEntry]
|
||||||
@ -403,7 +403,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
|||||||
if let remoteEntries = remoteEntries {
|
if let remoteEntries = remoteEntries {
|
||||||
remoteEntriesSignal = remoteEntries.get()
|
remoteEntriesSignal = remoteEntries.get()
|
||||||
} else {
|
} else {
|
||||||
remoteEntriesSignal = fetchedAvatarGalleryEntries(account: context.account, peer: peer)
|
remoteEntriesSignal = fetchedAvatarGalleryEntries(engine: context.engine, account: context.account, peer: peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
let initialSignal = initialAvatarGalleryEntries(account: context.account, peer: peer)
|
let initialSignal = initialAvatarGalleryEntries(account: context.account, peer: peer)
|
||||||
|
@ -889,7 +889,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
transferOwnershipDisposable.set((checkOwnershipTranfserAvailability(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, memberId: adminId) |> deliverOnMainQueue).start(error: { error in
|
transferOwnershipDisposable.set((context.engine.peers.checkOwnershipTranfserAvailability(memberId: adminId) |> deliverOnMainQueue).start(error: { error in
|
||||||
let controller = channelOwnershipTransferController(context: context, peer: peer, member: member, initialError: error, present: { c, a in
|
let controller = channelOwnershipTransferController(context: context, peer: peer, member: member, initialError: error, present: { c, a in
|
||||||
presentControllerImpl?(c, a)
|
presentControllerImpl?(c, a)
|
||||||
}, completion: { upgradedPeerId in
|
}, completion: { upgradedPeerId in
|
||||||
|
@ -665,7 +665,7 @@ public func channelAdminsController(context: AccountContext, peerId initialPeerI
|
|||||||
|> deliverOnMainQueue).start(next: { peerId in
|
|> deliverOnMainQueue).start(next: { peerId in
|
||||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
var didReportLoadCompleted = false
|
var didReportLoadCompleted = false
|
||||||
let membersAndLoadMoreControl: (Disposable, PeerChannelMemberCategoryControl?) = context.peerChannelMemberCategoriesContextsManager.admins(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId) { membersState in
|
let membersAndLoadMoreControl: (Disposable, PeerChannelMemberCategoryControl?) = context.peerChannelMemberCategoriesContextsManager.admins(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId) { membersState in
|
||||||
if case .loading = membersState.loadingState, membersState.list.isEmpty {
|
if case .loading = membersState.loadingState, membersState.list.isEmpty {
|
||||||
adminsPromise.set(.single(nil))
|
adminsPromise.set(.single(nil))
|
||||||
} else {
|
} else {
|
||||||
|
@ -506,7 +506,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
|
|||||||
state.updating = true
|
state.updating = true
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: memberId, bannedRights: nil)
|
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: nil)
|
||||||
|> deliverOnMainQueue).start(error: { _ in
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
|
|
||||||
}, completed: {
|
}, completed: {
|
||||||
@ -667,7 +667,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
|
|||||||
guard let upgradedPeerId = upgradedPeerId else {
|
guard let upgradedPeerId = upgradedPeerId else {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
return context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: upgradedPeerId, memberId: memberId, bannedRights: cleanResolvedRights)
|
return context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: upgradedPeerId, memberId: memberId, bannedRights: cleanResolvedRights)
|
||||||
|> mapToSignal { _ -> Signal<PeerId?, NoError> in
|
|> mapToSignal { _ -> Signal<PeerId?, NoError> in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
@ -700,7 +700,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: memberId, bannedRights: cleanResolvedRights)
|
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: cleanResolvedRights)
|
||||||
|> deliverOnMainQueue).start(error: { _ in
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
|
|
||||||
}, completed: {
|
}, completed: {
|
||||||
|
@ -324,7 +324,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
|
|||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let progress = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
|
let progress = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
|
||||||
presentControllerImpl?(progress, nil)
|
presentControllerImpl?(progress, nil)
|
||||||
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: peer.id, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max))
|
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: peer.id, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max))
|
||||||
|> deliverOnMainQueue).start(error: { [weak progress] _ in
|
|> deliverOnMainQueue).start(error: { [weak progress] _ in
|
||||||
progress?.dismiss()
|
progress?.dismiss()
|
||||||
dismissController?()
|
dismissController?()
|
||||||
@ -343,7 +343,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
|
|||||||
return $0.withUpdatedRemovingPeerId(memberId)
|
return $0.withUpdatedRemovingPeerId(memberId)
|
||||||
}
|
}
|
||||||
|
|
||||||
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: memberId, bannedRights: nil) |> deliverOnMainQueue).start(error: { _ in
|
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: nil) |> deliverOnMainQueue).start(error: { _ in
|
||||||
updateState {
|
updateState {
|
||||||
return $0.withUpdatedRemovingPeerId(nil)
|
return $0.withUpdatedRemovingPeerId(nil)
|
||||||
}
|
}
|
||||||
@ -388,7 +388,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
|
|||||||
updateState {
|
updateState {
|
||||||
return $0.withUpdatedRemovingPeerId(memberId)
|
return $0.withUpdatedRemovingPeerId(memberId)
|
||||||
}
|
}
|
||||||
let signal = context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: memberId, bannedRights: nil)
|
let signal = context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: nil)
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
|> then(
|
|> then(
|
||||||
context.peerChannelMemberCategoriesContextsManager.addMember(account: context.account, peerId: peerId, memberId: memberId)
|
context.peerChannelMemberCategoriesContextsManager.addMember(account: context.account, peerId: peerId, memberId: memberId)
|
||||||
@ -418,7 +418,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
|
|||||||
return $0.withUpdatedRemovingPeerId(memberId)
|
return $0.withUpdatedRemovingPeerId(memberId)
|
||||||
}
|
}
|
||||||
|
|
||||||
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: memberId, bannedRights: nil) |> deliverOnMainQueue).start(error: { _ in
|
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: nil) |> deliverOnMainQueue).start(error: { _ in
|
||||||
updateState {
|
updateState {
|
||||||
return $0.withUpdatedRemovingPeerId(nil)
|
return $0.withUpdatedRemovingPeerId(nil)
|
||||||
}
|
}
|
||||||
@ -437,7 +437,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
let (listDisposable, loadMoreControl) = context.peerChannelMemberCategoriesContextsManager.banned(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { listState in
|
let (listDisposable, loadMoreControl) = context.peerChannelMemberCategoriesContextsManager.banned(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { listState in
|
||||||
if case .loading(true) = listState.loadingState, listState.list.isEmpty {
|
if case .loading(true) = listState.loadingState, listState.list.isEmpty {
|
||||||
blacklistPromise.set(.single(nil))
|
blacklistPromise.set(.single(nil))
|
||||||
} else {
|
} else {
|
||||||
|
@ -230,7 +230,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
|||||||
let groupPeers = Promise<[Peer]?>()
|
let groupPeers = Promise<[Peer]?>()
|
||||||
groupPeers.set(.single(nil)
|
groupPeers.set(.single(nil)
|
||||||
|> then(
|
|> then(
|
||||||
availableGroupsForChannelDiscussion(postbox: context.account.postbox, network: context.account.network)
|
context.engine.peers.availableGroupsForChannelDiscussion()
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<[Peer]?, NoError> in
|
|> `catch` { _ -> Signal<[Peer]?, NoError> in
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
@ -260,7 +260,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
|||||||
}
|
}
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
pushControllerImpl?(context.sharedContext.makeCreateGroupController(context: context, peerIds: [], initialTitle: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) + " Chat", mode: .supergroup, completion: { groupId, dismiss in
|
pushControllerImpl?(context.sharedContext.makeCreateGroupController(context: context, peerIds: [], initialTitle: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) + " Chat", mode: .supergroup, completion: { groupId, dismiss in
|
||||||
var applySignal = updateGroupDiscussionForChannel(network: context.account.network, postbox: context.account.postbox, channelId: peerId, groupId: groupId)
|
var applySignal = context.engine.peers.updateGroupDiscussionForChannel(channelId: peerId, groupId: groupId)
|
||||||
var cancelImpl: (() -> Void)?
|
var cancelImpl: (() -> Void)?
|
||||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
@ -358,13 +358,13 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return updateGroupDiscussionForChannel(network: context.account.network, postbox: context.account.postbox, channelId: peerId, groupId: resultPeerId)
|
return context.engine.peers.updateGroupDiscussionForChannel(channelId: peerId, groupId: resultPeerId)
|
||||||
}
|
}
|
||||||
|> castError(ChannelDiscussionGroupError.self)
|
|> castError(ChannelDiscussionGroupError.self)
|
||||||
|> switchToLatest
|
|> switchToLatest
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
applySignal = updateGroupDiscussionForChannel(network: context.account.network, postbox: context.account.postbox, channelId: peerId, groupId: groupId)
|
applySignal = context.engine.peers.updateGroupDiscussionForChannel(channelId: peerId, groupId: groupId)
|
||||||
}
|
}
|
||||||
var cancelImpl: (() -> Void)?
|
var cancelImpl: (() -> Void)?
|
||||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
@ -413,7 +413,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
|||||||
case .groupHistoryIsCurrentlyPrivate:
|
case .groupHistoryIsCurrentlyPrivate:
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Channel_DiscussionGroup_MakeHistoryPublic, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Channel_DiscussionGroup_MakeHistoryPublicProceed, action: {
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Channel_DiscussionGroup_MakeHistoryPublic, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Channel_DiscussionGroup_MakeHistoryPublicProceed, action: {
|
||||||
var applySignal: Signal<Bool, ChannelDiscussionGroupError> = updateChannelHistoryAvailabilitySettingsInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: updatedPeerId ?? groupId, historyAvailableForNewMembers: true)
|
var applySignal: Signal<Bool, ChannelDiscussionGroupError> = context.engine.peers.updateChannelHistoryAvailabilitySettingsInteractively(peerId: updatedPeerId ?? groupId, historyAvailableForNewMembers: true)
|
||||||
|> mapError { _ -> ChannelDiscussionGroupError in
|
|> mapError { _ -> ChannelDiscussionGroupError in
|
||||||
return .generic
|
return .generic
|
||||||
}
|
}
|
||||||
@ -421,7 +421,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
|||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
|> then(
|
|> then(
|
||||||
updateGroupDiscussionForChannel(network: context.account.network, postbox: context.account.postbox, channelId: peerId, groupId: updatedPeerId ?? groupId)
|
context.engine.peers.updateGroupDiscussionForChannel(channelId: peerId, groupId: updatedPeerId ?? groupId)
|
||||||
)
|
)
|
||||||
var cancelImpl: (() -> Void)?
|
var cancelImpl: (() -> Void)?
|
||||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
@ -502,7 +502,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var applySignal = updateGroupDiscussionForChannel(network: context.account.network, postbox: context.account.postbox, channelId: applyPeerId, groupId: nil)
|
var applySignal = context.engine.peers.updateGroupDiscussionForChannel(channelId: applyPeerId, groupId: nil)
|
||||||
var cancelImpl: (() -> Void)?
|
var cancelImpl: (() -> Void)?
|
||||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
@ -836,11 +836,11 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
|
|||||||
}
|
}
|
||||||
let controller = notificationMuteSettingsController(presentationData: presentationData, notificationSettings: globalSettings.effective.groupChats, soundSettings: soundSettings, openSoundSettings: {
|
let controller = notificationMuteSettingsController(presentationData: presentationData, notificationSettings: globalSettings.effective.groupChats, soundSettings: soundSettings, openSoundSettings: {
|
||||||
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: peerSettings.messageSound, defaultSound: globalSettings.effective.groupChats.sound, completion: { sound in
|
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: peerSettings.messageSound, defaultSound: globalSettings.effective.groupChats.sound, completion: { sound in
|
||||||
let _ = updatePeerNotificationSoundInteractive(account: context.account, peerId: peerId, sound: sound).start()
|
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, sound: sound).start()
|
||||||
})
|
})
|
||||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}, updateSettings: { value in
|
}, updateSettings: { value in
|
||||||
changeMuteSettingsDisposable.set(updatePeerMuteSetting(account: context.account, peerId: peerId, muteInterval: value).start())
|
changeMuteSettingsDisposable.set(context.engine.peers.updatePeerMuteSetting(peerId: peerId, muteInterval: value).start())
|
||||||
})
|
})
|
||||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
})
|
})
|
||||||
@ -918,7 +918,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
|
|||||||
}, aboutLinkAction: { action, itemLink in
|
}, aboutLinkAction: { action, itemLink in
|
||||||
aboutLinkActionImpl?(action, itemLink)
|
aboutLinkActionImpl?(action, itemLink)
|
||||||
}, toggleSignatures: { enabled in
|
}, toggleSignatures: { enabled in
|
||||||
actionsDisposable.add(toggleShouldChannelMessagesSignatures(account: context.account, peerId: peerId, enabled: enabled).start())
|
actionsDisposable.add(context.engine.peers.toggleShouldChannelMessagesSignatures(peerId: peerId, enabled: enabled).start())
|
||||||
})
|
})
|
||||||
|
|
||||||
var wasEditing: Bool?
|
var wasEditing: Bool?
|
||||||
|
@ -443,7 +443,7 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
|
|||||||
return $0.withUpdatedRemovingPeerId(memberId)
|
return $0.withUpdatedRemovingPeerId(memberId)
|
||||||
}
|
}
|
||||||
|
|
||||||
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: memberId, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max))
|
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max))
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
updateState {
|
updateState {
|
||||||
return $0.withUpdatedRemovingPeerId(nil)
|
return $0.withUpdatedRemovingPeerId(nil)
|
||||||
@ -462,7 +462,7 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
|
|||||||
|
|
||||||
let peerView = context.account.viewTracker.peerView(peerId)
|
let peerView = context.account.viewTracker.peerView(peerId)
|
||||||
|
|
||||||
let (disposable, loadMoreControl) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { state in
|
let (disposable, loadMoreControl) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { state in
|
||||||
peersPromise.set(.single(state.list))
|
peersPromise.set(.single(state.list))
|
||||||
})
|
})
|
||||||
actionsDisposable.add(disposable)
|
actionsDisposable.add(disposable)
|
||||||
|
@ -231,13 +231,13 @@ private func categorySignal(context: AccountContext, peerId: PeerId, category: G
|
|||||||
}
|
}
|
||||||
switch category {
|
switch category {
|
||||||
case .admins:
|
case .admins:
|
||||||
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.admins(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: processListState)
|
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.admins(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: processListState)
|
||||||
case .contacts:
|
case .contacts:
|
||||||
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.contacts(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: processListState)
|
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.contacts(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: processListState)
|
||||||
case .bots:
|
case .bots:
|
||||||
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.bots(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: processListState)
|
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.bots(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: processListState)
|
||||||
case .members:
|
case .members:
|
||||||
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: processListState)
|
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: processListState)
|
||||||
}
|
}
|
||||||
|
|
||||||
let (disposable, _) = disposableAndLoadMoreControl
|
let (disposable, _) = disposableAndLoadMoreControl
|
||||||
@ -452,7 +452,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: memberId, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max))
|
return context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max))
|
||||||
|> afterDisposed {
|
|> afterDisposed {
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
updateState { state in
|
updateState { state in
|
||||||
@ -479,7 +479,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return removePeerMember(account: context.account, peerId: peerId, memberId: memberId)
|
return context.engine.peers.removePeerMember(peerId: peerId, memberId: memberId)
|
||||||
|> deliverOnMainQueue
|
|> deliverOnMainQueue
|
||||||
|> afterDisposed {
|
|> afterDisposed {
|
||||||
updateState { state in
|
updateState { state in
|
||||||
@ -608,7 +608,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
switch mode {
|
switch mode {
|
||||||
case .searchMembers, .banAndPromoteActions:
|
case .searchMembers, .banAndPromoteActions:
|
||||||
foundGroupMembers = Signal { subscriber in
|
foundGroupMembers = Signal { subscriber in
|
||||||
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
subscriber.putNext(state.list)
|
subscriber.putNext(state.list)
|
||||||
}
|
}
|
||||||
@ -619,11 +619,11 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
foundMembers = .single([])
|
foundMembers = .single([])
|
||||||
case .inviteActions:
|
case .inviteActions:
|
||||||
foundGroupMembers = .single([])
|
foundGroupMembers = .single([])
|
||||||
foundMembers = channelMembers(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, category: .recent(.search(query)))
|
foundMembers = context.engine.peers.channelMembers(peerId: peerId, category: .recent(.search(query)))
|
||||||
|> map { $0 ?? [] }
|
|> map { $0 ?? [] }
|
||||||
case .searchAdmins:
|
case .searchAdmins:
|
||||||
foundGroupMembers = Signal { subscriber in
|
foundGroupMembers = Signal { subscriber in
|
||||||
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.admins(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.admins(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
subscriber.putNext(state.list)
|
subscriber.putNext(state.list)
|
||||||
}
|
}
|
||||||
@ -633,7 +633,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
foundMembers = .single([])
|
foundMembers = .single([])
|
||||||
case .searchBanned:
|
case .searchBanned:
|
||||||
foundGroupMembers = Signal { subscriber in
|
foundGroupMembers = Signal { subscriber in
|
||||||
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.restricted(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.restricted(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
subscriber.putNext(state.list)
|
subscriber.putNext(state.list)
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
@ -643,7 +643,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
}
|
}
|
||||||
|> runOn(Queue.mainQueue())
|
|> runOn(Queue.mainQueue())
|
||||||
foundMembers = Signal { subscriber in
|
foundMembers = Signal { subscriber in
|
||||||
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
subscriber.putNext(state.list.filter({ participant in
|
subscriber.putNext(state.list.filter({ participant in
|
||||||
return participant.peer.id != context.account.peerId
|
return participant.peer.id != context.account.peerId
|
||||||
@ -655,7 +655,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
|||||||
|> runOn(Queue.mainQueue())
|
|> runOn(Queue.mainQueue())
|
||||||
case .searchKicked:
|
case .searchKicked:
|
||||||
foundGroupMembers = Signal { subscriber in
|
foundGroupMembers = Signal { subscriber in
|
||||||
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.banned(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.banned(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
subscriber.putNext(state.list)
|
subscriber.putNext(state.list)
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
|
@ -419,7 +419,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
|
|||||||
} else {
|
} else {
|
||||||
let membersState = Promise<ChannelMemberListState>()
|
let membersState = Promise<ChannelMemberListState>()
|
||||||
|
|
||||||
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { state in
|
disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { state in
|
||||||
membersState.set(.single(state))
|
membersState.set(.single(state))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ private func commitChannelOwnershipTransferController(context: AccountContext, p
|
|||||||
|
|
||||||
let signal: Signal<PeerId?, ChannelOwnershipTransferError>
|
let signal: Signal<PeerId?, ChannelOwnershipTransferError>
|
||||||
if let peer = peer as? TelegramChannel {
|
if let peer = peer as? TelegramChannel {
|
||||||
signal = context.peerChannelMemberCategoriesContextsManager.transferOwnership(account: context.account, peerId: peer.id, memberId: member.id, password: contentNode.password) |> mapToSignal { _ in
|
signal = context.peerChannelMemberCategoriesContextsManager.transferOwnership(engine: context.engine, peerId: peer.id, memberId: member.id, password: contentNode.password) |> mapToSignal { _ in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
|> then(.single(nil))
|
|> then(.single(nil))
|
||||||
@ -475,7 +475,7 @@ private func commitChannelOwnershipTransferController(context: AccountContext, p
|
|||||||
guard let upgradedPeerId = upgradedPeerId else {
|
guard let upgradedPeerId = upgradedPeerId else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
return context.peerChannelMemberCategoriesContextsManager.transferOwnership(account: context.account, peerId: upgradedPeerId, memberId: member.id, password: contentNode.password) |> mapToSignal { _ in
|
return context.peerChannelMemberCategoriesContextsManager.transferOwnership(engine: context.engine, peerId: upgradedPeerId, memberId: member.id, password: contentNode.password) |> mapToSignal { _ in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
|> then(.single(upgradedPeerId))
|
|> then(.single(upgradedPeerId))
|
||||||
|
@ -536,7 +536,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
|||||||
peersPromise.set(.single((peerId, nil)))
|
peersPromise.set(.single((peerId, nil)))
|
||||||
} else {
|
} else {
|
||||||
var loadCompletedCalled = false
|
var loadCompletedCalled = false
|
||||||
let disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.restricted(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { state in
|
let disposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.restricted(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { state in
|
||||||
if case .loading(true) = state.loadingState, !updated {
|
if case .loading(true) = state.loadingState, !updated {
|
||||||
peersPromise.set(.single((peerId, nil)))
|
peersPromise.set(.single((peerId, nil)))
|
||||||
} else {
|
} else {
|
||||||
@ -594,7 +594,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
|||||||
}
|
}
|
||||||
let state = stateValue.with { $0 }
|
let state = stateValue.with { $0 }
|
||||||
if let modifiedRightsFlags = state.modifiedRightsFlags {
|
if let modifiedRightsFlags = state.modifiedRightsFlags {
|
||||||
updateDefaultRightsDisposable.set((updateDefaultChannelMemberBannedRights(account: context.account, peerId: view.peerId, rights: TelegramChatBannedRights(flags: completeRights(modifiedRightsFlags), untilDate: Int32.max))
|
updateDefaultRightsDisposable.set((context.engine.peers.updateDefaultChannelMemberBannedRights(peerId: view.peerId, rights: TelegramChatBannedRights(flags: completeRights(modifiedRightsFlags), untilDate: Int32.max))
|
||||||
|> deliverOnMainQueue).start())
|
|> deliverOnMainQueue).start())
|
||||||
}
|
}
|
||||||
} else if let group = view.peers[view.peerId] as? TelegramGroup, let _ = view.cachedData as? CachedGroupData {
|
} else if let group = view.peers[view.peerId] as? TelegramGroup, let _ = view.cachedData as? CachedGroupData {
|
||||||
@ -624,7 +624,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
|||||||
}
|
}
|
||||||
let state = stateValue.with { $0 }
|
let state = stateValue.with { $0 }
|
||||||
if let modifiedRightsFlags = state.modifiedRightsFlags {
|
if let modifiedRightsFlags = state.modifiedRightsFlags {
|
||||||
updateDefaultRightsDisposable.set((updateDefaultChannelMemberBannedRights(account: context.account, peerId: view.peerId, rights: TelegramChatBannedRights(flags: completeRights(modifiedRightsFlags), untilDate: Int32.max))
|
updateDefaultRightsDisposable.set((context.engine.peers.updateDefaultChannelMemberBannedRights(peerId: view.peerId, rights: TelegramChatBannedRights(flags: completeRights(modifiedRightsFlags), untilDate: Int32.max))
|
||||||
|> deliverOnMainQueue).start())
|
|> deliverOnMainQueue).start())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -679,7 +679,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: context.account, peerId: peerId, memberId: memberId, bannedRights: nil)
|
removePeerDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: nil)
|
||||||
|> deliverOnMainQueue).start(error: { _ in
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
updateState { state in
|
updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
|
@ -1104,7 +1104,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
|
|||||||
switch subject {
|
switch subject {
|
||||||
case let .create(peer, _, share, shareViaException, _):
|
case let .create(peer, _, share, shareViaException, _):
|
||||||
if share, filteredPhoneNumbers.count <= 1, let peer = peer {
|
if share, filteredPhoneNumbers.count <= 1, let peer = peer {
|
||||||
addContactDisposable.set((addContactInteractively(account: context.account, peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "", addToPrivacyExceptions: shareViaException && addToPrivacyExceptions)
|
addContactDisposable.set((context.engine.contacts.addContactInteractively(peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "", addToPrivacyExceptions: shareViaException && addToPrivacyExceptions)
|
||||||
|> deliverOnMainQueue).start(error: { _ in
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
}, completed: {
|
}, completed: {
|
||||||
@ -1138,7 +1138,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
|
|||||||
switch subject {
|
switch subject {
|
||||||
case let .create(peer, _, share, shareViaException, _):
|
case let .create(peer, _, share, shareViaException, _):
|
||||||
if share, let peer = peer {
|
if share, let peer = peer {
|
||||||
return addContactInteractively(account: context.account, peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "", addToPrivacyExceptions: shareViaException && addToPrivacyExceptions)
|
return context.engine.contacts.addContactInteractively(peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "", addToPrivacyExceptions: shareViaException && addToPrivacyExceptions)
|
||||||
|> mapToSignal { _ -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in
|
|> mapToSignal { _ -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
@ -1153,7 +1153,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
return importContact(account: context.account, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers[0].value)
|
return context.engine.contacts.importContact(firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers[0].value)
|
||||||
|> castError(AddContactError.self)
|
|> castError(AddContactError.self)
|
||||||
|> mapToSignal { peerId -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in
|
|> mapToSignal { peerId -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in
|
||||||
if let peerId = peerId {
|
if let peerId = peerId {
|
||||||
|
@ -163,7 +163,7 @@ public func groupPreHistorySetupController(context: AccountContext, peerId: Peer
|
|||||||
if peerId.namespace == Namespaces.Peer.CloudGroup {
|
if peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||||
let signal = context.engine.peers.convertGroupToSupergroup(peerId: peerId)
|
let signal = context.engine.peers.convertGroupToSupergroup(peerId: peerId)
|
||||||
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, ConvertGroupToSupergroupError> in
|
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, ConvertGroupToSupergroupError> in
|
||||||
return updateChannelHistoryAvailabilitySettingsInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: upgradedPeerId, historyAvailableForNewMembers: value)
|
return context.engine.peers.updateChannelHistoryAvailabilitySettingsInteractively(peerId: upgradedPeerId, historyAvailableForNewMembers: value)
|
||||||
|> `catch` { _ -> Signal<Void, NoError> in
|
|> `catch` { _ -> Signal<Void, NoError> in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ public func groupPreHistorySetupController(context: AccountContext, peerId: Peer
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
applyDisposable.set((updateChannelHistoryAvailabilitySettingsInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: peerId, historyAvailableForNewMembers: value)
|
applyDisposable.set((context.engine.peers.updateChannelHistoryAvailabilitySettingsInteractively(peerId: peerId, historyAvailableForNewMembers: value)
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
}))
|
}))
|
||||||
|
@ -448,7 +448,7 @@ public func groupStickerPackSetupController(context: AccountContext, peerId: Pee
|
|||||||
state.isSaving = true
|
state.isSaving = true
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
saveDisposable.set((updateGroupSpecificStickerset(postbox: context.account.postbox, network: context.account.network, peerId: peerId, info: info)
|
saveDisposable.set((context.engine.peers.updateGroupSpecificStickerset(peerId: peerId, info: info)
|
||||||
|> deliverOnMainQueue).start(error: { _ in
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
updateState { state in
|
updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
|
@ -18,7 +18,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
|||||||
|> mapToSignal { cachedData -> Signal<([Peer], Bool), NoError> in
|
|> mapToSignal { cachedData -> Signal<([Peer], Bool), NoError> in
|
||||||
if case .peer = chatLocation, let cachedData = cachedData, let memberCount = cachedData.participantsSummary.memberCount, memberCount <= 64 {
|
if case .peer = chatLocation, let cachedData = cachedData, let memberCount = cachedData.participantsSummary.memberCount, memberCount <= 64 {
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, requestUpdate: false, updated: { state in
|
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, requestUpdate: false, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
let normalizedQuery = query.lowercased()
|
let normalizedQuery = query.lowercased()
|
||||||
subscriber.putNext((state.list.compactMap { participant -> Peer? in
|
subscriber.putNext((state.list.compactMap { participant -> Peer? in
|
||||||
@ -54,7 +54,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
|||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
switch chatLocation {
|
switch chatLocation {
|
||||||
case let .peer(peerId):
|
case let .peer(peerId):
|
||||||
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query.isEmpty ? nil : query, updated: { state in
|
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query.isEmpty ? nil : query, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
subscriber.putNext((state.list.compactMap { participant in
|
subscriber.putNext((state.list.compactMap { participant in
|
||||||
if participant.peer.isDeleted {
|
if participant.peer.isDeleted {
|
||||||
@ -69,7 +69,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
|||||||
disposable.dispose()
|
disposable.dispose()
|
||||||
}
|
}
|
||||||
case let .replyThread(replyThreadMessage):
|
case let .replyThread(replyThreadMessage):
|
||||||
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.mentions(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, threadMessageId: replyThreadMessage.messageId, searchQuery: query.isEmpty ? nil : query, updated: { state in
|
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.mentions(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, threadMessageId: replyThreadMessage.messageId, searchQuery: query.isEmpty ? nil : query, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
subscriber.putNext((state.list.compactMap { participant in
|
subscriber.putNext((state.list.compactMap { participant in
|
||||||
if participant.peer.isDeleted {
|
if participant.peer.isDeleted {
|
||||||
@ -117,6 +117,6 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return searchGroupMembers(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, query: query)
|
return context.engine.peers.searchGroupMembers(peerId: peerId, query: query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,16 +780,16 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
|||||||
let presentationData = context.sharedContext.currentPresentationData.modify {$0}
|
let presentationData = context.sharedContext.currentPresentationData.modify {$0}
|
||||||
|
|
||||||
let updatePeerSound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
|
let updatePeerSound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
|
||||||
return updatePeerNotificationSoundInteractive(account: context.account, peerId: peerId, sound: sound) |> deliverOnMainQueue
|
return context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, sound: sound) |> deliverOnMainQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
let updatePeerNotificationInterval:(PeerId, Int32?) -> Signal<Void, NoError> = { peerId, muteInterval in
|
let updatePeerNotificationInterval: (PeerId, Int32?) -> Signal<Void, NoError> = { peerId, muteInterval in
|
||||||
return updatePeerMuteSetting(account: context.account, peerId: peerId, muteInterval: muteInterval) |> deliverOnMainQueue
|
return context.engine.peers.updatePeerMuteSetting(peerId: peerId, muteInterval: muteInterval) |> deliverOnMainQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
let updatePeerDisplayPreviews:(PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = {
|
let updatePeerDisplayPreviews:(PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = {
|
||||||
peerId, displayPreviews in
|
peerId, displayPreviews in
|
||||||
return updatePeerDisplayPreviewsSetting(account: context.account, peerId: peerId, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
self.backgroundColor = presentationData.theme.list.blocksBackgroundColor
|
self.backgroundColor = presentationData.theme.list.blocksBackgroundColor
|
||||||
@ -842,13 +842,11 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
|||||||
updateNotificationsView({})
|
updateNotificationsView({})
|
||||||
})
|
})
|
||||||
}, removePeerFromExceptions: {
|
}, removePeerFromExceptions: {
|
||||||
let _ = (context.account.postbox.transaction { transaction -> Peer? in
|
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|
||||||
updatePeerMuteSetting(transaction: transaction, peerId: peerId, muteInterval: nil)
|
|> map { _ -> Peer? in }
|
||||||
updatePeerDisplayPreviewsSetting(transaction: transaction, peerId: peerId, displayPreviews: .default)
|
|> then(context.account.postbox.transaction { transaction -> Peer? in
|
||||||
updatePeerNotificationSoundInteractive(transaction: transaction, peerId: peerId, sound: .default)
|
|
||||||
return transaction.getPeer(peerId)
|
return transaction.getPeer(peerId)
|
||||||
}
|
})).start(next: { peer in
|
||||||
|> deliverOnMainQueue).start(next: { peer in
|
|
||||||
guard let peer = peer else {
|
guard let peer = peer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -917,11 +915,7 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
|||||||
updateState { value in
|
updateState { value in
|
||||||
return value.withUpdatedPeerMuteInterval(peer, nil).withUpdatedPeerSound(peer, .default).withUpdatedPeerDisplayPreviews(peer, .default)
|
return value.withUpdatedPeerMuteInterval(peer, nil).withUpdatedPeerSound(peer, .default).withUpdatedPeerDisplayPreviews(peer, .default)
|
||||||
}
|
}
|
||||||
_ = (context.account.postbox.transaction { transaction in
|
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peer.id])
|
||||||
updatePeerNotificationSoundInteractive(transaction: transaction, peerId: peer.id, sound: .default)
|
|
||||||
updatePeerMuteSetting(transaction: transaction, peerId: peer.id, muteInterval: nil)
|
|
||||||
updatePeerDisplayPreviewsSetting(transaction: transaction, peerId: peer.id, displayPreviews: .default)
|
|
||||||
}
|
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
updateNotificationsView({})
|
updateNotificationsView({})
|
||||||
})
|
})
|
||||||
@ -953,13 +947,7 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
let _ = (context.account.postbox.transaction { transaction -> Void in
|
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: values.map(\.peer.id))
|
||||||
for value in values {
|
|
||||||
updatePeerNotificationSoundInteractive(transaction: transaction, peerId: value.peer.id, sound: .default)
|
|
||||||
updatePeerMuteSetting(transaction: transaction, peerId: value.peer.id, muteInterval: nil)
|
|
||||||
updatePeerDisplayPreviewsSetting(transaction: transaction, peerId: value.peer.id, displayPreviews: .default)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
updateNotificationsView({})
|
updateNotificationsView({})
|
||||||
})
|
})
|
||||||
|
@ -426,7 +426,7 @@ public func dataPrivacyController(context: AccountContext) -> ViewController {
|
|||||||
})
|
})
|
||||||
}).start()
|
}).start()
|
||||||
|
|
||||||
actionsDisposable.add((deleteAllContacts(account: context.account)
|
actionsDisposable.add((context.engine.contacts.deleteAllContacts()
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
updateState { state in
|
updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
|
@ -506,11 +506,11 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
|||||||
actionsDisposable.add(updateAutoArchiveDisposable)
|
actionsDisposable.add(updateAutoArchiveDisposable)
|
||||||
|
|
||||||
let privacySettingsPromise = Promise<AccountPrivacySettings?>()
|
let privacySettingsPromise = Promise<AccountPrivacySettings?>()
|
||||||
privacySettingsPromise.set(.single(initialSettings) |> then(requestAccountPrivacySettings(account: context.account) |> map(Optional.init)))
|
privacySettingsPromise.set(.single(initialSettings) |> then(context.engine.privacy.requestAccountPrivacySettings() |> map(Optional.init)))
|
||||||
|
|
||||||
let blockedPeersContext = blockedPeersContext ?? BlockedPeersContext(account: context.account)
|
let blockedPeersContext = blockedPeersContext ?? BlockedPeersContext(account: context.account)
|
||||||
let activeSessionsContext = activeSessionsContext ?? ActiveSessionsContext(account: context.account)
|
let activeSessionsContext = activeSessionsContext ?? context.engine.privacy.activeSessions()
|
||||||
let webSessionsContext = webSessionsContext ?? WebSessionsContext(account: context.account)
|
let webSessionsContext = webSessionsContext ?? context.engine.privacy.webSessions()
|
||||||
|
|
||||||
let blockedPeersState = Promise<BlockedPeersContextState>()
|
let blockedPeersState = Promise<BlockedPeersContextState>()
|
||||||
blockedPeersState.set(blockedPeersContext.state)
|
blockedPeersState.set(blockedPeersContext.state)
|
||||||
@ -779,7 +779,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
|||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAutoArchiveDisposable.set((updateAccountAutoArchiveChats(account: context.account, value: archiveValue)
|
updateAutoArchiveDisposable.set((context.engine.privacy.updateAccountAutoArchiveChats(value: archiveValue)
|
||||||
|> mapToSignal { _ -> Signal<Void, NoError> in }
|
|> mapToSignal { _ -> Signal<Void, NoError> in }
|
||||||
|> then(applyTimeout)
|
|> then(applyTimeout)
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
@ -817,7 +817,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
|||||||
}
|
}
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
updateAccountTimeoutDisposable.set((updateAccountRemovalTimeout(account: context.account, timeout: timeout)
|
updateAccountTimeoutDisposable.set((context.engine.privacy.updateAccountRemovalTimeout(timeout: timeout)
|
||||||
|> then(applyTimeout)
|
|> then(applyTimeout)
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
updateState { state in
|
updateState { state in
|
||||||
|
@ -1038,14 +1038,14 @@ func selectivePrivacySettingsController(context: AccountContext, kind: Selective
|
|||||||
type = .phoneNumber
|
type = .phoneNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
let updateSettingsSignal = updateSelectiveAccountPrivacySettings(account: context.account, type: type, settings: settings)
|
let updateSettingsSignal = context.engine.privacy.updateSelectiveAccountPrivacySettings(type: type, settings: settings)
|
||||||
var updateCallP2PSettingsSignal: Signal<Void, NoError> = Signal.complete()
|
var updateCallP2PSettingsSignal: Signal<Void, NoError> = Signal.complete()
|
||||||
if let callP2PSettings = callP2PSettings {
|
if let callP2PSettings = callP2PSettings {
|
||||||
updateCallP2PSettingsSignal = updateSelectiveAccountPrivacySettings(account: context.account, type: .voiceCallsP2P, settings: callP2PSettings)
|
updateCallP2PSettingsSignal = context.engine.privacy.updateSelectiveAccountPrivacySettings(type: .voiceCallsP2P, settings: callP2PSettings)
|
||||||
}
|
}
|
||||||
var updatePhoneDiscoverySignal: Signal<Void, NoError> = Signal.complete()
|
var updatePhoneDiscoverySignal: Signal<Void, NoError> = Signal.complete()
|
||||||
if let phoneDiscoveryEnabled = phoneDiscoveryEnabled {
|
if let phoneDiscoveryEnabled = phoneDiscoveryEnabled {
|
||||||
updatePhoneDiscoverySignal = updatePhoneNumberDiscovery(account: context.account, value: phoneDiscoveryEnabled)
|
updatePhoneDiscoverySignal = context.engine.privacy.updatePhoneNumberDiscovery(value: phoneDiscoveryEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = (combineLatest(updateSettingsSignal, updateCallP2PSettingsSignal, updatePhoneDiscoverySignal)
|
let _ = (combineLatest(updateSettingsSignal, updateCallP2PSettingsSignal, updatePhoneDiscoverySignal)
|
||||||
|
@ -430,7 +430,7 @@ private func privacySearchableItems(context: AccountContext, privacySettings: Ac
|
|||||||
if let privacySettings = privacySettings {
|
if let privacySettings = privacySettings {
|
||||||
privacySignal = .single(privacySettings)
|
privacySignal = .single(privacySettings)
|
||||||
} else {
|
} else {
|
||||||
privacySignal = requestAccountPrivacySettings(account: context.account)
|
privacySignal = context.engine.privacy.requestAccountPrivacySettings()
|
||||||
}
|
}
|
||||||
let callsSignal: Signal<(VoiceCallSettings, VoipConfiguration)?, NoError>
|
let callsSignal: Signal<(VoiceCallSettings, VoipConfiguration)?, NoError>
|
||||||
if case .voiceCalls = kind {
|
if case .voiceCalls = kind {
|
||||||
@ -535,10 +535,10 @@ private func privacySearchableItems(context: AccountContext, privacySettings: Ac
|
|||||||
present(.push, twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: true, data: nil)))
|
present(.push, twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: true, data: nil)))
|
||||||
}),
|
}),
|
||||||
activeSessionsContext == nil ? nil : SettingsSearchableItem(id: .privacy(9), title: strings.Settings_Devices, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions) + [strings.PrivacySettings_AuthSessions], icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
activeSessionsContext == nil ? nil : SettingsSearchableItem(id: .privacy(9), title: strings.Settings_Devices, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions) + [strings.PrivacySettings_AuthSessions], icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
||||||
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext!, webSessionsContext: webSessionsContext ?? WebSessionsContext(account: context.account), websitesOnly: false))
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext!, webSessionsContext: webSessionsContext ?? context.engine.privacy.webSessions(), websitesOnly: false))
|
||||||
}),
|
}),
|
||||||
webSessionsContext == nil ? nil : SettingsSearchableItem(id: .privacy(10), title: strings.PrivacySettings_WebSessions, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
webSessionsContext == nil ? nil : SettingsSearchableItem(id: .privacy(10), title: strings.PrivacySettings_WebSessions, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
||||||
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext ?? ActiveSessionsContext(account: context.account), webSessionsContext: webSessionsContext ?? WebSessionsContext(account: context.account), websitesOnly: true))
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext ?? context.engine.privacy.activeSessions(), webSessionsContext: webSessionsContext ?? context.engine.privacy.webSessions(), websitesOnly: true))
|
||||||
}),
|
}),
|
||||||
SettingsSearchableItem(id: .privacy(11), title: strings.PrivacySettings_DeleteAccountTitle, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
SettingsSearchableItem(id: .privacy(11), title: strings.PrivacySettings_DeleteAccountTitle, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
||||||
presentPrivacySettings(context, present, .accountTimeout)
|
presentPrivacySettings(context, present, .accountTimeout)
|
||||||
|
@ -1136,7 +1136,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
let rawAdminIds: Signal<Set<PeerId>, NoError>
|
let rawAdminIds: Signal<Set<PeerId>, NoError>
|
||||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
rawAdminIds = Signal { subscriber in
|
rawAdminIds = Signal { subscriber in
|
||||||
let (disposable, _) = accountContext.peerChannelMemberCategoriesContextsManager.admins(postbox: accountContext.account.postbox, network: accountContext.account.network, accountPeerId: accountContext.account.peerId, peerId: peerId, updated: { list in
|
let (disposable, _) = accountContext.peerChannelMemberCategoriesContextsManager.admins(engine: accountContext.engine, postbox: accountContext.account.postbox, network: accountContext.account.network, accountPeerId: accountContext.account.peerId, peerId: peerId, updated: { list in
|
||||||
var peerIds = Set<PeerId>()
|
var peerIds = Set<PeerId>()
|
||||||
for item in list.list {
|
for item in list.list {
|
||||||
if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
|
if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
|
||||||
@ -1425,7 +1425,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
let peerId = strongSelf.peerId
|
let peerId = strongSelf.peerId
|
||||||
if strongSelf.peerId.namespace == Namespaces.Peer.CloudChannel {
|
if strongSelf.peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
peerAdminIds = Signal { subscriber in
|
peerAdminIds = Signal { subscriber in
|
||||||
let (disposable, _) = strongSelf.accountContext.peerChannelMemberCategoriesContextsManager.admins(postbox: strongSelf.accountContext.account.postbox, network: strongSelf.accountContext.account.network, accountPeerId: strongSelf.accountContext.account.peerId, peerId: peerId, updated: { list in
|
let (disposable, _) = strongSelf.accountContext.peerChannelMemberCategoriesContextsManager.admins(engine: strongSelf.accountContext.engine, postbox: strongSelf.accountContext.account.postbox, network: strongSelf.accountContext.account.network, accountPeerId: strongSelf.accountContext.account.peerId, peerId: peerId, updated: { list in
|
||||||
var peerIds = Set<PeerId>()
|
var peerIds = Set<PeerId>()
|
||||||
for item in list.list {
|
for item in list.list {
|
||||||
if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
|
if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
|
||||||
@ -1670,7 +1670,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
let rawAdminIds: Signal<Set<PeerId>, NoError>
|
let rawAdminIds: Signal<Set<PeerId>, NoError>
|
||||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
rawAdminIds = Signal { subscriber in
|
rawAdminIds = Signal { subscriber in
|
||||||
let (disposable, _) = accountContext.peerChannelMemberCategoriesContextsManager.admins(postbox: accountContext.account.postbox, network: accountContext.account.network, accountPeerId: accountContext.account.peerId, peerId: peerId, updated: { list in
|
let (disposable, _) = accountContext.peerChannelMemberCategoriesContextsManager.admins(engine: accountContext.engine, postbox: accountContext.account.postbox, network: accountContext.account.network, accountPeerId: accountContext.account.peerId, peerId: peerId, updated: { list in
|
||||||
var peerIds = Set<PeerId>()
|
var peerIds = Set<PeerId>()
|
||||||
for item in list.list {
|
for item in list.list {
|
||||||
if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
|
if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
|
||||||
|
@ -1711,7 +1711,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = strongSelf.context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: strongSelf.context.account, peerId: strongSelf.call.peerId, memberId: peer.id, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max)).start()
|
let _ = strongSelf.context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: strongSelf.context.engine, peerId: strongSelf.call.peerId, memberId: peer.id, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max)).start()
|
||||||
strongSelf.call.removedPeer(peer.id)
|
strongSelf.call.removedPeer(peer.id)
|
||||||
|
|
||||||
strongSelf.presentUndoOverlay(content: .banned(text: strongSelf.presentationData.strings.VoiceChat_RemovedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), action: { _ in return false })
|
strongSelf.presentUndoOverlay(content: .banned(text: strongSelf.presentationData.strings.VoiceChat_RemovedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), action: { _ in return false })
|
||||||
|
@ -4,7 +4,7 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
public func currentWebDocumentsHostDatacenterId(postbox: Postbox, isTestingEnvironment: Bool) -> Signal<Int32, NoError> {
|
func currentWebDocumentsHostDatacenterId(postbox: Postbox, isTestingEnvironment: Bool) -> Signal<Int32, NoError> {
|
||||||
return postbox.transaction { transaction -> Int32 in
|
return postbox.transaction { transaction -> Int32 in
|
||||||
if let entry = transaction.getPreferencesEntry(key: PreferencesKeys.remoteStorageConfiguration) as? RemoteStorageConfiguration {
|
if let entry = transaction.getPreferencesEntry(key: PreferencesKeys.remoteStorageConfiguration) as? RemoteStorageConfiguration {
|
||||||
return entry.webDocumentsHostDatacenterId
|
return entry.webDocumentsHostDatacenterId
|
@ -1,82 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import Postbox
|
|
||||||
import SwiftSignalKit
|
|
||||||
import TelegramApi
|
|
||||||
import MtProtoKit
|
|
||||||
|
|
||||||
import SyncCore
|
|
||||||
|
|
||||||
public func channelAdmins(account: Account, peerId: PeerId) -> Signal<[RenderedChannelParticipant], NoError> {
|
|
||||||
return account.postbox.transaction { transaction -> Signal<[RenderedChannelParticipant], NoError> in
|
|
||||||
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
|
||||||
return account.network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: .channelParticipantsAdmins, offset: 0, limit: 100, hash: 0))
|
|
||||||
|> retryRequest
|
|
||||||
|> mapToSignal { result -> Signal<[RenderedChannelParticipant], NoError> in
|
|
||||||
switch result {
|
|
||||||
case let .channelParticipants(count, participants, chats, users):
|
|
||||||
var items: [RenderedChannelParticipant] = []
|
|
||||||
|
|
||||||
var peers: [PeerId: Peer] = [:]
|
|
||||||
var presences:[PeerId: PeerPresence] = [:]
|
|
||||||
for user in users {
|
|
||||||
let peer = TelegramUser(user: user)
|
|
||||||
peers[peer.id] = peer
|
|
||||||
if let presence = TelegramUserPresence(apiUser: user) {
|
|
||||||
presences[peer.id] = presence
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for participant in CachedChannelParticipants(apiParticipants: participants).participants {
|
|
||||||
if let peer = peers[participant.peerId] {
|
|
||||||
items.append(RenderedChannelParticipant(participant: participant, peer: peer, peers: peers, presences: presences))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return account.postbox.transaction { transaction -> [RenderedChannelParticipant] in
|
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
|
||||||
if let cachedData = cachedData as? CachedChannelData {
|
|
||||||
return cachedData.withUpdatedParticipantsSummary(cachedData.participantsSummary.withUpdatedAdminCount(count))
|
|
||||||
} else {
|
|
||||||
return cachedData
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return items
|
|
||||||
}
|
|
||||||
case .channelParticipantsNotModified:
|
|
||||||
return .single([])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .single([])
|
|
||||||
}
|
|
||||||
} |> switchToLatest
|
|
||||||
}
|
|
||||||
|
|
||||||
public func channelAdminIds(postbox: Postbox, network: Network, peerId: PeerId, hash: Int32) -> Signal<[PeerId], NoError> {
|
|
||||||
return postbox.transaction { transaction in
|
|
||||||
if let peer = transaction.getPeer(peerId) as? TelegramChannel, case .group = peer.info, let apiChannel = apiInputChannel(peer) {
|
|
||||||
let api = Api.functions.channels.getParticipants(channel: apiChannel, filter: .channelParticipantsAdmins, offset: 0, limit: 100, hash: hash)
|
|
||||||
return network.request(api) |> retryRequest |> mapToSignal { result in
|
|
||||||
switch result {
|
|
||||||
case let .channelParticipants(_, participants, _, users):
|
|
||||||
let users = users.filter({ user in
|
|
||||||
return participants.contains(where: { participant in
|
|
||||||
switch participant {
|
|
||||||
case let .channelParticipantAdmin(_, userId, _, _, _, _, _):
|
|
||||||
return user.peerId.id._internalGetInt32Value() == userId
|
|
||||||
case let .channelParticipantCreator(_, userId, _, _):
|
|
||||||
return user.peerId.id._internalGetInt32Value() == userId
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return .single(users.map({TelegramUser(user: $0).id}))
|
|
||||||
default:
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return .complete()
|
|
||||||
} |> switchToLatest
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import Postbox
|
|
||||||
import SwiftSignalKit
|
|
||||||
import TelegramApi
|
|
||||||
import MtProtoKit
|
|
||||||
|
|
||||||
import SyncCore
|
|
||||||
|
|
||||||
public struct RenderedChannelParticipant: Equatable {
|
|
||||||
public let participant: ChannelParticipant
|
|
||||||
public let peer: Peer
|
|
||||||
public let peers: [PeerId: Peer]
|
|
||||||
public let presences: [PeerId: PeerPresence]
|
|
||||||
|
|
||||||
public init(participant: ChannelParticipant, peer: Peer, peers: [PeerId: Peer] = [:], presences: [PeerId: PeerPresence] = [:]) {
|
|
||||||
self.participant = participant
|
|
||||||
self.peer = peer
|
|
||||||
self.peers = peers
|
|
||||||
self.presences = presences
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: RenderedChannelParticipant, rhs: RenderedChannelParticipant) -> Bool {
|
|
||||||
return lhs.participant == rhs.participant && lhs.peer.isEqual(rhs.peer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateChannelParticipantsSummary(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
|
||||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
|
||||||
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
|
||||||
let admins = account.network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: .channelParticipantsAdmins, offset: 0, limit: 0, hash: 0))
|
|
||||||
let members = account.network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: .channelParticipantsRecent, offset: 0, limit: 0, hash: 0))
|
|
||||||
let banned = account.network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: .channelParticipantsBanned(q: ""), offset: 0, limit: 0, hash: 0))
|
|
||||||
let kicked = account.network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: .channelParticipantsKicked(q: ""), offset: 0, limit: 0, hash: 0))
|
|
||||||
return combineLatest(admins, members, banned, kicked)
|
|
||||||
|> mapToSignal { admins, members, banned, kicked -> Signal<Void, MTRpcError> in
|
|
||||||
return account.postbox.transaction { transaction -> Void in
|
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
|
||||||
if let current = current as? CachedChannelData {
|
|
||||||
let adminCount: Int32
|
|
||||||
switch admins {
|
|
||||||
case let .channelParticipants(count, _, _, _):
|
|
||||||
adminCount = count
|
|
||||||
case .channelParticipantsNotModified:
|
|
||||||
assertionFailure()
|
|
||||||
adminCount = 0
|
|
||||||
}
|
|
||||||
let memberCount: Int32
|
|
||||||
switch members {
|
|
||||||
case let .channelParticipants(count, _, _, _):
|
|
||||||
memberCount = count
|
|
||||||
case .channelParticipantsNotModified:
|
|
||||||
assertionFailure()
|
|
||||||
memberCount = 0
|
|
||||||
}
|
|
||||||
let bannedCount: Int32
|
|
||||||
switch banned {
|
|
||||||
case let .channelParticipants(count, _, _, _):
|
|
||||||
bannedCount = count
|
|
||||||
case .channelParticipantsNotModified:
|
|
||||||
assertionFailure()
|
|
||||||
bannedCount = 0
|
|
||||||
}
|
|
||||||
let kickedCount: Int32
|
|
||||||
switch kicked {
|
|
||||||
case let .channelParticipants(count, _, _, _):
|
|
||||||
kickedCount = count
|
|
||||||
case .channelParticipantsNotModified:
|
|
||||||
assertionFailure()
|
|
||||||
kickedCount = 0
|
|
||||||
}
|
|
||||||
return current.withUpdatedParticipantsSummary(CachedChannelParticipantsSummary(memberCount: memberCount, adminCount: adminCount, bannedCount: bannedCount, kickedCount: kickedCount))
|
|
||||||
}
|
|
||||||
return current
|
|
||||||
})
|
|
||||||
} |> mapError { _ -> MTRpcError in return MTRpcError(errorCode: 0, errorDescription: "") }
|
|
||||||
}
|
|
||||||
|> `catch` { _ -> Signal<Void, NoError> in
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
} |> switchToLatest
|
|
||||||
}
|
|
@ -461,7 +461,7 @@ final class MediaReferenceRevalidationContext {
|
|||||||
|
|
||||||
func peerAvatars(postbox: Postbox, network: Network, background: Bool, peer: PeerReference) -> Signal<[TelegramPeerPhoto], RevalidateMediaReferenceError> {
|
func peerAvatars(postbox: Postbox, network: Network, background: Bool, peer: PeerReference) -> Signal<[TelegramPeerPhoto], RevalidateMediaReferenceError> {
|
||||||
return self.genericItem(key: .peerAvatars(peer: peer), background: background, request: { next, error in
|
return self.genericItem(key: .peerAvatars(peer: peer), background: background, request: { next, error in
|
||||||
return (requestPeerPhotos(postbox: postbox, network: network, peerId: peer.id)
|
return (_internal_requestPeerPhotos(postbox: postbox, network: network, peerId: peer.id)
|
||||||
|> mapError { _ -> RevalidateMediaReferenceError in
|
|> mapError { _ -> RevalidateMediaReferenceError in
|
||||||
return .generic
|
return .generic
|
||||||
}).start(next: { value in
|
}).start(next: { value in
|
||||||
|
@ -1,210 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import Postbox
|
|
||||||
import SwiftSignalKit
|
|
||||||
import TelegramApi
|
|
||||||
import MtProtoKit
|
|
||||||
|
|
||||||
import SyncCore
|
|
||||||
|
|
||||||
public enum MessageReactionListCategory: Hashable {
|
|
||||||
case all
|
|
||||||
case reaction(String)
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class MessageReactionListCategoryItem: Equatable {
|
|
||||||
public let peer: Peer
|
|
||||||
public let reaction: String
|
|
||||||
|
|
||||||
init(peer: Peer, reaction: String) {
|
|
||||||
self.peer = peer
|
|
||||||
self.reaction = reaction
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: MessageReactionListCategoryItem, rhs: MessageReactionListCategoryItem) -> Bool {
|
|
||||||
if lhs.peer.id != rhs.peer.id {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if lhs.reaction != rhs.reaction {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct MessageReactionListCategoryState: Equatable {
|
|
||||||
public var count: Int
|
|
||||||
public var completed: Bool
|
|
||||||
public var items: [MessageReactionListCategoryItem]
|
|
||||||
public var loadingMore: Bool
|
|
||||||
fileprivate var nextOffset: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum LoadReactionsError {
|
|
||||||
case generic
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class MessageReactionCategoryContext {
|
|
||||||
private let postbox: Postbox
|
|
||||||
private let network: Network
|
|
||||||
private let messageId: MessageId
|
|
||||||
private let category: MessageReactionListCategory
|
|
||||||
private var state: MessageReactionListCategoryState
|
|
||||||
var statePromise: ValuePromise<MessageReactionListCategoryState>
|
|
||||||
|
|
||||||
private let loadingDisposable = MetaDisposable()
|
|
||||||
|
|
||||||
init(postbox: Postbox, network: Network, messageId: MessageId, category: MessageReactionListCategory, initialState: MessageReactionListCategoryState) {
|
|
||||||
self.postbox = postbox
|
|
||||||
self.network = network
|
|
||||||
self.messageId = messageId
|
|
||||||
self.category = category
|
|
||||||
self.state = initialState
|
|
||||||
self.statePromise = ValuePromise(initialState)
|
|
||||||
}
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
self.loadingDisposable.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadMore() {
|
|
||||||
if self.state.completed || self.state.loadingMore {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
/*self.state.loadingMore = true
|
|
||||||
self.statePromise.set(self.state)
|
|
||||||
|
|
||||||
var flags: Int32 = 0
|
|
||||||
var reaction: String?
|
|
||||||
switch self.category {
|
|
||||||
case .all:
|
|
||||||
break
|
|
||||||
case let .reaction(value):
|
|
||||||
flags |= 1 << 0
|
|
||||||
reaction = value
|
|
||||||
}
|
|
||||||
let messageId = self.messageId
|
|
||||||
let offset = self.state.nextOffset
|
|
||||||
var request = self.postbox.transaction { transaction -> Api.InputPeer? in
|
|
||||||
let inputPeer = transaction.getPeer(messageId.peerId).flatMap(apiInputPeer)
|
|
||||||
return inputPeer
|
|
||||||
}
|
|
||||||
|> castError(LoadReactionsError.self)
|
|
||||||
|> mapToSignal { inputPeer -> Signal<Api.messages.MessageReactionsList, LoadReactionsError> in
|
|
||||||
guard let inputPeer = inputPeer else {
|
|
||||||
return .fail(.generic)
|
|
||||||
}
|
|
||||||
return self.network.request(Api.functions.messages.getMessageReactionsList(flags: flags, peer: inputPeer, id: messageId.id, reaction: reaction, offset: offset, limit: 64))
|
|
||||||
|> mapError { _ -> LoadReactionsError in
|
|
||||||
return .generic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//#if DEBUG
|
|
||||||
//request = request |> delay(1.0, queue: .mainQueue())
|
|
||||||
//#endif
|
|
||||||
self.loadingDisposable.set((request
|
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
|
||||||
guard let strongSelf = self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let currentState = strongSelf.state
|
|
||||||
let _ = (strongSelf.postbox.transaction { transaction -> MessageReactionListCategoryState in
|
|
||||||
var mergedItems = currentState.items
|
|
||||||
var currentIds = Set(mergedItems.lazy.map { $0.peer.id })
|
|
||||||
switch result {
|
|
||||||
case let .messageReactionsList(_, count, reactions, users, nextOffset):
|
|
||||||
var peers: [Peer] = []
|
|
||||||
for user in users {
|
|
||||||
let parsedUser = TelegramUser(user: user)
|
|
||||||
peers.append(parsedUser)
|
|
||||||
}
|
|
||||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated in updated })
|
|
||||||
for reaction in reactions {
|
|
||||||
switch reaction {
|
|
||||||
case let .messageUserReaction(userId, reaction):
|
|
||||||
if let peer = transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)) {
|
|
||||||
if !currentIds.contains(peer.id) {
|
|
||||||
currentIds.insert(peer.id)
|
|
||||||
mergedItems.append(MessageReactionListCategoryItem(peer: peer, reaction: reaction))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return MessageReactionListCategoryState(count: max(mergedItems.count, Int(count)), completed: nextOffset == nil, items: mergedItems, loadingMore: false, nextOffset: nextOffset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|> deliverOnMainQueue).start(next: { state in
|
|
||||||
guard let strongSelf = self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongSelf.state = state
|
|
||||||
strongSelf.statePromise.set(state)
|
|
||||||
})
|
|
||||||
}, error: { _ in
|
|
||||||
|
|
||||||
}))*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct MessageReactionListState: Equatable {
|
|
||||||
public var states: [(MessageReactionListCategory, MessageReactionListCategoryState)]
|
|
||||||
|
|
||||||
public static func ==(lhs: MessageReactionListState, rhs: MessageReactionListState) -> Bool {
|
|
||||||
if lhs.states.count != rhs.states.count {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i in 0 ..< lhs.states.count {
|
|
||||||
if lhs.states[i].0 != rhs.states[i].0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if lhs.states[i].1 != rhs.states[i].1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class MessageReactionListContext {
|
|
||||||
private let postbox: Postbox
|
|
||||||
private let network: Network
|
|
||||||
|
|
||||||
private var categoryContexts: [MessageReactionListCategory: MessageReactionCategoryContext] = [:]
|
|
||||||
|
|
||||||
private let _state = Promise<MessageReactionListState>()
|
|
||||||
public var state: Signal<MessageReactionListState, NoError> {
|
|
||||||
return self._state.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(postbox: Postbox, network: Network, messageId: MessageId, initialReactions: [MessageReaction]) {
|
|
||||||
self.postbox = postbox
|
|
||||||
self.network = network
|
|
||||||
|
|
||||||
var allState = MessageReactionListCategoryState(count: 0, completed: false, items: [], loadingMore: false, nextOffset: nil)
|
|
||||||
var signals: [Signal<(MessageReactionListCategory, MessageReactionListCategoryState), NoError>] = []
|
|
||||||
for reaction in initialReactions {
|
|
||||||
allState.count += Int(reaction.count)
|
|
||||||
let context = MessageReactionCategoryContext(postbox: postbox, network: network, messageId: messageId, category: .reaction(reaction.value), initialState: MessageReactionListCategoryState(count: Int(reaction.count), completed: false, items: [], loadingMore: false, nextOffset: nil))
|
|
||||||
signals.append(context.statePromise.get() |> map { value -> (MessageReactionListCategory, MessageReactionListCategoryState) in
|
|
||||||
return (.reaction(reaction.value), value)
|
|
||||||
})
|
|
||||||
self.categoryContexts[.reaction(reaction.value)] = context
|
|
||||||
context.loadMore()
|
|
||||||
}
|
|
||||||
let allContext = MessageReactionCategoryContext(postbox: postbox, network: network, messageId: messageId, category: .all, initialState: allState)
|
|
||||||
signals.insert(allContext.statePromise.get() |> map { value -> (MessageReactionListCategory, MessageReactionListCategoryState) in
|
|
||||||
return (.all, value)
|
|
||||||
}, at: 0)
|
|
||||||
self.categoryContexts[.all] = allContext
|
|
||||||
|
|
||||||
self._state.set(combineLatest(queue: .mainQueue(), signals)
|
|
||||||
|> map { states in
|
|
||||||
return MessageReactionListState(states: states)
|
|
||||||
})
|
|
||||||
|
|
||||||
allContext.loadMore()
|
|
||||||
}
|
|
||||||
|
|
||||||
public func loadMore(category: MessageReactionListCategory) {
|
|
||||||
self.categoryContexts[category]?.loadMore()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import Postbox
|
|
||||||
import SwiftSignalKit
|
|
||||||
|
|
||||||
import SyncCore
|
|
||||||
|
|
||||||
private struct PeerParticipants: Equatable {
|
|
||||||
let peers: [Peer]
|
|
||||||
|
|
||||||
static func ==(lhs: PeerParticipants, rhs: PeerParticipants) -> Bool {
|
|
||||||
if lhs.peers.count != rhs.peers.count {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i in 0 ..< lhs.peers.count {
|
|
||||||
if !lhs.peers[i].isEqual(rhs.peers[i]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func peerParticipants(postbox: Postbox, id: PeerId) -> Signal<[Peer], NoError> {
|
|
||||||
return postbox.peerView(id: id) |> map { view -> PeerParticipants in
|
|
||||||
if let cachedGroupData = view.cachedData as? CachedGroupData, let participants = cachedGroupData.participants {
|
|
||||||
var peers: [Peer] = []
|
|
||||||
for participant in participants.participants {
|
|
||||||
if let peer = view.peers[participant.peerId] {
|
|
||||||
peers.append(peer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PeerParticipants(peers: peers)
|
|
||||||
} else {
|
|
||||||
return PeerParticipants(peers: [])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|> distinctUntilChanged |> map { participants in
|
|
||||||
return participants.peers
|
|
||||||
}
|
|
||||||
}
|
|
@ -65,5 +65,5 @@ public func unarchiveAutomaticallyArchivedPeer(account: Account, peerId: PeerId)
|
|||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start()
|
|> deliverOnMainQueue).start()
|
||||||
|
|
||||||
let _ = updatePeerMuteSetting(account: account, peerId: peerId, muteInterval: nil).start()
|
let _ = _internal_updatePeerMuteSetting(account: account, peerId: peerId, muteInterval: nil).start()
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ func syncContactsOnce(network: Network, postbox: Postbox, accountPeerId: PeerId)
|
|||||||
return appliedUpdatedPeers
|
return appliedUpdatedPeers
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deleteContactPeerInteractively(account: Account, peerId: PeerId) -> Signal<Never, NoError> {
|
func _internal_deleteContactPeerInteractively(account: Account, peerId: PeerId) -> Signal<Never, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Never, NoError> in
|
return account.postbox.transaction { transaction -> Signal<Never, NoError> in
|
||||||
if let peer = transaction.getPeer(peerId), let inputUser = apiInputUser(peer) {
|
if let peer = transaction.getPeer(peerId), let inputUser = apiInputUser(peer) {
|
||||||
return account.network.request(Api.functions.contacts.deleteContacts(id: [inputUser]))
|
return account.network.request(Api.functions.contacts.deleteContacts(id: [inputUser]))
|
||||||
@ -133,7 +133,7 @@ public func deleteContactPeerInteractively(account: Account, peerId: PeerId) ->
|
|||||||
|> switchToLatest
|
|> switchToLatest
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deleteAllContacts(account: Account) -> Signal<Never, NoError> {
|
func _internal_deleteAllContacts(account: Account) -> Signal<Never, NoError> {
|
||||||
return account.postbox.transaction { transaction -> [Api.InputUser] in
|
return account.postbox.transaction { transaction -> [Api.InputUser] in
|
||||||
return transaction.getContactPeerIds().compactMap(transaction.getPeer).compactMap({ apiInputUser($0) }).compactMap({ $0 })
|
return transaction.getContactPeerIds().compactMap(transaction.getPeer).compactMap({ apiInputUser($0) }).compactMap({ $0 })
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ public func deleteAllContacts(account: Account) -> Signal<Never, NoError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func resetSavedContacts(network: Network) -> Signal<Void, NoError> {
|
func _internal_resetSavedContacts(network: Network) -> Signal<Void, NoError> {
|
||||||
return network.request(Api.functions.contacts.resetSaved())
|
return network.request(Api.functions.contacts.resetSaved())
|
||||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||||
return .single(.boolFalse)
|
return .single(.boolFalse)
|
@ -4,8 +4,7 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
public func importContact(account: Account, firstName: String, lastName: String, phoneNumber: String) -> Signal<PeerId?, NoError> {
|
func _internal_importContact(account: Account, firstName: String, lastName: String, phoneNumber: String) -> Signal<PeerId?, NoError> {
|
||||||
|
|
||||||
let input = Api.InputContact.inputPhoneContact(clientId: 1, phone: phoneNumber, firstName: firstName, lastName: lastName)
|
let input = Api.InputContact.inputPhoneContact(clientId: 1, phone: phoneNumber, firstName: firstName, lastName: lastName)
|
||||||
|
|
||||||
return account.network.request(Api.functions.contacts.importContacts(contacts: [input]))
|
return account.network.request(Api.functions.contacts.importContacts(contacts: [input]))
|
||||||
@ -42,7 +41,7 @@ public enum AddContactError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func addContactInteractively(account: Account, peerId: PeerId, firstName: String, lastName: String, phoneNumber: String, addToPrivacyExceptions: Bool) -> Signal<Never, AddContactError> {
|
func _internal_addContactInteractively(account: Account, peerId: PeerId, firstName: String, lastName: String, phoneNumber: String, addToPrivacyExceptions: Bool) -> Signal<Never, AddContactError> {
|
||||||
return account.postbox.transaction { transaction -> (Api.InputUser, String)? in
|
return account.postbox.transaction { transaction -> (Api.InputUser, String)? in
|
||||||
if let user = transaction.getPeer(peerId) as? TelegramUser, let inputUser = apiInputUser(user) {
|
if let user = transaction.getPeer(peerId) as? TelegramUser, let inputUser = apiInputUser(user) {
|
||||||
return (inputUser, user.phone == nil ? phoneNumber : "")
|
return (inputUser, user.phone == nil ? phoneNumber : "")
|
||||||
@ -99,7 +98,7 @@ public enum AcceptAndShareContactError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func acceptAndShareContact(account: Account, peerId: PeerId) -> Signal<Never, AcceptAndShareContactError> {
|
func _internal_acceptAndShareContact(account: Account, peerId: PeerId) -> Signal<Never, AcceptAndShareContactError> {
|
||||||
return account.postbox.transaction { transaction -> Api.InputUser? in
|
return account.postbox.transaction { transaction -> Api.InputUser? in
|
||||||
return transaction.getPeer(peerId).flatMap(apiInputUser)
|
return transaction.getPeer(peerId).flatMap(apiInputUser)
|
||||||
}
|
}
|
@ -48,7 +48,7 @@ enum TelegramDeviceContactImportIdentifier: Hashable, Comparable, Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deviceContactsImportedByCount(postbox: Postbox, contacts: [(String, [DeviceContactNormalizedPhoneNumber])]) -> Signal<[String: Int32], NoError> {
|
func _internal_deviceContactsImportedByCount(postbox: Postbox, contacts: [(String, [DeviceContactNormalizedPhoneNumber])]) -> Signal<[String: Int32], NoError> {
|
||||||
return postbox.transaction { transaction -> [String: Int32] in
|
return postbox.transaction { transaction -> [String: Int32] in
|
||||||
var result: [String: Int32] = [:]
|
var result: [String: Int32] = [:]
|
||||||
for (id, numbers) in contacts {
|
for (id, numbers) in contacts {
|
@ -0,0 +1,44 @@
|
|||||||
|
import SwiftSignalKit
|
||||||
|
import Postbox
|
||||||
|
|
||||||
|
public extension TelegramEngine {
|
||||||
|
final class Contacts {
|
||||||
|
private let account: Account
|
||||||
|
|
||||||
|
init(account: Account) {
|
||||||
|
self.account = account
|
||||||
|
}
|
||||||
|
|
||||||
|
public func deleteContactPeerInteractively(peerId: PeerId) -> Signal<Never, NoError> {
|
||||||
|
return _internal_deleteContactPeerInteractively(account: self.account, peerId: peerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func deleteAllContacts() -> Signal<Never, NoError> {
|
||||||
|
return _internal_deleteAllContacts(account: self.account)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func resetSavedContacts() -> Signal<Void, NoError> {
|
||||||
|
return _internal_resetSavedContacts(network: self.account.network)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateContactName(peerId: PeerId, firstName: String, lastName: String) -> Signal<Void, UpdateContactNameError> {
|
||||||
|
return _internal_updateContactName(account: self.account, peerId: peerId, firstName: firstName, lastName: lastName)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func deviceContactsImportedByCount(contacts: [(String, [DeviceContactNormalizedPhoneNumber])]) -> Signal<[String: Int32], NoError> {
|
||||||
|
return _internal_deviceContactsImportedByCount(postbox: self.account.postbox, contacts: contacts)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func importContact(firstName: String, lastName: String, phoneNumber: String) -> Signal<PeerId?, NoError> {
|
||||||
|
return _internal_importContact(account: self.account, firstName: firstName, lastName: lastName, phoneNumber: phoneNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addContactInteractively(peerId: PeerId, firstName: String, lastName: String, phoneNumber: String, addToPrivacyExceptions: Bool) -> Signal<Never, AddContactError> {
|
||||||
|
return _internal_addContactInteractively(account: self.account, peerId: peerId, firstName: firstName, lastName: lastName, phoneNumber: phoneNumber, addToPrivacyExceptions: addToPrivacyExceptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func acceptAndShareContact(peerId: PeerId) -> Signal<Never, AcceptAndShareContactError> {
|
||||||
|
return _internal_acceptAndShareContact(account: self.account, peerId: peerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ public enum UpdateContactNameError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateContactName(account: Account, peerId: PeerId, firstName: String, lastName: String) -> Signal<Void, UpdateContactNameError> {
|
func _internal_updateContactName(account: Account, peerId: PeerId, firstName: String, lastName: String) -> Signal<Void, UpdateContactNameError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Void, UpdateContactNameError> in
|
return account.postbox.transaction { transaction -> Signal<Void, UpdateContactNameError> in
|
||||||
if let peer = transaction.getPeer(peerId) as? TelegramUser, let inputUser = apiInputUser(peer) {
|
if let peer = transaction.getPeer(peerId) as? TelegramUser, let inputUser = apiInputUser(peer) {
|
||||||
return account.network.request(Api.functions.contacts.addContact(flags: 0, id: inputUser, firstName: firstName, lastName: lastName, phone: ""))
|
return account.network.request(Api.functions.contacts.addContact(flags: 0, id: inputUser, firstName: firstName, lastName: lastName, phone: ""))
|
@ -11,7 +11,7 @@ public enum GetMessagesStrategy {
|
|||||||
case cloud
|
case cloud
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Postbox, network: Network, accountPeerId: PeerId, strategy: GetMessagesStrategy = .cloud) -> Signal <[Message], NoError> {
|
func _internal_getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Postbox, network: Network, accountPeerId: PeerId, strategy: GetMessagesStrategy = .cloud) -> Signal <[Message], NoError> {
|
||||||
let postboxSignal = postbox.transaction { transaction -> ([Message], Set<MessageId>, SimpleDictionary<PeerId, Peer>) in
|
let postboxSignal = postbox.transaction { transaction -> ([Message], Set<MessageId>, SimpleDictionary<PeerId, Peer>) in
|
||||||
var ids = messageIds
|
var ids = messageIds
|
||||||
|
|
@ -6,7 +6,7 @@ import MtProtoKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
public func markAllChatsAsRead(postbox: Postbox, network: Network, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
func _internal_markAllChatsAsRead(postbox: Postbox, network: Network, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
||||||
return network.request(Api.functions.messages.getDialogUnreadMarks())
|
return network.request(Api.functions.messages.getDialogUnreadMarks())
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<[Api.DialogPeer]?, NoError> in
|
|> `catch` { _ -> Signal<[Api.DialogPeer]?, NoError> in
|
@ -453,7 +453,7 @@ public enum FetchChannelReplyThreadMessageError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchChannelReplyThreadMessage(account: Account, messageId: MessageId, atMessageId: MessageId?) -> Signal<ChatReplyThreadMessage, FetchChannelReplyThreadMessageError> {
|
func _internal_fetchChannelReplyThreadMessage(account: Account, messageId: MessageId, atMessageId: MessageId?) -> Signal<ChatReplyThreadMessage, FetchChannelReplyThreadMessageError> {
|
||||||
return account.postbox.transaction { transaction -> Api.InputPeer? in
|
return account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||||
return transaction.getPeer(messageId.peerId).flatMap(apiInputPeer)
|
return transaction.getPeer(messageId.peerId).flatMap(apiInputPeer)
|
||||||
}
|
}
|
@ -6,7 +6,7 @@ import MtProtoKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
public func requestStartBot(account: Account, botPeerId: PeerId, payload: String?) -> Signal<Void, NoError> {
|
func _internal_requestStartBot(account: Account, botPeerId: PeerId, payload: String?) -> Signal<Void, NoError> {
|
||||||
if let payload = payload, !payload.isEmpty {
|
if let payload = payload, !payload.isEmpty {
|
||||||
return account.postbox.loadedPeerWithId(botPeerId)
|
return account.postbox.loadedPeerWithId(botPeerId)
|
||||||
|> mapToSignal { botPeer -> Signal<Void, NoError> in
|
|> mapToSignal { botPeer -> Signal<Void, NoError> in
|
||||||
@ -41,7 +41,7 @@ public enum StartBotInGroupResult {
|
|||||||
case channelParticipant(RenderedChannelParticipant)
|
case channelParticipant(RenderedChannelParticipant)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func requestStartBotInGroup(account: Account, botPeerId: PeerId, groupPeerId: PeerId, payload: String?) -> Signal<StartBotInGroupResult, RequestStartBotInGroupError> {
|
func _internal_requestStartBotInGroup(account: Account, botPeerId: PeerId, groupPeerId: PeerId, payload: String?) -> Signal<StartBotInGroupResult, RequestStartBotInGroupError> {
|
||||||
return account.postbox.transaction { transaction -> (Peer?, Peer?) in
|
return account.postbox.transaction { transaction -> (Peer?, Peer?) in
|
||||||
return (transaction.getPeer(botPeerId), transaction.getPeer(groupPeerId))
|
return (transaction.getPeer(botPeerId), transaction.getPeer(groupPeerId))
|
||||||
}
|
}
|
@ -94,5 +94,33 @@ public extension TelegramEngine {
|
|||||||
public func forwardGameWithScore(messageId: MessageId, to peerId: PeerId) -> Signal<Void, NoError> {
|
public func forwardGameWithScore(messageId: MessageId, to peerId: PeerId) -> Signal<Void, NoError> {
|
||||||
return _internal_forwardGameWithScore(account: self.account, messageId: messageId, to: peerId)
|
return _internal_forwardGameWithScore(account: self.account, messageId: messageId, to: peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func requestUpdatePinnedMessage(peerId: PeerId, update: PinnedMessageUpdate) -> Signal<Void, UpdatePinnedMessageError> {
|
||||||
|
return _internal_requestUpdatePinnedMessage(account: self.account, peerId: peerId, update: update)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func requestUnpinAllMessages(peerId: PeerId) -> Signal<Never, UpdatePinnedMessageError> {
|
||||||
|
return _internal_requestUnpinAllMessages(account: self.account, peerId: peerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func fetchChannelReplyThreadMessage(messageId: MessageId, atMessageId: MessageId?) -> Signal<ChatReplyThreadMessage, FetchChannelReplyThreadMessageError> {
|
||||||
|
return _internal_fetchChannelReplyThreadMessage(account: self.account, messageId: messageId, atMessageId: atMessageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func requestStartBot(botPeerId: PeerId, payload: String?) -> Signal<Void, NoError> {
|
||||||
|
return _internal_requestStartBot(account: self.account, botPeerId: botPeerId, payload: payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func requestStartBotInGroup(botPeerId: PeerId, groupPeerId: PeerId, payload: String?) -> Signal<StartBotInGroupResult, RequestStartBotInGroupError> {
|
||||||
|
return _internal_requestStartBotInGroup(account: self.account, botPeerId: botPeerId, groupPeerId: groupPeerId, payload: payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func markAllChatsAsRead() -> Signal<Void, NoError> {
|
||||||
|
return _internal_markAllChatsAsRead(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getMessagesLoadIfNecessary(_ messageIds: [MessageId], strategy: GetMessagesStrategy = .cloud) -> Signal <[Message], NoError> {
|
||||||
|
return _internal_getMessagesLoadIfNecessary(messageIds, postbox: self.account.postbox, network: self.account.network, accountPeerId: self.account.peerId, strategy: strategy)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public enum PinnedMessageUpdate {
|
|||||||
case clear(id: MessageId)
|
case clear(id: MessageId)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func requestUpdatePinnedMessage(account: Account, peerId: PeerId, update: PinnedMessageUpdate) -> Signal<Void, UpdatePinnedMessageError> {
|
func _internal_requestUpdatePinnedMessage(account: Account, peerId: PeerId, update: PinnedMessageUpdate) -> Signal<Void, UpdatePinnedMessageError> {
|
||||||
return account.postbox.transaction { transaction -> (Peer?, CachedPeerData?) in
|
return account.postbox.transaction { transaction -> (Peer?, CachedPeerData?) in
|
||||||
return (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId))
|
return (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId))
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ public func requestUpdatePinnedMessage(account: Account, peerId: PeerId, update:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func requestUnpinAllMessages(account: Account, peerId: PeerId) -> Signal<Never, UpdatePinnedMessageError> {
|
func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId) -> Signal<Never, UpdatePinnedMessageError> {
|
||||||
return account.postbox.transaction { transaction -> (Peer?, CachedPeerData?) in
|
return account.postbox.transaction { transaction -> (Peer?, CachedPeerData?) in
|
||||||
return (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId))
|
return (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId))
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
public func togglePeerMuted(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
func _internal_togglePeerMuted(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return account.postbox.transaction { transaction -> Void in
|
||||||
if let peer = transaction.getPeer(peerId) {
|
if let peer = transaction.getPeer(peerId) {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
@ -39,13 +39,13 @@ public func togglePeerMuted(account: Account, peerId: PeerId) -> Signal<Void, No
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatePeerMuteSetting(account: Account, peerId: PeerId, muteInterval: Int32?) -> Signal<Void, NoError> {
|
func _internal_updatePeerMuteSetting(account: Account, peerId: PeerId, muteInterval: Int32?) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return account.postbox.transaction { transaction -> Void in
|
||||||
updatePeerMuteSetting(transaction: transaction, peerId: peerId, muteInterval: muteInterval)
|
updatePeerMuteSetting(transaction: transaction, peerId: peerId, muteInterval: muteInterval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatePeerMuteSetting(transaction: Transaction, peerId: PeerId, muteInterval: Int32?) {
|
func updatePeerMuteSetting(transaction: Transaction, peerId: PeerId, muteInterval: Int32?) {
|
||||||
if let peer = transaction.getPeer(peerId) {
|
if let peer = transaction.getPeer(peerId) {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if let associatedPeerId = peer.associatedPeerId {
|
||||||
@ -82,13 +82,13 @@ public func updatePeerMuteSetting(transaction: Transaction, peerId: PeerId, mute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatePeerDisplayPreviewsSetting(account: Account, peerId: PeerId, displayPreviews: PeerNotificationDisplayPreviews) -> Signal<Void, NoError> {
|
func _internal_updatePeerDisplayPreviewsSetting(account: Account, peerId: PeerId, displayPreviews: PeerNotificationDisplayPreviews) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return account.postbox.transaction { transaction -> Void in
|
||||||
updatePeerDisplayPreviewsSetting(transaction: transaction, peerId: peerId, displayPreviews: displayPreviews)
|
updatePeerDisplayPreviewsSetting(transaction: transaction, peerId: peerId, displayPreviews: displayPreviews)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatePeerDisplayPreviewsSetting(transaction: Transaction, peerId: PeerId, displayPreviews: PeerNotificationDisplayPreviews) {
|
func updatePeerDisplayPreviewsSetting(transaction: Transaction, peerId: PeerId, displayPreviews: PeerNotificationDisplayPreviews) {
|
||||||
if let peer = transaction.getPeer(peerId) {
|
if let peer = transaction.getPeer(peerId) {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if let associatedPeerId = peer.associatedPeerId {
|
||||||
@ -108,13 +108,13 @@ public func updatePeerDisplayPreviewsSetting(transaction: Transaction, peerId: P
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatePeerNotificationSoundInteractive(account: Account, peerId: PeerId, sound: PeerMessageSound) -> Signal<Void, NoError> {
|
func _internal_updatePeerNotificationSoundInteractive(account: Account, peerId: PeerId, sound: PeerMessageSound) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return account.postbox.transaction { transaction -> Void in
|
||||||
updatePeerNotificationSoundInteractive(transaction: transaction, peerId: peerId, sound: sound)
|
updatePeerNotificationSoundInteractive(transaction: transaction, peerId: peerId, sound: sound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatePeerNotificationSoundInteractive(transaction: Transaction, peerId: PeerId, sound: PeerMessageSound) {
|
func updatePeerNotificationSoundInteractive(transaction: Transaction, peerId: PeerId, sound: PeerMessageSound) {
|
||||||
if let peer = transaction.getPeer(peerId) {
|
if let peer = transaction.getPeer(peerId) {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if let associatedPeerId = peer.associatedPeerId {
|
@ -96,7 +96,7 @@ public final class ChannelAdminEventLogContext {
|
|||||||
|
|
||||||
private let loadMoreDisposable = MetaDisposable()
|
private let loadMoreDisposable = MetaDisposable()
|
||||||
|
|
||||||
public init(postbox: Postbox, network: Network, peerId: PeerId) {
|
init(postbox: Postbox, network: Network, peerId: PeerId) {
|
||||||
self.postbox = postbox
|
self.postbox = postbox
|
||||||
self.network = network
|
self.network = network
|
||||||
self.peerId = peerId
|
self.peerId = peerId
|
@ -114,7 +114,7 @@ private func boolFromApiValue(_ value: Api.Bool) -> Bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: PeerId, maxId: AdminLogEventId, minId: AdminLogEventId, limit: Int32 = 100, query: String? = nil, filter: AdminLogEventsFlags? = nil, admins: [PeerId]? = nil) -> Signal<AdminLogEventsResult, ChannelAdminLogEventError> {
|
func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: PeerId, maxId: AdminLogEventId, minId: AdminLogEventId, limit: Int32 = 100, query: String? = nil, filter: AdminLogEventsFlags? = nil, admins: [PeerId]? = nil) -> Signal<AdminLogEventsResult, ChannelAdminLogEventError> {
|
||||||
return postbox.transaction { transaction -> (Peer?, [Peer]?) in
|
return postbox.transaction { transaction -> (Peer?, [Peer]?) in
|
||||||
return (transaction.getPeer(peerId), admins?.compactMap { transaction.getPeer($0) })
|
return (transaction.getPeer(peerId), admins?.compactMap { transaction.getPeer($0) })
|
||||||
}
|
}
|
@ -3,138 +3,9 @@ import Postbox
|
|||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import TelegramApi
|
import TelegramApi
|
||||||
import MtProtoKit
|
import MtProtoKit
|
||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
private enum ChannelBlacklistFilter {
|
func _internal_updateChannelMemberBannedRights(account: Account, peerId: PeerId, memberId: PeerId, rights: TelegramChatBannedRights?) -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> {
|
||||||
case restricted
|
|
||||||
case banned
|
|
||||||
}
|
|
||||||
|
|
||||||
private func fetchChannelBlacklist(account: Account, peerId: PeerId, filter: ChannelBlacklistFilter) -> Signal<[RenderedChannelParticipant], NoError> {
|
|
||||||
return account.postbox.transaction { transaction -> Signal<[RenderedChannelParticipant], NoError> in
|
|
||||||
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
|
||||||
let apiFilter: Api.ChannelParticipantsFilter
|
|
||||||
switch filter {
|
|
||||||
case .restricted:
|
|
||||||
apiFilter = .channelParticipantsBanned(q: "")
|
|
||||||
case .banned:
|
|
||||||
apiFilter = .channelParticipantsKicked(q: "")
|
|
||||||
}
|
|
||||||
return account.network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: apiFilter, offset: 0, limit: 100, hash: 0))
|
|
||||||
|> retryRequest
|
|
||||||
|> map { result -> [RenderedChannelParticipant] in
|
|
||||||
var items: [RenderedChannelParticipant] = []
|
|
||||||
switch result {
|
|
||||||
case let .channelParticipants(_, participants, chats, users):
|
|
||||||
var peers: [PeerId: Peer] = [:]
|
|
||||||
var presences: [PeerId: PeerPresence] = [:]
|
|
||||||
for user in users {
|
|
||||||
let peer = TelegramUser(user: user)
|
|
||||||
peers[peer.id] = peer
|
|
||||||
if let presence = TelegramUserPresence(apiUser: user) {
|
|
||||||
presences[peer.id] = presence
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for chat in chats {
|
|
||||||
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
|
||||||
peers[groupOrChannel.id] = groupOrChannel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for participant in CachedChannelParticipants(apiParticipants: participants).participants {
|
|
||||||
if let peer = peers[participant.peerId] {
|
|
||||||
items.append(RenderedChannelParticipant(participant: participant, peer: peer, peers: peers, presences: presences))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
case .channelParticipantsNotModified:
|
|
||||||
assertionFailure()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return items
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .single([])
|
|
||||||
}
|
|
||||||
} |> switchToLatest
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct ChannelBlacklist {
|
|
||||||
public let banned: [RenderedChannelParticipant]
|
|
||||||
public let restricted: [RenderedChannelParticipant]
|
|
||||||
|
|
||||||
public init(banned: [RenderedChannelParticipant], restricted: [RenderedChannelParticipant]) {
|
|
||||||
self.banned = banned
|
|
||||||
self.restricted = restricted
|
|
||||||
}
|
|
||||||
|
|
||||||
public var isEmpty: Bool {
|
|
||||||
return banned.isEmpty && restricted.isEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
public func withRemovedPeerId(_ memberId:PeerId) -> ChannelBlacklist {
|
|
||||||
var updatedRestricted = restricted
|
|
||||||
var updatedBanned = banned
|
|
||||||
|
|
||||||
for i in 0 ..< updatedBanned.count {
|
|
||||||
if updatedBanned[i].peer.id == memberId {
|
|
||||||
updatedBanned.remove(at: i)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i in 0 ..< updatedRestricted.count {
|
|
||||||
if updatedRestricted[i].peer.id == memberId {
|
|
||||||
updatedRestricted.remove(at: i)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ChannelBlacklist(banned: updatedBanned, restricted: updatedRestricted)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func withRemovedParticipant(_ participant:RenderedChannelParticipant) -> ChannelBlacklist {
|
|
||||||
let updated = self.withRemovedPeerId(participant.participant.peerId)
|
|
||||||
var updatedRestricted = updated.restricted
|
|
||||||
var updatedBanned = updated.banned
|
|
||||||
|
|
||||||
if case let .member(_, _, _, maybeBanInfo, _) = participant.participant, let banInfo = maybeBanInfo {
|
|
||||||
if banInfo.rights.flags.contains(.banReadMessages) {
|
|
||||||
updatedBanned.insert(participant, at: 0)
|
|
||||||
} else {
|
|
||||||
if !banInfo.rights.flags.isEmpty {
|
|
||||||
updatedRestricted.insert(participant, at: 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return ChannelBlacklist(banned: updatedBanned, restricted: updatedRestricted)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func channelBlacklistParticipants(account: Account, peerId: PeerId) -> Signal<ChannelBlacklist, NoError> {
|
|
||||||
return combineLatest(fetchChannelBlacklist(account: account, peerId: peerId, filter: .restricted), fetchChannelBlacklist(account: account, peerId: peerId, filter: .banned))
|
|
||||||
|> map { restricted, banned in
|
|
||||||
var r: [RenderedChannelParticipant] = []
|
|
||||||
var b: [RenderedChannelParticipant] = []
|
|
||||||
var peerIds = Set<PeerId>()
|
|
||||||
for participant in restricted {
|
|
||||||
if !peerIds.contains(participant.peer.id) {
|
|
||||||
peerIds.insert(participant.peer.id)
|
|
||||||
r.append(participant)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for participant in banned {
|
|
||||||
if !peerIds.contains(participant.peer.id) {
|
|
||||||
peerIds.insert(participant.peer.id)
|
|
||||||
b.append(participant)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ChannelBlacklist(banned: b, restricted: r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, memberId: PeerId, rights: TelegramChatBannedRights?) -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> {
|
|
||||||
return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId)
|
return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId)
|
||||||
|> mapToSignal { currentParticipant -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> in
|
|> mapToSignal { currentParticipant -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> in
|
||||||
return account.postbox.transaction { transaction -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> in
|
return account.postbox.transaction { transaction -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> in
|
||||||
@ -263,7 +134,7 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateDefaultChannelMemberBannedRights(account: Account, peerId: PeerId, rights: TelegramChatBannedRights) -> Signal<Never, NoError> {
|
func _internal_updateDefaultChannelMemberBannedRights(account: Account, peerId: PeerId, rights: TelegramChatBannedRights) -> Signal<Never, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Never, NoError> in
|
return account.postbox.transaction { transaction -> Signal<Never, NoError> in
|
||||||
guard let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer), let _ = transaction.getPeer(account.peerId) else {
|
guard let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer), let _ = transaction.getPeer(account.peerId) else {
|
||||||
return .complete()
|
return .complete()
|
@ -71,11 +71,11 @@ private func createChannel(account: Account, title: String, description: String?
|
|||||||
|> switchToLatest
|
|> switchToLatest
|
||||||
}
|
}
|
||||||
|
|
||||||
public func createChannel(account: Account, title: String, description: String?) -> Signal<PeerId, CreateChannelError> {
|
func _internal_createChannel(account: Account, title: String, description: String?) -> Signal<PeerId, CreateChannelError> {
|
||||||
return createChannel(account: account, title: title, description: description, isSupergroup: false)
|
return createChannel(account: account, title: title, description: description, isSupergroup: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func createSupergroup(account: Account, title: String, description: String?, location: (latitude: Double, longitude: Double, address: String)? = nil, isForHistoryImport: Bool = false) -> Signal<PeerId, CreateChannelError> {
|
func _internal_createSupergroup(account: Account, title: String, description: String?, location: (latitude: Double, longitude: Double, address: String)? = nil, isForHistoryImport: Bool = false) -> Signal<PeerId, CreateChannelError> {
|
||||||
return createChannel(account: account, title: title, description: description, isSupergroup: true, location: location, isForHistoryImport: isForHistoryImport)
|
return createChannel(account: account, title: title, description: description, isSupergroup: true, location: location, isForHistoryImport: isForHistoryImport)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ public enum DeleteChannelError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deleteChannel(account: Account, peerId: PeerId) -> Signal<Void, DeleteChannelError> {
|
func _internal_deleteChannel(account: Account, peerId: PeerId) -> Signal<Void, DeleteChannelError> {
|
||||||
return account.postbox.transaction { transaction -> Api.InputChannel? in
|
return account.postbox.transaction { transaction -> Api.InputChannel? in
|
||||||
return transaction.getPeer(peerId).flatMap(apiInputChannel)
|
return transaction.getPeer(peerId).flatMap(apiInputChannel)
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ public enum ChannelHistoryAvailabilityError {
|
|||||||
case hasNotPermissions
|
case hasNotPermissions
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateChannelHistoryAvailabilitySettingsInteractively(postbox: Postbox, network: Network, accountStateManager: AccountStateManager, peerId: PeerId, historyAvailableForNewMembers: Bool) -> Signal<Void, ChannelHistoryAvailabilityError> {
|
func _internal_updateChannelHistoryAvailabilitySettingsInteractively(postbox: Postbox, network: Network, accountStateManager: AccountStateManager, peerId: PeerId, historyAvailableForNewMembers: Bool) -> Signal<Void, ChannelHistoryAvailabilityError> {
|
||||||
return postbox.transaction { transaction -> Peer? in
|
return postbox.transaction { transaction -> Peer? in
|
||||||
return transaction.getPeer(peerId)
|
return transaction.getPeer(peerId)
|
||||||
}
|
}
|
@ -21,7 +21,7 @@ public enum ChannelMembersCategory {
|
|||||||
case mentions(threadId: MessageId?, filter: ChannelMembersCategoryFilter)
|
case mentions(threadId: MessageId?, filter: ChannelMembersCategoryFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func channelMembers(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, category: ChannelMembersCategory = .recent(.all), offset: Int32 = 0, limit: Int32 = 64, hash: Int32 = 0) -> Signal<[RenderedChannelParticipant]?, NoError> {
|
func _internal_channelMembers(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, category: ChannelMembersCategory = .recent(.all), offset: Int32 = 0, limit: Int32 = 64, hash: Int32 = 0) -> Signal<[RenderedChannelParticipant]?, NoError> {
|
||||||
return postbox.transaction { transaction -> Signal<[RenderedChannelParticipant]?, NoError> in
|
return postbox.transaction { transaction -> Signal<[RenderedChannelParticipant]?, NoError> in
|
||||||
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
||||||
let apiFilter: Api.ChannelParticipantsFilter
|
let apiFilter: Api.ChannelParticipantsFilter
|
@ -21,7 +21,7 @@ public enum ChannelOwnershipTransferError {
|
|||||||
case userBlocked
|
case userBlocked
|
||||||
}
|
}
|
||||||
|
|
||||||
public func checkOwnershipTranfserAvailability(postbox: Postbox, network: Network, accountStateManager: AccountStateManager, memberId: PeerId) -> Signal<Never, ChannelOwnershipTransferError> {
|
func _internal_checkOwnershipTranfserAvailability(postbox: Postbox, network: Network, accountStateManager: AccountStateManager, memberId: PeerId) -> Signal<Never, ChannelOwnershipTransferError> {
|
||||||
return postbox.transaction { transaction -> Peer? in
|
return postbox.transaction { transaction -> Peer? in
|
||||||
return transaction.getPeer(memberId)
|
return transaction.getPeer(memberId)
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ public func checkOwnershipTranfserAvailability(postbox: Postbox, network: Networ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateChannelOwnership(account: Account, accountStateManager: AccountStateManager, channelId: PeerId, memberId: PeerId, password: String) -> Signal<[(ChannelParticipant?, RenderedChannelParticipant)], ChannelOwnershipTransferError> {
|
func _internal_updateChannelOwnership(account: Account, accountStateManager: AccountStateManager, channelId: PeerId, memberId: PeerId, password: String) -> Signal<[(ChannelParticipant?, RenderedChannelParticipant)], ChannelOwnershipTransferError> {
|
||||||
guard !password.isEmpty else {
|
guard !password.isEmpty else {
|
||||||
return .fail(.invalidPassword)
|
return .fail(.invalidPassword)
|
||||||
}
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import Foundation
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramApi
|
||||||
|
import MtProtoKit
|
||||||
|
|
||||||
|
import SyncCore
|
||||||
|
|
||||||
|
public struct RenderedChannelParticipant: Equatable {
|
||||||
|
public let participant: ChannelParticipant
|
||||||
|
public let peer: Peer
|
||||||
|
public let peers: [PeerId: Peer]
|
||||||
|
public let presences: [PeerId: PeerPresence]
|
||||||
|
|
||||||
|
public init(participant: ChannelParticipant, peer: Peer, peers: [PeerId: Peer] = [:], presences: [PeerId: PeerPresence] = [:]) {
|
||||||
|
self.participant = participant
|
||||||
|
self.peer = peer
|
||||||
|
self.peers = peers
|
||||||
|
self.presences = presences
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: RenderedChannelParticipant, rhs: RenderedChannelParticipant) -> Bool {
|
||||||
|
return lhs.participant == rhs.participant && lhs.peer.isEqual(rhs.peer)
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ public enum JoinChannelError {
|
|||||||
case tooMuchUsers
|
case tooMuchUsers
|
||||||
}
|
}
|
||||||
|
|
||||||
public func joinChannel(account: Account, peerId: PeerId, hash: String?) -> Signal<RenderedChannelParticipant?, JoinChannelError> {
|
func _internal_joinChannel(account: Account, peerId: PeerId, hash: String?) -> Signal<RenderedChannelParticipant?, JoinChannelError> {
|
||||||
return account.postbox.loadedPeerWithId(peerId)
|
return account.postbox.loadedPeerWithId(peerId)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> castError(JoinChannelError.self)
|
|> castError(JoinChannelError.self)
|
@ -9,7 +9,7 @@ public enum AvailableChannelDiscussionGroupError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func availableGroupsForChannelDiscussion(postbox: Postbox, network: Network) -> Signal<[Peer], AvailableChannelDiscussionGroupError> {
|
func _internal_availableGroupsForChannelDiscussion(postbox: Postbox, network: Network) -> Signal<[Peer], AvailableChannelDiscussionGroupError> {
|
||||||
return network.request(Api.functions.channels.getGroupsForDiscussion())
|
return network.request(Api.functions.channels.getGroupsForDiscussion())
|
||||||
|> mapError { error in
|
|> mapError { error in
|
||||||
return .generic
|
return .generic
|
||||||
@ -39,7 +39,7 @@ public enum ChannelDiscussionGroupError {
|
|||||||
case tooManyChannels
|
case tooManyChannels
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateGroupDiscussionForChannel(network: Network, postbox: Postbox, channelId: PeerId?, groupId: PeerId?) -> Signal<Bool, ChannelDiscussionGroupError> {
|
func _internal_updateGroupDiscussionForChannel(network: Network, postbox: Postbox, channelId: PeerId?, groupId: PeerId?) -> Signal<Bool, ChannelDiscussionGroupError> {
|
||||||
return postbox.transaction { transaction -> (channel: Peer?, group: Peer?) in
|
return postbox.transaction { transaction -> (channel: Peer?, group: Peer?) in
|
||||||
return (channel: channelId.flatMap(transaction.getPeer), group: groupId.flatMap(transaction.getPeer))
|
return (channel: channelId.flatMap(transaction.getPeer), group: groupId.flatMap(transaction.getPeer))
|
||||||
}
|
}
|
@ -26,7 +26,7 @@ public struct PeerCommands: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func peerCommands(account: Account, id: PeerId) -> Signal<PeerCommands, NoError> {
|
func _internal_peerCommands(account: Account, id: PeerId) -> Signal<PeerCommands, NoError> {
|
||||||
return account.postbox.peerView(id: id) |> map { view -> PeerCommands in
|
return account.postbox.peerView(id: id) |> map { view -> PeerCommands in
|
||||||
if let cachedUserData = view.cachedData as? CachedUserData {
|
if let cachedUserData = view.cachedData as? CachedUserData {
|
||||||
if let botInfo = cachedUserData.botInfo {
|
if let botInfo = cachedUserData.botInfo {
|
@ -6,9 +6,9 @@ import MtProtoKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
public func removePeerMember(account: Account, peerId: PeerId, memberId: PeerId) -> Signal<Void, NoError> {
|
func _internal_removePeerMember(account: Account, peerId: PeerId, memberId: PeerId) -> Signal<Void, NoError> {
|
||||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
return updateChannelMemberBannedRights(account: account, peerId: peerId, memberId: memberId, rights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: 0))
|
return _internal_updateChannelMemberBannedRights(account: account, peerId: peerId, memberId: memberId, rights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: 0))
|
||||||
|> mapToSignal { _ -> Signal<Void, NoError> in
|
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ public struct TelegramPeerPhoto {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func requestPeerPhotos(postbox: Postbox, network: Network, peerId: PeerId) -> Signal<[TelegramPeerPhoto], NoError> {
|
func _internal_requestPeerPhotos(postbox: Postbox, network: Network, peerId: PeerId) -> Signal<[TelegramPeerPhoto], NoError> {
|
||||||
return postbox.transaction{ transaction -> Peer? in
|
return postbox.transaction{ transaction -> Peer? in
|
||||||
return transaction.getPeer(peerId)
|
return transaction.getPeer(peerId)
|
||||||
}
|
}
|
@ -4,6 +4,41 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
|
private struct PeerParticipants: Equatable {
|
||||||
|
let peers: [Peer]
|
||||||
|
|
||||||
|
static func ==(lhs: PeerParticipants, rhs: PeerParticipants) -> Bool {
|
||||||
|
if lhs.peers.count != rhs.peers.count {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i in 0 ..< lhs.peers.count {
|
||||||
|
if !lhs.peers[i].isEqual(rhs.peers[i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func peerParticipants(postbox: Postbox, id: PeerId) -> Signal<[Peer], NoError> {
|
||||||
|
return postbox.peerView(id: id) |> map { view -> PeerParticipants in
|
||||||
|
if let cachedGroupData = view.cachedData as? CachedGroupData, let participants = cachedGroupData.participants {
|
||||||
|
var peers: [Peer] = []
|
||||||
|
for participant in participants.participants {
|
||||||
|
if let peer = view.peers[participant.peerId] {
|
||||||
|
peers.append(peer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PeerParticipants(peers: peers)
|
||||||
|
} else {
|
||||||
|
return PeerParticipants(peers: [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged |> map { participants in
|
||||||
|
return participants.peers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func searchLocalGroupMembers(postbox: Postbox, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
|
private func searchLocalGroupMembers(postbox: Postbox, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
|
||||||
return peerParticipants(postbox: postbox, id: peerId)
|
return peerParticipants(postbox: postbox, id: peerId)
|
||||||
|> map { peers -> [Peer] in
|
|> map { peers -> [Peer] in
|
||||||
@ -28,7 +63,7 @@ private func searchLocalGroupMembers(postbox: Postbox, peerId: PeerId, query: St
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func searchGroupMembers(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
|
func _internal_searchGroupMembers(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
|
||||||
if peerId.namespace == Namespaces.Peer.CloudChannel && !query.isEmpty {
|
if peerId.namespace == Namespaces.Peer.CloudChannel && !query.isEmpty {
|
||||||
return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query)
|
return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query)
|
||||||
|> mapToSignal { local -> Signal<[Peer], NoError> in
|
|> mapToSignal { local -> Signal<[Peer], NoError> in
|
||||||
@ -40,7 +75,7 @@ public func searchGroupMembers(postbox: Postbox, network: Network, accountPeerId
|
|||||||
}
|
}
|
||||||
return localResult
|
return localResult
|
||||||
|> then(
|
|> then(
|
||||||
channelMembers(postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, category: .recent(.search(query)))
|
_internal_channelMembers(postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId, category: .recent(.search(query)))
|
||||||
|> map { participants -> [Peer] in
|
|> map { participants -> [Peer] in
|
||||||
var result: [Peer] = local
|
var result: [Peer] = local
|
||||||
let existingIds = Set(local.map { $0.id })
|
let existingIds = Set(local.map { $0.id })
|
@ -128,5 +128,108 @@ public extension TelegramEngine {
|
|||||||
public func reportRepliesMessage(messageId: MessageId, deleteMessage: Bool, deleteHistory: Bool, reportSpam: Bool) -> Signal<Never, NoError> {
|
public func reportRepliesMessage(messageId: MessageId, deleteMessage: Bool, deleteHistory: Bool, reportSpam: Bool) -> Signal<Never, NoError> {
|
||||||
return _internal_reportRepliesMessage(account: self.account, messageId: messageId, deleteMessage: deleteMessage, deleteHistory: deleteHistory, reportSpam: reportSpam)
|
return _internal_reportRepliesMessage(account: self.account, messageId: messageId, deleteMessage: deleteMessage, deleteHistory: deleteHistory, reportSpam: reportSpam)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func togglePeerMuted(peerId: PeerId) -> Signal<Void, NoError> {
|
||||||
|
return _internal_togglePeerMuted(account: self.account, peerId: peerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updatePeerMuteSetting(peerId: PeerId, muteInterval: Int32?) -> Signal<Void, NoError> {
|
||||||
|
return _internal_updatePeerMuteSetting(account: self.account, peerId: peerId, muteInterval: muteInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updatePeerDisplayPreviewsSetting(peerId: PeerId, displayPreviews: PeerNotificationDisplayPreviews) -> Signal<Void, NoError> {
|
||||||
|
return _internal_updatePeerDisplayPreviewsSetting(account: self.account, peerId: peerId, displayPreviews: displayPreviews)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updatePeerNotificationSoundInteractive(peerId: PeerId, sound: PeerMessageSound) -> Signal<Void, NoError> {
|
||||||
|
return _internal_updatePeerNotificationSoundInteractive(account: self.account, peerId: peerId, sound: sound)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func removeCustomNotificationSettings(peerIds: [PeerId]) -> Signal<Never, NoError> {
|
||||||
|
return self.account.postbox.transaction { transaction -> Void in
|
||||||
|
for peerId in peerIds {
|
||||||
|
TelegramCore.updatePeerNotificationSoundInteractive(transaction: transaction, peerId: peerId, sound: .default)
|
||||||
|
TelegramCore.updatePeerMuteSetting(transaction: transaction, peerId: peerId, muteInterval: nil)
|
||||||
|
TelegramCore.updatePeerDisplayPreviewsSetting(transaction: transaction, peerId: peerId, displayPreviews: .default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
|
||||||
|
public func channelAdminEventLog(peerId: PeerId) -> ChannelAdminEventLogContext {
|
||||||
|
return ChannelAdminEventLogContext(postbox: self.account.postbox, network: self.account.network, peerId: peerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateChannelMemberBannedRights(peerId: PeerId, memberId: PeerId, rights: TelegramChatBannedRights?) -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> {
|
||||||
|
return _internal_updateChannelMemberBannedRights(account: self.account, peerId: peerId, memberId: memberId, rights: rights)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateDefaultChannelMemberBannedRights(peerId: PeerId, rights: TelegramChatBannedRights) -> Signal<Never, NoError> {
|
||||||
|
return _internal_updateDefaultChannelMemberBannedRights(account: self.account, peerId: peerId, rights: rights)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func createChannel(title: String, description: String?) -> Signal<PeerId, CreateChannelError> {
|
||||||
|
return _internal_createChannel(account: self.account, title: title, description: description)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func createSupergroup(title: String, description: String?, location: (latitude: Double, longitude: Double, address: String)? = nil, isForHistoryImport: Bool = false) -> Signal<PeerId, CreateChannelError> {
|
||||||
|
return _internal_createSupergroup(account: self.account, title: title, description: description, location: location, isForHistoryImport: isForHistoryImport)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func deleteChannel(peerId: PeerId) -> Signal<Void, DeleteChannelError> {
|
||||||
|
return _internal_deleteChannel(account: self.account, peerId: peerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateChannelHistoryAvailabilitySettingsInteractively(peerId: PeerId, historyAvailableForNewMembers: Bool) -> Signal<Void, ChannelHistoryAvailabilityError> {
|
||||||
|
return _internal_updateChannelHistoryAvailabilitySettingsInteractively(postbox: self.account.postbox, network: self.account.network, accountStateManager: self.account.stateManager, peerId: peerId, historyAvailableForNewMembers: historyAvailableForNewMembers)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func channelMembers(peerId: PeerId, category: ChannelMembersCategory = .recent(.all), offset: Int32 = 0, limit: Int32 = 64, hash: Int32 = 0) -> Signal<[RenderedChannelParticipant]?, NoError> {
|
||||||
|
return _internal_channelMembers(postbox: self.account.postbox, network: self.account.network, accountPeerId: self.account.peerId, peerId: peerId, category: category, offset: offset, limit: limit, hash: hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func checkOwnershipTranfserAvailability(memberId: PeerId) -> Signal<Never, ChannelOwnershipTransferError> {
|
||||||
|
return _internal_checkOwnershipTranfserAvailability(postbox: self.account.postbox, network: self.account.network, accountStateManager: self.account.stateManager, memberId: memberId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateChannelOwnership(channelId: PeerId, memberId: PeerId, password: String) -> Signal<[(ChannelParticipant?, RenderedChannelParticipant)], ChannelOwnershipTransferError> {
|
||||||
|
return _internal_updateChannelOwnership(account: self.account, accountStateManager: self.account.stateManager, channelId: channelId, memberId: memberId, password: password)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func searchGroupMembers(peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
|
||||||
|
return _internal_searchGroupMembers(postbox: self.account.postbox, network: self.account.network, accountPeerId: self.account.peerId, peerId: peerId, query: query)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func toggleShouldChannelMessagesSignatures(peerId: PeerId, enabled: Bool) -> Signal<Void, NoError> {
|
||||||
|
return _internal_toggleShouldChannelMessagesSignatures(account: self.account, peerId: peerId, enabled: enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func requestPeerPhotos(peerId: PeerId) -> Signal<[TelegramPeerPhoto], NoError> {
|
||||||
|
return _internal_requestPeerPhotos(postbox: self.account.postbox, network: self.account.network, peerId: peerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateGroupSpecificStickerset(peerId: PeerId, info: StickerPackCollectionInfo?) -> Signal<Void, UpdateGroupSpecificStickersetError> {
|
||||||
|
return _internal_updateGroupSpecificStickerset(postbox: self.account.postbox, network: self.account.network, peerId: peerId, info: info)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func joinChannel(peerId: PeerId, hash: String?) -> Signal<RenderedChannelParticipant?, JoinChannelError> {
|
||||||
|
return _internal_joinChannel(account: self.account, peerId: peerId, hash: hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func removePeerMember(peerId: PeerId, memberId: PeerId) -> Signal<Void, NoError> {
|
||||||
|
return _internal_removePeerMember(account: self.account, peerId: peerId, memberId: memberId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func availableGroupsForChannelDiscussion() -> Signal<[Peer], AvailableChannelDiscussionGroupError> {
|
||||||
|
return _internal_availableGroupsForChannelDiscussion(postbox: self.account.postbox, network: self.account.network)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateGroupDiscussionForChannel(channelId: PeerId?, groupId: PeerId?) -> Signal<Bool, ChannelDiscussionGroupError> {
|
||||||
|
return _internal_updateGroupDiscussionForChannel(network: self.account.network, postbox: self.account.postbox, channelId: channelId, groupId: groupId)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func peerCommands(id: PeerId) -> Signal<PeerCommands, NoError> {
|
||||||
|
return _internal_peerCommands(account: self.account, id: id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import MtProtoKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
public func toggleShouldChannelMessagesSignatures(account:Account, peerId:PeerId, enabled: Bool) -> Signal<Void, NoError> {
|
func _internal_toggleShouldChannelMessagesSignatures(account:Account, peerId:PeerId, enabled: Bool) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
if let peer = transaction.getPeer(peerId) as? TelegramChannel, let inputChannel = apiInputChannel(peer) {
|
if let peer = transaction.getPeer(peerId) as? TelegramChannel, let inputChannel = apiInputChannel(peer) {
|
||||||
return account.network.request(Api.functions.channels.toggleSignatures(channel: inputChannel, enabled: enabled ? .boolTrue : .boolFalse)) |> retryRequest |> map { updates -> Void in
|
return account.network.request(Api.functions.channels.toggleSignatures(channel: inputChannel, enabled: enabled ? .boolTrue : .boolFalse)) |> retryRequest |> map { updates -> Void in
|
@ -9,7 +9,7 @@ public enum UpdateGroupSpecificStickersetError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateGroupSpecificStickerset(postbox: Postbox, network: Network, peerId: PeerId, info: StickerPackCollectionInfo?) -> Signal<Void, UpdateGroupSpecificStickersetError> {
|
func _internal_updateGroupSpecificStickerset(postbox: Postbox, network: Network, peerId: PeerId, info: StickerPackCollectionInfo?) -> Signal<Void, UpdateGroupSpecificStickersetError> {
|
||||||
return postbox.loadedPeerWithId(peerId)
|
return postbox.loadedPeerWithId(peerId)
|
||||||
|> castError(UpdateGroupSpecificStickersetError.self)
|
|> castError(UpdateGroupSpecificStickersetError.self)
|
||||||
|> mapToSignal { peer -> Signal<Void, UpdateGroupSpecificStickersetError> in
|
|> mapToSignal { peer -> Signal<Void, UpdateGroupSpecificStickersetError> in
|
@ -136,7 +136,7 @@ public final class ActiveSessionsContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(account: Account) {
|
init(account: Account) {
|
||||||
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
|
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
|
||||||
return ActiveSessionsContextImpl(account: account)
|
return ActiveSessionsContextImpl(account: account)
|
||||||
})
|
})
|
||||||
@ -218,7 +218,7 @@ public final class WebSessionsContext {
|
|||||||
|
|
||||||
private let disposable = MetaDisposable()
|
private let disposable = MetaDisposable()
|
||||||
|
|
||||||
public init(account: Account) {
|
init(account: Account) {
|
||||||
assert(Queue.mainQueue().isCurrent())
|
assert(Queue.mainQueue().isCurrent())
|
||||||
|
|
||||||
self.account = account
|
self.account = account
|
@ -3,7 +3,7 @@ import Postbox
|
|||||||
import TelegramApi
|
import TelegramApi
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
|
||||||
public func requestRecentAccountSessions(account: Account) -> Signal<[RecentAccountSession], NoError> {
|
func requestRecentAccountSessions(account: Account) -> Signal<[RecentAccountSession], NoError> {
|
||||||
return account.network.request(Api.functions.account.getAuthorizations())
|
return account.network.request(Api.functions.account.getAuthorizations())
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> map { result -> [RecentAccountSession] in
|
|> map { result -> [RecentAccountSession] in
|
||||||
@ -23,7 +23,7 @@ public enum TerminateSessionError {
|
|||||||
case freshReset
|
case freshReset
|
||||||
}
|
}
|
||||||
|
|
||||||
public func terminateAccountSession(account: Account, hash: Int64) -> Signal<Void, TerminateSessionError> {
|
func terminateAccountSession(account: Account, hash: Int64) -> Signal<Void, TerminateSessionError> {
|
||||||
return account.network.request(Api.functions.account.resetAuthorization(hash: hash))
|
return account.network.request(Api.functions.account.resetAuthorization(hash: hash))
|
||||||
|> mapError { error -> TerminateSessionError in
|
|> mapError { error -> TerminateSessionError in
|
||||||
if error.errorCode == 406 {
|
if error.errorCode == 406 {
|
||||||
@ -36,7 +36,7 @@ public func terminateAccountSession(account: Account, hash: Int64) -> Signal<Voi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func terminateOtherAccountSessions(account: Account) -> Signal<Void, TerminateSessionError> {
|
func terminateOtherAccountSessions(account: Account) -> Signal<Void, TerminateSessionError> {
|
||||||
return account.network.request(Api.functions.auth.resetAuthorizations())
|
return account.network.request(Api.functions.auth.resetAuthorizations())
|
||||||
|> mapError { error -> TerminateSessionError in
|
|> mapError { error -> TerminateSessionError in
|
||||||
if error.errorCode == 406 {
|
if error.errorCode == 406 {
|
@ -21,7 +21,7 @@ public struct WebAuthorization : Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func webSessions(network: Network) -> Signal<([WebAuthorization], [PeerId: Peer]), NoError> {
|
func webSessions(network: Network) -> Signal<([WebAuthorization], [PeerId: Peer]), NoError> {
|
||||||
return network.request(Api.functions.account.getWebAuthorizations())
|
return network.request(Api.functions.account.getWebAuthorizations())
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> map { result -> ([WebAuthorization], [PeerId : Peer]) in
|
|> map { result -> ([WebAuthorization], [PeerId : Peer]) in
|
||||||
@ -46,7 +46,7 @@ public func webSessions(network: Network) -> Signal<([WebAuthorization], [PeerId
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public func terminateWebSession(network: Network, hash: Int64) -> Signal<Bool, NoError> {
|
func terminateWebSession(network: Network, hash: Int64) -> Signal<Bool, NoError> {
|
||||||
return network.request(Api.functions.account.resetWebAuthorization(hash: hash))
|
return network.request(Api.functions.account.resetWebAuthorization(hash: hash))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> map { result in
|
|> map { result in
|
||||||
@ -61,7 +61,7 @@ public func terminateWebSession(network: Network, hash: Int64) -> Signal<Bool, N
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public func terminateAllWebSessions(network: Network) -> Signal<Void, NoError> {
|
func terminateAllWebSessions(network: Network) -> Signal<Void, NoError> {
|
||||||
return network.request(Api.functions.account.resetWebAuthorizations())
|
return network.request(Api.functions.account.resetWebAuthorizations())
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> map { _ in }
|
|> map { _ in }
|
@ -12,5 +12,33 @@ public extension TelegramEngine {
|
|||||||
public func requestUpdatePeerIsBlocked(peerId: PeerId, isBlocked: Bool) -> Signal<Void, NoError> {
|
public func requestUpdatePeerIsBlocked(peerId: PeerId, isBlocked: Bool) -> Signal<Void, NoError> {
|
||||||
return _internal_requestUpdatePeerIsBlocked(account: self.account, peerId: peerId, isBlocked: isBlocked)
|
return _internal_requestUpdatePeerIsBlocked(account: self.account, peerId: peerId, isBlocked: isBlocked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func activeSessions() -> ActiveSessionsContext {
|
||||||
|
return ActiveSessionsContext(account: self.account)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func webSessions() -> WebSessionsContext {
|
||||||
|
return WebSessionsContext(account: self.account)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func requestAccountPrivacySettings() -> Signal<AccountPrivacySettings, NoError> {
|
||||||
|
return _internal_requestAccountPrivacySettings(account: self.account)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateAccountAutoArchiveChats(value: Bool) -> Signal<Never, NoError> {
|
||||||
|
return _internal_updateAccountAutoArchiveChats(account: self.account, value: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateAccountRemovalTimeout(timeout: Int32) -> Signal<Void, NoError> {
|
||||||
|
return _internal_updateAccountRemovalTimeout(account: self.account, timeout: timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updatePhoneNumberDiscovery(value: Bool) -> Signal<Void, NoError> {
|
||||||
|
return _internal_updatePhoneNumberDiscovery(account: self.account, value: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateSelectiveAccountPrivacySettings(type: UpdateSelectiveAccountPrivacySettingsType, settings: SelectivePrivacySettings) -> Signal<Void, NoError> {
|
||||||
|
return _internal_updateSelectiveAccountPrivacySettings(account: self.account, type: type, settings: settings)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
public func requestAccountPrivacySettings(account: Account) -> Signal<AccountPrivacySettings, NoError> {
|
func _internal_requestAccountPrivacySettings(account: Account) -> Signal<AccountPrivacySettings, NoError> {
|
||||||
let lastSeenPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyStatusTimestamp))
|
let lastSeenPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyStatusTimestamp))
|
||||||
let groupPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyChatInvite))
|
let groupPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyChatInvite))
|
||||||
let voiceCallPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyPhoneCall))
|
let voiceCallPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyPhoneCall))
|
||||||
@ -140,8 +140,7 @@ public func requestAccountPrivacySettings(account: Account) -> Signal<AccountPri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateAccountAutoArchiveChats(account: Account, value: Bool) -> Signal<Never, NoError> {
|
func _internal_updateAccountAutoArchiveChats(account: Account, value: Bool) -> Signal<Never, NoError> {
|
||||||
|
|
||||||
return account.network.request(Api.functions.account.setGlobalPrivacySettings(
|
return account.network.request(Api.functions.account.setGlobalPrivacySettings(
|
||||||
settings: .globalPrivacySettings(flags: 1 << 0, archiveAndMuteNewNoncontactPeers: value ? .boolTrue : .boolFalse)
|
settings: .globalPrivacySettings(flags: 1 << 0, archiveAndMuteNewNoncontactPeers: value ? .boolTrue : .boolFalse)
|
||||||
))
|
))
|
||||||
@ -149,7 +148,7 @@ public func updateAccountAutoArchiveChats(account: Account, value: Bool) -> Sign
|
|||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateAccountRemovalTimeout(account: Account, timeout: Int32) -> Signal<Void, NoError> {
|
func _internal_updateAccountRemovalTimeout(account: Account, timeout: Int32) -> Signal<Void, NoError> {
|
||||||
return account.network.request(Api.functions.account.setAccountTTL(ttl: .accountDaysTTL(days: timeout / (24 * 60 * 60))))
|
return account.network.request(Api.functions.account.setAccountTTL(ttl: .accountDaysTTL(days: timeout / (24 * 60 * 60))))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> mapToSignal { _ -> Signal<Void, NoError> in
|
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||||
@ -157,7 +156,7 @@ public func updateAccountRemovalTimeout(account: Account, timeout: Int32) -> Sig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatePhoneNumberDiscovery(account: Account, value: Bool) -> Signal<Void, NoError> {
|
func _internal_updatePhoneNumberDiscovery(account: Account, value: Bool) -> Signal<Void, NoError> {
|
||||||
var rules: [Api.InputPrivacyRule] = []
|
var rules: [Api.InputPrivacyRule] = []
|
||||||
if value {
|
if value {
|
||||||
rules.append(.inputPrivacyValueAllowAll)
|
rules.append(.inputPrivacyValueAllowAll)
|
||||||
@ -223,7 +222,7 @@ private func apiUserAndGroupIds(peerIds: [PeerId: SelectivePrivacyPeer]) -> (use
|
|||||||
return (users, groups)
|
return (users, groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateSelectiveAccountPrivacySettings(account: Account, type: UpdateSelectiveAccountPrivacySettingsType, settings: SelectivePrivacySettings) -> Signal<Void, NoError> {
|
func _internal_updateSelectiveAccountPrivacySettings(account: Account, type: UpdateSelectiveAccountPrivacySettingsType, settings: SelectivePrivacySettings) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
var rules: [Api.InputPrivacyRule] = []
|
var rules: [Api.InputPrivacyRule] = []
|
||||||
switch settings {
|
switch settings {
|
@ -59,6 +59,10 @@ public final class TelegramEngine {
|
|||||||
public lazy var historyImport: HistoryImport = {
|
public lazy var historyImport: HistoryImport = {
|
||||||
return HistoryImport(account: self.account)
|
return HistoryImport(account: self.account)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
public lazy var contacts: Contacts = {
|
||||||
|
return Contacts(account: self.account)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class TelegramEngineUnauthorized {
|
public final class TelegramEngineUnauthorized {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user