Refactoring

This commit is contained in:
Ali 2022-05-28 18:26:23 +04:00
parent 3edd84cf95
commit e8d124c812
62 changed files with 1459 additions and 993 deletions

View File

@ -1,39 +0,0 @@
import TelegramCore
public struct VideoCallsConfiguration: Equatable {
public enum VideoCallsSupport {
case disabled
case full
case onlyVideo
}
public var videoCallsSupport: VideoCallsSupport
public init(appConfiguration: AppConfiguration) {
var videoCallsSupport: VideoCallsSupport = .full
if let data = appConfiguration.data, let value = data["video_calls_support"] as? String {
switch value {
case "disabled":
videoCallsSupport = .disabled
case "full":
videoCallsSupport = .full
case "only_video":
videoCallsSupport = .onlyVideo
default:
videoCallsSupport = .full
}
}
self.videoCallsSupport = videoCallsSupport
}
}
public extension VideoCallsConfiguration {
var areVideoCallsEnabled: Bool {
switch self.videoCallsSupport {
case .disabled:
return false
case .full, .onlyVideo:
return true
}
}
}

View File

@ -51,20 +51,18 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
let strings = presentationData.strings
return combineLatest(
context.account.postbox.transaction { transaction -> (PeerGroupId, ChatListIndex)? in
transaction.getPeerChatListIndex(peerId)
},
context.engine.data.get(TelegramEngine.EngineData.Item.Messages.ChatListGroup(id: peerId)),
context.engine.peers.recentlySearchedPeers() |> take(1)
)
|> mapToSignal { groupAndIndex, recentlySearchedPeers -> Signal<[ContextMenuItem], NoError> in
|> mapToSignal { peerGroup, recentlySearchedPeers -> Signal<[ContextMenuItem], NoError> in
let location: TogglePeerChatPinnedLocation
var chatListFilter: ChatListFilter?
if case let .chatList(filter) = source, let chatFilter = filter {
chatListFilter = chatFilter
location = .filter(chatFilter.id)
} else {
if let (group, _) = groupAndIndex {
location = .group(group)
if let peerGroup = peerGroup {
location = .group(peerGroup._asGroup())
} else {
location = .group(.root)
}
@ -292,9 +290,9 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
}
let archiveEnabled = !isSavedMessages && peerId != PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(777000)) && peerId == context.account.peerId
if let (group, _) = groupAndIndex {
if let group = peerGroup {
if archiveEnabled {
let isArchived = group == Namespaces.PeerGroup.archive
let isArchived = group == .archive
items.append(.action(ContextMenuActionItem(text: isArchived ? strings.ChatList_Context_Unarchive : strings.ChatList_Context_Archive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isArchived ? "Chat/Context Menu/Unarchive" : "Chat/Context Menu/Archive"), color: theme.contextMenu.primaryColor) }, action: { _, f in
if isArchived {
let _ = (context.account.postbox.transaction { transaction -> Void in
@ -412,7 +410,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
}
}
if case .chatList = source, groupAndIndex != nil {
if case .chatList = source, peerGroup != nil {
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { _, f in
if let chatListController = chatListController {
chatListController.deletePeerChat(peerId: peerId, joined: joined)

View File

@ -1268,7 +1268,7 @@ public final class ChatListNode: ListView {
}
self.setChatListLocation(initialLocation)
let postbox = context.account.postbox
let engine = context.engine
let previousPeerCache = Atomic<[EnginePeer.Id: EnginePeer]>(value: [:])
let previousActivities = Atomic<ChatListNodePeerInputActivities?>(value: nil)
self.activityStatusesDisposable = (context.account.allPeerInputActivities()
@ -1295,7 +1295,18 @@ public final class ChatListNode: ListView {
if foundAllPeers {
return .single(cachedResult)
} else {
return postbox.transaction { transaction -> [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] in
return engine.data.get(EngineDataMap(
activitiesByPeerId.keys.filter { key in
if case .global = key.category {
return false
} else {
return true
}
}.map { key in
return TelegramEngine.EngineData.Item.Peer.Peer(id: key.peerId)
}
))
|> map { peerMap -> [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] in
var result: [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] = [:]
var peerCache: [EnginePeer.Id: EnginePeer] = [:]
for (chatPeerId, activities) in activitiesByPeerId {
@ -1305,9 +1316,9 @@ public final class ChatListNode: ListView {
var chatResult: [(EnginePeer, PeerInputActivity)] = []
for (peerId, activity) in activities {
if let peer = transaction.getPeer(peerId) {
chatResult.append((EnginePeer(peer), activity))
peerCache[peerId] = EnginePeer(peer)
if let maybePeer = peerMap[peerId], let peer = maybePeer {
chatResult.append((peer, activity))
peerCache[peerId] = peer
}
}
@ -2012,13 +2023,14 @@ public final class ChatListNode: ListView {
} else {
position = .later(than: nil)
}
let postbox = self.context.account.postbox
let engine = self.context.engine
let _ = (relativeUnreadChatListIndex(position: position)
|> mapToSignal { index -> Signal<(EngineChatList.Item.Index, EnginePeer)?, NoError> in
if let index = index {
return postbox.transaction { transaction -> (EngineChatList.Item.Index, EnginePeer)? in
return transaction.getPeer(index.messageIndex.id.peerId).flatMap { peer -> (EngineChatList.Item.Index, EnginePeer)? in
(index, EnginePeer(peer))
return engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: index.messageIndex.id.peerId))
|> map { peer -> (EngineChatList.Item.Index, EnginePeer)? in
return peer.flatMap { peer -> (EngineChatList.Item.Index, EnginePeer)? in
(index, peer)
}
}
} else {
@ -2058,9 +2070,7 @@ public final class ChatListNode: ListView {
self.peerSelected?(target.1, false, false, nil)
}
case let .peerId(peerId):
let _ = (self.context.account.postbox.transaction { transaction -> EnginePeer? in
return transaction.getPeer(peerId).flatMap(EnginePeer.init)
}
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let strongSelf = self, let peer = peer else {
return

View File

@ -12,11 +12,15 @@ import LocalizedPeerData
func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, contactsController: ContactsController?) -> Signal<[ContextMenuItem], NoError> {
let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings
return context.account.postbox.transaction { [weak contactsController] transaction -> [ContextMenuItem] in
return context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.AreVoiceCallsAvailable(id: peerId),
TelegramEngine.EngineData.Item.Peer.AreVideoCallsAvailable(id: peerId)
)
|> map { [weak contactsController] peer, areVoiceCallsAvailable, areVideoCallsAvailable -> [ContextMenuItem] in
var items: [ContextMenuItem] = []
let peer = transaction.getPeer(peerId)
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_SendMessage, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Message"), color: theme.contextMenu.primaryColor) }, action: { _, f in
if let contactsController = contactsController, let navigationController = contactsController.navigationController as? NavigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), peekData: nil))
@ -25,34 +29,13 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
})))
var canStartSecretChat = true
if let user = peer as? TelegramUser, user.flags.contains(.isSupport) {
if case let .user(user) = peer, user.flags.contains(.isSupport) {
canStartSecretChat = false
}
if canStartSecretChat {
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_StartSecretChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Timer"), color: theme.contextMenu.primaryColor) }, action: { _, f in
let _ = (context.account.postbox.transaction { transaction -> EnginePeer.Id? in
let filteredPeerIds = Array(transaction.getAssociatedPeerIds(peerId)).filter { $0.namespace == Namespaces.Peer.SecretChat }
var activeIndices: [EngineChatList.Item.Index] = []
for associatedId in filteredPeerIds {
if let state = (transaction.getPeer(associatedId) as? TelegramSecretChat)?.embeddedState {
switch state {
case .active, .handshake:
if let (_, index) = transaction.getPeerChatListIndex(associatedId) {
activeIndices.append(index)
}
default:
break
}
}
}
activeIndices.sort()
if let index = activeIndices.last {
return index.messageIndex.id.peerId
} else {
return nil
}
}
let _ = (context.engine.peers.mostRecentSecretChat(id: peerId)
|> deliverOnMainQueue).start(next: { currentPeerId in
if let currentPeerId = currentPeerId {
if let contactsController = contactsController, let navigationController = (contactsController.navigationController as? NavigationController) {
@ -113,15 +96,13 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
}
var canCall = true
if let user = peer as? TelegramUser, let cachedUserData = transaction.getPeerCachedData(peerId: peerId) as? CachedUserData, user.flags.contains(.isSupport) || cachedUserData.callsPrivate {
if case let .user(user) = peer, (user.flags.contains(.isSupport) || !areVoiceCallsAvailable) {
canCall = false
}
var canVideoCall = false
if canCall {
if let cachedUserData = transaction.getPeerCachedData(peerId: peerId) as? CachedUserData {
if cachedUserData.videoCallsAvailable {
canVideoCall = true
}
if areVideoCallsAvailable {
canVideoCall = true
}
}

View File

@ -1070,17 +1070,22 @@ public final class ContactListNode: ASDisplayNode {
resultPeers.append(FoundPeer(peer: mainPeer, subscribers: nil))
}
}
return context.account.postbox.transaction { transaction -> ([FoundPeer], [EnginePeer.Id: EnginePeer.Presence]) in
return context.engine.data.get(
EngineDataMap(resultPeers.map(\.peer.id).map(TelegramEngine.EngineData.Item.Peer.Presence.init)),
EngineDataMap(resultPeers.map(\.peer.id).map(TelegramEngine.EngineData.Item.Peer.ParticipantCount.init))
)
|> map { presenceMap, participantCountMap -> ([FoundPeer], [EnginePeer.Id: EnginePeer.Presence]) in
var resultPresences: [EnginePeer.Id: EnginePeer.Presence] = [:]
var mappedPeers: [FoundPeer] = []
for peer in resultPeers {
if let presence = transaction.getPeerPresence(peerId: peer.peer.id) {
resultPresences[peer.peer.id] = EnginePeer.Presence(presence)
if let maybePresence = presenceMap[peer.peer.id], let presence = maybePresence {
resultPresences[peer.peer.id] = presence
}
if let _ = peer.peer as? TelegramChannel {
var subscribers: Int32?
if let cachedData = transaction.getPeerCachedData(peerId: peer.peer.id) as? CachedChannelData {
subscribers = cachedData.participantsSummary.memberCount
if let maybeMemberCount = participantCountMap[peer.peer.id], let memberCount = maybeMemberCount {
subscribers = Int32(memberCount)
}
mappedPeers.append(FoundPeer(peer: peer.peer, subscribers: subscribers))
} else {
@ -1257,24 +1262,39 @@ public final class ContactListNode: ASDisplayNode {
chatListSignal = self.context.account.viewTracker.tailChatListView(groupId: .root, count: 100)
|> take(1)
|> mapToSignal { view, _ -> Signal<[(EnginePeer, Int32)], NoError> in
return context.account.postbox.transaction { transaction -> [(EnginePeer, Int32)] in
return context.engine.data.get(EngineDataMap(
view.entries.compactMap { entry -> EnginePeer.Id? in
switch entry {
case let .MessageEntry(_, _, _, _, _, renderedPeer, _, _, _, _):
if let peer = renderedPeer.peer {
if let channel = peer as? TelegramChannel, case .group = channel.info {
return peer.id
}
}
default:
break
}
return nil
}.map(TelegramEngine.EngineData.Item.Peer.ParticipantCount.init)
))
|> map { participantCountMap -> [(EnginePeer, Int32)] in
var peers: [(EnginePeer, Int32)] = []
for entry in view.entries {
switch entry {
case let .MessageEntry(_, _, _, _, _, renderedPeer, _, _, _, _):
if let peer = renderedPeer.peer {
if peer is TelegramGroup {
peers.append((EnginePeer(peer), 0))
} else if let channel = peer as? TelegramChannel, case .group = channel.info {
var memberCount: Int32 = 0
if let cachedData = transaction.getPeerCachedData(peerId: peer.id) as? CachedChannelData {
memberCount = cachedData.participantsSummary.memberCount ?? 0
}
peers.append((EnginePeer(peer), memberCount))
case let .MessageEntry(_, _, _, _, _, renderedPeer, _, _, _, _):
if let peer = renderedPeer.peer {
if peer is TelegramGroup {
peers.append((EnginePeer(peer), 0))
} else if let channel = peer as? TelegramChannel, case .group = channel.info {
var memberCount: Int32 = 0
if let maybeParticipantCount = participantCountMap[peer.id], let participantCount = maybeParticipantCount {
memberCount = Int32(participantCount)
}
peers.append((EnginePeer(peer), memberCount))
}
default:
break
}
default:
break
}
}
return peers

View File

@ -1275,16 +1275,14 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
}
shareController.completed = { [weak self] peerIds in
if let strongSelf = self {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { [weak self] peers in
let _ = (strongSelf.context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { [weak self] peerList in
if let strongSelf = self {
let peers = peerList.compactMap { $0 }
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
@ -1294,14 +1292,14 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(peers.count - 1)").string
} else {
text = ""
@ -1345,16 +1343,14 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
}
shareController.completed = { [weak self] peerIds in
if let strongSelf = self {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { [weak self] peers in
let _ = (strongSelf.context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { [weak self] peerList in
if let strongSelf = self {
let peers = peerList.compactMap { $0 }
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
@ -1364,14 +1360,14 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(peers.count - 1)").string
} else {
text = ""
@ -1472,16 +1468,14 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
}
shareController.completed = { [weak self] peerIds in
if let strongSelf = self {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { [weak self] peers in
let _ = (strongSelf.context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { [weak self] peerList in
if let strongSelf = self {
let peers = peerList.compactMap { $0 }
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
@ -1491,14 +1485,14 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
} else {
text = ""

View File

@ -436,16 +436,14 @@ public final class InviteLinkInviteController: ViewController {
let shareController = ShareController(context: context, subject: .url(inviteLink), updatedPresentationData: updatedPresentationData)
shareController.completed = { [weak self] peerIds in
if let strongSelf = self {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { [weak self] peers in
let _ = (strongSelf.context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { [weak self] peerList in
if let strongSelf = self {
let peers = peerList.compactMap { $0 }
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
@ -455,14 +453,14 @@ public final class InviteLinkInviteController: ViewController {
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_Chat_One(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
} else {
text = ""

View File

@ -434,15 +434,13 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
}
let shareController = ShareController(context: context, subject: .url(inviteLink), updatedPresentationData: updatedPresentationData)
shareController.completed = { peerIds in
let _ = (context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { peers in
let _ = (context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { peerList in
let peers = peerList.compactMap { $0 }
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let text: String
@ -452,14 +450,14 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_Chat_One(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
} else {
text = ""
@ -638,15 +636,13 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
let shareController = ShareController(context: context, subject: .url(inviteLink), updatedPresentationData: updatedPresentationData)
shareController.completed = { peerIds in
let _ = (context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { peers in
let _ = (context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { peerList in
let peers = peerList.compactMap { $0 }
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let text: String
@ -656,14 +652,14 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_Chat_One(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
} else {
text = ""

View File

@ -489,16 +489,14 @@ public final class InviteLinkViewController: ViewController {
let shareController = ShareController(context: context, subject: .url(inviteLink))
shareController.completed = { [weak self] peerIds in
if let strongSelf = self {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { [weak self] peers in
let _ = (strongSelf.context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { [weak self] peerList in
if let strongSelf = self {
let peers = peerList.compactMap { $0 }
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
@ -508,14 +506,14 @@ public final class InviteLinkViewController: ViewController {
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_Chat_One(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.InviteLink_InviteLinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
} else {
text = ""

View File

@ -348,9 +348,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
let previousEntries = Atomic<[LocationViewEntry]?>(value: nil)
let previousHadTravelTimes = Atomic<Bool>(value: false)
let selfPeer = context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(context.account.peerId)
}
let selfPeer = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
self.disposable = (combineLatest(self.presentationDataPromise.get(), self.statePromise.get(), selfPeer, liveLocations, self.headerNode.mapNode.userLocation, userLocation, address, eta, self.travelTimesPromise.get())
|> deliverOnMainQueue).start(next: { [weak self] presentationData, state, selfPeer, liveLocations, userLocation, distance, address, eta, travelTimes in
@ -462,7 +460,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
let timestamp = CACurrentMediaTime()
if message.localTags.contains(.OutgoingLiveLocation), let selfPeer = selfPeer {
userAnnotation = LocationPinAnnotation(context: context, theme: presentationData.theme, message: message, selfPeer: selfPeer, isSelf: true, heading: location.heading)
userAnnotation = LocationPinAnnotation(context: context, theme: presentationData.theme, message: message, selfPeer: selfPeer._asPeer(), isSelf: true, heading: location.heading)
} else {
var drivingTime: ExpectedTravelTime = .unknown
var transitTime: ExpectedTravelTime = .unknown
@ -517,7 +515,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
}
}
annotations.append(LocationPinAnnotation(context: context, theme: presentationData.theme, message: message, selfPeer: selfPeer, isSelf: message.author?.id == context.account.peerId, heading: location.heading))
annotations.append(LocationPinAnnotation(context: context, theme: presentationData.theme, message: message, selfPeer: selfPeer?._asPeer(), isSelf: message.author?.id == context.account.peerId, heading: location.heading))
entries.append(.liveLocation(presentationData.theme, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, message, distance, drivingTime, transitTime, walkingTime, index))
}
index += 1

View File

@ -216,16 +216,19 @@ public final class SecureIdAuthController: ViewController, StandalonePresentable
case let .form(peerId, scope, publicKey, callbackUrl, _, _):
self.formDisposable = (combineLatest(requestSecureIdForm(postbox: context.account.postbox, network: context.account.network, peerId: peerId, scope: scope, publicKey: publicKey), secureIdConfiguration(postbox: context.account.postbox, network: context.account.network) |> castError(RequestSecureIdFormError.self))
|> mapToSignal { form, configuration -> Signal<SecureIdEncryptedFormData, RequestSecureIdFormError> in
return context.account.postbox.transaction { transaction -> Signal<SecureIdEncryptedFormData, RequestSecureIdFormError> in
guard let accountPeer = transaction.getPeer(context.account.peerId), let servicePeer = transaction.getPeer(form.peerId) else {
return context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: form.peerId)
)
|> castError(RequestSecureIdFormError.self)
|> mapToSignal { accountPeer, servicePeer -> Signal<SecureIdEncryptedFormData, RequestSecureIdFormError> in
guard let accountPeer = accountPeer, let servicePeer = servicePeer else {
return .fail(.generic)
}
let primaryLanguageByCountry = configuration.nativeLanguageByCountry
return .single(SecureIdEncryptedFormData(form: form, primaryLanguageByCountry: primaryLanguageByCountry, accountPeer: accountPeer, servicePeer: servicePeer))
return .single(SecureIdEncryptedFormData(form: form, primaryLanguageByCountry: primaryLanguageByCountry, accountPeer: accountPeer._asPeer(), servicePeer: servicePeer._asPeer()))
}
|> castError(RequestSecureIdFormError.self)
|> switchToLatest
}
|> deliverOnMainQueue).start(next: { [weak self] formData in
if let strongSelf = self {
@ -245,15 +248,16 @@ public final class SecureIdAuthController: ViewController, StandalonePresentable
handleError(error, callbackUrl, peerId)
})
case .list:
self.formDisposable = (combineLatest(getAllSecureIdValues(network: self.context.account.network), secureIdConfiguration(postbox: context.account.postbox, network: context.account.network) |> castError(GetAllSecureIdValuesError.self), context.account.postbox.transaction { transaction -> Signal<Peer, GetAllSecureIdValuesError> in
guard let accountPeer = transaction.getPeer(context.account.peerId) else {
return .fail(.generic)
self.formDisposable = (combineLatest(
getAllSecureIdValues(network: self.context.account.network),
secureIdConfiguration(postbox: context.account.postbox, network: context.account.network) |> castError(GetAllSecureIdValuesError.self),
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)) |> castError(GetAllSecureIdValuesError.self) |> mapToSignal { accountPeer -> Signal<EnginePeer, GetAllSecureIdValuesError> in
guard let accountPeer = accountPeer else {
return .fail(.generic)
}
return .single(accountPeer)
}
return .single(accountPeer)
}
|> castError(GetAllSecureIdValuesError.self)
|> switchToLatest)
)
|> deliverOnMainQueue).start(next: { [weak self] values, configuration, accountPeer in
if let strongSelf = self {
strongSelf.updateState { state in
@ -261,13 +265,13 @@ public final class SecureIdAuthController: ViewController, StandalonePresentable
let primaryLanguageByCountry = configuration.nativeLanguageByCountry
switch state {
case .form:
break
case var .list(list):
list.accountPeer = accountPeer
list.primaryLanguageByCountry = primaryLanguageByCountry
list.encryptedValues = values
return .list(list)
case .form:
break
case var .list(list):
list.accountPeer = accountPeer._asPeer()
list.primaryLanguageByCountry = primaryLanguageByCountry
list.encryptedValues = values
return .list(list)
}
return state
}

View File

@ -27,7 +27,7 @@ public func peerInfoProfilePhotos(context: AccountContext, peerId: PeerId) -> Si
guard let peer = (view.views[.basicPeer(peerId)] as? BasicPeerView)?.peer else {
return .single(nil)
}
return initialAvatarGalleryEntries(account: context.account, peer: peer)
return initialAvatarGalleryEntries(account: context.account, engine: context.engine, peer: peer)
}
|> distinctUntilChanged
|> mapToSignal { entries -> Signal<(Bool, [AvatarGalleryEntry])?, NoError> in
@ -176,22 +176,18 @@ public func normalizeEntries(_ entries: [AvatarGalleryEntry]) -> [AvatarGalleryE
return updatedEntries
}
public func initialAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<[AvatarGalleryEntry]?, NoError> {
public func initialAvatarGalleryEntries(account: Account, engine: TelegramEngine, peer: Peer) -> Signal<[AvatarGalleryEntry]?, NoError> {
var initialEntries: [AvatarGalleryEntry] = []
if !peer.profileImageRepresentations.isEmpty, let peerReference = PeerReference(peer) {
initialEntries.append(.topImage(peer.profileImageRepresentations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatar(peer: peerReference, resource: $0.resource)) }), [], peer, nil, nil, nil))
}
if peer is TelegramChannel || peer is TelegramGroup, let peerReference = PeerReference(peer) {
return account.postbox.transaction { transaction in
return transaction.getPeerCachedData(peerId: peer.id)
} |> map { cachedData in
return engine.data.get(TelegramEngine.EngineData.Item.Peer.Photo(id: peer.id))
|> map { peerPhoto in
var initialPhoto: TelegramMediaImage?
if let cachedData = cachedData as? CachedGroupData, let photo = cachedData.photo {
initialPhoto = photo
}
else if let cachedData = cachedData as? CachedChannelData, let photo = cachedData.photo {
initialPhoto = photo
if case let .known(value) = peerPhoto {
initialPhoto = value
}
if let photo = initialPhoto {
@ -201,7 +197,11 @@ public func initialAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<
}
return [.image(photo.imageId, photo.reference, representations, photo.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, nil, nil, nil, photo.immediateThumbnailData, nil)]
} else {
return cachedData != nil ? [] : nil
if case .known = peerPhoto {
return []
} else {
return nil
}
}
}
} else {
@ -210,7 +210,7 @@ public func initialAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<
}
public func fetchedAvatarGalleryEntries(engine: TelegramEngine, account: Account, peer: Peer) -> Signal<[AvatarGalleryEntry], NoError> {
return initialAvatarGalleryEntries(account: account, peer: peer)
return initialAvatarGalleryEntries(account: account, engine: engine, peer: peer)
|> map { entries -> [AvatarGalleryEntry] in
return entries ?? []
}
@ -405,7 +405,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
remoteEntriesSignal = fetchedAvatarGalleryEntries(engine: context.engine, account: context.account, peer: peer)
}
let initialSignal = initialAvatarGalleryEntries(account: context.account, peer: peer)
let initialSignal = initialAvatarGalleryEntries(account: context.account, engine: context.engine, peer: peer)
|> map { entries -> [AvatarGalleryEntry] in
return entries ?? []
}

View File

@ -859,19 +859,20 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
return current.withUpdatedUpdatedFlags(updated)
}
}, toggleRightWhileDisabled: { right, _ in
let _ = (context.account.postbox.transaction { transaction -> (peer: Peer?, member: Peer?) in
return (peer: transaction.getPeer(peerId), member: transaction.getPeer(adminId))
}
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: adminId)
)
|> deliverOnMainQueue).start(next: { peer, member in
guard let peer = peer, let _ = member as? TelegramUser else {
guard let peer = peer, case .user = member else {
return
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let text: String
if !canEditAdminRights(accountPeerId: context.account.peerId, channelPeer: peer, initialParticipant: initialParticipant) {
if !canEditAdminRights(accountPeerId: context.account.peerId, channelPeer: peer._asPeer(), initialParticipant: initialParticipant) {
text = presentationData.strings.Channel_EditAdmin_CannotEdit
} else if rightEnabledByDefault(channelPeer: peer, right: right) {
} else if rightEnabledByDefault(channelPeer: peer._asPeer(), right: right) {
text = presentationData.strings.Channel_EditAdmin_PermissionEnabledByDefault
} else {
text = presentationData.strings.Channel_EditAdmin_CannotEdit
@ -880,15 +881,17 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
})
}, transferOwnership: {
let _ = (context.account.postbox.transaction { transaction -> (peer: Peer?, member: Peer?) in
return (peer: transaction.getPeer(peerId), member: transaction.getPeer(adminId))
} |> deliverOnMainQueue).start(next: { peer, member in
guard let peer = peer, let member = member as? TelegramUser else {
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: adminId)
)
|> deliverOnMainQueue).start(next: { peer, member in
guard let peer = peer, case let .user(member) = member else {
return
}
transferOwnershipDisposable.set((context.engine.peers.checkOwnershipTranfserAvailability(memberId: adminId) |> deliverOnMainQueue).start(error: { error in
let controller = channelOwnershipTransferController(context: context, updatedPresentationData: updatedPresentationData, peer: peer, member: member, initialError: error, present: { c, a in
let controller = channelOwnershipTransferController(context: context, updatedPresentationData: updatedPresentationData, peer: peer._asPeer(), member: member, initialError: error, present: { c, a in
presentControllerImpl?(c, a)
}, completion: { upgradedPeerId in
if let upgradedPeerId = upgradedPeerId {

View File

@ -508,15 +508,16 @@ public func channelAdminsController(context: AccountContext, updatedPresentation
let _ = (currentPeerId.get()
|> take(1)
|> mapToSignal { peerId in
context.account.postbox.transaction { transaction -> (channel: Peer?, user: Peer?) in
return (channel: transaction.getPeer(peerId), user: transaction.getPeer(memberId))
}
return context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: memberId)
)
}
|> deliverOnMainQueue).start(next: { peer, user in
guard let peer = peer, let user = user else {
return
}
presentControllerImpl?(UndoOverlayController(presentationData: context.sharedContext.currentPresentationData.with { $0 }, content: .succeed(text: presentationData.strings.Channel_OwnershipTransfer_TransferCompleted(EnginePeer(user).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string), elevatedLayout: false, action: { _ in return false }), nil)
presentControllerImpl?(UndoOverlayController(presentationData: context.sharedContext.currentPresentationData.with { $0 }, content: .succeed(text: presentationData.strings.Channel_OwnershipTransfer_TransferCompleted(user.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string), elevatedLayout: false, action: { _ in return false }), nil)
})
}

View File

@ -250,15 +250,13 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
actionsDisposable.add(applyGroupDisposable)
let arguments = ChannelDiscussionGroupSetupControllerArguments(context: context, createGroup: {
let _ = (context.account.postbox.transaction { transaction -> Peer? in
transaction.getPeer(peerId)
}
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
guard let peer = peer else {
return
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
pushControllerImpl?(context.sharedContext.makeCreateGroupController(context: context, peerIds: [], initialTitle: EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) + " Chat", mode: .supergroup, completion: { groupId, dismiss in
pushControllerImpl?(context.sharedContext.makeCreateGroupController(context: context, peerIds: [], initialTitle: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) + " Chat", mode: .supergroup, completion: { groupId, dismiss in
var applySignal = context.engine.peers.updateGroupDiscussionForChannel(channelId: peerId, groupId: groupId)
var cancelImpl: (() -> Void)?
let progressSignal = Signal<Never, NoError> { subscriber in
@ -294,24 +292,23 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
dismiss()
}, completed: {
dismiss()
/*let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = OverlayStatusController(theme: presentationData.theme, type: .success)
presentControllerImpl?(controller, nil)*/
}))
}))
})
}, selectGroup: { groupId in
dismissInputImpl?()
let _ = (context.account.postbox.transaction { transaction -> (CachedChannelData?, Peer?, Peer?) in
return (transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, transaction.getPeer(peerId), transaction.getPeer(groupId))
}
|> deliverOnMainQueue).start(next: { cachedData, channelPeer, groupPeer in
guard let cachedData = cachedData, let channelPeer = channelPeer, let groupPeer = groupPeer else {
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.LinkedDiscussionPeerId(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: groupId)
)
|> deliverOnMainQueue).start(next: { linkedDiscussionPeerId, channelPeer, groupPeer in
guard let channelPeer = channelPeer, let groupPeer = groupPeer else {
return
}
if case let .known(maybeLinkedDiscussionPeerId) = cachedData.linkedDiscussionPeerId, maybeLinkedDiscussionPeerId == groupId {
if case let .known(maybeLinkedDiscussionPeerId) = linkedDiscussionPeerId, maybeLinkedDiscussionPeerId == groupId {
navigateToGroupImpl?(groupId)
return
}
@ -319,13 +316,13 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationData: presentationData)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ChannelDiscussionGroupActionSheetItem(context: context, channelPeer: channelPeer, groupPeer: groupPeer, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder),
ChannelDiscussionGroupActionSheetItem(context: context, channelPeer: channelPeer._asPeer(), groupPeer: groupPeer._asPeer(), strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder),
ActionSheetButtonItem(title: presentationData.strings.Channel_DiscussionGroup_LinkGroup, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
var applySignal: Signal<Bool, ChannelDiscussionGroupError>
var updatedPeerId: PeerId? = nil
if let legacyGroup = groupPeer as? TelegramGroup {
if case let .legacyGroup(legacyGroup) = groupPeer {
applySignal = context.engine.peers.convertGroupToSupergroup(peerId: legacyGroup.id)
|> mapError { error -> ChannelDiscussionGroupError in
switch error {
@ -339,8 +336,10 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
|> mapToSignal { resultPeerId -> Signal<Bool, ChannelDiscussionGroupError> in
updatedPeerId = resultPeerId
return context.account.postbox.transaction { transaction -> Signal<Bool, ChannelDiscussionGroupError> in
if let groupPeer = transaction.getPeer(resultPeerId) {
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: resultPeerId))
|> castError(ChannelDiscussionGroupError.self)
|> mapToSignal { groupPeer -> Signal<Bool, ChannelDiscussionGroupError> in
if let groupPeer = groupPeer {
let _ = (groupPeers.get()
|> take(1)
|> deliverOnMainQueue).start(next: { groups in
@ -349,7 +348,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
}
for i in 0 ..< groups.count {
if groups[i].id == groupId {
groups[i] = groupPeer
groups[i] = groupPeer._asPeer()
break
}
}
@ -359,8 +358,6 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
return context.engine.peers.updateGroupDiscussionForChannel(channelId: peerId, groupId: resultPeerId)
}
|> castError(ChannelDiscussionGroupError.self)
|> switchToLatest
}
} else {
applySignal = context.engine.peers.updateGroupDiscussionForChannel(channelId: peerId, groupId: groupId)
@ -481,18 +478,19 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
presentControllerImpl?(actionSheet, nil)
})
}, unlinkGroup: {
let _ = (context.account.postbox.transaction { transaction -> (CachedChannelData?, Peer?) in
return (transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, transaction.getPeer(peerId))
}
|> deliverOnMainQueue).start(next: { cachedData, peer in
guard let cachedData = cachedData, let peer = peer as? TelegramChannel else {
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.LinkedDiscussionPeerId(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> deliverOnMainQueue).start(next: { linkedDiscussionPeerId, peer in
guard case let .channel(peer) = peer else {
return
}
let applyPeerId: PeerId
if case .broadcast = peer.info {
applyPeerId = peerId
} else if case let .known(maybeLinkedDiscussionPeerId) = cachedData.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId {
} else if case let .known(maybeLinkedDiscussionPeerId) = linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId {
applyPeerId = linkedDiscussionPeerId
} else {
return

View File

@ -434,9 +434,7 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
}
}).start(error: { [weak contactsController] error in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let _ = (context.account.postbox.transaction { transaction in
return transaction.getPeer(peerId)
}
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
let text: String
switch error {
@ -449,13 +447,13 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
case .restricted:
text = presentationData.strings.Channel_ErrorAddBlocked
case .notMutualContact:
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
if case let .channel(peer) = peer, case .broadcast = peer.info {
text = presentationData.strings.Channel_AddUserLeftError
} else {
text = presentationData.strings.GroupInfo_AddUserLeftError
}
case let .bot(memberId):
guard let peer = peer as? TelegramChannel else {
guard case let .channel(peer) = peer else {
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
contactsController?.dismiss()
return

View File

@ -1214,17 +1214,9 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
}, action: { _, f in
f(.dismissWithoutContent)
let _ = (context.account.postbox.transaction { transaction -> String? in
if let cachedData = transaction.getPeerCachedData(peerId: peerId) {
if let cachedData = cachedData as? CachedChannelData {
return cachedData.exportedInvitation?.link
} else if let cachedData = cachedData as? CachedGroupData {
return cachedData.exportedInvitation?.link
}
}
return nil
} |> deliverOnMainQueue).start(next: { link in
if let link = link {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: peerId))
|> deliverOnMainQueue).start(next: { exportedInvitation in
if let link = exportedInvitation?.link {
UIPasteboard.general.string = link
dismissTooltipsImpl?()
@ -1240,16 +1232,8 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
}, action: { _, f in
f(.dismissWithoutContent)
let _ = (context.account.postbox.transaction { transaction -> ExportedInvitation? in
if let cachedData = transaction.getPeerCachedData(peerId: peerId) {
if let cachedData = cachedData as? CachedChannelData {
return cachedData.exportedInvitation
} else if let cachedData = cachedData as? CachedGroupData {
return cachedData.exportedInvitation
}
}
return nil
} |> deliverOnMainQueue).start(next: { invite in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: peerId))
|> deliverOnMainQueue).start(next: { invite in
if let invite = invite {
let _ = (context.account.postbox.loadedPeerWithId(peerId)
|> deliverOnMainQueue).start(next: { peer in
@ -1289,17 +1273,9 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
ActionSheetButtonItem(title: presentationData.strings.GroupInfo_InviteLink_RevokeLink, color: .destructive, action: {
dismissAction()
let _ = (context.account.postbox.transaction { transaction -> String? in
if let cachedData = transaction.getPeerCachedData(peerId: peerId) {
if let cachedData = cachedData as? CachedChannelData {
return cachedData.exportedInvitation?.link
} else if let cachedData = cachedData as? CachedGroupData {
return cachedData.exportedInvitation?.link
}
}
return nil
} |> deliverOnMainQueue).start(next: { link in
if let link = link {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: peerId))
|> deliverOnMainQueue).start(next: { exportedInvitation in
if let link = exportedInvitation?.link {
var revoke = false
updateState { state in
if !state.revokingPrivateLink {

View File

@ -865,12 +865,20 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
var displayCopyContextMenuImpl: ((DeviceContactInfoEntryTag, String) -> Void)?
let callImpl: (String) -> Void = { number in
let _ = (context.account.postbox.transaction { transaction -> TelegramUser? in
if let peer = subject.peer {
return transaction.getPeer(peer.id) as? TelegramUser
let user: Signal<TelegramUser?, NoError>
if let peer = subject.peer {
user = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id))
|> map { peer -> TelegramUser? in
if case let .user(user) = peer {
return user
} else {
return nil
}
}
return nil
} else {
user = .single(nil)
}
let _ = (user
|> deliverOnMainQueue).start(next: { user in
if let user = user, let phone = user.phone, formatPhoneNumber(phone) == formatPhoneNumber(number) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -1137,10 +1145,11 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|> mapToSignal { _ -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in
}
|> then(
context.account.postbox.transaction { transaction -> (DeviceContactStableId, DeviceContactExtendedData, Peer?)? in
return (id, data, transaction.getPeer(peer.id))
}
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id))
|> castError(AddContactError.self)
|> map { result -> (DeviceContactStableId, DeviceContactExtendedData, Peer?)? in
return (id, data, result?._asPeer())
}
)
}
default:
@ -1151,10 +1160,11 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|> castError(AddContactError.self)
|> mapToSignal { peerId -> Signal<(DeviceContactStableId, DeviceContactExtendedData, Peer?)?, AddContactError> in
if let peerId = peerId {
return context.account.postbox.transaction { transaction -> (DeviceContactStableId, DeviceContactExtendedData, Peer?)? in
return (id, data, transaction.getPeer(peerId))
}
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> castError(AddContactError.self)
|> map { result -> (DeviceContactStableId, DeviceContactExtendedData, Peer?)? in
return (id, data, result?._asPeer())
}
} else {
return .single((id, data, nil))
}

View File

@ -348,18 +348,11 @@ public func oldChannelsController(context: AccountContext, updatedPresentationDa
|> take(1)
|> mapToSignal { peers -> Signal<Never, NoError> in
let peers = peers ?? []
return context.account.postbox.transaction { transaction -> Void in
for peer in peers {
if state.selectedPeers.contains(peer.peer.id) {
if transaction.getPeer(peer.peer.id) == nil {
updatePeers(transaction: transaction, peers: [peer.peer], update: { _, updated in
return updated
})
}
}
}
}
|> ignoreValues
let ensureStoredPeers = peers.map { $0.peer }.filter { state.selectedPeers.contains($0.id) }
let ensureStoredPeersSignal: Signal<Never, NoError> = context.engine.peers.ensurePeersAreLocallyAvailable(peers: ensureStoredPeers.map(EnginePeer.init))
return ensureStoredPeersSignal
|> then(context.engine.peers.removePeerChats(peerIds: Array(peers.map(\.peer.id))))
}
|> deliverOnMainQueue).start(completed: {

View File

@ -196,20 +196,11 @@ public func peerAllowedReactionListController(
let _ = dismissImpl
let actionsDisposable = DisposableSet()
actionsDisposable.add((context.account.postbox.transaction { transaction -> Set<String>? in
let cachedData = transaction.getPeerCachedData(peerId: peerId)
if let cachedData = cachedData as? CachedChannelData {
return cachedData.allowedReactions.flatMap(Set.init)
} else if let cachedData = cachedData as? CachedGroupData {
return cachedData.allowedReactions.flatMap(Set.init)
} else {
return nil
}
}
actionsDisposable.add((context.engine.data.get(TelegramEngine.EngineData.Item.Peer.AllowedReactions(id: peerId))
|> deliverOnMainQueue).start(next: { allowedReactions in
updateState { state in
var state = state
state.updatedAllowedReactions = allowedReactions
state.updatedAllowedReactions = allowedReactions.flatMap(Set.init)
return state
}
}))
@ -303,17 +294,10 @@ public func peerAllowedReactionListController(
let controller = ItemListController(context: context, state: signal)
controller.willDisappear = { _ in
let _ = (context.account.postbox.transaction { transaction -> Set<String>? in
let cachedData = transaction.getPeerCachedData(peerId: peerId)
if let cachedData = cachedData as? CachedChannelData {
return cachedData.allowedReactions.flatMap(Set.init)
} else if let cachedData = cachedData as? CachedGroupData {
return cachedData.allowedReactions.flatMap(Set.init)
} else {
return nil
}
}
|> deliverOnMainQueue).start(next: { initialAllowedReactions in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.AllowedReactions(id: peerId))
|> deliverOnMainQueue).start(next: { initialAllowedReactionList in
let initialAllowedReactions = initialAllowedReactionList.flatMap(Set.init)
let updatedAllowedReactions = stateValue.with({ $0 }).updatedAllowedReactions
if let updatedAllowedReactions = updatedAllowedReactions, initialAllowedReactions != updatedAllowedReactions {
let _ = context.engine.peers.updatePeerAllowedReactions(peerId: peerId, allowedReactions: Array(updatedAllowedReactions)).start()

View File

@ -28,31 +28,36 @@ import LocalizedPeerData
import PhoneNumberFormat
import TelegramIntents
private func getUserPeer(postbox: Postbox, peerId: PeerId) -> Signal<(Peer?, CachedPeerData?), NoError> {
return postbox.transaction { transaction -> (Peer?, CachedPeerData?) in
guard let peer = transaction.getPeer(peerId) else {
return (nil, nil)
}
var resultPeer: Peer?
if let peer = peer as? TelegramSecretChat {
resultPeer = transaction.getPeer(peer.regularPeerId)
private func getUserPeer(engine: TelegramEngine, peerId: EnginePeer.Id) -> Signal<(EnginePeer?, EnginePeer.StatusSettings?), NoError> {
return engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> mapToSignal { peer -> Signal<EnginePeer?, NoError> in
if case let .secretChat(secretChat) = peer {
return engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: secretChat.regularPeerId))
} else {
resultPeer = peer
return .single(peer)
}
}
|> mapToSignal { peer -> Signal<(EnginePeer?, EnginePeer.StatusSettings?), NoError> in
guard let peer = peer else {
return .single((nil, nil))
}
return engine.data.get(TelegramEngine.EngineData.Item.Peer.StatusSettings(id: peer.id))
|> map { statusSettings -> (EnginePeer?, EnginePeer.StatusSettings?) in
return (peer, statusSettings)
}
return (resultPeer, resultPeer.flatMap({ transaction.getPeerCachedData(peerId: $0.id) }))
}
}
public func openAddPersonContactImpl(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, pushController: @escaping (ViewController) -> Void, present: @escaping (ViewController, Any?) -> Void) {
let _ = (getUserPeer(postbox: context.account.postbox, peerId: peerId)
|> deliverOnMainQueue).start(next: { peer, cachedData in
guard let user = peer as? TelegramUser, let contactData = DeviceContactExtendedData(peer: user) else {
public func openAddPersonContactImpl(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, pushController: @escaping (ViewController) -> Void, present: @escaping (ViewController, Any?) -> Void) {
let _ = (getUserPeer(engine: context.engine, peerId: peerId)
|> deliverOnMainQueue).start(next: { peer, statusSettings in
guard case let .user(user) = peer, let contactData = DeviceContactExtendedData(peer: user) else {
return
}
var shareViaException = false
if let cachedData = cachedData as? CachedUserData, let peerStatusSettings = cachedData.peerStatusSettings {
shareViaException = peerStatusSettings.contains(.addExceptionWhenAddingContact)
if let statusSettings = statusSettings {
shareViaException = statusSettings.contains(.addExceptionWhenAddingContact)
}
pushController(deviceContactInfoController(context: context, updatedPresentationData: updatedPresentationData, subject: .create(peer: user, contactData: contactData, isSharing: true, shareViaException: shareViaException, completion: { peer, stableId, contactData in

View File

@ -524,26 +524,41 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
guard let peersNearby = peersNearby else {
return .single(nil)
}
return context.account.postbox.transaction { transaction -> PeersNearbyData? in
let peerIds = peersNearby.map { entry -> EnginePeer.Id in
switch entry {
case let .peer(id, _, _):
return id
case .selfPeer:
return context.account.peerId
}
}
return context.engine.data.get(
EngineDataMap(peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(peerIds.map(TelegramEngine.EngineData.Item.Peer.ParticipantCount.init))
)
|> map { peerMap, participantCountMap -> PeersNearbyData? in
var users: [PeerNearbyEntry] = []
var groups: [PeerNearbyEntry] = []
var visible = false
for peerNearby in peersNearby {
switch peerNearby {
case let .peer(id, expires, distance):
if let peer = transaction.getPeer(id) {
if id.namespace == Namespaces.Peer.CloudUser {
users.append(PeerNearbyEntry(peer: EnginePeer(peer), memberCount: nil, expires: expires, distance: distance))
} else {
let cachedData = transaction.getPeerCachedData(peerId: id) as? CachedChannelData
groups.append(PeerNearbyEntry(peer: EnginePeer(peer), memberCount: cachedData?.participantsSummary.memberCount, expires: expires, distance: distance))
case let .peer(id, expires, distance):
if let maybePeer = peerMap[id], let peer = maybePeer {
if id.namespace == Namespaces.Peer.CloudUser {
users.append(PeerNearbyEntry(peer: peer, memberCount: nil, expires: expires, distance: distance))
} else {
var participantCount: Int32?
if let maybeParticipantCount = participantCountMap[id] {
participantCount = maybeParticipantCount.flatMap(Int32.init)
}
groups.append(PeerNearbyEntry(peer: peer, memberCount: participantCount, expires: expires, distance: distance))
}
case let .selfPeer(expires):
visible = true
if let peer = transaction.getPeer(context.account.peerId) {
users.append(PeerNearbyEntry(peer: EnginePeer(peer), memberCount: nil, expires: expires, distance: 0))
}
}
case let .selfPeer(expires):
visible = true
if let maybePeer = peerMap[context.account.peerId], let peer = maybePeer {
users.append(PeerNearbyEntry(peer: peer, memberCount: nil, expires: expires, distance: 0))
}
}
}
return PeersNearbyData(latitude: coordinate.latitude, longitude: coordinate.longitude, address: address, visible: visible, accountPeerId: context.account.peerId, users: users, groups: groups, channels: [])

View File

@ -0,0 +1,54 @@
import Foundation
final class MutableChatListIndexView: MutablePostboxView {
fileprivate let id: PeerId
fileprivate var chatListIndex: ChatListIndex?
fileprivate var inclusion: PeerChatListInclusion
init(postbox: PostboxImpl, id: PeerId) {
self.id = id
self.chatListIndex = postbox.chatListIndexTable.get(peerId: id).includedIndex(peerId: self.id)?.1
self.inclusion = postbox.chatListIndexTable.get(peerId: id).inclusion
}
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool {
var updated = false
if transaction.currentUpdatedChatListInclusions[self.id] != nil || transaction.currentOperationsByPeerId[self.id] != nil {
updated = true
}
if updated {
let chatListIndex = postbox.chatListIndexTable.get(peerId: id).includedIndex(peerId: self.id)?.1
let inclusion = postbox.chatListIndexTable.get(peerId: id).inclusion
if self.chatListIndex != chatListIndex || self.inclusion != inclusion {
self.chatListIndex = chatListIndex
self.inclusion = inclusion
return true
} else {
return false
}
} else {
return false
}
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return ChatListIndexView(self)
}
}
public final class ChatListIndexView: PostboxView {
public let chatListIndex: ChatListIndex?
public let inclusion: PeerChatListInclusion
init(_ view: MutableChatListIndexView) {
self.chatListIndex = view.chatListIndex
self.inclusion = view.inclusion
}
}

View File

@ -2107,7 +2107,7 @@ final class PostboxImpl {
return indices.max()
}
fileprivate func getPeerChatListInclusion(_ id: PeerId) -> PeerChatListInclusion {
func getPeerChatListInclusion(_ id: PeerId) -> PeerChatListInclusion {
if let inclusion = self.currentUpdatedChatListInclusions[id] {
return inclusion
} else {

View File

@ -36,6 +36,7 @@ public enum PostboxViewKey: Hashable {
case notice(key: NoticeEntryKey)
case messageGroup(id: MessageId)
case isContact(id: PeerId)
case chatListIndex(id: PeerId)
public func hash(into hasher: inout Hasher) {
switch self {
@ -118,6 +119,8 @@ public enum PostboxViewKey: Hashable {
hasher.combine(id)
case let .isContact(id):
hasher.combine(id)
case let .chatListIndex(id):
hasher.combine(id)
}
}
@ -333,6 +336,12 @@ public enum PostboxViewKey: Hashable {
} else {
return false
}
case let .chatListIndex(id):
if case .chatListIndex(id) = rhs {
return true
} else {
return false
}
}
}
}
@ -409,5 +418,7 @@ func postboxViewForKey(postbox: PostboxImpl, key: PostboxViewKey) -> MutablePost
return MutableMessageGroupView(postbox: postbox, id: id)
case let .isContact(id):
return MutableIsContactView(postbox: postbox, id: id)
case let .chatListIndex(id):
return MutableChatListIndexView(postbox: postbox, id: id)
}
}

View File

@ -662,15 +662,15 @@ private func preparedExceptionsListNodeTransition(presentationData: ItemListPres
return NotificationExceptionNodeTransition(deletions: deletions, insertions: insertions, updates: updates, firstTime: firstTime, animated: animated)
}
private extension PeerMuteState {
private extension EnginePeer.NotificationSettings.MuteState {
var timeInterval: Int32? {
switch self {
case .default:
return nil
case .unmuted:
return 0
case let .muted(until):
return until
case .default:
return nil
case .unmuted:
return 0
case let .muted(until):
return until
}
}
}
@ -744,26 +744,30 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
updateNotificationsDisposable.set((context.account.postbox.combinedView(keys: [key])
|> deliverOnMainQueue).start(next: { view in
if let view = view.views[key] as? PeerNotificationSettingsView {
_ = context.account.postbox.transaction { transaction in
let _ = (context.engine.data.get(
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init))
)
|> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in
updateState { current in
var current = current
for (key, value) in view.notificationSettings {
if let value = value as? TelegramPeerNotificationSettings {
if let local = current.mode.settings[key] {
if !value.isEqual(to: local.settings), let peer = transaction.getPeer(key), let settings = transaction.getPeerNotificationSettings(key) as? TelegramPeerNotificationSettings, !settings.isEqual(to: local.settings) {
current = current.withUpdatedPeerSound(peer, settings.messageSound).withUpdatedPeerMuteInterval(peer, settings.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer, settings.displayPreviews)
if !value.isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) {
current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), settings.displayPreviews._asDisplayPreviews())
}
} else if let peer = transaction.getPeer(key) {
} else if let maybePeer = peerMap[key], let peer = maybePeer {
if case .default = value.messageSound, case .unmuted = value.muteState, case .default = value.displayPreviews {
} else {
current = current.withUpdatedPeerSound(peer, value.messageSound).withUpdatedPeerMuteInterval(peer, value.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer, value.displayPreviews)
current = current.withUpdatedPeerSound(peer._asPeer(), value.messageSound).withUpdatedPeerMuteInterval(peer._asPeer(), EnginePeer.NotificationSettings.MuteState(value.muteState).timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews)
}
}
}
}
return current
}
}.start(completed: {
completion()
})
} else {
@ -804,9 +808,7 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
let presentPeerSettings: (PeerId, @escaping () -> Void) -> Void = { [weak self] peerId, completion in
(self?.searchDisplayController?.contentNode as? NotificationExceptionsSearchContainerNode)?.listNode.clearHighlightAnimated(true)
let _ = (context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
}
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
completion()
@ -817,43 +819,49 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
let mode = stateValue.with { $0.mode }
dismissInputImpl?()
presentControllerImpl?(notificationPeerExceptionController(context: context, peer: peer, mode: mode, updatePeerSound: { peerId, sound in
presentControllerImpl?(notificationPeerExceptionController(context: context, peer: peer._asPeer(), mode: mode, updatePeerSound: { peerId, sound in
_ = updatePeerSound(peer.id, sound).start(next: { _ in
updateNotificationsDisposable.set(nil)
_ = combineLatest(updatePeerSound(peer.id, sound), context.account.postbox.loadedPeerWithId(peerId) |> deliverOnMainQueue).start(next: { _, peer in
updateState { value in
return value.withUpdatedPeerSound(peer, sound)
_ = combineLatest(updatePeerSound(peer.id, sound), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerSound(peer._asPeer(), sound)
}
}
updateNotificationsView({})
})
})
}, updatePeerNotificationInterval: { peerId, muteInterval in
updateNotificationsDisposable.set(nil)
_ = combineLatest(updatePeerNotificationInterval(peerId, muteInterval), context.account.postbox.loadedPeerWithId(peerId) |> deliverOnMainQueue).start(next: { _, peer in
updateState { value in
return value.withUpdatedPeerMuteInterval(peer, muteInterval)
_ = combineLatest(updatePeerNotificationInterval(peerId, muteInterval), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerMuteInterval(peer._asPeer(), muteInterval)
}
}
updateNotificationsView({})
})
}, updatePeerDisplayPreviews: { peerId, displayPreviews in
updateNotificationsDisposable.set(nil)
_ = combineLatest(updatePeerDisplayPreviews(peerId, displayPreviews), context.account.postbox.loadedPeerWithId(peerId) |> deliverOnMainQueue).start(next: { _, peer in
updateState { value in
return value.withUpdatedPeerDisplayPreviews(peer, displayPreviews)
_ = combineLatest(updatePeerDisplayPreviews(peerId, displayPreviews), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerDisplayPreviews(peer._asPeer(), displayPreviews)
}
}
updateNotificationsView({})
})
}, removePeerFromExceptions: {
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|> map { _ -> Peer? in }
|> then(context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
})).start(next: { peer in
|> map { _ -> EnginePeer? in }
|> then(
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
)).start(next: { peer in
guard let peer = peer else {
return
}
updateState { value in
return value.withUpdatedPeerDisplayPreviews(peer, .default).withUpdatedPeerSound(peer, .default).withUpdatedPeerMuteInterval(peer, nil)
return value.withUpdatedPeerDisplayPreviews(peer._asPeer(), .default).withUpdatedPeerSound(peer._asPeer(), .default).withUpdatedPeerMuteInterval(peer._asPeer(), nil)
}
updateNotificationsView({})
})
@ -867,20 +875,6 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
openSearch()
}, openPeer: { peer in
presentPeerSettings(peer.id, {})
/*if let strongSelf = self {
_ = (strongSelf.context.account.postbox.transaction { transaction in
if transaction.getPeer(peer.id) == nil {
updatePeers(transaction: transaction, peers: [peer], update: { previousPeer, updatedPeer in
return updatedPeer
})
}
} |> deliverOnMainQueue).start(completed: { [weak strongSelf] in
if let strongSelf = strongSelf, let infoController = peerInfoController(context: strongSelf.context, peer: peer) {
strongSelf.pushController(infoController)
strongSelf.requestDeactivateSearch()
}
})
}*/
}, selectPeer: {
var filter: ChatListNodePeersFilter = [.excludeRecent, .doNotSearchMessages, .removeSearchHeader]
switch mode {
@ -908,11 +902,8 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
return current.withUpdatedRevealedPeerId(peerId)
}
}, deletePeer: { peer in
_ = (context.account.postbox.transaction { transaction in
if transaction.getPeer(peer.id) == nil {
updatePeers(transaction: transaction, peers: [peer], update: { _, updated in return updated})
}
} |> deliverOnMainQueue).start(completed: {
let _ = (context.engine.peers.ensurePeersAreLocallyAvailable(peers: [EnginePeer(peer)])
|> deliverOnMainQueue).start(completed: {
updateNotificationsDisposable.set(nil)
updateState { value in
return value.withUpdatedPeerMuteInterval(peer, nil).withUpdatedPeerSound(peer, .default).withUpdatedPeerDisplayPreviews(peer, .default)
@ -931,15 +922,7 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
actionSheet?.dismissAnimated()
let values = stateValue.with { $0.mode.settings.values }
let _ = (context.account.postbox.transaction { transaction -> Void in
for value in values {
if transaction.getPeer(value.peer.id) == nil {
updatePeers(transaction: transaction, peers: [value.peer], update: { _, updated in
updated
})
}
}
}
let _ = (context.engine.peers.ensurePeersAreLocallyAvailable(peers: values.map { EnginePeer($0.peer) })
|> deliverOnMainQueue).start(completed: {
updateNotificationsDisposable.set(nil)
updateState { state in
@ -1196,19 +1179,23 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
updateNotificationsDisposable.set(context.account.postbox.combinedView(keys: [key]).start(next: { view in
if let view = view.views[key] as? PeerNotificationSettingsView {
_ = context.account.postbox.transaction { transaction in
let _ = (context.engine.data.get(
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init))
)
|> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in
updateState { current in
var current = current
for (key, value) in view.notificationSettings {
if let value = value as? TelegramPeerNotificationSettings,let local = current.mode.settings[key] {
if !value.isEqual(to: local.settings), let peer = transaction.getPeer(key), let settings = transaction.getPeerNotificationSettings(key) as? TelegramPeerNotificationSettings, !settings.isEqual(to: local.settings) {
current = current.withUpdatedPeerSound(peer, settings.messageSound).withUpdatedPeerMuteInterval(peer, settings.muteState.timeInterval)
if !value.isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) {
current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval)
}
}
}
return current
}
}.start(completed: {
completion()
})
} else {

View File

@ -418,16 +418,20 @@ public func notificationPeerExceptionController(context: AccountContext, updated
deleteSoundImpl?(sound, title)
})
statePromise.set(context.account.postbox.transaction { transaction -> NotificationExceptionPeerState in
var state = NotificationExceptionPeerState(canRemove: mode.peerIds.contains(peer.id), notifications: transaction.getPeerNotificationSettings(peer.id) as? TelegramPeerNotificationSettings)
let globalSettings: GlobalNotificationSettings = transaction.getPreferencesEntry(key: PreferencesKeys.globalNotifications)?.get(GlobalNotificationSettings.self) ?? GlobalNotificationSettings.defaultSettings
statePromise.set(context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peer.id),
TelegramEngine.EngineData.Item.NotificationSettings.Global()
)
|> map { notificationSettings, globalNotificationSettings -> NotificationExceptionPeerState in
var state = NotificationExceptionPeerState(canRemove: mode.peerIds.contains(peer.id), notifications: notificationSettings._asNotificationSettings())
let globalSettings = globalNotificationSettings
switch mode {
case .channels:
state.defaultSound = globalSettings.effective.channels.sound
state.defaultSound = globalSettings.channels.sound._asMessageSound()
case .groups:
state.defaultSound = globalSettings.effective.groupChats.sound
state.defaultSound = globalSettings.groupChats.sound._asMessageSound()
case .users:
state.defaultSound = globalSettings.effective.privateChats.sound
state.defaultSound = globalSettings.privateChats.sound._asMessageSound()
}
let _ = stateValue.swap(state)
return state

View File

@ -19,15 +19,15 @@ import TelegramStringFormatting
import ItemListPeerItem
import ItemListPeerActionItem
private extension PeerMuteState {
private extension EnginePeer.NotificationSettings.MuteState {
var timeInterval: Int32? {
switch self {
case .default:
return nil
case .unmuted:
return 0
case let .muted(until):
return until
case .default:
return nil
case .unmuted:
return 0
case let .muted(until):
return until
}
}
}
@ -459,26 +459,30 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
updateNotificationsDisposable.set((context.account.postbox.combinedView(keys: [key])
|> deliverOnMainQueue).start(next: { view in
if let view = view.views[key] as? PeerNotificationSettingsView {
_ = context.account.postbox.transaction { transaction in
let _ = (context.engine.data.get(
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init))
)
|> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in
updateState { current in
var current = current
for (key, value) in view.notificationSettings {
if let value = value as? TelegramPeerNotificationSettings {
if let local = current.mode.settings[key] {
if !value.isEqual(to: local.settings), let peer = transaction.getPeer(key), let settings = transaction.getPeerNotificationSettings(key) as? TelegramPeerNotificationSettings, !settings.isEqual(to: local.settings) {
current = current.withUpdatedPeerSound(peer, settings.messageSound).withUpdatedPeerMuteInterval(peer, settings.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer, settings.displayPreviews)
if !value.isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) {
current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), settings.displayPreviews._asDisplayPreviews())
}
} else if let peer = transaction.getPeer(key) {
} else if let maybePeer = peerMap[key], let peer = maybePeer {
if case .default = value.messageSound, case .unmuted = value.muteState, case .default = value.displayPreviews {
} else {
current = current.withUpdatedPeerSound(peer, value.messageSound).withUpdatedPeerMuteInterval(peer, value.muteState.timeInterval).withUpdatedPeerDisplayPreviews(peer, value.displayPreviews)
current = current.withUpdatedPeerSound(peer._asPeer(), value.messageSound).withUpdatedPeerMuteInterval(peer._asPeer(), EnginePeer.NotificationSettings.MuteState(value.muteState).timeInterval).withUpdatedPeerDisplayPreviews(peer._asPeer(), value.displayPreviews)
}
}
}
}
return current
}
}.start(completed: {
completion()
})
} else {
@ -492,9 +496,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
updateNotificationsView({})
let presentPeerSettings: (PeerId, @escaping () -> Void) -> Void = { peerId, completion in
let _ = (context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
}
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
completion()
@ -503,43 +505,49 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
}
let mode = stateValue.with { $0.mode }
pushControllerImpl?(notificationPeerExceptionController(context: context, peer: peer, mode: mode, updatePeerSound: { peerId, sound in
pushControllerImpl?(notificationPeerExceptionController(context: context, peer: peer._asPeer(), mode: mode, updatePeerSound: { peerId, sound in
_ = updatePeerSound(peer.id, sound).start(next: { _ in
updateNotificationsDisposable.set(nil)
_ = combineLatest(updatePeerSound(peer.id, sound), context.account.postbox.loadedPeerWithId(peerId) |> deliverOnMainQueue).start(next: { _, peer in
updateState { value in
return value.withUpdatedPeerSound(peer, sound)
_ = combineLatest(updatePeerSound(peer.id, sound), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerSound(peer._asPeer(), sound)
}
}
updateNotificationsView({})
})
})
}, updatePeerNotificationInterval: { peerId, muteInterval in
updateNotificationsDisposable.set(nil)
_ = combineLatest(updatePeerNotificationInterval(peerId, muteInterval), context.account.postbox.loadedPeerWithId(peerId) |> deliverOnMainQueue).start(next: { _, peer in
updateState { value in
return value.withUpdatedPeerMuteInterval(peer, muteInterval)
_ = combineLatest(updatePeerNotificationInterval(peerId, muteInterval), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerMuteInterval(peer._asPeer(), muteInterval)
}
}
updateNotificationsView({})
})
}, updatePeerDisplayPreviews: { peerId, displayPreviews in
updateNotificationsDisposable.set(nil)
_ = combineLatest(updatePeerDisplayPreviews(peerId, displayPreviews), context.account.postbox.loadedPeerWithId(peerId) |> deliverOnMainQueue).start(next: { _, peer in
updateState { value in
return value.withUpdatedPeerDisplayPreviews(peer, displayPreviews)
_ = combineLatest(updatePeerDisplayPreviews(peerId, displayPreviews), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerDisplayPreviews(peer._asPeer(), displayPreviews)
}
}
updateNotificationsView({})
})
}, removePeerFromExceptions: {
let _ = (context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|> map { _ -> Peer? in }
|> then(context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
})).start(next: { peer in
let _ = (
context.engine.peers.removeCustomNotificationSettings(peerIds: [peerId])
|> map { _ -> EnginePeer? in }
|> then(context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)))
).start(next: { peer in
guard let peer = peer else {
return
}
updateState { value in
return value.withUpdatedPeerDisplayPreviews(peer, .default).withUpdatedPeerSound(peer, .default).withUpdatedPeerMuteInterval(peer, nil)
return value.withUpdatedPeerDisplayPreviews(peer._asPeer(), .default).withUpdatedPeerSound(peer._asPeer(), .default).withUpdatedPeerMuteInterval(peer._asPeer(), nil)
}
updateNotificationsView({})
})
@ -624,15 +632,8 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
actionSheet?.dismissAnimated()
let values = stateValue.with { $0.mode.settings.values }
let _ = (context.account.postbox.transaction { transaction -> Void in
for value in values {
if transaction.getPeer(value.peer.id) == nil {
updatePeers(transaction: transaction, peers: [value.peer], update: { _, updated in
updated
})
}
}
}
let _ = (context.engine.peers.ensurePeersAreLocallyAvailable(peers: values.map { EnginePeer($0.peer) })
|> deliverOnMainQueue).start(completed: {
updateNotificationsDisposable.set(nil)
updateState { state in
@ -659,11 +660,8 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
return current.withUpdatedRevealedPeerId(peerId)
}
}, removePeer: { peer in
_ = (context.account.postbox.transaction { transaction in
if transaction.getPeer(peer.id) == nil {
updatePeers(transaction: transaction, peers: [peer], update: { _, updated in return updated})
}
} |> deliverOnMainQueue).start(completed: {
let _ = (context.engine.peers.ensurePeersAreLocallyAvailable(peers: [EnginePeer(peer)])
|> deliverOnMainQueue).start(completed: {
updateNotificationsDisposable.set(nil)
updateState { value in
return value.withUpdatedPeerMuteInterval(peer, nil).withUpdatedPeerSound(peer, .default).withUpdatedPeerDisplayPreviews(peer, .default)

View File

@ -785,23 +785,35 @@ func selectivePrivacySettingsController(context: AccountContext, kind: Selective
controller?.dismiss()
return
}
let _ = (context.account.postbox.transaction { transaction -> [PeerId: SelectivePrivacyPeer] in
let filteredIds = peerIds.compactMap { peerId -> EnginePeer.Id? in
if case let .peer(value) = peerId {
return value
} else {
return nil
}
}
let _ = (context.engine.data.get(
EngineDataMap(filteredIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(filteredIds.map(TelegramEngine.EngineData.Item.Peer.ParticipantCount.init))
)
|> map { peerMap, participantCountMap -> [PeerId: SelectivePrivacyPeer] in
var updatedPeers: [PeerId: SelectivePrivacyPeer] = [:]
var existingIds = Set(updatedPeers.values.map { $0.peer.id })
for peerId in peerIds {
guard case let .peer(peerId) = peerId else {
continue
}
if let peer = transaction.getPeer(peerId), !existingIds.contains(peerId) {
if let maybePeer = peerMap[peerId], let peer = maybePeer, !existingIds.contains(peerId) {
existingIds.insert(peerId)
var participantCount: Int32?
if let channel = peer as? TelegramChannel, case .group = channel.info {
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData {
participantCount = cachedData.participantsSummary.memberCount
if case let .channel(channel) = peer, case .group = channel.info {
if let maybeParticipantCount = participantCountMap[peerId], let participantCountValue = maybeParticipantCount {
participantCount = Int32(participantCountValue)
}
}
updatedPeers[peer.id] = SelectivePrivacyPeer(peer: peer, participantCount: participantCount)
updatedPeers[peer.id] = SelectivePrivacyPeer(peer: peer._asPeer(), participantCount: participantCount)
}
}
return updatedPeers
@ -945,14 +957,15 @@ func selectivePrivacySettingsController(context: AccountContext, kind: Selective
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
})
let peer = context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(context.account.peerId) as? TelegramUser
}
let peer = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), peer) |> deliverOnMainQueue
|> map { presentationData, state, peer -> (ItemListControllerState, (ItemListNodeState, Any)) in
let peerName = peer.flatMap(EnginePeer.init)?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let phoneNumber = (peer as? TelegramUser)?.phone ?? ""
let peerName = peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
var phoneNumber = ""
if case let .user(user) = peer {
phoneNumber = user.phone ?? ""
}
let title: String
switch kind {

View File

@ -275,23 +275,34 @@ public func selectivePrivacyPeersController(context: AccountContext, title: Stri
let applyPeers: Signal<Void, NoError> = peersPromise.get()
|> take(1)
|> mapToSignal { peers -> Signal<[SelectivePrivacyPeer], NoError> in
return context.account.postbox.transaction { transaction -> [SelectivePrivacyPeer] in
let filteredPeerIds = peerIds.compactMap { peerId -> EnginePeer.Id? in
if case let .peer(value) = peerId {
return value
} else {
return nil
}
}
return context.engine.data.get(
EngineDataMap(filteredPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(filteredPeerIds.map(TelegramEngine.EngineData.Item.Peer.ParticipantCount.init))
)
|> map { peerMap, participantCountMap -> [SelectivePrivacyPeer] in
var updatedPeers = peers
var existingIds = Set(updatedPeers.map { $0.peer.id })
for peerId in peerIds {
guard case let .peer(peerId) = peerId else {
continue
}
if let peer = transaction.getPeer(peerId), !existingIds.contains(peerId) {
if let maybePeer = peerMap[peerId], let peer = maybePeer, !existingIds.contains(peerId) {
existingIds.insert(peerId)
var participantCount: Int32?
if let channel = peer as? TelegramChannel, case .group = channel.info {
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData {
participantCount = cachedData.participantsSummary.memberCount
if case let .channel(channel) = peer, case .group = channel.info {
if let maybeParticipantCount = participantCountMap[peerId], let participantCountValue = maybeParticipantCount {
participantCount = Int32(participantCountValue)
}
}
updatedPeers.append(SelectivePrivacyPeer(peer: peer, participantCount: participantCount))
updatedPeers.append(SelectivePrivacyPeer(peer: peer._asPeer(), participantCount: participantCount))
}
}
return updatedPeers
@ -315,11 +326,9 @@ public func selectivePrivacyPeersController(context: AccountContext, title: Stri
}))
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
}, openPeer: { peerId in
let _ = (context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
}
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in
guard let peer = peer, let controller = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
guard let peer = peer, let controller = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
return
}
pushControllerImpl?(controller)

View File

@ -190,11 +190,13 @@ private func profileSearchableItems(context: AccountContext, canAddAccount: Bool
var items: [SettingsSearchableItem] = []
items.append(SettingsSearchableItem(id: .profile(2), title: strings.Settings_PhoneNumber, alternate: synonyms(strings.SettingsSearch_Synonyms_EditProfile_PhoneNumber), icon: icon, breadcrumbs: [strings.EditProfile_Title], present: { context, _, present in
let _ = (context.account.postbox.transaction { transaction -> String in
return (transaction.getPeer(context.account.peerId) as? TelegramUser)?.phone ?? ""
}
|> deliverOnMainQueue).start(next: { phoneNumber in
present(.push, PrivacyIntroController(context: context, mode: .changePhoneNumber(phoneNumber), proceedAction: {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|> deliverOnMainQueue).start(next: { peer in
var phoneNumber: String?
if case let .user(user) = peer {
phoneNumber = user.phone
}
present(.push, PrivacyIntroController(context: context, mode: .changePhoneNumber(phoneNumber ?? ""), proceedAction: {
present(.push, ChangePhoneNumberController(context: context))
}))
})
@ -209,12 +211,14 @@ private func profileSearchableItems(context: AccountContext, canAddAccount: Bool
}))
}
items.append(SettingsSearchableItem(id: .profile(5), title: strings.Settings_Logout, alternate: synonyms(strings.SettingsSearch_Synonyms_EditProfile_Logout), icon: icon, breadcrumbs: [strings.EditProfile_Title], present: { context, navigationController, present in
let _ = (context.account.postbox.transaction { transaction -> String in
return (transaction.getPeer(context.account.peerId) as? TelegramUser)?.phone ?? ""
}
|> deliverOnMainQueue).start(next: { phoneNumber in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|> deliverOnMainQueue).start(next: { peer in
var phoneNumber: String?
if case let .user(user) = peer {
phoneNumber = user.phone
}
if let navigationController = navigationController {
present(.modal, logoutOptionsController(context: context, navigationController: navigationController, canAddAccounts: canAddAccount, phoneNumber: phoneNumber))
present(.modal, logoutOptionsController(context: context, navigationController: navigationController, canAddAccounts: canAddAccount, phoneNumber: phoneNumber ?? ""))
}
})
}))

View File

@ -112,19 +112,21 @@ private struct CollectableExternalShareItem {
let mediaReference: AnyMediaReference?
}
private func collectExternalShareItems(strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameOrder: PresentationPersonNameOrder, postbox: Postbox, collectableItems: [CollectableExternalShareItem], takeOne: Bool = true) -> Signal<ExternalShareItemsState, NoError> {
private func collectExternalShareItems(strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameOrder: PresentationPersonNameOrder, engine: TelegramEngine, postbox: Postbox, collectableItems: [CollectableExternalShareItem], takeOne: Bool = true) -> Signal<ExternalShareItemsState, NoError> {
var signals: [Signal<ExternalShareItemStatus, NoError>] = []
let authorsPeerIds = collectableItems.compactMap { $0.author }
let authorsPromise = Promise<[PeerId: String]>()
authorsPromise.set(postbox.transaction { transaction in
var result: [PeerId: String] = [:]
for peerId in authorsPeerIds {
if let title = transaction.getPeer(peerId).flatMap(EnginePeer.init)?.displayTitle(strings: strings, displayOrder: nameOrder) {
result[peerId] = title
}
let peerTitles = engine.data.get(EngineDataMap(
authorsPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
))
|> map { peerMap -> [EnginePeer.Id: String] in
return peerMap.compactMapValues { peer -> String? in
return peer?.displayTitle(strings: strings, displayOrder: nameOrder)
}
return result
})
}
authorsPromise.set(peerTitles)
for item in collectableItems {
if let mediaReference = item.mediaReference, let file = mediaReference.media as? TelegramMediaFile {
signals.append(collectExternalShareResource(postbox: postbox, resourceReference: mediaReference.resourceReference(file.resource), statsCategory: statsCategoryForFileWithAttributes(file.attributes))
@ -311,7 +313,7 @@ public final class ShareController: ViewController {
private let segmentedValues: [ShareControllerSegmentedValue]?
private let fromForeignApp: Bool
private let peers = Promise<([(RenderedPeer, PeerPresence?)], Peer)>()
private let peers = Promise<([(EngineRenderedPeer, PeerPresence?)], EnginePeer)>()
private let peersDisposable = MetaDisposable()
private let readyDisposable = MetaDisposable()
private let accountActiveDisposable = MetaDisposable()
@ -785,7 +787,7 @@ public final class ShareController: ViewController {
case .fromExternal:
break
}
return (collectExternalShareItems(strings: strongSelf.presentationData.strings, dateTimeFormat: strongSelf.presentationData.dateTimeFormat, nameOrder: strongSelf.presentationData.nameDisplayOrder, postbox: strongSelf.currentAccount.postbox, collectableItems: collectableItems, takeOne: !strongSelf.immediateExternalShare)
return (collectExternalShareItems(strings: strongSelf.presentationData.strings, dateTimeFormat: strongSelf.presentationData.dateTimeFormat, nameOrder: strongSelf.presentationData.nameDisplayOrder, engine: TelegramEngine(account: strongSelf.currentAccount), postbox: strongSelf.currentAccount.postbox, collectableItems: collectableItems, takeOne: !strongSelf.immediateExternalShare)
|> deliverOnMainQueue)
|> map { state in
switch state {
@ -965,18 +967,19 @@ public final class ShareController: ViewController {
self.accountActiveDisposable.set(self.sharedContext.setAccountUserInterfaceInUse(account.id))
self.peers.set(combineLatest(
self.currentAccount.postbox.loadedPeerWithId(self.currentAccount.peerId)
|> take(1),
TelegramEngine(account: self.currentAccount).data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.currentAccount.peerId)),
self.currentAccount.viewTracker.tailChatListView(groupId: .root, count: 150)
|> take(1)
)
|> mapToSignal { accountPeer, view -> Signal<([(RenderedPeer, PeerPresence?)], Peer), NoError> in
var peers: [RenderedPeer] = []
|> mapToSignal { maybeAccountPeer, view -> Signal<([(EngineRenderedPeer, PeerPresence?)], EnginePeer), NoError> in
let accountPeer = maybeAccountPeer!
var peers: [EngineRenderedPeer] = []
for entry in view.0.entries.reversed() {
switch entry {
case let .MessageEntry(_, _, _, _, _, renderedPeer, _, _, _, _):
if let peer = renderedPeer.peers[renderedPeer.peerId], peer.id != accountPeer.id, canSendMessagesToPeer(peer) {
peers.append(renderedPeer)
peers.append(EngineRenderedPeer(renderedPeer))
}
default:
break
@ -984,8 +987,8 @@ public final class ShareController: ViewController {
}
let key = PostboxViewKey.peerPresences(peerIds: Set(peers.map { $0.peerId }))
return account.postbox.combinedView(keys: [key])
|> map { views -> ([(RenderedPeer, PeerPresence?)], Peer) in
var resultPeers: [(RenderedPeer, PeerPresence?)] = []
|> map { views -> ([(EngineRenderedPeer, PeerPresence?)], EnginePeer) in
var resultPeers: [(EngineRenderedPeer, PeerPresence?)] = []
if let presencesView = views.views[key] as? PeerPresencesView {
for peer in peers {
resultPeers.append((peer, presencesView.presences[peer.peerId]))

View File

@ -614,7 +614,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
func send(peerId: PeerId? = nil, showNames: Bool = true, silently: Bool = false) {
if !self.inputFieldNode.text.isEmpty {
for peer in self.controllerInteraction!.selectedPeers {
if let channel = peer.peer as? TelegramChannel, channel.isRestrictedBySlowmode {
if case let .channel(channel) = peer.peer, channel.isRestrictedBySlowmode {
self.presentError(channel.title, self.presentationData.strings.Share_MultipleMessagesDisabled)
return
}
@ -804,7 +804,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
}
}
func updatePeers(context: AccountContext, switchableAccounts: [AccountWithInfo], peers: [(RenderedPeer, PeerPresence?)], accountPeer: Peer, defaultAction: ShareControllerAction?) {
func updatePeers(context: AccountContext, switchableAccounts: [AccountWithInfo], peers: [(EngineRenderedPeer, PeerPresence?)], accountPeer: EnginePeer, defaultAction: ShareControllerAction?) {
self.context = context
if let peersContentNode = self.peersContentNode, peersContentNode.accountPeer.id == accountPeer.id {
@ -814,9 +814,8 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
if let peerId = self.immediatePeerId {
self.immediatePeerId = nil
let _ = (context.account.postbox.transaction { transaction -> RenderedPeer? in
return transaction.getPeer(peerId).flatMap(RenderedPeer.init(peer:))
} |> deliverOnMainQueue).start(next: { [weak self] peer in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.RenderedPeer(id: peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
if let strongSelf = self, let peer = peer {
strongSelf.controllerInteraction?.togglePeer(peer, peer.peerId != context.account.peerId)
}

View File

@ -13,12 +13,12 @@ import AccountContext
import ShimmerEffect
final class ShareControllerInteraction {
var foundPeers: [RenderedPeer] = []
var foundPeers: [EngineRenderedPeer] = []
var selectedPeerIds = Set<PeerId>()
var selectedPeers: [RenderedPeer] = []
let togglePeer: (RenderedPeer, Bool) -> Void
var selectedPeers: [EngineRenderedPeer] = []
let togglePeer: (EngineRenderedPeer, Bool) -> Void
init(togglePeer: @escaping (RenderedPeer, Bool) -> Void) {
init(togglePeer: @escaping (EngineRenderedPeer, Bool) -> Void) {
self.togglePeer = togglePeer
}
}
@ -90,14 +90,14 @@ final class ShareControllerPeerGridItem: GridItem {
let context: AccountContext
let theme: PresentationTheme
let strings: PresentationStrings
let peer: RenderedPeer?
let peer: EngineRenderedPeer?
let presence: PeerPresence?
let controllerInteraction: ShareControllerInteraction
let search: Bool
let section: GridSection?
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: RenderedPeer?, presence: PeerPresence?, controllerInteraction: ShareControllerInteraction, sectionTitle: String? = nil, search: Bool = false) {
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: PeerPresence?, controllerInteraction: ShareControllerInteraction, sectionTitle: String? = nil, search: Bool = false) {
self.context = context
self.theme = theme
self.strings = strings
@ -131,7 +131,7 @@ final class ShareControllerPeerGridItem: GridItem {
}
final class ShareControllerPeerGridItemNode: GridItemNode {
private var currentState: (AccountContext, PresentationTheme, PresentationStrings, RenderedPeer?, Bool, PeerPresence?)?
private var currentState: (AccountContext, PresentationTheme, PresentationStrings, EngineRenderedPeer?, Bool, PeerPresence?)?
private let peerNode: SelectablePeerNode
private var presenceManager: PeerPresenceStatusManager?
@ -171,13 +171,13 @@ final class ShareControllerPeerGridItemNode: GridItemNode {
}
}
func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: RenderedPeer?, presence: PeerPresence?, search: Bool, synchronousLoad: Bool, force: Bool) {
func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: PeerPresence?, search: Bool, synchronousLoad: Bool, force: Bool) {
if force || self.currentState == nil || self.currentState!.0 !== context || self.currentState!.3 != peer || !arePeerPresencesEqual(self.currentState!.5, presence) {
let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: theme.chatList.secretTitleColor, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.checkContentColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor)
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
var online = false
if let peer = peer?.peer as? TelegramUser, let presence = presence as? TelegramUserPresence, !isServicePeer(peer) && !peer.flags.contains(.isSupport) && peer.id != context.account.peerId {
if case let .user(peer) = peer?.peer, let presence = presence as? TelegramUserPresence, !isServicePeer(peer) && !peer.flags.contains(.isSupport) && peer.id != context.account.peerId {
let relativeStatus = relativeUserPresenceStatus(EnginePeer.Presence(presence), relativeTo: timestamp)
if case .online = relativeStatus {
online = true
@ -186,7 +186,7 @@ final class ShareControllerPeerGridItemNode: GridItemNode {
self.peerNode.theme = itemTheme
if let peer = peer {
self.peerNode.setup(context: context, theme: theme, strings: strings, peer: EngineRenderedPeer(peer), online: online, synchronousLoad: synchronousLoad)
self.peerNode.setup(context: context, theme: theme, strings: strings, peer: peer, online: online, synchronousLoad: synchronousLoad)
if let shimmerNode = self.placeholderNode {
self.placeholderNode = nil
shimmerNode.removeFromSupernode()

View File

@ -61,7 +61,7 @@ final class ShareControllerRecentPeersGridItemNode: GridItemNode {
peersNode.updateThemeAndStrings(theme: theme, strings: strings)
} else {
peersNode = ChatListSearchRecentPeersNode(context: context, theme: theme, mode: .actionSheet, strings: strings, peerSelected: { [weak self] peer in
self?.controllerInteraction?.togglePeer(RenderedPeer(peer: peer._asPeer()), true)
self?.controllerInteraction?.togglePeer(EngineRenderedPeer(peer: peer), true)
}, peerContextAction: { _, _, gesture in gesture?.cancel() }, isPeerSelected: { [weak self] peerId in
return self?.controllerInteraction?.selectedPeerIds.contains(peerId) ?? false
}, share: true)

View File

@ -19,7 +19,7 @@ private let subtitleFont = Font.regular(12.0)
private struct SharePeerEntry: Comparable, Identifiable {
let index: Int32
let peer: RenderedPeer
let peer: EngineRenderedPeer
let presence: PeerPresence?
let theme: PresentationTheme
let strings: PresentationStrings
@ -84,8 +84,8 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
private let debugAction: () -> Void
private let extendedInitialReveal: Bool
let accountPeer: Peer
private let foundPeers = Promise<[RenderedPeer]>([])
let accountPeer: EnginePeer
private let foundPeers = Promise<[EngineRenderedPeer]>([])
private let disposable = MetaDisposable()
private var entries: [SharePeerEntry] = []
@ -115,9 +115,9 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
private var validLayout: (CGSize, CGFloat)?
private var overrideGridOffsetTransition: ContainedViewLayoutTransition?
let peersValue = Promise<[(RenderedPeer, PeerPresence?)]>()
let peersValue = Promise<[(EngineRenderedPeer, PeerPresence?)]>()
init(sharedContext: SharedAccountContext, context: AccountContext, switchableAccounts: [AccountWithInfo], theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, peers: [(RenderedPeer, PeerPresence?)], accountPeer: Peer, controllerInteraction: ShareControllerInteraction, externalShare: Bool, switchToAnotherAccount: @escaping () -> Void, debugAction: @escaping () -> Void, extendedInitialReveal: Bool, segmentedValues: [ShareControllerSegmentedValue]?) {
init(sharedContext: SharedAccountContext, context: AccountContext, switchableAccounts: [AccountWithInfo], theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, peers: [(EngineRenderedPeer, PeerPresence?)], accountPeer: EnginePeer, controllerInteraction: ShareControllerInteraction, externalShare: Bool, switchToAnotherAccount: @escaping () -> Void, debugAction: @escaping () -> Void, extendedInitialReveal: Bool, segmentedValues: [ShareControllerSegmentedValue]?) {
self.sharedContext = sharedContext
self.context = context
self.theme = theme
@ -138,7 +138,7 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
var index: Int32 = 0
var existingPeerIds: Set<PeerId> = Set()
entries.append(SharePeerEntry(index: index, peer: RenderedPeer(peer: accountPeer), presence: nil, theme: theme, strings: strings))
entries.append(SharePeerEntry(index: index, peer: EngineRenderedPeer(peer: accountPeer), presence: nil, theme: theme, strings: strings))
existingPeerIds.insert(accountPeer.id)
index += 1
@ -442,7 +442,7 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
if peer.peerId == self.accountPeer.id {
text = self.strings.DialogList_SavedMessages
} else {
text = peer.chatMainPeer.flatMap(EnginePeer.init)?.displayTitle(strings: self.strings, displayOrder: self.nameDisplayOrder) ?? ""
text = peer.chatMainPeer?.displayTitle(strings: self.strings, displayOrder: self.nameDisplayOrder) ?? ""
}
if !string.isEmpty {

View File

@ -93,7 +93,7 @@ private enum ShareSearchRecentEntry: Comparable, Identifiable {
if let associatedPeer = associatedPeer {
peers[associatedPeer.id] = associatedPeer
}
let peer = RenderedPeer(peerId: peer.id, peers: SimpleDictionary(peers))
let peer = EngineRenderedPeer(RenderedPeer(peerId: peer.id, peers: SimpleDictionary(peers)))
return ShareControllerPeerGridItem(context: context, theme: theme, strings: strings, peer: peer, presence: presence, controllerInteraction: interfaceInteraction, sectionTitle: strings.DialogList_SearchSectionRecent, search: true)
}
}
@ -101,7 +101,7 @@ private enum ShareSearchRecentEntry: Comparable, Identifiable {
private struct ShareSearchPeerEntry: Comparable, Identifiable {
let index: Int32
let peer: RenderedPeer?
let peer: EngineRenderedPeer?
let presence: PeerPresence?
let theme: PresentationTheme
let strings: PresentationStrings
@ -262,7 +262,7 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
if strings.DialogList_SavedMessages.lowercased().hasPrefix(lowercasedQuery) || "saved messages".hasPrefix(lowercasedQuery) {
if !existingPeerIds.contains(accountPeer.id) {
existingPeerIds.insert(accountPeer.id)
entries.append(ShareSearchPeerEntry(index: index, peer: RenderedPeer(peer: accountPeer), presence: nil, theme: theme, strings: strings))
entries.append(ShareSearchPeerEntry(index: index, peer: EngineRenderedPeer(RenderedPeer(peer: accountPeer)), presence: nil, theme: theme, strings: strings))
index += 1
}
}
@ -271,7 +271,7 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
if let peer = renderedPeer.peers[renderedPeer.peerId], peer.id != accountPeer.id {
if !existingPeerIds.contains(renderedPeer.peerId) && canSendMessagesToPeer(peer) {
existingPeerIds.insert(renderedPeer.peerId)
entries.append(ShareSearchPeerEntry(index: index, peer: renderedPeer, presence: nil, theme: theme, strings: strings))
entries.append(ShareSearchPeerEntry(index: index, peer: EngineRenderedPeer(renderedPeer), presence: nil, theme: theme, strings: strings))
index += 1
}
}
@ -289,7 +289,7 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
let peer = foundPeer.peer
if !existingPeerIds.contains(peer.id) && canSendMessagesToPeer(peer) {
existingPeerIds.insert(peer.id)
entries.append(ShareSearchPeerEntry(index: index, peer: RenderedPeer(peer: foundPeer.peer), presence: nil, theme: theme, strings: strings))
entries.append(ShareSearchPeerEntry(index: index, peer: EngineRenderedPeer(RenderedPeer(peer: foundPeer.peer)), presence: nil, theme: theme, strings: strings))
index += 1
}
}
@ -298,7 +298,7 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
let peer = foundPeer.peer
if !existingPeerIds.contains(peer.id) && canSendMessagesToPeer(peer) {
existingPeerIds.insert(peer.id)
entries.append(ShareSearchPeerEntry(index: index, peer: RenderedPeer(peer: peer), presence: nil, theme: theme, strings: strings))
entries.append(ShareSearchPeerEntry(index: index, peer: EngineRenderedPeer(RenderedPeer(peer: peer)), presence: nil, theme: theme, strings: strings))
index += 1
}
}

View File

@ -410,7 +410,7 @@ private func channelStatsControllerEntries(data: ChannelStats?, messages: [Messa
return entries
}
public func channelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, cachedPeerData: CachedPeerData) -> ViewController {
public func channelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, statsDatacenterId: Int32?) -> ViewController {
var openMessageStatsImpl: ((MessageId) -> Void)?
var contextActionImpl: ((MessageId, ASDisplayNode, ContextGesture?) -> Void)?
@ -418,10 +418,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
let dataPromise = Promise<ChannelStats?>(nil)
let messagesPromise = Promise<MessageHistoryView?>(nil)
var datacenterId: Int32 = 0
if let cachedData = cachedPeerData as? CachedChannelData {
datacenterId = cachedData.statsDatacenterId
}
let datacenterId: Int32 = statsDatacenterId ?? 0
let statsContext = ChannelStatsContext(postbox: context.account.postbox, network: context.account.network, datacenterId: datacenterId, peerId: peerId)
let dataSignal: Signal<ChannelStats?, NoError> = statsContext.state
@ -505,10 +502,6 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
controller?.clearItemNodesHighlight(animated: true)
}
openMessageStatsImpl = { [weak controller] messageId in
var statsDatacenterId: Int32?
if let cachedData = cachedPeerData as? CachedChannelData {
statsDatacenterId = cachedData.statsDatacenterId
}
controller?.push(messageStatsController(context: context, messageId: messageId, statsDatacenterId: statsDatacenterId))
}
contextActionImpl = { [weak controller] messageId, sourceNode, gesture in

View File

@ -478,7 +478,7 @@ private enum StatsEntry: ItemListNodeEntry {
}
}
private func groupStatsControllerEntries(accountPeerId: PeerId, state: GroupStatsState, data: GroupStats?, channelPeer: Peer, peers: [PeerId: Peer]?, presentationData: PresentationData) -> [StatsEntry] {
private func groupStatsControllerEntries(accountPeerId: PeerId, state: GroupStatsState, data: GroupStats?, channelPeer: Peer, peers: [EnginePeer.Id: EnginePeer]?, presentationData: PresentationData) -> [StatsEntry] {
var entries: [StatsEntry] = []
if let data = data {
@ -545,7 +545,7 @@ private func groupStatsControllerEntries(accountPeerId: PeerId, state: GroupStat
for topPoster in topPosters {
if let peer = peers[topPoster.peerId], topPoster.messageCount > 0 {
entries.append(.topPoster(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topPoster, topPoster.peerId == state.posterPeerIdWithRevealedOptions, canPromote))
entries.append(.topPoster(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), topPoster, topPoster.peerId == state.posterPeerIdWithRevealedOptions, canPromote))
index += 1
}
}
@ -568,7 +568,7 @@ private func groupStatsControllerEntries(accountPeerId: PeerId, state: GroupStat
for topAdmin in data.topAdmins {
if let peer = peers[topAdmin.peerId], (topAdmin.deletedCount + topAdmin.kickedCount + topAdmin.bannedCount) > 0 {
entries.append(.topAdmin(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topAdmin, topAdmin.peerId == state.adminPeerIdWithRevealedOptions, canPromote))
entries.append(.topAdmin(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), topAdmin, topAdmin.peerId == state.adminPeerIdWithRevealedOptions, canPromote))
index += 1
}
}
@ -591,7 +591,7 @@ private func groupStatsControllerEntries(accountPeerId: PeerId, state: GroupStat
for topInviter in data.topInviters {
if let peer = peers[topInviter.peerId], topInviter.inviteCount > 0 {
entries.append(.topInviter(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topInviter, topInviter.peerId == state.inviterPeerIdWithRevealedOptions, canPromote))
entries.append(.topInviter(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), topInviter, topInviter.peerId == state.inviterPeerIdWithRevealedOptions, canPromote))
index += 1
}
}
@ -708,7 +708,7 @@ private func canEditAdminRights(accountPeerId: PeerId, channelPeer: Peer, initia
}
}
public func groupStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, cachedPeerData: CachedPeerData) -> ViewController {
public func groupStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, statsDatacenterId: Int32?) -> ViewController {
let statePromise = ValuePromise(GroupStatsState())
let stateValue = Atomic(value: GroupStatsState())
let updateState: ((GroupStatsState) -> GroupStatsState) -> Void = { f in
@ -717,12 +717,9 @@ public func groupStatsController(context: AccountContext, updatedPresentationDat
let actionsDisposable = DisposableSet()
let dataPromise = Promise<GroupStats?>(nil)
let peersPromise = Promise<[PeerId: Peer]?>(nil)
let peersPromise = Promise<[EnginePeer.Id: EnginePeer]?>(nil)
var datacenterId: Int32 = 0
if let cachedData = cachedPeerData as? CachedChannelData {
datacenterId = cachedData.statsDatacenterId
}
let datacenterId: Int32 = statsDatacenterId ?? 0
var openPeerImpl: ((PeerId) -> Void)?
var openPeerHistoryImpl: ((PeerId) -> Void)?
@ -757,27 +754,26 @@ public func groupStatsController(context: AccountContext, updatedPresentationDat
return value != nil
}
|> take(1)
|> map { stats -> [PeerId]? in
|> map { stats -> [EnginePeer.Id]? in
guard let stats = stats else {
return nil
}
var peerIds = Set<PeerId>()
var peerIds = Set<EnginePeer.Id>()
peerIds.formUnion(stats.topPosters.map { $0.peerId })
peerIds.formUnion(stats.topAdmins.map { $0.peerId })
peerIds.formUnion(stats.topInviters.map { $0.peerId })
return Array(peerIds)
}
|> mapToSignal { peerIds -> Signal<[PeerId: Peer]?, NoError> in
return context.account.postbox.transaction { transaction -> [PeerId: Peer]? in
var peers: [PeerId: Peer] = [:]
if let peerIds = peerIds {
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers[peerId] = peer
}
}
|> mapToSignal { peerIds -> Signal<[EnginePeer.Id: EnginePeer]?, NoError> in
if let peerIds = peerIds {
return context.engine.data.get(EngineDataMap(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
))
|> map { peerMap -> [EnginePeer.Id: EnginePeer]? in
return peerMap.compactMapValues { $0 }
}
return peers
} else {
return .single([:])
}
}))

View File

@ -201,14 +201,16 @@ final class StickerPackPreviewControllerNode: ViewControllerTracingNode, UIScrol
if let strongSelf = self {
if let itemNode = strongSelf.contentGridNode.itemNodeAtPoint(point) as? StickerPackPreviewGridItemNode, let item = itemNode.stickerPackItem {
let accountPeerId = strongSelf.context.account.peerId
return strongSelf.context.account.postbox.transaction { transaction -> (Bool, Bool) in
let isStarred = getIsStickerSaved(transaction: transaction, fileId: item.file.fileId)
var hasPremium = false
if let peer = transaction.getPeer(accountPeerId) as? TelegramUser, peer.isPremium {
hasPremium = true
return combineLatest(
strongSelf.context.engine.stickers.isStickerSaved(id: item.file.fileId),
strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: accountPeerId)) |> map { peer -> Bool in
var hasPremium = false
if case let .user(user) = peer, user.isPremium {
hasPremium = true
}
return hasPremium
}
return (isStarred, hasPremium)
}
)
|> deliverOnMainQueue
|> map { isStarred, hasPremium -> (ASDisplayNode, PeekControllerContent)? in
if let strongSelf = self {

View File

@ -335,14 +335,16 @@ private final class StickerPackContainer: ASDisplayNode {
if let strongSelf = self {
if let itemNode = strongSelf.gridNode.itemNodeAtPoint(point) as? StickerPackPreviewGridItemNode, let item = itemNode.stickerPackItem {
let accountPeerId = strongSelf.context.account.peerId
return strongSelf.context.account.postbox.transaction { transaction -> (Bool, Bool) in
let isStarred = getIsStickerSaved(transaction: transaction, fileId: item.file.fileId)
var hasPremium = false
if let peer = transaction.getPeer(accountPeerId) as? TelegramUser, peer.isPremium {
hasPremium = true
return combineLatest(
strongSelf.context.engine.stickers.isStickerSaved(id: item.file.fileId),
strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: accountPeerId)) |> map { peer -> Bool in
var hasPremium = false
if case let .user(user) = peer, user.isPremium {
hasPremium = true
}
return hasPremium
}
return (isStarred, hasPremium)
}
)
|> deliverOnMainQueue
|> map { isStarred, hasPremium -> (ASDisplayNode, PeekControllerContent)? in
if let strongSelf = self {

View File

@ -877,28 +877,24 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|> map { peer in
return [FoundPeer(peer: peer, subscribers: nil)]
}
let cachedData = context.account.postbox.transaction { transaction -> CachedPeerData? in
return transaction.getPeerCachedData(peerId: peerId)
}
let _ = (combineLatest(currentAccountPeer, context.engine.calls.cachedGroupCallDisplayAsAvailablePeers(peerId: peerId), cachedData)
|> map { currentAccountPeer, availablePeers, cachedData -> ([FoundPeer], CachedPeerData?) in
let _ = (combineLatest(
currentAccountPeer,
context.engine.calls.cachedGroupCallDisplayAsAvailablePeers(peerId: peerId),
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.CallJoinAsPeerId(id: peerId))
)
|> map { currentAccountPeer, availablePeers, callJoinAsPeerId -> ([FoundPeer], EnginePeer.Id?) in
var result = currentAccountPeer
result.append(contentsOf: availablePeers)
return (result, cachedData)
return (result, callJoinAsPeerId)
}
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] peers, cachedData in
|> deliverOnMainQueue).start(next: { [weak self] peers, callJoinAsPeerId in
guard let strongSelf = self else {
return
}
var defaultJoinAsPeerId: PeerId?
if let cachedData = cachedData as? CachedChannelData {
defaultJoinAsPeerId = cachedData.callJoinPeerId
} else if let cachedData = cachedData as? CachedGroupData {
defaultJoinAsPeerId = cachedData.callJoinPeerId
}
let defaultJoinAsPeerId: PeerId? = callJoinAsPeerId
if peers.count == 1, let peer = peers.first {
completion(peer.peer.id)

View File

@ -598,10 +598,7 @@ public final class MediaStreamComponent: CombinedComponent {
strongSelf.updated(transition: .immediate)
})
let peerId = call.peerId
let callPeer = call.accountContext.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
}
let callPeer = call.accountContext.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: call.peerId))
self.infoDisposable = (combineLatest(queue: .mainQueue(), call.state, call.members, callPeer)
|> deliverOnMainQueue).start(next: { [weak self] state, members, callPeer in
@ -618,7 +615,7 @@ public final class MediaStreamComponent: CombinedComponent {
strongSelf.peerTitle = callPeer.debugDisplayTitle
updated = true
}
strongSelf.chatPeer = callPeer
strongSelf.chatPeer = callPeer._asPeer()
if strongSelf.callTitle != state.title {
strongSelf.callTitle = state.title
@ -1252,18 +1249,17 @@ public final class MediaStreamComponentController: ViewControllerComponentContai
return
}
let callPeerId = strongSelf.call.peerId
let _ = (strongSelf.call.accountContext.account.postbox.transaction { transaction -> GroupCallInviteLinks? in
let _ = (strongSelf.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.call.peerId),
TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: strongSelf.call.peerId)
)
|> map { peer, exportedInvitation -> GroupCallInviteLinks? in
if let inviteLinks = inviteLinks {
return inviteLinks
} else if let peer = transaction.getPeer(callPeerId), let addressName = peer.addressName, !addressName.isEmpty {
} else if let peer = peer, let addressName = peer.addressName, !addressName.isEmpty {
return GroupCallInviteLinks(listenerLink: "https://t.me/\(addressName)?voicechat", speakerLink: nil)
} else if let cachedData = transaction.getPeerCachedData(peerId: callPeerId) {
if let cachedData = cachedData as? CachedChannelData, let link = cachedData.exportedInvitation?.link {
return GroupCallInviteLinks(listenerLink: link, speakerLink: nil)
} else if let cachedData = cachedData as? CachedGroupData, let link = cachedData.exportedInvitation?.link {
return GroupCallInviteLinks(listenerLink: link, speakerLink: nil)
}
} else if let link = exportedInvitation?.link {
return GroupCallInviteLinks(listenerLink: link, speakerLink: nil)
}
return nil
}
@ -1313,30 +1309,28 @@ public final class MediaStreamComponentController: ViewControllerComponentContai
let shareController = ShareController(context: strongSelf.context, subject: .url(inviteLinks.listenerLink), segmentedValues: segmentedValues, forceTheme: defaultDarkPresentationTheme, forcedActionTitle: presentationData.strings.VoiceChat_CopyInviteLink)
shareController.completed = { [weak self] peerIds in
if let strongSelf = self {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { [weak self] peers in
let _ = (strongSelf.context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { [weak self] peerList in
if let strongSelf = self {
let peers = peerList.compactMap { $0 }
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
var isSavedMessages = false
if peers.count == 1, let peer = peers.first {
isSavedMessages = peer.id == strongSelf.context.account.peerId
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.VoiceChat_ForwardTooltip_Chat(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.VoiceChat_ForwardTooltip_TwoChats(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.VoiceChat_ForwardTooltip_ManyChats(peerName, "\(peers.count - 1)").string
} else {
text = ""

View File

@ -194,9 +194,13 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
return .single(([], enableCallKit && enabledMicrophoneAccess))
} else {
return combineLatest(ringingStatesByAccount.map { context, state, networkType -> Signal<(AccountContext, Peer, CallSessionRingingState, Bool, NetworkType)?, NoError> in
return context.account.postbox.transaction { transaction -> (AccountContext, Peer, CallSessionRingingState, Bool, NetworkType)? in
if let peer = transaction.getPeer(state.peerId) {
return (context, peer, state, transaction.isPeerContact(peerId: state.peerId), networkType)
return context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: state.peerId),
TelegramEngine.EngineData.Item.Peer.IsContact(id: state.peerId)
)
|> map { peer, isContact -> (AccountContext, Peer, CallSessionRingingState, Bool, NetworkType)? in
if let peer = peer {
return (context, peer._asPeer(), state, isContact, networkType)
} else {
return nil
}
@ -493,37 +497,20 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
return .single(false)
}
let request = context.account.postbox.transaction { transaction -> (VideoCallsConfiguration, CachedUserData?) in
let appConfiguration: AppConfiguration = transaction.getPreferencesEntry(key: PreferencesKeys.appConfiguration)?.get(AppConfiguration.self) ?? AppConfiguration.defaultValue
return (VideoCallsConfiguration(appConfiguration: appConfiguration), transaction.getPeerCachedData(peerId: peerId) as? CachedUserData)
}
|> mapToSignal { callsConfiguration, cachedUserData -> Signal<CallSessionInternalId, NoError> in
var isVideoPossible: Bool
switch callsConfiguration.videoCallsSupport {
case .disabled:
isVideoPossible = isVideo
case .full:
isVideoPossible = true
case .onlyVideo:
isVideoPossible = isVideo
}
if let cachedUserData = cachedUserData, cachedUserData.videoCallsAvailable {
} else {
isVideoPossible = false
}
let areVideoCallsAvailable = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.AreVideoCallsAvailable(id: peerId))
let request = areVideoCallsAvailable
|> mapToSignal { areVideoCallsAvailable -> Signal<CallSessionInternalId, NoError> in
let isVideoPossible: Bool = areVideoCallsAvailable
return context.account.callSessionManager.request(peerId: peerId, isVideo: isVideo, enableVideo: isVideoPossible, internalId: internalId)
}
let cachedUserData = context.account.postbox.transaction { transaction -> CachedUserData? in
return transaction.getPeerCachedData(peerId: peerId) as? CachedUserData
}
return (combineLatest(queue: .mainQueue(), request, networkType |> take(1), context.account.postbox.peerView(id: peerId) |> map { peerView -> Bool in
return peerView.peerIsContact
} |> take(1), context.account.postbox.preferencesView(keys: [PreferencesKeys.voipConfiguration, ApplicationSpecificPreferencesKeys.voipDerivedState, PreferencesKeys.appConfiguration]) |> take(1), accountManager.sharedData(keys: [SharedDataKeys.autodownloadSettings, ApplicationSpecificSharedDataKeys.experimentalUISettings]) |> take(1), cachedUserData)
} |> take(1), context.account.postbox.preferencesView(keys: [PreferencesKeys.voipConfiguration, ApplicationSpecificPreferencesKeys.voipDerivedState, PreferencesKeys.appConfiguration]) |> take(1), accountManager.sharedData(keys: [SharedDataKeys.autodownloadSettings, ApplicationSpecificSharedDataKeys.experimentalUISettings]) |> take(1), areVideoCallsAvailable)
|> deliverOnMainQueue
|> beforeNext { internalId, currentNetworkType, isContact, preferences, sharedData, cachedUserData in
|> beforeNext { internalId, currentNetworkType, isContact, preferences, sharedData, areVideoCallsAvailable in
if let strongSelf = self, accessEnabled {
if let currentCall = strongSelf.currentCall {
currentCall.rejectBusy()
@ -534,20 +521,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
let autodownloadSettings = sharedData.entries[SharedDataKeys.autodownloadSettings]?.get(AutodownloadSettings.self) ?? .defaultSettings
let appConfiguration = preferences.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) ?? AppConfiguration.defaultValue
let callsConfiguration = VideoCallsConfiguration(appConfiguration: appConfiguration)
var isVideoPossible: Bool
switch callsConfiguration.videoCallsSupport {
case .disabled:
isVideoPossible = isVideo
case .full:
isVideoPossible = true
case .onlyVideo:
isVideoPossible = isVideo
}
if let cachedUserData = cachedUserData, cachedUserData.videoCallsAvailable {
} else {
isVideoPossible = false
}
let isVideoPossible: Bool = areVideoCallsAvailable
let experimentalSettings = sharedData.entries[ApplicationSpecificSharedDataKeys.experimentalUISettings]?.get(ExperimentalUISettings.self) ?? .defaultSettings

View File

@ -1191,27 +1191,33 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
private func switchToTemporaryParticipantsContext(sourceContext: GroupCallParticipantsContext?, oldMyPeerId: PeerId) {
let myPeerId = self.joinAsPeerId
let accountContext = self.accountContext
let myPeer = self.accountContext.account.postbox.transaction { transaction -> (Peer, CachedPeerData?)? in
if let peer = transaction.getPeer(myPeerId) {
return (peer, transaction.getPeerCachedData(peerId: myPeerId))
} else {
let myPeerData = self.accountContext.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: myPeerId),
TelegramEngine.EngineData.Item.Peer.AboutText(id: myPeerId)
)
|> map { peer, aboutText -> (EnginePeer, String?)? in
guard let peer = peer else {
return nil
}
}
|> beforeNext { view in
if let view = view, view.1 == nil {
switch aboutText {
case let .known(value):
return (peer, value)
case .unknown:
let _ = accountContext.engine.peers.fetchAndUpdateCachedPeerData(peerId: myPeerId).start()
return (peer, nil)
}
}
if let sourceContext = sourceContext, let initialState = sourceContext.immediateState {
let temporaryParticipantsContext = self.accountContext.engine.calls.groupCall(peerId: self.peerId, myPeerId: myPeerId, id: sourceContext.id, accessHash: sourceContext.accessHash, state: initialState, previousServiceState: sourceContext.serviceState)
self.temporaryParticipantsContext = temporaryParticipantsContext
self.participantsContextStateDisposable.set((combineLatest(queue: .mainQueue(),
myPeer,
myPeerData,
temporaryParticipantsContext.state,
temporaryParticipantsContext.activeSpeakers
)
|> take(1)).start(next: { [weak self] myPeerAndCachedData, state, activeSpeakers in
|> take(1)).start(next: { [weak self] myPeerData, state, activeSpeakers in
guard let strongSelf = self else {
return
}
@ -1240,17 +1246,15 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
if !participants.contains(where: { $0.peer.id == myPeerId }) {
if let (myPeer, cachedData) = myPeerAndCachedData {
if let (myPeer, aboutText) = myPeerData {
let about: String?
if let cachedData = cachedData as? CachedUserData {
about = cachedData.about
} else if let cachedData = cachedData as? CachedUserData {
about = cachedData.about
if let aboutText = aboutText {
about = aboutText
} else {
about = " "
}
participants.append(GroupCallParticipantsContext.Participant(
peer: myPeer,
peer: myPeer._asPeer(),
ssrc: nil,
videoDescription: nil,
presentationDescription: nil,
@ -1304,9 +1308,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}))
} else {
self.temporaryParticipantsContext = nil
self.participantsContextStateDisposable.set((myPeer
self.participantsContextStateDisposable.set((myPeerData
|> deliverOnMainQueue
|> take(1)).start(next: { [weak self] myPeerAndCachedData in
|> take(1)).start(next: { [weak self] myPeerData in
guard let strongSelf = self else {
return
}
@ -1322,17 +1326,15 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
var participants: [GroupCallParticipantsContext.Participant] = []
if let (myPeer, cachedData) = myPeerAndCachedData {
if let (myPeer, aboutText) = myPeerData {
let about: String?
if let cachedData = cachedData as? CachedUserData {
about = cachedData.about
} else if let cachedData = cachedData as? CachedUserData {
about = cachedData.about
if let aboutText = aboutText {
about = aboutText
} else {
about = " "
}
participants.append(GroupCallParticipantsContext.Participant(
peer: myPeer,
peer: myPeer._asPeer(),
ssrc: nil,
videoDescription: nil,
presentationDescription: nil,
@ -1454,24 +1456,30 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
self.participantsContext = participantsContext
let myPeerId = self.joinAsPeerId
let myPeer = self.accountContext.account.postbox.transaction { transaction -> (Peer, CachedPeerData?)? in
if let peer = transaction.getPeer(myPeerId) {
return (peer, transaction.getPeerCachedData(peerId: myPeerId))
} else {
let myPeerData = self.accountContext.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: myPeerId),
TelegramEngine.EngineData.Item.Peer.AboutText(id: myPeerId)
)
|> map { peer, aboutText -> (EnginePeer, String?)? in
guard let peer = peer else {
return nil
}
}
|> beforeNext { view in
if let view = view, view.1 == nil {
switch aboutText {
case let .known(value):
return (peer, value)
case .unknown:
let _ = accountContext.engine.peers.fetchAndUpdateCachedPeerData(peerId: myPeerId).start()
return (peer, nil)
}
}
self.participantsContextStateDisposable.set(combineLatest(queue: .mainQueue(),
participantsContext.state,
adminIds,
myPeer,
myPeerData,
accountContext.account.postbox.peerView(id: peerId)
).start(next: { [weak self] state, adminIds, myPeerAndCachedData, view in
).start(next: { [weak self] state, adminIds, myPeerData, view in
guard let strongSelf = self else {
return
}
@ -1488,17 +1496,15 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
var participants: [GroupCallParticipantsContext.Participant] = []
var topParticipants: [GroupCallParticipantsContext.Participant] = []
if let (myPeer, cachedData) = myPeerAndCachedData {
if let (myPeer, aboutText) = myPeerData {
let about: String?
if let cachedData = cachedData as? CachedUserData {
about = cachedData.about
} else if let cachedData = cachedData as? CachedUserData {
about = cachedData.about
if let aboutText = aboutText {
about = aboutText
} else {
about = " "
}
participants.append(GroupCallParticipantsContext.Participant(
peer: myPeer,
peer: myPeer._asPeer(),
ssrc: nil,
videoDescription: nil,
presentationDescription: nil,
@ -2340,19 +2346,22 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
}))
let postbox = self.accountContext.account.postbox
let engine = self.accountContext.engine
self.memberEventsPipeDisposable.set((participantsContext.memberEvents
|> mapToSignal { event -> Signal<PresentationGroupCallMemberEvent, NoError> in
return postbox.transaction { transaction -> Signal<PresentationGroupCallMemberEvent, NoError> in
if let peer = transaction.getPeer(event.peerId) {
let isContact = transaction.isPeerContact(peerId: event.peerId)
let isInChatList = transaction.getPeerChatListIndex(event.peerId) != nil
return .single(PresentationGroupCallMemberEvent(peer: peer, isContact: isContact, isInChatList: isInChatList, canUnmute: event.canUnmute, joined: event.joined))
return engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: event.peerId),
TelegramEngine.EngineData.Item.Peer.IsContact(id: event.peerId),
TelegramEngine.EngineData.Item.Messages.ChatListIndex(id: event.peerId)
)
|> mapToSignal { peer, isContact, chatListIndex -> Signal<PresentationGroupCallMemberEvent, NoError> in
if let peer = peer {
let isInChatList = chatListIndex != nil
return .single(PresentationGroupCallMemberEvent(peer: peer._asPeer(), isContact: isContact, isInChatList: isInChatList, canUnmute: event.canUnmute, joined: event.joined))
} else {
return .complete()
}
}
|> switchToLatest
}
|> deliverOnMainQueue).start(next: { [weak self] event in
guard let strongSelf = self, event.peer.id != strongSelf.stateValue.myPeerId else {
@ -2559,9 +2568,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
if peerId == self.joinAsPeerId {
return
}
let _ = (self.accountContext.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
}
let _ = (self.accountContext.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { [weak self] myPeer in
guard let strongSelf = self, let myPeer = myPeer else {
return
@ -2575,14 +2582,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
if strongSelf.stateValue.scheduleTimestamp != nil {
strongSelf.stateValue.myPeerId = peerId
strongSelf.reconnectedAsEventsPipe.putNext(myPeer)
strongSelf.reconnectedAsEventsPipe.putNext(myPeer._asPeer())
strongSelf.switchToTemporaryScheduledParticipantsContext()
} else {
strongSelf.disableVideo()
strongSelf.isMutedValue = .muted(isPushToTalkActive: false)
strongSelf.isMutedPromise.set(strongSelf.isMutedValue)
strongSelf.reconnectingAsPeer = myPeer
strongSelf.reconnectingAsPeer = myPeer._asPeer()
if let participantsContext = strongSelf.participantsContext, let immediateState = participantsContext.immediateState {
for participant in immediateState.participants {

View File

@ -838,7 +838,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
private var currentSpeakingSubtitle: String?
private var currentCallMembers: ([GroupCallParticipantsContext.Participant], String?)?
private var currentTotalCount: Int32 = 0
private var currentInvitedPeers: [Peer]?
private var currentInvitedPeers: [EnginePeer]?
private var currentSpeakingPeers: Set<PeerId>?
private var currentContentOffset: CGFloat?
private var currentNormalButtonColor: UIColor?
@ -1194,11 +1194,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
return
}
let groupPeerId = strongSelf.call.peerId
let groupPeer = strongSelf.context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(groupPeerId)
}
let groupPeer = strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.call.peerId))
let _ = combineLatest(queue: Queue.mainQueue(), groupPeer, strongSelf.inviteLinksPromise.get() |> take(1)).start(next: { groupPeer, inviteLinks in
guard let strongSelf = self else {
return
@ -1207,7 +1203,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
return
}
if let groupPeer = groupPeer as? TelegramChannel {
if case let .channel(groupPeer) = groupPeer {
var canInviteMembers = true
if case .broadcast = groupPeer.info, !(groupPeer.addressName?.isEmpty ?? true) {
canInviteMembers = false
@ -1224,11 +1220,11 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
if let (currentCallMembers, _) = strongSelf.currentCallMembers {
filters.append(.disable(Array(currentCallMembers.map { $0.peer.id })))
}
if let groupPeer = groupPeer as? TelegramChannel {
if case let .channel(groupPeer) = groupPeer {
if !groupPeer.hasPermission(.inviteMembers) && inviteLinks?.listenerLink == nil {
filters.append(.excludeNonMembers)
}
} else if let groupPeer = groupPeer as? TelegramGroup {
} else if case let .legacyGroup(groupPeer) = groupPeer {
if groupPeer.hasBannedPermission(.banAddMembers) {
filters.append(.excludeNonMembers)
}
@ -1242,6 +1238,8 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
return
}
let peer = EnginePeer(peer)
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
if peer.id == strongSelf.callState?.myPeerId {
return
@ -1252,15 +1250,15 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
if strongSelf.call.invitePeer(participant.peer.id) {
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: EnginePeer(participant.peer), text: text), action: { _ in return false })
}
} else {
if let groupPeer = groupPeer as? TelegramChannel, let listenerLink = inviteLinks?.listenerLink, !groupPeer.hasPermission(.inviteMembers) {
let text = strongSelf.presentationData.strings.VoiceChat_SendPublicLinkText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), EnginePeer(groupPeer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
if case let .channel(groupPeer) = groupPeer, let listenerLink = inviteLinks?.listenerLink, !groupPeer.hasPermission(.inviteMembers) {
let text = strongSelf.presentationData.strings.VoiceChat_SendPublicLinkText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), EnginePeer(groupPeer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
strongSelf.controller?.present(textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.VoiceChat_SendPublicLinkSend, action: { [weak self] in
dismissController?()
@ -1269,17 +1267,17 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: listenerLink, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)])
|> deliverOnMainQueue).start(next: { [weak self] _ in
if let strongSelf = self {
strongSelf.presentUndoOverlay(content: .forward(savedMessages: false, text: strongSelf.presentationData.strings.UserInfo_LinkForwardTooltip_Chat_One(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), action: { _ in return true })
strongSelf.presentUndoOverlay(content: .forward(savedMessages: false, text: strongSelf.presentationData.strings.UserInfo_LinkForwardTooltip_Chat_One(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), action: { _ in return true })
}
})
}
})]), in: .window(.root))
} else {
let text: String
if let groupPeer = groupPeer as? TelegramChannel, case .broadcast = groupPeer.info {
text = strongSelf.presentationData.strings.VoiceChat_InviteMemberToChannelFirstText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), EnginePeer(groupPeer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
if case let .channel(groupPeer) = groupPeer, case .broadcast = groupPeer.info {
text = strongSelf.presentationData.strings.VoiceChat_InviteMemberToChannelFirstText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), EnginePeer(groupPeer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_InviteMemberToGroupFirstText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), EnginePeer(groupPeer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
text = strongSelf.presentationData.strings.VoiceChat_InviteMemberToGroupFirstText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), groupPeer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.controller?.present(textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.VoiceChat_InviteMemberToGroupFirstAdd, action: {
@ -1287,7 +1285,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
return
}
if let groupPeer = groupPeer as? TelegramChannel {
if case let .channel(groupPeer) = groupPeer {
let selfController = strongSelf.controller
let inviteDisposable = strongSelf.inviteDisposable
var inviteSignal = strongSelf.context.peerChannelMemberCategoriesContextsManager.addMembers(engine: strongSelf.context.engine, peerId: groupPeer.id, memberIds: [peer.id])
@ -1360,14 +1358,14 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
if strongSelf.call.invitePeer(peer.id) {
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: EnginePeer(peer), text: text), action: { _ in return false })
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: text), action: { _ in return false })
}
}))
} else if let groupPeer = groupPeer as? TelegramGroup {
} else if case let .legacyGroup(groupPeer) = groupPeer {
let selfController = strongSelf.controller
let inviteDisposable = strongSelf.inviteDisposable
var inviteSignal = strongSelf.context.engine.peers.addGroupMember(peerId: groupPeer.id, memberId: peer.id)
@ -1428,11 +1426,11 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
if strongSelf.call.invitePeer(peer.id) {
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: EnginePeer(peer), text: text), action: { _ in return false })
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: text), action: { _ in return false })
}
}))
}
@ -1448,19 +1446,20 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
}
let callPeerId = strongSelf.call.peerId
let _ = (strongSelf.context.account.postbox.transaction { transaction -> String? in
let _ = (strongSelf.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: callPeerId),
TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: callPeerId)
)
|> map { peer, exportedInvitation -> String? in
if let link = inviteLinks?.listenerLink {
return link
} else if let peer = transaction.getPeer(callPeerId), let addressName = peer.addressName, !addressName.isEmpty {
} else if let peer = peer, let addressName = peer.addressName, !addressName.isEmpty {
return "https://t.me/\(addressName)"
} else if let cachedData = transaction.getPeerCachedData(peerId: callPeerId) {
if let cachedData = cachedData as? CachedChannelData {
return cachedData.exportedInvitation?.link
} else if let cachedData = cachedData as? CachedGroupData {
return cachedData.exportedInvitation?.link
}
} else if let link = exportedInvitation?.link {
return link
} else {
return nil
}
return nil
}
|> deliverOnMainQueue).start(next: { link in
guard let strongSelf = self else {
@ -1877,10 +1876,13 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
self.updateDecorationsColors()
let invitedPeers: Signal<[Peer], NoError> = self.call.invitedPeers
|> mapToSignal { ids -> Signal<[Peer], NoError> in
return context.account.postbox.transaction { transaction -> [Peer] in
return ids.compactMap(transaction.getPeer)
let invitedPeers: Signal<[EnginePeer], NoError> = self.call.invitedPeers
|> mapToSignal { ids -> Signal<[EnginePeer], NoError> in
return context.engine.data.get(EngineDataList(
ids.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
))
|> map { itemList -> [EnginePeer] in
return itemList.compactMap { $0 }
}
}
@ -3394,30 +3396,28 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
let shareController = ShareController(context: strongSelf.context, subject: .url(inviteLinks.listenerLink), segmentedValues: segmentedValues, forceTheme: strongSelf.darkTheme, forcedActionTitle: presentationData.strings.VoiceChat_CopyInviteLink)
shareController.completed = { [weak self] peerIds in
if let strongSelf = self {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { [weak self] peers in
let _ = (strongSelf.context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { [weak self] peerList in
if let strongSelf = self {
let peers = peerList.compactMap { $0 }
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
var isSavedMessages = false
if peers.count == 1, let peer = peers.first {
isSavedMessages = peer.id == strongSelf.context.account.peerId
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.VoiceChat_ForwardTooltip_Chat(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.VoiceChat_ForwardTooltip_TwoChats(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = presentationData.strings.VoiceChat_ForwardTooltip_ManyChats(peerName, "\(peers.count - 1)").string
} else {
text = ""
@ -3603,18 +3603,17 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
return
}
let callPeerId = strongSelf.call.peerId
let _ = (strongSelf.context.account.postbox.transaction { transaction -> GroupCallInviteLinks? in
let _ = (strongSelf.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.call.peerId),
TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: strongSelf.call.peerId)
)
|> map { peer, exportedInvitation -> GroupCallInviteLinks? in
if let inviteLinks = inviteLinks {
return inviteLinks
} else if let peer = transaction.getPeer(callPeerId), let addressName = peer.addressName, !addressName.isEmpty {
} else if let peer = peer, let addressName = peer.addressName, !addressName.isEmpty {
return GroupCallInviteLinks(listenerLink: "https://t.me/\(addressName)?voicechat", speakerLink: nil)
} else if let cachedData = transaction.getPeerCachedData(peerId: callPeerId) {
if let cachedData = cachedData as? CachedChannelData, let link = cachedData.exportedInvitation?.link {
return GroupCallInviteLinks(listenerLink: link, speakerLink: nil)
} else if let cachedData = cachedData as? CachedGroupData, let link = cachedData.exportedInvitation?.link {
return GroupCallInviteLinks(listenerLink: link, speakerLink: nil)
}
} else if let link = exportedInvitation?.link {
return GroupCallInviteLinks(listenerLink: link, speakerLink: nil)
}
return nil
}
@ -5014,7 +5013,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
self.updateMembers(muteState: self.effectiveMuteState, callMembers: self.currentCallMembers ?? ([], nil), invitedPeers: self.currentInvitedPeers ?? [], speakingPeers: self.currentSpeakingPeers ?? Set(), maybeUpdateVideo: maybeUpdateVideo, force: force)
}
private func updateMembers(muteState: GroupCallParticipantsContext.Participant.MuteState?, callMembers: ([GroupCallParticipantsContext.Participant], String?), invitedPeers: [Peer], speakingPeers: Set<PeerId>, maybeUpdateVideo: Bool = true, force: Bool = false) {
private func updateMembers(muteState: GroupCallParticipantsContext.Participant.MuteState?, callMembers: ([GroupCallParticipantsContext.Participant], String?), invitedPeers: [EnginePeer], speakingPeers: Set<EnginePeer.Id>, maybeUpdateVideo: Bool = true, force: Bool = false) {
var disableAnimation = false
if self.currentCallMembers?.1 != callMembers.1 {
disableAnimation = true
@ -5296,7 +5295,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
processedPeerIds.insert(peer.id)
entries.append(.peer(VoiceChatPeerEntry(
peer: peer,
peer: peer._asPeer(),
about: nil,
isMyPeer: false,
videoEndpointId: nil,

View File

@ -73,14 +73,12 @@ public final class VoiceChatJoinScreen: ViewController {
let invite = self.invite
let signal = context.engine.calls.updatedCurrentPeerGroupCall(peerId: peerId)
|> castError(GetCurrentGroupCallError.self)
|> mapToSignal { call -> Signal<(Peer, GroupCallSummary)?, GetCurrentGroupCallError> in
|> mapToSignal { call -> Signal<(EnginePeer, GroupCallSummary)?, GetCurrentGroupCallError> in
if let call = call {
let peer = context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
}
let peer = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> castError(GetCurrentGroupCallError.self)
return combineLatest(peer, context.engine.calls.getCurrentGroupCall(callId: call.id, accessHash: call.accessHash))
|> map { peer, call -> (Peer, GroupCallSummary)? in
|> map { peer, call -> (EnginePeer, GroupCallSummary)? in
if let peer = peer, let call = call {
return (peer, call)
} else {
@ -92,9 +90,7 @@ public final class VoiceChatJoinScreen: ViewController {
}
}
let cachedData = context.account.postbox.transaction { transaction -> CachedPeerData? in
return transaction.getPeerCachedData(peerId: peerId)
}
let callJoinAsPeerId = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.CallJoinAsPeerId(id: peerId))
|> castError(GetCurrentGroupCallError.self)
let currentGroupCall: Signal<(PresentationGroupCall, Int64, Bool)?, GetCurrentGroupCallError>
@ -124,7 +120,7 @@ public final class VoiceChatJoinScreen: ViewController {
currentGroupCall = .single(nil)
}
self.disposable.set(combineLatest(queue: Queue.mainQueue(), signal, context.engine.calls.cachedGroupCallDisplayAsAvailablePeers(peerId: peerId) |> castError(GetCurrentGroupCallError.self), cachedData, currentGroupCall).start(next: { [weak self] peerAndCall, availablePeers, cachedData, currentGroupCallIdAndCanUnmute in
self.disposable.set(combineLatest(queue: Queue.mainQueue(), signal, context.engine.calls.cachedGroupCallDisplayAsAvailablePeers(peerId: peerId) |> castError(GetCurrentGroupCallError.self), callJoinAsPeerId, currentGroupCall).start(next: { [weak self] peerAndCall, availablePeers, callJoinAsPeerId, currentGroupCallIdAndCanUnmute in
if let strongSelf = self {
if let (peer, call) = peerAndCall {
if let (currentGroupCall, currentGroupCallId, canUnmute) = currentGroupCallIdAndCanUnmute, call.info.id == currentGroupCallId {
@ -137,19 +133,14 @@ public final class VoiceChatJoinScreen: ViewController {
return
}
var defaultJoinAsPeerId: PeerId?
if let cachedData = cachedData as? CachedChannelData {
defaultJoinAsPeerId = cachedData.callJoinPeerId
} else if let cachedData = cachedData as? CachedGroupData {
defaultJoinAsPeerId = cachedData.callJoinPeerId
}
let defaultJoinAsPeerId: PeerId? = callJoinAsPeerId
let activeCall = CachedChannelData.ActiveCall(id: call.info.id, accessHash: call.info.accessHash, title: call.info.title, scheduleTimestamp: call.info.scheduleTimestamp, subscribedToScheduled: call.info.subscribedToScheduled, isStream: call.info.isStream)
if availablePeers.count > 0 && defaultJoinAsPeerId == nil {
strongSelf.dismiss()
strongSelf.join(activeCall)
} else {
strongSelf.controllerNode.setPeer(call: activeCall, peer: peer, title: call.info.title, memberCount: call.info.participantCount, isStream: call.info.isStream)
strongSelf.controllerNode.setPeer(call: activeCall, peer: peer._asPeer(), title: call.info.title, memberCount: call.info.participantCount, isStream: call.info.isStream)
}
} else {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }

View File

@ -173,5 +173,53 @@ public extension TelegramEngine.EngineData.Item {
return EngineTotalReadCounters(state: total)
}
}
public struct ChatListIndex: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = EngineChatList.Item.Index?
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .chatListIndex(id: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? ChatListIndexView else {
preconditionFailure()
}
return view.chatListIndex
}
}
public struct ChatListGroup: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = EngineChatList.Group?
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .chatListIndex(id: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? ChatListIndexView else {
preconditionFailure()
}
return view.inclusion.groupId.flatMap(EngineChatList.Group.init)
}
}
}
}

View File

@ -3,6 +3,11 @@ import Postbox
public typealias EngineExportedPeerInvitation = ExportedInvitation
public enum EnginePeerCachedInfoItem<T> {
case known(T)
case unknown
}
public extension TelegramEngine.EngineData.Item {
enum NotificationSettings {
public struct Global: TelegramEngineDataItem, PostboxViewDataItem {
@ -92,7 +97,7 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct Presence: TelegramEngineDataItem, PostboxViewDataItem {
public struct Presence: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Optional<EnginePeer.Presence>
fileprivate var id: EnginePeer.Id
@ -150,7 +155,7 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct ParticipantCount: TelegramEngineDataItem, PostboxViewDataItem {
public struct ParticipantCount: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Optional<Int>
fileprivate var id: EnginePeer.Id
@ -184,7 +189,7 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct GroupCallDescription: TelegramEngineDataItem, PostboxViewDataItem {
public struct GroupCallDescription: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Optional<EngineGroupCallDescription>
fileprivate var id: EnginePeer.Id
@ -218,7 +223,7 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct ExportedInvitation: TelegramEngineDataItem, PostboxViewDataItem {
public struct ExportedInvitation: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Optional<EngineExportedPeerInvitation>
fileprivate var id: EnginePeer.Id
@ -252,7 +257,7 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct StatsDatacenterId: TelegramEngineDataItem, PostboxViewDataItem {
public struct StatsDatacenterId: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Optional<Int32>
fileprivate var id: EnginePeer.Id
@ -284,7 +289,7 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct ThemeEmoticon: TelegramEngineDataItem, PostboxViewDataItem {
public struct ThemeEmoticon: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Optional<String>
fileprivate var id: EnginePeer.Id
@ -319,7 +324,7 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct IsContact: TelegramEngineDataItem, PostboxViewDataItem {
public struct IsContact: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Bool
fileprivate var id: EnginePeer.Id
@ -343,7 +348,7 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct StickerPack: TelegramEngineDataItem, PostboxViewDataItem {
public struct StickerPack: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = StickerPackCollectionInfo?
fileprivate var id: EnginePeer.Id
@ -369,5 +374,306 @@ public extension TelegramEngine.EngineData.Item {
return cachedData.stickerPack
}
}
public struct AllowedReactions: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = [String]?
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedChannelData {
return cachedData.allowedReactions
} else if let cachedData = view.cachedPeerData as? CachedGroupData {
return cachedData.allowedReactions
} else {
return nil
}
}
}
public struct CallJoinAsPeerId: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = EnginePeer.Id?
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedChannelData {
return cachedData.callJoinPeerId
} else if let cachedData = view.cachedPeerData as? CachedGroupData {
return cachedData.callJoinPeerId
} else {
return nil
}
}
}
public struct LinkedDiscussionPeerId: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = EnginePeerCachedInfoItem<EnginePeer.Id?>
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedChannelData {
switch cachedData.linkedDiscussionPeerId {
case let .known(value):
return .known(value)
case .unknown:
return .unknown
}
} else {
return .unknown
}
}
}
public struct StatusSettings: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = EnginePeer.StatusSettings?
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return cachedData.peerStatusSettings.flatMap(EnginePeer.StatusSettings.init)
} else if let cachedData = view.cachedPeerData as? CachedChannelData {
return cachedData.peerStatusSettings.flatMap(EnginePeer.StatusSettings.init)
} else if let cachedData = view.cachedPeerData as? CachedGroupData {
return cachedData.peerStatusSettings.flatMap(EnginePeer.StatusSettings.init)
} else {
return nil
}
}
}
public struct AreVideoCallsAvailable: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Bool
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return cachedData.videoCallsAvailable
} else {
return false
}
}
}
public struct AreVoiceCallsAvailable: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Bool
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return !cachedData.callsPrivate
} else {
return true
}
}
}
public struct AboutText: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = EnginePeerCachedInfoItem<String?>
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return .known(cachedData.about)
} else if let cachedData = view.cachedPeerData as? CachedGroupData {
return .known(cachedData.about)
} else if let cachedData = view.cachedPeerData as? CachedChannelData {
return .known(cachedData.about)
} else {
return .unknown
}
}
}
public struct Photo: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = EnginePeerCachedInfoItem<TelegramMediaImage?>
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return .known(cachedData.photo)
} else if let cachedData = view.cachedPeerData as? CachedGroupData {
return .known(cachedData.photo)
} else if let cachedData = view.cachedPeerData as? CachedChannelData {
return .known(cachedData.photo)
} else {
return .unknown
}
}
}
public struct CanViewStats: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Bool
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedChannelData {
return cachedData.flags.contains(.canViewStats)
} else {
return false
}
}
}
public struct CanDeleteHistory: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Bool
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedChannelData {
return cachedData.flags.contains(.canDeleteHistory)
} else {
return false
}
}
}
}
}

View File

@ -99,6 +99,50 @@ public enum EnginePeer: Equatable {
self.displayPreviews = displayPreviews
}
}
public struct StatusSettings: Equatable {
public struct Flags: OptionSet {
public var rawValue: Int32
public init(rawValue: Int32) {
self.rawValue = rawValue
}
public static let canReport = Flags(rawValue: 1 << 1)
public static let canShareContact = Flags(rawValue: 1 << 2)
public static let canBlock = Flags(rawValue: 1 << 3)
public static let canAddContact = Flags(rawValue: 1 << 4)
public static let addExceptionWhenAddingContact = Flags(rawValue: 1 << 5)
public static let canReportIrrelevantGeoLocation = Flags(rawValue: 1 << 6)
public static let autoArchived = Flags(rawValue: 1 << 7)
public static let suggestAddMembers = Flags(rawValue: 1 << 8)
}
public var flags: Flags
public var geoDistance: Int32?
public var requestChatTitle: String?
public var requestChatDate: Int32?
public var requestChatIsChannel: Bool?
public init(
flags: Flags,
geoDistance: Int32?,
requestChatTitle: String?,
requestChatDate: Int32?,
requestChatIsChannel: Bool?
) {
self.flags = flags
self.geoDistance = geoDistance
self.requestChatTitle = requestChatTitle
self.requestChatDate = requestChatDate
self.requestChatIsChannel = requestChatIsChannel
}
public func contains(_ member: Flags) -> Bool {
return self.flags.contains(member)
}
}
public enum IndexName: Equatable {
case title(title: String, addressName: String?)
@ -296,6 +340,18 @@ public extension EnginePeer.NotificationSettings {
}
}
public extension EnginePeer.StatusSettings {
init(_ statusSettings: PeerStatusSettings) {
self.init(
flags: Flags(rawValue: statusSettings.flags.rawValue),
geoDistance: statusSettings.geoDistance,
requestChatTitle: statusSettings.requestChatTitle,
requestChatDate: statusSettings.requestChatDate,
requestChatIsChannel: statusSettings.requestChatIsChannel
)
}
}
public extension EnginePeer.Presence {
init(_ presence: PeerPresence) {
if let presence = presence as? TelegramUserPresence {

View File

@ -728,6 +728,10 @@ public extension TelegramEngine {
return _internal_storedMessageFromSearchPeer(account: self.account, peer: peer._asPeer())
}
public func ensurePeersAreLocallyAvailable(peers: [EnginePeer]) -> Signal<Never, NoError> {
return _internal_storedMessageFromSearchPeers(account: self.account, peers: peers.map { $0._asPeer() })
}
public func mostRecentSecretChat(id: EnginePeer.Id) -> Signal<EnginePeer.Id?, NoError> {
return self.account.postbox.transaction { transaction -> EnginePeer.Id? in
let filteredPeerIds = Array(transaction.getAssociatedPeerIds(id)).filter { $0.namespace == Namespaces.Peer.SecretChat }

View File

@ -112,5 +112,11 @@ public extension TelegramEngine {
}).start()
return _internal_updateDefaultReaction(account: self.account, reaction: reaction)
}
public func isStickerSaved(id: EngineMedia.Id) -> Signal<Bool, NoError> {
return self.account.postbox.transaction { transaction -> Bool in
return getIsStickerSaved(transaction: transaction, fileId: id)
}
}
}
}

View File

@ -16,6 +16,19 @@ func _internal_storedMessageFromSearchPeer(account: Account, peer: Peer) -> Sign
}
}
func _internal_storedMessageFromSearchPeers(account: Account, peers: [Peer]) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> Void in
for peer in peers {
if transaction.getPeer(peer.id) == nil {
updatePeers(transaction: transaction, peers: [peer], update: { previousPeer, updatedPeer in
return updatedPeer
})
}
}
}
|> ignoreValues
}
func _internal_storeMessageFromSearch(transaction: Transaction, message: Message) {
if transaction.getMessage(message.id) == nil {
for (_, peer) in message.peers {

View File

@ -76,13 +76,19 @@ public func donateSendMessageIntent(account: Account, sharedContext: SharedAccou
if case .chat = intentContext, settings.onlyShared {
return .single([])
}
return account.postbox.transaction { transaction -> [(Peer, SendMessageIntentSubject)] in
return TelegramEngine(account: account).data.get(
EngineDataMap(peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
EngineDataMap(peerIds.map(TelegramEngine.EngineData.Item.Peer.IsContact.init)),
EngineDataMap(peerIds.map(TelegramEngine.EngineData.Item.Messages.ChatListGroup.init))
)
|> map { peerMap, isContactMap, chatListGroupMap -> [(Peer, SendMessageIntentSubject)] in
var peers: [(Peer, SendMessageIntentSubject)] = []
for peerId in peerIds {
if peerId.namespace != Namespaces.Peer.SecretChat, let peer = transaction.getPeer(peerId) {
if peerId.namespace != Namespaces.Peer.SecretChat, let maybePeer = peerMap[peerId], let peer = maybePeer {
var subject: SendMessageIntentSubject?
let chatListIndex = transaction.getPeerChatListIndex(peerId)
if chatListIndex?.0 == Namespaces.PeerGroup.archive {
let chatListGroup = chatListGroupMap[peerId]
if chatListGroup == .archive {
continue
}
if peerId.namespace == Namespaces.Peer.CloudUser {
@ -91,7 +97,7 @@ public func donateSendMessageIntent(account: Account, sharedContext: SharedAccou
continue
}
subject = .savedMessages
} else if transaction.isPeerContact(peerId: peerId) {
} else if let isContact = isContactMap[peerId], isContact {
if !settings.contacts {
continue
}
@ -107,7 +113,7 @@ public func donateSendMessageIntent(account: Account, sharedContext: SharedAccou
continue
}
subject = .group
} else if let peer = peer as? TelegramChannel {
} else if case let .channel(peer) = peer {
if case .group = peer.info {
if !settings.groups {
continue
@ -121,7 +127,7 @@ public func donateSendMessageIntent(account: Account, sharedContext: SharedAccou
}
if let subject = subject {
peers.append((peer, subject))
peers.append((peer._asPeer(), subject))
}
}
}

View File

@ -392,9 +392,22 @@ public final class AccountContextImpl: AccountContext {
if currentPeerId == peerId {
self.sharedContext.navigateToCurrentCall()
} else {
let _ = (self.account.postbox.transaction { transaction -> (Peer?, Peer?) in
return (transaction.getPeer(peerId), currentPeerId.flatMap(transaction.getPeer))
let dataInput: Signal<(EnginePeer?, EnginePeer?), NoError>
if let currentPeerId = currentPeerId {
dataInput = self.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: currentPeerId)
)
} else {
dataInput = self.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> map { peer -> (EnginePeer?, EnginePeer?) in
return (peer, nil)
}
}
let _ = (dataInput
|> deliverOnMainQueue).start(next: { [weak self] peer, current in
guard let strongSelf = self else {
return
@ -404,15 +417,16 @@ public final class AccountContextImpl: AccountContext {
}
let presentationData = strongSelf.sharedContext.currentPresentationData.with { $0 }
if let current = current {
if current is TelegramChannel || current is TelegramGroup {
switch current {
case .channel, .legacyGroup:
let title: String
let text: String
if let channel = current as? TelegramChannel, case .broadcast = channel.info {
if case let .channel(channel) = current, case .broadcast = channel.info {
title = presentationData.strings.Call_LiveStreamInProgressTitle
text = presentationData.strings.Call_LiveStreamInProgressMessage(EnginePeer(current).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string
text = presentationData.strings.Call_LiveStreamInProgressMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
} else {
title = presentationData.strings.Call_VoiceChatInProgressTitle
text = presentationData.strings.Call_VoiceChatInProgressMessage(EnginePeer(current).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string
text = presentationData.strings.Call_VoiceChatInProgressMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
}
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: title, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
@ -421,12 +435,12 @@ public final class AccountContextImpl: AccountContext {
}
let _ = strongSelf.sharedContext.callManager?.joinGroupCall(context: strongSelf, peerId: peer.id, invite: invite, requestJoinAsPeerId: requestJoinAsPeerId, initialCall: activeCall, endCurrentIfAny: true)
})]), on: .root)
} else {
default:
let text: String
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
text = presentationData.strings.Call_CallInProgressLiveStreamMessage(EnginePeer(current).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string
if case let .channel(channel) = peer, case .broadcast = channel.info {
text = presentationData.strings.Call_CallInProgressLiveStreamMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
} else {
text = presentationData.strings.Call_CallInProgressVoiceChatMessage(EnginePeer(current).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string
text = presentationData.strings.Call_CallInProgressVoiceChatMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
}
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_CallInProgressTitle, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
guard let strongSelf = self else {
@ -454,9 +468,22 @@ public final class AccountContextImpl: AccountContext {
completion()
self.sharedContext.navigateToCurrentCall()
} else {
let _ = (self.account.postbox.transaction { transaction -> (Peer?, Peer?) in
return (transaction.getPeer(peerId), currentPeerId.flatMap(transaction.getPeer))
let dataInput: Signal<(EnginePeer?, EnginePeer?), NoError>
if let currentPeerId = currentPeerId {
dataInput = self.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.Peer(id: currentPeerId)
)
} else {
dataInput = self.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> map { peer -> (EnginePeer?, EnginePeer?) in
return (peer, nil)
}
}
let _ = (dataInput
|> deliverOnMainQueue).start(next: { [weak self] peer, current in
guard let strongSelf = self else {
return
@ -466,12 +493,13 @@ public final class AccountContextImpl: AccountContext {
}
let presentationData = strongSelf.sharedContext.currentPresentationData.with { $0 }
if let current = current {
if current is TelegramChannel || current is TelegramGroup {
switch current {
case .channel, .legacyGroup:
let text: String
if let channel = current as? TelegramChannel, case .broadcast = channel.info {
text = presentationData.strings.Call_LiveStreamInProgressCallMessage(EnginePeer(current).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string
if case let .channel(channel) = current, case .broadcast = channel.info {
text = presentationData.strings.Call_LiveStreamInProgressCallMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
} else {
text = presentationData.strings.Call_VoiceChatInProgressCallMessage(EnginePeer(current).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string
text = presentationData.strings.Call_VoiceChatInProgressCallMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
}
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_VoiceChatInProgressTitle, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
guard let strongSelf = self else {
@ -480,8 +508,8 @@ public final class AccountContextImpl: AccountContext {
let _ = strongSelf.sharedContext.callManager?.requestCall(context: strongSelf, peerId: peerId, isVideo: isVideo, endCurrentIfAny: true)
completion()
})]), on: .root)
} else {
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_CallInProgressTitle, text: presentationData.strings.Call_CallInProgressMessage(EnginePeer(current).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
default:
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_CallInProgressTitle, text: presentationData.strings.Call_CallInProgressMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
guard let strongSelf = self else {
return
}

View File

@ -961,8 +961,9 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|> mapToSignal { authAndAccounts -> Signal<(UnauthorizedAccount, ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]))?, NoError> in
if let (primary, auth, accounts) = authAndAccounts {
let phoneNumbers = combineLatest(accounts.map { context -> Signal<(AccountRecordId, String, Bool)?, NoError> in
return context.account.postbox.transaction { transaction -> (AccountRecordId, String, Bool)? in
if let phone = (transaction.getPeer(context.account.peerId) as? TelegramUser)?.phone {
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|> map { peer -> (AccountRecordId, String, Bool)? in
if case let .user(user) = peer, let phone = user.phone {
return (context.account.id, phone, context.account.testingEnvironment)
} else {
return nil
@ -1766,10 +1767,11 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
guard let context = self.contextValue?.context else {
return true
}
let _ = (context.account.postbox.transaction { transaction -> PeerId? in
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false))
|> map { contactList -> PeerId? in
var result: PeerId?
for peerId in transaction.getContactPeerIds() {
if let peer = transaction.getPeer(peerId) as? TelegramUser, let peerPhoneNumber = peer.phone {
for peer in contactList.peers {
if case let .user(peer) = peer, let peerPhoneNumber = peer.phone {
if matchPhoneNumbers(phoneNumber, peerPhoneNumber) {
result = peer.id
break
@ -1777,7 +1779,8 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
}
}
return result
} |> deliverOnMainQueue).start(next: { peerId in
}
|> deliverOnMainQueue).start(next: { peerId in
if let peerId = peerId {
startCall(peerId.id._internalGetInt64Value())
}
@ -1816,8 +1819,9 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|> take(1)
|> mapToSignal { primary, contexts, _ -> Signal<(AccountRecordId?, [AccountContext?]), NoError> in
return combineLatest(contexts.map { _, context, _ -> Signal<AccountContext?, NoError> in
return context.account.postbox.transaction { transaction -> AccountContext? in
if transaction.getPeer(peerId) != nil {
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> map { peer -> AccountContext? in
if peer != nil {
return context
} else {
return nil

View File

@ -274,19 +274,28 @@ final class AuthorizedApplicationContext {
}
}))
let postbox = context.account.postbox
let engine = context.engine
self.notificationMessagesDisposable.set((context.account.stateManager.notificationMessages
|> mapToSignal { messageList -> Signal<[([Message], PeerGroupId, Bool)], NoError> in
return postbox.transaction { transaction -> [([Message], PeerGroupId, Bool)] in
return engine.data.get(EngineDataMap(
messageList.compactMap { item -> TelegramEngine.EngineData.Item.Messages.ChatListIndex? in
if let message = item.0.first {
return TelegramEngine.EngineData.Item.Messages.ChatListIndex(id: message.id.peerId)
} else {
return nil
}
}
))
|> map { chatListIndexMap -> [([Message], PeerGroupId, Bool)] in
return messageList.filter { item in
guard let message = item.0.first else {
return false
}
let inclusion = transaction.getPeerChatListInclusion(message.id.peerId)
if case .notIncluded = inclusion {
if let maybeChatListIndex = chatListIndexMap[message.id.peerId], maybeChatListIndex != nil {
return true
} else {
return false
}
return true
}
}
}

View File

@ -2084,43 +2084,44 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
shareController.completed = { [weak self] peerIds in
if let strongSelf = self {
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
var peers: [Peer] = []
for peerId in peerIds {
if let peer = transaction.getPeer(peerId) {
peers.append(peer)
}
}
return peers
} |> deliverOnMainQueue).start(next: { [weak self] peers in
if let strongSelf = self {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
var savedMessages = false
if peerIds.count == 1, let peerId = peerIds.first, peerId == strongSelf.context.account.peerId {
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(firstPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : EnginePeer(secondPeer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(peers.count - 1)").string
} else {
text = ""
}
}
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
}
})
guard let strongSelf = self else {
return
}
let _ = (strongSelf.context.engine.data.get(
EngineDataList(
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
)
)
|> deliverOnMainQueue).start(next: { [weak self] peerList in
guard let strongSelf = self else {
return
}
let peers = peerList.compactMap { $0 }
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
var savedMessages = false
if peerIds.count == 1, let peerId = peerIds.first, peerId == strongSelf.context.account.peerId {
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many
savedMessages = true
} else {
if peers.count == 1, let peer = peers.first {
let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
} else if let peer = peers.first {
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(peers.count - 1)").string
} else {
text = ""
}
}
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})
}
strongSelf.chatDisplayNode.dismissInput()
strongSelf.present(shareController, in: .window(.root), blockInteraction: true)
@ -3645,7 +3646,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}, synchronousLoad: true)
galleryController.setHintWillBePresentedInPreviewingContext(true)
let items: Signal<[ContextMenuItem], NoError> = context.account.postbox.transaction { transaction -> [ContextMenuItem] in
let items: Signal<[ContextMenuItem], NoError> = context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.CanViewStats(id: peer.id),
TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: peer.id)
)
|> map { canViewStats, statsDatacenterId -> [ContextMenuItem] in
var items: [ContextMenuItem] = [
.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.actionSheet.primaryTextColor)
@ -3654,7 +3659,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self?.navigationButtonAction(.openChatInfo(expandAvatar: true))
}))
]
if let cachedData = transaction.getPeerCachedData(peerId: peer.id) as? CachedChannelData, cachedData.flags.contains(.canViewStats) {
if canViewStats {
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ChannelInfo_Stats, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Statistics"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
@ -3666,9 +3671,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let statsController: ViewController
if let channel = peer as? TelegramChannel, case .group = channel.info {
statsController = groupStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id, cachedPeerData: cachedData)
statsController = groupStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id, statsDatacenterId: statsDatacenterId)
} else {
statsController = channelStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id, cachedPeerData: cachedData)
statsController = channelStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id, statsDatacenterId: statsDatacenterId)
}
strongSelf.push(statsController)
})))
@ -8623,7 +8628,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
let postbox = self.context.account.postbox
let engine = self.context.engine
let previousPeerCache = Atomic<[PeerId: Peer]>(value: [:])
let activitySpace: PeerActivitySpace?
@ -8654,13 +8659,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if foundAllPeers {
return .single(cachedResult)
} else {
return postbox.transaction { transaction -> [(Peer, PeerInputActivity)] in
return engine.data.get(EngineDataMap(
activities.map { TelegramEngine.EngineData.Item.Peer.Peer(id: $0.0) }
))
|> map { peerMap -> [(Peer, PeerInputActivity)] in
var result: [(Peer, PeerInputActivity)] = []
var peerCache: [PeerId: Peer] = [:]
for (peerId, activity) in activities {
if let peer = transaction.getPeer(peerId) {
result.append((peer, activity))
peerCache[peerId] = peer
if let maybePeer = peerMap[peerId], let peer = maybePeer {
result.append((peer._asPeer(), activity))
peerCache[peerId] = peer._asPeer()
}
}
let _ = previousPeerCache.swap(peerCache)
@ -8959,14 +8967,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in
return chatNavigationStack.compactMap(transaction.getPeer)
}
|> deliverOnMainQueue).start(next: { peers in
let _ = (strongSelf.context.engine.data.get(EngineDataList(
chatNavigationStack.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
))
|> deliverOnMainQueue).start(next: { peerList in
guard let strongSelf = self, let backButtonNode = strongSelf.chatDisplayNode.navigationBar?.backButtonNode else {
return
}
let peers = peerList.compactMap { $0 }
let avatarSize = CGSize(width: 28.0, height: 28.0)
var items: [ContextMenuItem] = []
@ -8977,8 +8987,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
title = strongSelf.presentationData.strings.DialogList_SavedMessages
iconSource = nil
} else {
title = EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)
iconSource = ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: strongSelf.context.account, peer: EnginePeer(peer), size: avatarSize))
title = peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)
iconSource = ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: strongSelf.context.account, peer: peer, size: avatarSize))
}
let isSavedMessages = peer.id == strongSelf.context.account.peerId
@ -10089,9 +10099,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self?.beginClearHistory(type: type)
}
let _ = (self.context.account.postbox.transaction { transaction -> (isLargeGroupOrChannel: Bool, canClearChannel: Bool) in
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, let memberCount = cachedData.participantsSummary.memberCount {
return (memberCount > 1000, cachedData.flags.contains(.canDeleteHistory))
let _ = (self.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.ParticipantCount(id: peerId),
TelegramEngine.EngineData.Item.Peer.CanDeleteHistory(id: peerId)
)
|> map { participantCount, canDeleteHistory -> (isLargeGroupOrChannel: Bool, canClearChannel: Bool) in
if let participantCount = participantCount {
return (participantCount > 1000, canDeleteHistory)
} else {
return (false, false)
}
@ -10987,15 +11001,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else {
selfPeerId = strongSelf.context.account.peerId
}
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(selfPeerId)
}
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: selfPeerId))
|> deliverOnMainQueue).start(next: { [weak self] selfPeer in
guard let strongSelf = self, let selfPeer = selfPeer else {
return
}
let hasLiveLocation = peer.id.namespace != Namespaces.Peer.SecretChat && peer.id != strongSelf.context.account.peerId && strongSelf.presentationInterfaceState.subject != .scheduledMessages
let controller = LocationPickerController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mode: .share(peer: peer, selfPeer: selfPeer, hasLiveLocation: hasLiveLocation), completion: { [weak self] location, _ in
let controller = LocationPickerController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mode: .share(peer: peer, selfPeer: selfPeer._asPeer(), hasLiveLocation: hasLiveLocation), completion: { [weak self] location, _ in
guard let strongSelf = self else {
return
}
@ -11901,32 +11913,30 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else {
selfPeerId = self.context.account.peerId
}
let _ = (self.context.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(selfPeerId)
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: selfPeerId))
|> deliverOnMainQueue).start(next: { [weak self] selfPeer in
guard let strongSelf = self, let selfPeer = selfPeer else {
return
}
|> deliverOnMainQueue).start(next: { [weak self] selfPeer in
guard let strongSelf = self, let selfPeer = selfPeer else {
let hasLiveLocation = peer.id.namespace != Namespaces.Peer.SecretChat && peer.id != strongSelf.context.account.peerId && strongSelf.presentationInterfaceState.subject != .scheduledMessages
let controller = LocationPickerController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mode: .share(peer: peer, selfPeer: selfPeer._asPeer(), hasLiveLocation: hasLiveLocation), completion: { [weak self] location, _ in
guard let strongSelf = self else {
return
}
let hasLiveLocation = peer.id.namespace != Namespaces.Peer.SecretChat && peer.id != strongSelf.context.account.peerId && strongSelf.presentationInterfaceState.subject != .scheduledMessages
let controller = LocationPickerController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mode: .share(peer: peer, selfPeer: selfPeer, hasLiveLocation: hasLiveLocation), completion: { [weak self] location, _ in
guard let strongSelf = self else {
return
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)
strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: false, {
$0.updatedInterfaceState { $0.withUpdatedReplyMessageId(nil) }
})
}
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)
strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({
if let strongSelf = self {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: false, {
$0.updatedInterfaceState { $0.withUpdatedReplyMessageId(nil) }
})
}
}, nil)
strongSelf.sendMessages([message])
})
strongSelf.effectiveNavigationController?.pushViewController(controller)
strongSelf.chatDisplayNode.dismissInput()
}, nil)
strongSelf.sendMessages([message])
})
strongSelf.effectiveNavigationController?.pushViewController(controller)
strongSelf.chatDisplayNode.dismissInput()
})
}
private func presentContactPicker() {
@ -16124,13 +16134,14 @@ enum AllowedReactions {
}
func peerAllowedReactions(context: AccountContext, peerId: PeerId) -> Signal<AllowedReactions?, NoError> {
return context.account.postbox.transaction { transaction -> AllowedReactions? in
let cachedData = transaction.getPeerCachedData(peerId: peerId)
if let cachedData = cachedData as? CachedChannelData {
return cachedData.allowedReactions.flatMap { return AllowedReactions.set(Set($0)) }
} else if let cachedData = cachedData as? CachedGroupData {
return cachedData.allowedReactions.flatMap { return AllowedReactions.set(Set($0)) }
} else if peerId.namespace == Namespaces.Peer.CloudUser {
return context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.AllowedReactions(id: peerId)
)
|> map { peer, allowedReactions -> AllowedReactions? in
if let allowedReactions = allowedReactions {
return .set(Set(allowedReactions))
} else if case .user = peer {
return .all
} else {
return nil

View File

@ -543,19 +543,9 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
}
var loadStickerSaveStatusSignal: Signal<Bool?, NoError> = .single(nil)
if loadStickerSaveStatus != nil {
loadStickerSaveStatusSignal = context.account.postbox.transaction { transaction -> Bool? in
var starStatus: Bool?
if let loadStickerSaveStatus = loadStickerSaveStatus {
if getIsStickerSaved(transaction: transaction, fileId: loadStickerSaveStatus) {
starStatus = true
} else {
starStatus = false
}
}
return starStatus
}
if let loadStickerSaveStatus = loadStickerSaveStatus {
loadStickerSaveStatusSignal = context.engine.stickers.isStickerSaved(id: loadStickerSaveStatus)
|> map(Optional.init)
}
var loadResourceStatusSignal: Signal<MediaResourceStatus?, NoError> = .single(nil)
@ -575,6 +565,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
return transaction.getPeerCachedData(peerId: messages[0].id.peerId)
}
//let readState = context.engine.data.get(TelegramEngine.EngineData.Item.Messages.PeerUnreadCount)
let readState = context.account.postbox.transaction { transaction -> CombinedPeerReadState? in
return transaction.getCombinedPeerReadState(messages[0].id.peerId)
}

View File

@ -1668,14 +1668,16 @@ final class ChatMediaInputNode: ChatInputNode {
if let (itemNode, item) = itemNodeAndItem {
let accountPeerId = strongSelf.context.account.peerId
return strongSelf.context.account.postbox.transaction { transaction -> (Bool, Bool) in
let isStarred = getIsStickerSaved(transaction: transaction, fileId: item.file.fileId)
var hasPremium = false
if let peer = transaction.getPeer(accountPeerId) as? TelegramUser, peer.isPremium {
hasPremium = true
return combineLatest(
strongSelf.context.engine.stickers.isStickerSaved(id: item.file.fileId),
strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: accountPeerId)) |> map { peer -> Bool in
var hasPremium = false
if case let .user(user) = peer, user.isPremium {
hasPremium = true
}
return hasPremium
}
return (isStarred, hasPremium)
}
)
|> deliverOnMainQueue
|> map { isStarred, hasPremium -> (ASDisplayNode, PeekControllerContent)? in
if let strongSelf = self {

View File

@ -2026,7 +2026,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
self.isAvatarExpanded = avatarInitiallyExpanded
self.isOpenedFromChat = isOpenedFromChat
self.isSettings = isSettings
self.videoCallsEnabled = VideoCallsConfiguration(appConfiguration: context.currentAppConfiguration.with { $0 }).areVideoCallsEnabled
self.videoCallsEnabled = true
self.avatarListNode = PeerInfoAvatarListNode(context: context, readyWhenGalleryLoads: avatarInitiallyExpanded, isSettings: isSettings)

View File

@ -1689,7 +1689,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
self.context = context
self.peerId = peerId
self.isOpenedFromChat = isOpenedFromChat
self.videoCallsEnabled = VideoCallsConfiguration(appConfiguration: context.currentAppConfiguration.with { $0 }).areVideoCallsEnabled
self.videoCallsEnabled = true
self.presentationData = controller.presentationData
self.nearbyPeerDistance = nearbyPeerDistance
self.callMessages = callMessages
@ -4957,11 +4957,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
self.view.endEditing(true)
var statsDatacenterId: Int32?
if let cachedData = cachedData as? CachedChannelData {
statsDatacenterId = cachedData.statsDatacenterId
}
let statsController: ViewController
if let channel = peer as? TelegramChannel, case .group = channel.info {
statsController = groupStatsController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id, cachedPeerData: cachedData)
statsController = groupStatsController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id, statsDatacenterId: statsDatacenterId)
} else {
statsController = channelStatsController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id, cachedPeerData: cachedData)
statsController = channelStatsController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id, statsDatacenterId: statsDatacenterId)
}
controller.push(statsController)
}