mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Privacy settings
This commit is contained in:
parent
5b7d4984ac
commit
eeba8a7db1
70 changed files with 2586 additions and 521 deletions
|
|
@ -20,6 +20,8 @@ import TelegramIntents
|
|||
import AnimationCache
|
||||
import MultiAnimationRenderer
|
||||
import ObjectiveC
|
||||
import PremiumUI
|
||||
import UndoUI
|
||||
|
||||
private var ObjCKey_DeinitWatcher: Int?
|
||||
|
||||
|
|
@ -356,6 +358,7 @@ public protocol ShareControllerAccountContext: AnyObject {
|
|||
var accountId: AccountRecordId { get }
|
||||
var accountPeerId: EnginePeer.Id { get }
|
||||
var stateManager: AccountStateManager { get }
|
||||
var engineData: TelegramEngine.EngineData { get }
|
||||
var animationCache: AnimationCache { get }
|
||||
var animationRenderer: MultiAnimationRenderer { get }
|
||||
var contentSettings: ContentSettings { get }
|
||||
|
|
@ -376,6 +379,9 @@ public final class ShareControllerAppAccountContext: ShareControllerAccountConte
|
|||
public var stateManager: AccountStateManager {
|
||||
return self.context.account.stateManager
|
||||
}
|
||||
public var engineData: TelegramEngine.EngineData {
|
||||
return self.context.engine.data
|
||||
}
|
||||
public var animationCache: AnimationCache {
|
||||
return self.context.animationCache
|
||||
}
|
||||
|
|
@ -446,7 +452,7 @@ public final class ShareController: ViewController {
|
|||
private let segmentedValues: [ShareControllerSegmentedValue]?
|
||||
private let fromForeignApp: Bool
|
||||
|
||||
private let peers = Promise<([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer)>()
|
||||
private let peers = Promise<([(peer: EngineRenderedPeer, presence: EnginePeer.Presence?, requiresPremiumForMessaging: Bool)], EnginePeer)>()
|
||||
private let peersDisposable = MetaDisposable()
|
||||
private let readyDisposable = MetaDisposable()
|
||||
private let accountActiveDisposable = MetaDisposable()
|
||||
|
|
@ -470,6 +476,8 @@ public final class ShareController: ViewController {
|
|||
|
||||
public var debugAction: (() -> Void)?
|
||||
|
||||
public var parentNavigationController: NavigationController?
|
||||
|
||||
public convenience init(context: AccountContext, subject: ShareControllerSubject, presetText: String? = nil, preferredAction: ShareControllerPreferredAction = .default, showInChat: ((Message) -> Void)? = nil, fromForeignApp: Bool = false, segmentedValues: [ShareControllerSegmentedValue]? = nil, externalShare: Bool = true, immediateExternalShare: Bool = false, switchableAccounts: [AccountWithInfo] = [], immediatePeerId: PeerId? = nil, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, forceTheme: PresentationTheme? = nil, forcedActionTitle: String? = nil, shareAsLink: Bool = false) {
|
||||
self.init(
|
||||
environment: ShareControllerAppEnvironment(sharedContext: context.sharedContext),
|
||||
|
|
@ -515,6 +523,7 @@ public final class ShareController: ViewController {
|
|||
super.init(navigationBarPresentationData: nil)
|
||||
|
||||
self.statusBar.statusBarStyle = .Ignore
|
||||
self.automaticallyControlPresentationContextLayout = false
|
||||
|
||||
switch subject {
|
||||
case let .url(text):
|
||||
|
|
@ -695,7 +704,7 @@ public final class ShareController: ViewController {
|
|||
fromPublicChannel = true
|
||||
}
|
||||
|
||||
self.displayNode = ShareControllerNode(environment: self.environment, presentationData: self.presentationData, presetText: self.presetText, defaultAction: self.defaultAction, requestLayout: { [weak self] transition in
|
||||
self.displayNode = ShareControllerNode(controller: self, environment: self.environment, presentationData: self.presentationData, presetText: self.presetText, defaultAction: self.defaultAction, requestLayout: { [weak self] transition in
|
||||
self?.requestLayout(transition: transition)
|
||||
}, presentError: { [weak self] title, text in
|
||||
guard let strongSelf = self else {
|
||||
|
|
@ -1197,6 +1206,31 @@ public final class ShareController: ViewController {
|
|||
strongSelf.view.endEditing(true)
|
||||
strongSelf.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}
|
||||
self.controllerNode.disabledPeerSelected = { [weak self] peer in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
self.forEachController { c in
|
||||
if let c = c as? UndoOverlayController {
|
||||
c.dismiss()
|
||||
}
|
||||
return true
|
||||
}
|
||||
//TODO:localize
|
||||
self.present(UndoOverlayController(presentationData: presentationData, content: .premiumPaywall(title: nil, text: "**\(peer.compactDisplayTitle)** only accepts messages from contacts and **Premium** users.", customUndoText: (self.environment is ShareControllerAppEnvironment) ? "View" : nil, timeout: nil, linkAction: { _ in
|
||||
}), elevatedLayout: false, animateInAsReplacement: false, action: { [weak self] action in
|
||||
guard let self, let parentNavigationController = self.parentNavigationController, let context = self.currentContext as? ShareControllerAppAccountContext else {
|
||||
return false
|
||||
}
|
||||
if case .undo = action {
|
||||
self.controllerNode.cancel?()
|
||||
let premiumController = PremiumIntroScreen(context: context.context, source: .settings)
|
||||
parentNavigationController.pushViewController(premiumController)
|
||||
}
|
||||
return false
|
||||
}), in: .current)
|
||||
}
|
||||
self.controllerNode.debugAction = { [weak self] in
|
||||
self?.debugAction?()
|
||||
}
|
||||
|
|
@ -2416,36 +2450,56 @@ public final class ShareController: ViewController {
|
|||
peer,
|
||||
tailChatList |> take(1)
|
||||
)
|
||||
|> mapToSignal { maybeAccountPeer, view -> Signal<([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer), NoError> in
|
||||
|> mapToSignal { maybeAccountPeer, view -> Signal<([(peer: EngineRenderedPeer, presence: EnginePeer.Presence?, requiresPremiumForMessaging: Bool)], EnginePeer), NoError> in
|
||||
let accountPeer = maybeAccountPeer!
|
||||
|
||||
var peers: [EngineRenderedPeer] = []
|
||||
var possiblePremiumRequiredPeers = Set<EnginePeer.Id>()
|
||||
for entry in view.0.entries.reversed() {
|
||||
switch entry {
|
||||
case let .MessageEntry(entryData):
|
||||
if let peer = entryData.renderedPeer.peers[entryData.renderedPeer.peerId], peer.id != accountPeer.id, canSendMessagesToPeer(peer) {
|
||||
peers.append(EngineRenderedPeer(entryData.renderedPeer))
|
||||
case let .MessageEntry(entryData):
|
||||
if let peer = entryData.renderedPeer.peers[entryData.renderedPeer.peerId], peer.id != accountPeer.id, canSendMessagesToPeer(peer) {
|
||||
peers.append(EngineRenderedPeer(entryData.renderedPeer))
|
||||
if let user = peer as? TelegramUser, user.flags.contains(.requirePremium) {
|
||||
possiblePremiumRequiredPeers.insert(user.id)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let key = PostboxViewKey.peerPresences(peerIds: Set(peers.map(\.peerId)))
|
||||
return account.stateManager.postbox.combinedView(keys: [key])
|
||||
|> map { views -> [EnginePeer.Id: EnginePeer.Presence?] in
|
||||
let peerPresencesKey = PostboxViewKey.peerPresences(peerIds: Set(peers.map(\.peerId)))
|
||||
|
||||
var keys: [PostboxViewKey] = []
|
||||
keys.append(peerPresencesKey)
|
||||
|
||||
for id in possiblePremiumRequiredPeers {
|
||||
keys.append(.cachedPeerData(peerId: id))
|
||||
}
|
||||
|
||||
return account.stateManager.postbox.combinedView(keys: keys)
|
||||
|> map { views -> ([EnginePeer.Id: EnginePeer.Presence?], [EnginePeer.Id: Bool]) in
|
||||
var result: [EnginePeer.Id: EnginePeer.Presence?] = [:]
|
||||
if let view = views.views[key] as? PeerPresencesView {
|
||||
if let view = views.views[peerPresencesKey] as? PeerPresencesView {
|
||||
result = view.presences.mapValues { value -> EnginePeer.Presence? in
|
||||
return EnginePeer.Presence(value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
var requiresPremiumForMessaging: [EnginePeer.Id: Bool] = [:]
|
||||
for id in possiblePremiumRequiredPeers {
|
||||
if let view = views.views[.cachedPeerData(peerId: id)] as? CachedPeerDataView, let data = view.cachedPeerData as? CachedUserData {
|
||||
requiresPremiumForMessaging[id] = data.flags.contains(.premiumRequired)
|
||||
} else {
|
||||
requiresPremiumForMessaging[id] = false
|
||||
}
|
||||
}
|
||||
return (result, requiresPremiumForMessaging)
|
||||
}
|
||||
|> map { presenceMap -> ([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer) in
|
||||
var resultPeers: [(EngineRenderedPeer, EnginePeer.Presence?)] = []
|
||||
|> map { presenceMap, requiresPremiumForMessaging -> ([(peer: EngineRenderedPeer, presence: EnginePeer.Presence?, requiresPremiumForMessaging: Bool)], EnginePeer) in
|
||||
var resultPeers: [(peer: EngineRenderedPeer, presence: EnginePeer.Presence?, requiresPremiumForMessaging: Bool)] = []
|
||||
for peer in peers {
|
||||
resultPeers.append((peer, presenceMap[peer.peerId].flatMap { $0 }))
|
||||
resultPeers.append((peer, presenceMap[peer.peerId].flatMap { $0 }, requiresPremiumForMessaging[peer.peerId] ?? false))
|
||||
}
|
||||
return (resultPeers, accountPeer)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue