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
|
||||
}
|
||||
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: {
|
||||
f(.default)
|
||||
})
|
||||
@ -332,7 +332,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
if case .search = source {
|
||||
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
|
||||
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)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
@ -688,7 +688,7 @@ public final class ChatListNode: ListView {
|
||||
return
|
||||
}
|
||||
strongSelf.setCurrentRemovingPeerId(peerId)
|
||||
let _ = (togglePeerMuted(account: context.account, peerId: peerId)
|
||||
let _ = (context.engine.peers.togglePeerMuted(peerId: peerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
self?.updateState { state in
|
||||
var state = state
|
||||
|
@ -365,7 +365,7 @@ final class InviteContactsControllerNode: ASDisplayNode {
|
||||
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
|
||||
var result: [(DeviceContactStableId, DeviceContactBasicData, Int32)] = []
|
||||
var contactValues: [DeviceContactStableId: DeviceContactBasicData] = [:]
|
||||
|
@ -310,7 +310,7 @@ final class InstantPagePeerReferenceNode: ASDisplayNode, InstantPageNode {
|
||||
@objc func joinPressed() {
|
||||
if let peer = self.peer, case .notJoined = self.joinState {
|
||||
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 case .inProgress = strongSelf.joinState {
|
||||
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 {
|
||||
return context.account.postbox.loadedPeerWithId(peerId)
|
||||
|> 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)
|
||||
}
|
||||
} 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)
|
||||
|> map { entries -> [AvatarGalleryEntry] in
|
||||
return entries ?? []
|
||||
@ -218,7 +218,7 @@ public func fetchedAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<
|
||||
|> mapToSignal { initialEntries in
|
||||
return .single(initialEntries)
|
||||
|> then(
|
||||
requestPeerPhotos(postbox: account.postbox, network: account.network, peerId: peer.id)
|
||||
engine.peers.requestPeerPhotos(peerId: peer.id)
|
||||
|> map { photos -> [AvatarGalleryEntry] in
|
||||
var result: [AvatarGalleryEntry] = []
|
||||
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]
|
||||
return Signal<(Bool, [AvatarGalleryEntry]), NoError>.single((false, initialEntries))
|
||||
|> then(
|
||||
requestPeerPhotos(postbox: account.postbox, network: account.network, peerId: peer.id)
|
||||
engine.peers.requestPeerPhotos(peerId: peer.id)
|
||||
|> map { photos -> (Bool, [AvatarGalleryEntry]) in
|
||||
var result: [AvatarGalleryEntry] = []
|
||||
let initialEntries = [firstEntry]
|
||||
@ -403,7 +403,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
||||
if let remoteEntries = remoteEntries {
|
||||
remoteEntriesSignal = remoteEntries.get()
|
||||
} 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)
|
||||
|
@ -889,7 +889,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
|
||||
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
|
||||
presentControllerImpl?(c, a)
|
||||
}, completion: { upgradedPeerId in
|
||||
|
@ -665,7 +665,7 @@ public func channelAdminsController(context: AccountContext, peerId initialPeerI
|
||||
|> deliverOnMainQueue).start(next: { peerId in
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
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 {
|
||||
adminsPromise.set(.single(nil))
|
||||
} else {
|
||||
|
@ -506,7 +506,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
|
||||
state.updating = true
|
||||
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
|
||||
|
||||
}, completed: {
|
||||
@ -667,7 +667,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
|
||||
guard let upgradedPeerId = upgradedPeerId else {
|
||||
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
|
||||
return .complete()
|
||||
}
|
||||
@ -700,7 +700,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI
|
||||
}
|
||||
}))
|
||||
} 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
|
||||
|
||||
}, completed: {
|
||||
|
@ -324,7 +324,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let progress = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: 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
|
||||
progress?.dismiss()
|
||||
dismissController?()
|
||||
@ -343,7 +343,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
|
||||
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 {
|
||||
return $0.withUpdatedRemovingPeerId(nil)
|
||||
}
|
||||
@ -388,7 +388,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
|
||||
updateState {
|
||||
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
|
||||
|> then(
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
blacklistPromise.set(.single(nil))
|
||||
} else {
|
||||
|
@ -230,7 +230,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
||||
let groupPeers = Promise<[Peer]?>()
|
||||
groupPeers.set(.single(nil)
|
||||
|> then(
|
||||
availableGroupsForChannelDiscussion(postbox: context.account.postbox, network: context.account.network)
|
||||
context.engine.peers.availableGroupsForChannelDiscussion()
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<[Peer]?, NoError> in
|
||||
return .single(nil)
|
||||
@ -260,7 +260,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
||||
}
|
||||
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
|
||||
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)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
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)
|
||||
|> switchToLatest
|
||||
}
|
||||
} 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)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
@ -413,7 +413,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
||||
case .groupHistoryIsCurrentlyPrivate:
|
||||
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: {
|
||||
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
|
||||
return .generic
|
||||
}
|
||||
@ -421,7 +421,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
||||
return .complete()
|
||||
}
|
||||
|> 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)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
@ -502,7 +502,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, peerI
|
||||
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)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
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 = 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))
|
||||
}, 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))
|
||||
})
|
||||
@ -918,7 +918,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
|
||||
}, aboutLinkAction: { action, itemLink in
|
||||
aboutLinkActionImpl?(action, itemLink)
|
||||
}, 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?
|
||||
|
@ -443,7 +443,7 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
|
||||
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: {
|
||||
updateState {
|
||||
return $0.withUpdatedRemovingPeerId(nil)
|
||||
@ -462,7 +462,7 @@ public func channelMembersController(context: AccountContext, peerId: 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))
|
||||
})
|
||||
actionsDisposable.add(disposable)
|
||||
|
@ -231,13 +231,13 @@ private func categorySignal(context: AccountContext, peerId: PeerId, category: G
|
||||
}
|
||||
switch category {
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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
|
||||
@ -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 {
|
||||
Queue.mainQueue().async {
|
||||
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
|
||||
|> afterDisposed {
|
||||
updateState { state in
|
||||
@ -608,7 +608,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
||||
switch mode {
|
||||
case .searchMembers, .banAndPromoteActions:
|
||||
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 {
|
||||
subscriber.putNext(state.list)
|
||||
}
|
||||
@ -619,11 +619,11 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
||||
foundMembers = .single([])
|
||||
case .inviteActions:
|
||||
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 ?? [] }
|
||||
case .searchAdmins:
|
||||
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 {
|
||||
subscriber.putNext(state.list)
|
||||
}
|
||||
@ -633,7 +633,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
||||
foundMembers = .single([])
|
||||
case .searchBanned:
|
||||
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 {
|
||||
subscriber.putNext(state.list)
|
||||
subscriber.putCompletion()
|
||||
@ -643,7 +643,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
||||
}
|
||||
|> runOn(Queue.mainQueue())
|
||||
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 {
|
||||
subscriber.putNext(state.list.filter({ participant in
|
||||
return participant.peer.id != context.account.peerId
|
||||
@ -655,7 +655,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
|
||||
|> runOn(Queue.mainQueue())
|
||||
case .searchKicked:
|
||||
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 {
|
||||
subscriber.putNext(state.list)
|
||||
subscriber.putCompletion()
|
||||
|
@ -419,7 +419,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
|
||||
} else {
|
||||
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))
|
||||
})
|
||||
|
||||
|
@ -455,7 +455,7 @@ private func commitChannelOwnershipTransferController(context: AccountContext, p
|
||||
|
||||
let signal: Signal<PeerId?, ChannelOwnershipTransferError>
|
||||
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()
|
||||
}
|
||||
|> then(.single(nil))
|
||||
@ -475,7 +475,7 @@ private func commitChannelOwnershipTransferController(context: AccountContext, p
|
||||
guard let upgradedPeerId = upgradedPeerId else {
|
||||
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()
|
||||
}
|
||||
|> then(.single(upgradedPeerId))
|
||||
|
@ -536,7 +536,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
||||
peersPromise.set(.single((peerId, nil)))
|
||||
} else {
|
||||
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 {
|
||||
peersPromise.set(.single((peerId, nil)))
|
||||
} else {
|
||||
@ -594,7 +594,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
||||
}
|
||||
let state = stateValue.with { $0 }
|
||||
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())
|
||||
}
|
||||
} 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 }
|
||||
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())
|
||||
}
|
||||
}
|
||||
@ -679,7 +679,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
||||
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
|
||||
updateState { state in
|
||||
var state = state
|
||||
|
@ -1104,7 +1104,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
|
||||
switch subject {
|
||||
case let .create(peer, _, share, shareViaException, _):
|
||||
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
|
||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
}, completed: {
|
||||
@ -1138,7 +1138,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
|
||||
switch subject {
|
||||
case let .create(peer, _, share, shareViaException, _):
|
||||
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
|
||||
return .complete()
|
||||
}
|
||||
@ -1153,7 +1153,7 @@ public func deviceContactInfoController(context: AccountContext, subject: Device
|
||||
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)
|
||||
|> mapToSignal { peerId -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in
|
||||
if let peerId = peerId {
|
||||
|
@ -163,7 +163,7 @@ public func groupPreHistorySetupController(context: AccountContext, peerId: Peer
|
||||
if peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
let signal = context.engine.peers.convertGroupToSupergroup(peerId: peerId)
|
||||
|> 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
|
||||
return .complete()
|
||||
}
|
||||
@ -190,7 +190,7 @@ public func groupPreHistorySetupController(context: AccountContext, peerId: Peer
|
||||
}
|
||||
}))
|
||||
} 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: {
|
||||
dismissImpl?()
|
||||
}))
|
||||
|
@ -448,7 +448,7 @@ public func groupStickerPackSetupController(context: AccountContext, peerId: Pee
|
||||
state.isSaving = true
|
||||
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
|
||||
updateState { state in
|
||||
var state = state
|
||||
|
@ -18,7 +18,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
||||
|> mapToSignal { cachedData -> Signal<([Peer], Bool), NoError> in
|
||||
if case .peer = chatLocation, let cachedData = cachedData, let memberCount = cachedData.participantsSummary.memberCount, memberCount <= 64 {
|
||||
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 {
|
||||
let normalizedQuery = query.lowercased()
|
||||
subscriber.putNext((state.list.compactMap { participant -> Peer? in
|
||||
@ -54,7 +54,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
||||
return Signal { subscriber in
|
||||
switch chatLocation {
|
||||
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 {
|
||||
subscriber.putNext((state.list.compactMap { participant in
|
||||
if participant.peer.isDeleted {
|
||||
@ -69,7 +69,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
||||
disposable.dispose()
|
||||
}
|
||||
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 {
|
||||
subscriber.putNext((state.list.compactMap { participant in
|
||||
if participant.peer.isDeleted {
|
||||
@ -117,6 +117,6 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
||||
}
|
||||
}
|
||||
} 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 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
|
||||
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> = {
|
||||
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
|
||||
@ -842,13 +842,11 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
||||
updateNotificationsView({})
|
||||
})
|
||||
}, removePeerFromExceptions: {
|
||||
let _ = (context.account.postbox.transaction { transaction -> Peer? in
|
||||
updatePeerMuteSetting(transaction: transaction, peerId: peerId, muteInterval: nil)
|
||||
updatePeerDisplayPreviewsSetting(transaction: transaction, peerId: peerId, displayPreviews: .default)
|
||||
updatePeerNotificationSoundInteractive(transaction: transaction, peerId: peerId, sound: .default)
|
||||
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|
||||
|> map { _ -> Peer? in }
|
||||
|> then(context.account.postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(peerId)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
})).start(next: { peer in
|
||||
guard let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -917,11 +915,7 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
||||
updateState { value in
|
||||
return value.withUpdatedPeerMuteInterval(peer, nil).withUpdatedPeerSound(peer, .default).withUpdatedPeerDisplayPreviews(peer, .default)
|
||||
}
|
||||
_ = (context.account.postbox.transaction { transaction in
|
||||
updatePeerNotificationSoundInteractive(transaction: transaction, peerId: peer.id, sound: .default)
|
||||
updatePeerMuteSetting(transaction: transaction, peerId: peer.id, muteInterval: nil)
|
||||
updatePeerDisplayPreviewsSetting(transaction: transaction, peerId: peer.id, displayPreviews: .default)
|
||||
}
|
||||
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peer.id])
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
updateNotificationsView({})
|
||||
})
|
||||
@ -953,13 +947,7 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
return state
|
||||
}
|
||||
let _ = (context.account.postbox.transaction { transaction -> Void in
|
||||
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)
|
||||
}
|
||||
}
|
||||
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: values.map(\.peer.id))
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
updateNotificationsView({})
|
||||
})
|
||||
|
@ -426,7 +426,7 @@ public func dataPrivacyController(context: AccountContext) -> ViewController {
|
||||
})
|
||||
}).start()
|
||||
|
||||
actionsDisposable.add((deleteAllContacts(account: context.account)
|
||||
actionsDisposable.add((context.engine.contacts.deleteAllContacts()
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
updateState { state in
|
||||
var state = state
|
||||
|
@ -506,11 +506,11 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
actionsDisposable.add(updateAutoArchiveDisposable)
|
||||
|
||||
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 activeSessionsContext = activeSessionsContext ?? ActiveSessionsContext(account: context.account)
|
||||
let webSessionsContext = webSessionsContext ?? WebSessionsContext(account: context.account)
|
||||
let activeSessionsContext = activeSessionsContext ?? context.engine.privacy.activeSessions()
|
||||
let webSessionsContext = webSessionsContext ?? context.engine.privacy.webSessions()
|
||||
|
||||
let blockedPeersState = Promise<BlockedPeersContextState>()
|
||||
blockedPeersState.set(blockedPeersContext.state)
|
||||
@ -779,7 +779,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
return .complete()
|
||||
}
|
||||
|
||||
updateAutoArchiveDisposable.set((updateAccountAutoArchiveChats(account: context.account, value: archiveValue)
|
||||
updateAutoArchiveDisposable.set((context.engine.privacy.updateAccountAutoArchiveChats(value: archiveValue)
|
||||
|> mapToSignal { _ -> Signal<Void, NoError> in }
|
||||
|> then(applyTimeout)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
@ -817,7 +817,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
updateAccountTimeoutDisposable.set((updateAccountRemovalTimeout(account: context.account, timeout: timeout)
|
||||
updateAccountTimeoutDisposable.set((context.engine.privacy.updateAccountRemovalTimeout(timeout: timeout)
|
||||
|> then(applyTimeout)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
updateState { state in
|
||||
|
@ -1038,14 +1038,14 @@ func selectivePrivacySettingsController(context: AccountContext, kind: Selective
|
||||
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()
|
||||
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()
|
||||
if let phoneDiscoveryEnabled = phoneDiscoveryEnabled {
|
||||
updatePhoneDiscoverySignal = updatePhoneNumberDiscovery(account: context.account, value: phoneDiscoveryEnabled)
|
||||
updatePhoneDiscoverySignal = context.engine.privacy.updatePhoneNumberDiscovery(value: phoneDiscoveryEnabled)
|
||||
}
|
||||
|
||||
let _ = (combineLatest(updateSettingsSignal, updateCallP2PSettingsSignal, updatePhoneDiscoverySignal)
|
||||
|
@ -430,7 +430,7 @@ private func privacySearchableItems(context: AccountContext, privacySettings: Ac
|
||||
if let privacySettings = privacySettings {
|
||||
privacySignal = .single(privacySettings)
|
||||
} else {
|
||||
privacySignal = requestAccountPrivacySettings(account: context.account)
|
||||
privacySignal = context.engine.privacy.requestAccountPrivacySettings()
|
||||
}
|
||||
let callsSignal: Signal<(VoiceCallSettings, VoipConfiguration)?, NoError>
|
||||
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)))
|
||||
}),
|
||||
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
|
||||
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
|
||||
presentPrivacySettings(context, present, .accountTimeout)
|
||||
|
@ -1136,7 +1136,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
let rawAdminIds: Signal<Set<PeerId>, NoError>
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
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>()
|
||||
for item in list.list {
|
||||
if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
|
||||
@ -1425,7 +1425,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
let peerId = strongSelf.peerId
|
||||
if strongSelf.peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
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>()
|
||||
for item in list.list {
|
||||
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>
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
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>()
|
||||
for item in list.list {
|
||||
if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
|
||||
|
@ -1711,7 +1711,7 @@ public final class VoiceChatController: ViewController {
|
||||
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.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
|
||||
|
||||
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
|
||||
if let entry = transaction.getPreferencesEntry(key: PreferencesKeys.remoteStorageConfiguration) as? RemoteStorageConfiguration {
|
||||
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> {
|
||||
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
|
||||
return .generic
|
||||
}).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()
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
if let peer = transaction.getPeer(peerId), let inputUser = apiInputUser(peer) {
|
||||
return account.network.request(Api.functions.contacts.deleteContacts(id: [inputUser]))
|
||||
@ -133,7 +133,7 @@ public func deleteContactPeerInteractively(account: Account, peerId: PeerId) ->
|
||||
|> 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 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())
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
@ -4,8 +4,7 @@ import SwiftSignalKit
|
||||
|
||||
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)
|
||||
|
||||
return account.network.request(Api.functions.contacts.importContacts(contacts: [input]))
|
||||
@ -42,7 +41,7 @@ public enum AddContactError {
|
||||
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
|
||||
if let user = transaction.getPeer(peerId) as? TelegramUser, let inputUser = apiInputUser(user) {
|
||||
return (inputUser, user.phone == nil ? phoneNumber : "")
|
||||
@ -99,7 +98,7 @@ public enum AcceptAndShareContactError {
|
||||
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 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
|
||||
var result: [String: Int32] = [:]
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
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: ""))
|
@ -11,7 +11,7 @@ public enum GetMessagesStrategy {
|
||||
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
|
||||
var ids = messageIds
|
||||
|
@ -6,7 +6,7 @@ import MtProtoKit
|
||||
|
||||
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())
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<[Api.DialogPeer]?, NoError> in
|
@ -453,7 +453,7 @@ public enum FetchChannelReplyThreadMessageError {
|
||||
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 transaction.getPeer(messageId.peerId).flatMap(apiInputPeer)
|
||||
}
|
@ -6,7 +6,7 @@ import MtProtoKit
|
||||
|
||||
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 {
|
||||
return account.postbox.loadedPeerWithId(botPeerId)
|
||||
|> mapToSignal { botPeer -> Signal<Void, NoError> in
|
||||
@ -41,7 +41,7 @@ public enum StartBotInGroupResult {
|
||||
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 (transaction.getPeer(botPeerId), transaction.getPeer(groupPeerId))
|
||||
}
|
@ -94,5 +94,33 @@ public extension TelegramEngine {
|
||||
public func forwardGameWithScore(messageId: MessageId, to peerId: PeerId) -> Signal<Void, NoError> {
|
||||
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)
|
||||
}
|
||||
|
||||
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 (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 (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId))
|
||||
}
|
@ -4,7 +4,7 @@ import SwiftSignalKit
|
||||
|
||||
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
|
||||
if let peer = transaction.getPeer(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
|
||||
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) {
|
||||
var notificationPeerId = peerId
|
||||
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
|
||||
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) {
|
||||
var notificationPeerId = peerId
|
||||
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
|
||||
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) {
|
||||
var notificationPeerId = peerId
|
||||
if let associatedPeerId = peer.associatedPeerId {
|
@ -96,7 +96,7 @@ public final class ChannelAdminEventLogContext {
|
||||
|
||||
private let loadMoreDisposable = MetaDisposable()
|
||||
|
||||
public init(postbox: Postbox, network: Network, peerId: PeerId) {
|
||||
init(postbox: Postbox, network: Network, peerId: PeerId) {
|
||||
self.postbox = postbox
|
||||
self.network = network
|
||||
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 (transaction.getPeer(peerId), admins?.compactMap { transaction.getPeer($0) })
|
||||
}
|
@ -3,138 +3,9 @@ import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
import MtProtoKit
|
||||
|
||||
import SyncCore
|
||||
|
||||
private enum ChannelBlacklistFilter {
|
||||
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> {
|
||||
func _internal_updateChannelMemberBannedRights(account: Account, peerId: PeerId, memberId: PeerId, rights: TelegramChatBannedRights?) -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> {
|
||||
return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId)
|
||||
|> mapToSignal { currentParticipant -> 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
|
||||
guard let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer), let _ = transaction.getPeer(account.peerId) else {
|
||||
return .complete()
|
@ -71,11 +71,11 @@ private func createChannel(account: Account, title: String, description: String?
|
||||
|> 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ public enum DeleteChannelError {
|
||||
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 transaction.getPeer(peerId).flatMap(apiInputChannel)
|
||||
}
|
@ -9,7 +9,7 @@ public enum ChannelHistoryAvailabilityError {
|
||||
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 transaction.getPeer(peerId)
|
||||
}
|
@ -21,7 +21,7 @@ public enum ChannelMembersCategory {
|
||||
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
|
||||
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
|
||||
let apiFilter: Api.ChannelParticipantsFilter
|
@ -21,7 +21,7 @@ public enum ChannelOwnershipTransferError {
|
||||
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 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 {
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
|> take(1)
|
||||
|> castError(JoinChannelError.self)
|
@ -9,7 +9,7 @@ public enum AvailableChannelDiscussionGroupError {
|
||||
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())
|
||||
|> mapError { error in
|
||||
return .generic
|
||||
@ -39,7 +39,7 @@ public enum ChannelDiscussionGroupError {
|
||||
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 (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
|
||||
if let cachedUserData = view.cachedData as? CachedUserData {
|
||||
if let botInfo = cachedUserData.botInfo {
|
@ -6,9 +6,9 @@ import MtProtoKit
|
||||
|
||||
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 {
|
||||
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
|
||||
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 transaction.getPeer(peerId)
|
||||
}
|
@ -4,6 +4,41 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
return peerParticipants(postbox: postbox, id: peerId)
|
||||
|> 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 {
|
||||
return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query)
|
||||
|> mapToSignal { local -> Signal<[Peer], NoError> in
|
||||
@ -40,7 +75,7 @@ public func searchGroupMembers(postbox: Postbox, network: Network, accountPeerId
|
||||
}
|
||||
return localResult
|
||||
|> 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
|
||||
var result: [Peer] = local
|
||||
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> {
|
||||
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
|
||||
|
||||
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
|
||||
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
|
@ -9,7 +9,7 @@ public enum UpdateGroupSpecificStickersetError {
|
||||
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)
|
||||
|> castError(UpdateGroupSpecificStickersetError.self)
|
||||
|> 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: {
|
||||
return ActiveSessionsContextImpl(account: account)
|
||||
})
|
||||
@ -218,7 +218,7 @@ public final class WebSessionsContext {
|
||||
|
||||
private let disposable = MetaDisposable()
|
||||
|
||||
public init(account: Account) {
|
||||
init(account: Account) {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.account = account
|
@ -3,7 +3,7 @@ import Postbox
|
||||
import TelegramApi
|
||||
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())
|
||||
|> retryRequest
|
||||
|> map { result -> [RecentAccountSession] in
|
||||
@ -23,7 +23,7 @@ public enum TerminateSessionError {
|
||||
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))
|
||||
|> mapError { error -> TerminateSessionError in
|
||||
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())
|
||||
|> mapError { error -> TerminateSessionError in
|
||||
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())
|
||||
|> retryRequest
|
||||
|> 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))
|
||||
|> retryRequest
|
||||
|> 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())
|
||||
|> retryRequest
|
||||
|> map { _ in }
|
@ -12,5 +12,33 @@ public extension TelegramEngine {
|
||||
public func requestUpdatePeerIsBlocked(peerId: PeerId, isBlocked: Bool) -> Signal<Void, NoError> {
|
||||
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
|
||||
|
||||
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 groupPrivacy = account.network.request(Api.functions.account.getPrivacy(key: .inputPrivacyKeyChatInvite))
|
||||
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(
|
||||
settings: .globalPrivacySettings(flags: 1 << 0, archiveAndMuteNewNoncontactPeers: value ? .boolTrue : .boolFalse)
|
||||
))
|
||||
@ -149,7 +148,7 @@ public func updateAccountAutoArchiveChats(account: Account, value: Bool) -> Sign
|
||||
|> 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))))
|
||||
|> retryRequest
|
||||
|> 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] = []
|
||||
if value {
|
||||
rules.append(.inputPrivacyValueAllowAll)
|
||||
@ -223,7 +222,7 @@ private func apiUserAndGroupIds(peerIds: [PeerId: SelectivePrivacyPeer]) -> (use
|
||||
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
|
||||
var rules: [Api.InputPrivacyRule] = []
|
||||
switch settings {
|
@ -59,6 +59,10 @@ public final class TelegramEngine {
|
||||
public lazy var historyImport: HistoryImport = {
|
||||
return HistoryImport(account: self.account)
|
||||
}()
|
||||
|
||||
public lazy var contacts: Contacts = {
|
||||
return Contacts(account: self.account)
|
||||
}()
|
||||
}
|
||||
|
||||
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