mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Refactoring
This commit is contained in:
parent
1a0bba8e45
commit
af1b794332
@ -388,7 +388,7 @@
|
||||
"Tour.Text5" = "**Telegram** lets you access your\nmessages from multiple devices.";
|
||||
|
||||
"Tour.Title6" = "Free";
|
||||
"Tour.Text6" = "**Telegram** is free forever. No ads.\nNo subscription fees.";
|
||||
"Tour.Text6" = "**Telegram** isprovides free unlimited cloud storage\nfor chats and media.";
|
||||
|
||||
"Tour.StartButton" = "Start Messaging";
|
||||
|
||||
|
@ -148,8 +148,6 @@ public enum FetchManagerPriority: Comparable {
|
||||
}
|
||||
}
|
||||
|
||||
public let FetchCompleteRange = IndexSet(integersIn: 0 ..< Int(Int32.max) as Range<Int>)
|
||||
|
||||
public protocol FetchManager {
|
||||
var queue: Queue { get }
|
||||
|
||||
|
@ -56,7 +56,7 @@ public func messageMediaImageInteractiveFetched(fetchManager: FetchManager, mess
|
||||
if let range = range {
|
||||
ranges = IndexSet(integersIn: Int(range.lowerBound) ..< Int(range.upperBound))
|
||||
} else {
|
||||
ranges = FetchCompleteRange
|
||||
ranges = IndexSet(integersIn: Int(0) ..< Int(Int64.max))
|
||||
}
|
||||
return fetchManager.interactivelyFetched(category: .image, location: .chat(messageId.peerId), locationKey: .messageId(messageId), mediaReference: mediaReference, resourceReference: mediaReference.resourceReference(resource), ranges: ranges, statsCategory: .image, elevatedPriority: false, userInitiated: userInitiated, priority: priority, storeToDownloadsPeerType: storeToDownloadsPeerType)
|
||||
}
|
||||
|
@ -186,6 +186,9 @@ private final class FetchManagerCategoryContext {
|
||||
if self.topEntryIdAndPriority?.0 == id {
|
||||
self.topEntryIdAndPriority = nil
|
||||
}
|
||||
if let entry = self.entries[id] {
|
||||
Logger.shared.log("FetchManager", "Canceled fetching \(entry.resourceReference.resource.id.stringRepresentation)")
|
||||
}
|
||||
self.entries.removeValue(forKey: id)
|
||||
removedEntries = true
|
||||
}
|
||||
@ -232,6 +235,7 @@ private final class FetchManagerCategoryContext {
|
||||
}
|
||||
activeContext.disposable?.dispose()
|
||||
let postbox = self.postbox
|
||||
Logger.shared.log("FetchManager", "Begin fetching \(entry.resourceReference.resource.id.stringRepresentation) ranges: \(String(describing: parsedRanges))")
|
||||
activeContext.disposable = (fetchedMediaResource(mediaBox: postbox.mediaBox, reference: entry.resourceReference, ranges: parsedRanges, statsCategory: entry.statsCategory, reportResultStatus: true, continueInBackground: entry.userInitiated)
|
||||
|> mapToSignal { type -> Signal<FetchResourceSourceType, FetchResourceError> in
|
||||
if filterDownloadStatsEntry(entry: entry), case let .message(message, _) = entry.mediaReference, let messageId = message.id, case .remote = type {
|
||||
@ -248,6 +252,7 @@ private final class FetchManagerCategoryContext {
|
||||
return .single(type)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
Logger.shared.log("FetchManager", "Completed fetching \(entry.resourceReference.resource.id.stringRepresentation)")
|
||||
entryCompleted(id)
|
||||
})
|
||||
} else {
|
||||
@ -356,6 +361,7 @@ private final class FetchManagerCategoryContext {
|
||||
} else if ranges.isEmpty {
|
||||
} else {
|
||||
let postbox = self.postbox
|
||||
Logger.shared.log("FetchManager", "Begin fetching \(entry.resourceReference.resource.id.stringRepresentation) ranges: \(String(describing: parsedRanges))")
|
||||
activeContext.disposable = (fetchedMediaResource(mediaBox: postbox.mediaBox, reference: entry.resourceReference, ranges: parsedRanges, statsCategory: entry.statsCategory, reportResultStatus: true, continueInBackground: entry.userInitiated)
|
||||
|> mapToSignal { type -> Signal<FetchResourceSourceType, FetchResourceError> in
|
||||
if filterDownloadStatsEntry(entry: entry), case let .message(message, _) = entry.mediaReference, let messageId = message.id, case .remote = type {
|
||||
@ -372,6 +378,7 @@ private final class FetchManagerCategoryContext {
|
||||
return .single(type)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
Logger.shared.log("FetchManager", "Completed fetching \(entry.resourceReference.resource.id.stringRepresentation)")
|
||||
entryCompleted(topEntryId)
|
||||
})
|
||||
}
|
||||
@ -411,7 +418,8 @@ private final class FetchManagerCategoryContext {
|
||||
var entriesRemoved = false
|
||||
let _ = entriesRemoved
|
||||
|
||||
if let _ = self.entries[id] {
|
||||
if let entry = self.entries[id] {
|
||||
Logger.shared.log("FetchManager", "Cancel fetching \(entry.resourceReference.resource.id.stringRepresentation)")
|
||||
self.entries.removeValue(forKey: id)
|
||||
entriesRemoved = true
|
||||
|
||||
|
@ -1016,9 +1016,8 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
|
||||
@objc func deleteButtonPressed() {
|
||||
if let currentMessage = self.currentMessage {
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> [Message] in
|
||||
return transaction.getMessageGroup(currentMessage.id) ?? []
|
||||
} |> deliverOnMainQueue).start(next: { [weak self] messages in
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.MessageGroup(id: currentMessage.id))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messages in
|
||||
if let strongSelf = self, !messages.isEmpty {
|
||||
if messages.count == 1 {
|
||||
strongSelf.commitDeleteMessages(messages, ask: true)
|
||||
@ -1032,7 +1031,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
|
||||
var generalMessageContentKind: MessageContentKind?
|
||||
for message in messages {
|
||||
let currentKind = messageContentKind(contentSettings: strongSelf.context.currentContentSettings.with { $0 }, message: EngineMessage(message), strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, dateTimeFormat: presentationData.dateTimeFormat, accountPeerId: strongSelf.context.account.peerId)
|
||||
let currentKind = messageContentKind(contentSettings: strongSelf.context.currentContentSettings.with { $0 }, message: message, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, dateTimeFormat: presentationData.dateTimeFormat, accountPeerId: strongSelf.context.account.peerId)
|
||||
if generalMessageContentKind == nil || generalMessageContentKind == currentKind {
|
||||
generalMessageContentKind = currentKind
|
||||
} else {
|
||||
@ -1057,7 +1056,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
}
|
||||
}
|
||||
|
||||
let deleteAction: ([Message]) -> Void = { messages in
|
||||
let deleteAction: ([EngineMessage]) -> Void = { messages in
|
||||
if let strongSelf = self {
|
||||
strongSelf.commitDeleteMessages(messages, ask: false)
|
||||
}
|
||||
@ -1070,7 +1069,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
let items: [ActionSheetItem] = [
|
||||
ActionSheetButtonItem(title: singleText, color: .destructive, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
deleteAction([currentMessage])
|
||||
deleteAction([EngineMessage(currentMessage)])
|
||||
}),
|
||||
ActionSheetButtonItem(title: multipleText, color: .destructive, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
@ -1093,7 +1092,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
}
|
||||
}
|
||||
|
||||
private func commitDeleteMessages(_ messages: [Message], ask: Bool) {
|
||||
private func commitDeleteMessages(_ messages: [EngineMessage], ask: Bool) {
|
||||
self.messageContextDisposable.set((self.context.sharedContext.chatAvailableMessageActions(postbox: self.context.account.postbox, accountPeerId: self.context.account.peerId, messageIds: Set(messages.map { $0.id })) |> deliverOnMainQueue).start(next: { [weak self] actions in
|
||||
if let strongSelf = self, let controllerInteration = strongSelf.controllerInteraction, !actions.options.isEmpty {
|
||||
var presentationData = strongSelf.presentationData
|
||||
@ -1166,9 +1165,8 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
self.interacting?(true)
|
||||
|
||||
if let currentMessage = self.currentMessage {
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> [Message] in
|
||||
return transaction.getMessageGroup(currentMessage.id) ?? []
|
||||
} |> deliverOnMainQueue).start(next: { [weak self] messages in
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.MessageGroup(id: currentMessage.id))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messages in
|
||||
if let strongSelf = self, !messages.isEmpty {
|
||||
var presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
var forceTheme: PresentationTheme?
|
||||
@ -1181,7 +1179,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
var messageContentKinds = Set<MessageContentKindKey>()
|
||||
|
||||
for message in messages {
|
||||
let currentKind = messageContentKind(contentSettings: strongSelf.context.currentContentSettings.with { $0 }, message: EngineMessage(message), strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, dateTimeFormat: presentationData.dateTimeFormat, accountPeerId: strongSelf.context.account.peerId)
|
||||
let currentKind = messageContentKind(contentSettings: strongSelf.context.currentContentSettings.with { $0 }, message: message, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, dateTimeFormat: presentationData.dateTimeFormat, accountPeerId: strongSelf.context.account.peerId)
|
||||
if beganContentKindScanning && currentKind != generalMessageContentKind {
|
||||
generalMessageContentKind = nil
|
||||
} else if !beganContentKindScanning || currentKind == generalMessageContentKind {
|
||||
@ -1210,10 +1208,10 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
}
|
||||
|
||||
if messages.count == 1 {
|
||||
var subject: ShareControllerSubject = ShareControllerSubject.messages(messages)
|
||||
var subject: ShareControllerSubject = ShareControllerSubject.messages(messages.map { $0._asMessage() })
|
||||
for m in messages[0].media {
|
||||
if let image = m as? TelegramMediaImage {
|
||||
subject = .image(image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: .media(media: .message(message: MessageReference(messages[0]), media: m), resource: $0.resource)) }))
|
||||
subject = .image(image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: .media(media: .message(message: MessageReference(messages[0]._asMessage()), media: m), resource: $0.resource)) }))
|
||||
} else if let webpage = m as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content {
|
||||
if content.embedType == "iframe" {
|
||||
let item = OpenInItem.url(url: content.url)
|
||||
@ -1246,12 +1244,12 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
}
|
||||
}
|
||||
} else if let file = m as? TelegramMediaFile {
|
||||
subject = .media(.message(message: MessageReference(messages[0]), media: file))
|
||||
subject = .media(.message(message: MessageReference(messages[0]._asMessage()), media: file))
|
||||
if file.isAnimated {
|
||||
preferredAction = .custom(action: ShareControllerAction(title: presentationData.strings.Preview_SaveGif, action: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let message = messages[0]
|
||||
let _ = addSavedGif(postbox: strongSelf.context.account.postbox, fileReference: .message(message: MessageReference(message), media: file)).start()
|
||||
let _ = addSavedGif(postbox: strongSelf.context.account.postbox, fileReference: .message(message: MessageReference(message._asMessage()), media: file)).start()
|
||||
|
||||
strongSelf.controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved), elevatedLayout: true, animateInAsReplacement: true, action: { _ in return false }), nil)
|
||||
}
|
||||
@ -1397,7 +1395,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
}),
|
||||
ActionSheetButtonItem(title: multipleText, color: .accent, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
shareAction(messages)
|
||||
shareAction(messages.map { $0._asMessage() })
|
||||
})
|
||||
]
|
||||
|
||||
|
@ -1664,7 +1664,7 @@ public func internalMediaGridMessageVideo(postbox: Postbox, videoReference: File
|
||||
}
|
||||
}
|
||||
|
||||
public func chatMessagePhotoStatus(context: AccountContext, messageId: MessageId, photoReference: ImageMediaReference, displayAtSize: Int = 1000) -> Signal<MediaResourceStatus, NoError> {
|
||||
public func chatMessagePhotoStatus(context: AccountContext, messageId: MessageId, photoReference: ImageMediaReference, displayAtSize: Int? = nil) -> Signal<MediaResourceStatus, NoError> {
|
||||
if let largestRepresentation = largestRepresentationForPhoto(photoReference.media) {
|
||||
if let range = representationFetchRangeForDisplayAtSize(representation: largestRepresentation, dimension: displayAtSize) {
|
||||
return combineLatest(
|
||||
|
43
submodules/Postbox/Sources/IsContactView.swift
Normal file
43
submodules/Postbox/Sources/IsContactView.swift
Normal file
@ -0,0 +1,43 @@
|
||||
import Foundation
|
||||
|
||||
final class MutableIsContactView: MutablePostboxView {
|
||||
fileprivate let id: PeerId
|
||||
fileprivate var isContact: Bool
|
||||
|
||||
init(postbox: PostboxImpl, id: PeerId) {
|
||||
self.id = id
|
||||
self.isContact = postbox.contactsTable.isContact(peerId: self.id)
|
||||
}
|
||||
|
||||
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool {
|
||||
var updated = false
|
||||
if transaction.replaceContactPeerIds != nil {
|
||||
let isContact = postbox.contactsTable.isContact(peerId: self.id)
|
||||
if self.isContact != isContact {
|
||||
self.isContact = isContact
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
if updated {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func immutableView() -> PostboxView {
|
||||
return IsContactView(self)
|
||||
}
|
||||
}
|
||||
|
||||
public final class IsContactView: PostboxView {
|
||||
public let isContact: Bool
|
||||
|
||||
init(_ view: MutableIsContactView) {
|
||||
self.isContact = view.isContact
|
||||
}
|
||||
}
|
65
submodules/Postbox/Sources/MessageGroupView.swift
Normal file
65
submodules/Postbox/Sources/MessageGroupView.swift
Normal file
@ -0,0 +1,65 @@
|
||||
import Foundation
|
||||
|
||||
final class MutableMessageGroupView: MutablePostboxView {
|
||||
fileprivate let id: MessageId
|
||||
fileprivate let groupingKey: Int64?
|
||||
fileprivate var messages: [Message] = []
|
||||
|
||||
init(postbox: PostboxImpl, id: MessageId) {
|
||||
self.id = id
|
||||
self.messages = postbox.getMessageGroup(at: id) ?? []
|
||||
self.groupingKey = self.messages.first?.groupingKey
|
||||
}
|
||||
|
||||
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool {
|
||||
var updated = false
|
||||
if let operations = transaction.currentOperationsByPeerId[self.id.peerId] {
|
||||
outer: for operation in operations {
|
||||
switch operation {
|
||||
case let .InsertMessage(message):
|
||||
if let groupingKey = self.groupingKey, message.groupingKey == groupingKey {
|
||||
updated = true
|
||||
break outer
|
||||
} else if message.id == self.id {
|
||||
updated = true
|
||||
break outer
|
||||
}
|
||||
case let .Remove(indices):
|
||||
for index in indices {
|
||||
for message in self.messages {
|
||||
if index.0.id == message.id {
|
||||
updated = true
|
||||
break outer
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if updated {
|
||||
self.messages = postbox.getMessageGroup(at: self.id) ?? []
|
||||
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func immutableView() -> PostboxView {
|
||||
return MessageGroupView(self)
|
||||
}
|
||||
}
|
||||
|
||||
public final class MessageGroupView: PostboxView {
|
||||
public let messages: [Message]
|
||||
|
||||
init(_ view: MutableMessageGroupView) {
|
||||
self.messages = view.messages
|
||||
}
|
||||
}
|
@ -34,6 +34,8 @@ public enum PostboxViewKey: Hashable {
|
||||
case contacts(accountPeerId: PeerId?, includePresences: Bool)
|
||||
case deletedMessages(peerId: PeerId)
|
||||
case notice(key: NoticeEntryKey)
|
||||
case messageGroup(id: MessageId)
|
||||
case isContact(id: PeerId)
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
switch self {
|
||||
@ -112,6 +114,10 @@ public enum PostboxViewKey: Hashable {
|
||||
hasher.combine(peerId)
|
||||
case let .notice(key):
|
||||
hasher.combine(key)
|
||||
case let .messageGroup(id):
|
||||
hasher.combine(id)
|
||||
case let .isContact(id):
|
||||
hasher.combine(id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,6 +321,18 @@ public enum PostboxViewKey: Hashable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .messageGroup(id):
|
||||
if case .messageGroup(id) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .isContact(id):
|
||||
if case .isContact(id) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -387,5 +405,9 @@ func postboxViewForKey(postbox: PostboxImpl, key: PostboxViewKey) -> MutablePost
|
||||
return MutableDeletedMessagesView(peerId: peerId)
|
||||
case let .notice(key):
|
||||
return MutableLocalNoticeEntryView(postbox: postbox, key: key)
|
||||
case let .messageGroup(id):
|
||||
return MutableMessageGroupView(postbox: postbox, id: id)
|
||||
case let .isContact(id):
|
||||
return MutableIsContactView(postbox: postbox, id: id)
|
||||
}
|
||||
}
|
||||
|
@ -505,7 +505,11 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
controller?.clearItemNodesHighlight(animated: true)
|
||||
}
|
||||
openMessageStatsImpl = { [weak controller] messageId in
|
||||
controller?.push(messageStatsController(context: context, messageId: messageId, cachedPeerData: cachedPeerData))
|
||||
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
|
||||
guard let controller = controller, let sourceNode = sourceNode as? ContextExtractedContentContainingNode else {
|
||||
|
@ -185,17 +185,14 @@ private func messageStatsControllerEntries(data: MessageStats?, messages: Search
|
||||
return entries
|
||||
}
|
||||
|
||||
public func messageStatsController(context: AccountContext, messageId: MessageId, cachedPeerData: CachedPeerData) -> ViewController {
|
||||
public func messageStatsController(context: AccountContext, messageId: MessageId, statsDatacenterId: Int32?) -> ViewController {
|
||||
var navigateToMessageImpl: ((MessageId) -> Void)?
|
||||
|
||||
let actionsDisposable = DisposableSet()
|
||||
let dataPromise = Promise<MessageStats?>(nil)
|
||||
let messagesPromise = Promise<(SearchMessagesResult, SearchMessagesState)?>(nil)
|
||||
|
||||
var datacenterId: Int32 = 0
|
||||
if let cachedData = cachedPeerData as? CachedChannelData {
|
||||
datacenterId = cachedData.statsDatacenterId
|
||||
}
|
||||
let datacenterId: Int32 = statsDatacenterId ?? 0
|
||||
|
||||
let statsContext = MessageStatsContext(postbox: context.account.postbox, network: context.account.network, datacenterId: datacenterId, messageId: messageId)
|
||||
let dataSignal: Signal<MessageStats?, NoError> = statsContext.state
|
||||
|
@ -48,9 +48,8 @@ private func presentLiveLocationController(context: AccountContext, peerId: Peer
|
||||
}
|
||||
}
|
||||
if let id = context.liveLocationManager?.internalMessageForPeerId(peerId) {
|
||||
let _ = (context.account.postbox.transaction { transaction -> EngineMessage? in
|
||||
return transaction.getMessage(id).flatMap(EngineMessage.init)
|
||||
} |> deliverOnMainQueue).start(next: presentImpl)
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: id))
|
||||
|> deliverOnMainQueue).start(next: presentImpl)
|
||||
} else if let liveLocationManager = context.liveLocationManager {
|
||||
let _ = (liveLocationManager.summaryManager.peersBroadcastingTo(peerId: peerId)
|
||||
|> take(1)
|
||||
|
@ -325,18 +325,7 @@ private enum MultipartFetchSource {
|
||||
return .fail(.revalidateMediaReference)
|
||||
case .revalidate:
|
||||
return .fail(.revalidateMediaReference)
|
||||
case let .location(parsedLocation):
|
||||
#if DEBUG
|
||||
switch parsedLocation {
|
||||
case let .inputDocumentFileLocation(id, _, _, _):
|
||||
if id == 5467475273110788326 {
|
||||
return Signal<Data, MultipartFetchDownloadError>.single(Data(count: Int(limit))) |> delay(0.01, queue: .concurrentDefaultQueue())
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
#endif
|
||||
|
||||
case let .location(parsedLocation):
|
||||
return download.request(Api.functions.upload.getFile(flags: 0, location: parsedLocation, offset: offset, limit: Int32(limit)), tag: tag, continueInBackground: continueInBackground)
|
||||
|> mapError { error -> MultipartFetchDownloadError in
|
||||
if error.errorDescription.hasPrefix("FILEREF_INVALID") || error.errorDescription.hasPrefix("FILE_REFERENCE_") {
|
||||
|
@ -81,6 +81,27 @@ public extension TelegramEngine.EngineData.Item {
|
||||
return EngineMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
public struct MessageGroup: TelegramEngineDataItem, PostboxViewDataItem {
|
||||
public typealias Result = [EngineMessage]
|
||||
|
||||
fileprivate var id: EngineMessage.Id
|
||||
|
||||
public init(id: EngineMessage.Id) {
|
||||
self.id = id
|
||||
}
|
||||
|
||||
var key: PostboxViewKey {
|
||||
return .messageGroup(id: self.id)
|
||||
}
|
||||
|
||||
func extract(view: PostboxView) -> Result {
|
||||
guard let view = view as? MessageGroupView else {
|
||||
preconditionFailure()
|
||||
}
|
||||
return view.messages.map(EngineMessage.init)
|
||||
}
|
||||
}
|
||||
|
||||
public struct Messages: TelegramEngineDataItem, PostboxViewDataItem {
|
||||
public typealias Result = [EngineMessage.Id: EngineMessage]
|
||||
|
@ -4,6 +4,29 @@ import Postbox
|
||||
public typealias EngineExportedPeerInvitation = ExportedInvitation
|
||||
|
||||
public extension TelegramEngine.EngineData.Item {
|
||||
enum NotificationSettings {
|
||||
public struct Global: TelegramEngineDataItem, PostboxViewDataItem {
|
||||
public typealias Result = EngineGlobalNotificationSettings
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
var key: PostboxViewKey {
|
||||
return .preferences(keys: Set([PreferencesKeys.globalNotifications]))
|
||||
}
|
||||
|
||||
func extract(view: PostboxView) -> Result {
|
||||
guard let view = view as? PreferencesView else {
|
||||
preconditionFailure()
|
||||
}
|
||||
guard let notificationSettings = view.values[PreferencesKeys.globalNotifications]?.get(GlobalNotificationSettings.self) else {
|
||||
return EngineGlobalNotificationSettings(GlobalNotificationSettings.defaultSettings.effective)
|
||||
}
|
||||
return EngineGlobalNotificationSettings(notificationSettings.effective)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Peer {
|
||||
public struct Peer: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
|
||||
public typealias Result = Optional<EnginePeer>
|
||||
@ -101,7 +124,7 @@ public extension TelegramEngine.EngineData.Item {
|
||||
}
|
||||
|
||||
public struct NotificationSettings: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
|
||||
public typealias Result = Optional<EnginePeer.NotificationSettings>
|
||||
public typealias Result = EnginePeer.NotificationSettings
|
||||
|
||||
fileprivate var id: EnginePeer.Id
|
||||
public var mapKey: EnginePeer.Id {
|
||||
@ -121,7 +144,7 @@ public extension TelegramEngine.EngineData.Item {
|
||||
preconditionFailure()
|
||||
}
|
||||
guard let notificationSettings = view.notificationSettings as? TelegramPeerNotificationSettings else {
|
||||
return nil
|
||||
return EnginePeer.NotificationSettings(TelegramPeerNotificationSettings.defaultSettings)
|
||||
}
|
||||
return EnginePeer.NotificationSettings(notificationSettings)
|
||||
}
|
||||
@ -228,5 +251,96 @@ public extension TelegramEngine.EngineData.Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct StatsDatacenterId: TelegramEngineDataItem, PostboxViewDataItem {
|
||||
public typealias Result = Optional<Int32>
|
||||
|
||||
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()
|
||||
}
|
||||
guard let cachedPeerData = view.cachedPeerData else {
|
||||
return nil
|
||||
}
|
||||
switch cachedPeerData {
|
||||
case let channel as CachedChannelData:
|
||||
return channel.statsDatacenterId
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct ThemeEmoticon: TelegramEngineDataItem, PostboxViewDataItem {
|
||||
public typealias Result = Optional<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()
|
||||
}
|
||||
guard let cachedPeerData = view.cachedPeerData else {
|
||||
return nil
|
||||
}
|
||||
if let cachedData = cachedPeerData as? CachedUserData {
|
||||
return cachedData.themeEmoticon
|
||||
} else if let cachedData = cachedPeerData as? CachedGroupData {
|
||||
return cachedData.themeEmoticon
|
||||
} else if let cachedData = cachedPeerData as? CachedChannelData {
|
||||
return cachedData.themeEmoticon
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct IsContact: TelegramEngineDataItem, 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 .isContact(id: self.id)
|
||||
}
|
||||
|
||||
func extract(view: PostboxView) -> Result {
|
||||
guard let view = view as? IsContactView else {
|
||||
preconditionFailure()
|
||||
}
|
||||
return view.isContact
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,37 @@ public final class EngineDataMap<Item: TelegramEngineDataItem & TelegramEngineMa
|
||||
}
|
||||
}
|
||||
|
||||
public final class EngineDataList<Item: TelegramEngineDataItem & TelegramEngineMapKeyDataItem>: TelegramEngineDataItem, AnyPostboxViewDataItem {
|
||||
public typealias Result = [Item.Result]
|
||||
|
||||
private let items: [Item]
|
||||
|
||||
public init(_ items: [Item]) {
|
||||
self.items = items
|
||||
}
|
||||
|
||||
var keys: [PostboxViewKey] {
|
||||
var keys = Set<PostboxViewKey>()
|
||||
for item in self.items {
|
||||
for key in (item as! AnyPostboxViewDataItem).keys {
|
||||
keys.insert(key)
|
||||
}
|
||||
}
|
||||
return Array(keys)
|
||||
}
|
||||
|
||||
func _extract(views: [PostboxViewKey: PostboxView]) -> Any {
|
||||
var result: [Item.Result] = []
|
||||
|
||||
for item in self.items {
|
||||
let itemResult = (item as! AnyPostboxViewDataItem)._extract(views: views)
|
||||
result.append(itemResult as! Item.Result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
public extension TelegramEngine {
|
||||
final class EngineData {
|
||||
public struct Item {
|
||||
|
@ -366,5 +366,17 @@ public extension TelegramEngine {
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
|
||||
public func findRandomMessage(peerId: EnginePeer.Id, namespace: EngineMessage.Id.Namespace, tag: EngineMessage.Tags, ignoreIds: ([EngineMessage.Id], Set<EngineMessage.Id>)) -> Signal<EngineMessage.Index?, NoError> {
|
||||
return self.account.postbox.transaction { transaction -> EngineMessage.Index? in
|
||||
return transaction.findRandomMessage(peerId: peerId, namespace: namespace, tag: tag, ignoreIds: ignoreIds)
|
||||
}
|
||||
}
|
||||
|
||||
public func failedMessageGroup(id: EngineMessage.Id) -> Signal<[EngineMessage], NoError> {
|
||||
return self.account.postbox.transaction { transaction -> [EngineMessage] in
|
||||
return transaction.getMessageFailedGroup(id)?.map(EngineMessage.init) ?? []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,37 @@ public enum EnginePeer: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public struct EngineGlobalNotificationSettings: Equatable {
|
||||
public struct CategorySettings: Equatable {
|
||||
public var enabled: Bool
|
||||
public var displayPreviews: Bool
|
||||
public var sound: EnginePeer.NotificationSettings.MessageSound
|
||||
|
||||
public init(enabled: Bool, displayPreviews: Bool, sound: EnginePeer.NotificationSettings.MessageSound) {
|
||||
self.enabled = enabled
|
||||
self.displayPreviews = displayPreviews
|
||||
self.sound = sound
|
||||
}
|
||||
}
|
||||
|
||||
public var privateChats: CategorySettings
|
||||
public var groupChats: CategorySettings
|
||||
public var channels: CategorySettings
|
||||
public var contactsJoined: Bool
|
||||
|
||||
public init(
|
||||
privateChats: CategorySettings,
|
||||
groupChats: CategorySettings,
|
||||
channels: CategorySettings,
|
||||
contactsJoined: Bool
|
||||
) {
|
||||
self.privateChats = privateChats
|
||||
self.groupChats = groupChats
|
||||
self.channels = channels
|
||||
self.contactsJoined = contactsJoined
|
||||
}
|
||||
}
|
||||
|
||||
public extension EnginePeer.NotificationSettings.MuteState {
|
||||
init(_ muteState: PeerMuteState) {
|
||||
switch muteState {
|
||||
@ -495,3 +526,32 @@ public extension EngineRenderedPeer {
|
||||
self.init(RenderedPeer(message: message._asMessage()))
|
||||
}
|
||||
}
|
||||
|
||||
public extension EngineGlobalNotificationSettings.CategorySettings {
|
||||
init(_ categorySettings: MessageNotificationSettings) {
|
||||
self.init(
|
||||
enabled: categorySettings.enabled,
|
||||
displayPreviews: categorySettings.displayPreviews,
|
||||
sound: EnginePeer.NotificationSettings.MessageSound(categorySettings.sound)
|
||||
)
|
||||
}
|
||||
|
||||
func _asMessageNotificationSettings() -> MessageNotificationSettings {
|
||||
return MessageNotificationSettings(
|
||||
enabled: self.enabled,
|
||||
displayPreviews: self.displayPreviews,
|
||||
sound: self.sound._asMessageSound()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public extension EngineGlobalNotificationSettings {
|
||||
init(_ globalNotificationSettings: GlobalNotificationSettingsSet) {
|
||||
self.init(
|
||||
privateChats: CategorySettings(globalNotificationSettings.privateChats),
|
||||
groupChats: CategorySettings(globalNotificationSettings.groupChats),
|
||||
channels: CategorySettings(globalNotificationSettings.channels),
|
||||
contactsJoined: globalNotificationSettings.contactsJoined
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,11 @@ public extension TelegramEngine {
|
||||
}
|
||||
}
|
||||
|
||||
public func findChannelById(channelId: Int64) -> Signal<Peer?, NoError> {
|
||||
public func findChannelById(channelId: Int64) -> Signal<EnginePeer?, NoError> {
|
||||
return _internal_findChannelById(postbox: self.account.postbox, network: self.account.network, channelId: channelId)
|
||||
|> map { peer in
|
||||
return peer.flatMap(EnginePeer.init)
|
||||
}
|
||||
}
|
||||
|
||||
public func supportPeerId() -> Signal<PeerId?, NoError> {
|
||||
@ -724,6 +727,31 @@ public extension TelegramEngine {
|
||||
public func ensurePeerIsLocallyAvailable(peer: EnginePeer) -> Signal<EnginePeer.Id, NoError> {
|
||||
return _internal_storedMessageFromSearchPeer(account: self.account, peer: peer._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 }
|
||||
var activeIndices: [ChatListIndex] = []
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -899,9 +899,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
} |> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
guard let strongSelf = self, let message = message else {
|
||||
return
|
||||
}
|
||||
@ -1641,9 +1640,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
}
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { message in
|
||||
guard let strongSelf = self, let message = message else {
|
||||
return
|
||||
@ -1690,7 +1687,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
strongSelf.chatDisplayNode.dismissInput()
|
||||
strongSelf.effectiveNavigationController?.pushViewController(GameController(context: strongSelf.context, url: url, message: EngineMessage(message)))
|
||||
strongSelf.effectiveNavigationController?.pushViewController(GameController(context: strongSelf.context, url: url, message: message))
|
||||
}
|
||||
|
||||
var botPeer: TelegramUser?
|
||||
@ -1702,7 +1699,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
}
|
||||
if botPeer == nil {
|
||||
if let peer = message.author as? TelegramUser, peer.botInfo != nil {
|
||||
if case let .user(peer) = message.author, peer.botInfo != nil {
|
||||
botPeer = peer
|
||||
} else if let peer = message.peers[message.id.peerId] as? TelegramUser, peer.botInfo != nil {
|
||||
botPeer = peer
|
||||
@ -2525,9 +2522,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
strongSelf.commitPurposefulAction()
|
||||
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
}
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { message in
|
||||
guard let strongSelf = self, let message = message else {
|
||||
return
|
||||
@ -2608,9 +2603,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
if id.namespace == Namespaces.Message.ScheduledCloud {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Message] in
|
||||
return transaction.getMessageGroup(id) ?? []
|
||||
} |> deliverOnMainQueue).start(next: { messages in
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.MessageGroup(id: id))
|
||||
|> deliverOnMainQueue).start(next: { messages in
|
||||
guard let strongSelf = self, let message = messages.filter({ $0.id == id }).first else {
|
||||
return
|
||||
}
|
||||
@ -2636,13 +2630,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor)
|
||||
}, action: { [weak self] controller, f in
|
||||
if let strongSelf = self {
|
||||
strongSelf.interfaceInteraction?.deleteMessages(messages, controller, f)
|
||||
strongSelf.interfaceInteraction?.deleteMessages(messages.map { $0._asMessage() }, controller, f)
|
||||
}
|
||||
})))
|
||||
|
||||
strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts()
|
||||
|
||||
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: message, selectAll: true)), items: .single(ContextController.Items(content: .list(actions))), recognizer: nil)
|
||||
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatMessageContextExtractedContentSource(chatNode: strongSelf.chatDisplayNode, postbox: strongSelf.context.account.postbox, message: message._asMessage(), selectAll: true)), items: .single(ContextController.Items(content: .list(actions))), recognizer: nil)
|
||||
strongSelf.currentContextController = controller
|
||||
strongSelf.forEachController({ controller in
|
||||
if let controller = controller as? TooltipScreen {
|
||||
@ -2653,9 +2647,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongSelf.window?.presentInGlobalOverlay(controller)
|
||||
})
|
||||
} else {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Message] in
|
||||
return transaction.getMessageFailedGroup(id) ?? []
|
||||
} |> deliverOnMainQueue).start(next: { messages in
|
||||
let _ = (strongSelf.context.engine.messages.failedMessageGroup(id: id)
|
||||
|> deliverOnMainQueue).start(next: { messages in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2666,9 +2659,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if groups[groupInfo.stableId] == nil {
|
||||
groups[groupInfo.stableId] = []
|
||||
}
|
||||
groups[groupInfo.stableId]?.append(message)
|
||||
groups[groupInfo.stableId]?.append(message._asMessage())
|
||||
} else {
|
||||
notGrouped.append(message)
|
||||
notGrouped.append(message._asMessage())
|
||||
}
|
||||
}
|
||||
|
||||
@ -2856,9 +2849,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.presentVoiceMessageDiscardAlert(action: {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
}
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { message in
|
||||
guard let message = message else {
|
||||
return
|
||||
@ -2957,9 +2948,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}, editScheduledMessagesTime: { [weak self] messageIds in
|
||||
if let strongSelf = self, let messageId = messageIds.first {
|
||||
let _ = strongSelf.presentVoiceMessageDiscardAlert(action: {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
} |> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
guard let strongSelf = self, let message = message else {
|
||||
return
|
||||
}
|
||||
@ -3085,9 +3075,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.presentVoiceMessageDiscardAlert(action: {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
}
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { message in
|
||||
guard let message = message else {
|
||||
return
|
||||
@ -3140,21 +3128,35 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongSelf.dismissAllTooltips()
|
||||
|
||||
let context = strongSelf.context
|
||||
let _ = (context.account.postbox.transaction { transaction -> (Peer?, Message?) in
|
||||
return (transaction.getPeer(peer.id), messageId.flatMap { transaction.getMessage($0) })
|
||||
|
||||
let dataSignal: Signal<(EnginePeer?, EngineMessage?), NoError>
|
||||
if let messageId = messageId {
|
||||
dataSignal = context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id),
|
||||
TelegramEngine.EngineData.Item.Messages.Message(id: messageId)
|
||||
)
|
||||
} else {
|
||||
dataSignal = context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id)
|
||||
)
|
||||
|> map { peer -> (EnginePeer?, EngineMessage?) in
|
||||
return (peer, nil)
|
||||
}
|
||||
}
|
||||
|
||||
let _ = (dataSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, message in
|
||||
guard let strongSelf = self, let peer = peer, peer.smallProfileImage != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
let galleryController = AvatarGalleryController(context: context, peer: peer, remoteEntries: nil, replaceRootController: { controller, ready in
|
||||
let galleryController = AvatarGalleryController(context: context, peer: peer._asPeer(), remoteEntries: nil, replaceRootController: { controller, ready in
|
||||
}, synchronousLoad: true)
|
||||
galleryController.setHintWillBePresentedInPreviewingContext(true)
|
||||
|
||||
let items: Signal<[ContextMenuItem], NoError> = context.account.postbox.transaction { transaction -> [ContextMenuItem] in
|
||||
var isChannel = false
|
||||
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
|
||||
if case let .channel(peer) = peer, case .broadcast = peer.info {
|
||||
isChannel = true
|
||||
}
|
||||
var items: [ContextMenuItem] = [
|
||||
@ -3187,7 +3189,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if inputMode == .none {
|
||||
inputMode = .text
|
||||
}
|
||||
return (chatTextInputAddMentionAttribute(current, peer: peer), inputMode)
|
||||
return (chatTextInputAddMentionAttribute(current, peer: peer._asPeer()), inputMode)
|
||||
}
|
||||
}, delay: true)
|
||||
})))
|
||||
@ -3235,17 +3237,25 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
let _ = strongSelf.presentVoiceMessageDiscardAlert(action: {
|
||||
let _ = (context.account.postbox.transaction { transaction -> (MessageId, CachedPeerData?)? in
|
||||
if let message = transaction.getMessage(id), let sourceMessageId = message.forwardInfo?.sourceMessageId {
|
||||
return (sourceMessageId, transaction.getPeerCachedData(peerId: sourceMessageId.peerId))
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: id))
|
||||
|> mapToSignal { message -> Signal<(EngineMessage.Id, Int32?)?, NoError> in
|
||||
if let message = message, let sourceMessageId = message.forwardInfo?.sourceMessageId {
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: sourceMessageId.peerId))
|
||||
|> map { statsDatacenterId -> (EngineMessage.Id, Int32?)? in
|
||||
return (sourceMessageId, statsDatacenterId)
|
||||
}
|
||||
} else {
|
||||
return (id, transaction.getPeerCachedData(peerId: id.peerId))
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: id.peerId))
|
||||
|> map { statsDatacenterId -> (EngineMessage.Id, Int32?)? in
|
||||
return (id, statsDatacenterId)
|
||||
}
|
||||
}
|
||||
} |> deliverOnMainQueue).start(next: { [weak self] messageIdAndCachedPeerData in
|
||||
guard let strongSelf = self, let (id, cachedPeerDataValue) = messageIdAndCachedPeerData, let cachedPeerData = cachedPeerDataValue else {
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messageIdAndStatsDatacenterId in
|
||||
guard let strongSelf = self, let (id, statsDatacenterId) = messageIdAndStatsDatacenterId, let statsDatacenterId = statsDatacenterId else {
|
||||
return
|
||||
}
|
||||
strongSelf.push(messageStatsController(context: context, messageId: id, cachedPeerData: cachedPeerData))
|
||||
strongSelf.push(messageStatsController(context: context, messageId: id, statsDatacenterId: statsDatacenterId))
|
||||
})
|
||||
}, delay: true)
|
||||
}, editMessageMedia: { [weak self] messageId, draw in
|
||||
@ -3256,9 +3266,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongSelf.chatDisplayNode.dismissInput()
|
||||
|
||||
if draw {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
} |> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
guard let strongSelf = self, let message = message else {
|
||||
return
|
||||
}
|
||||
@ -6114,9 +6123,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
if let messageId = strongSelf.presentationInterfaceState.interfaceState.editMessage?.messageId {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
} |> deliverOnMainQueue).start(next: { message in
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { message in
|
||||
guard let strongSelf = self, let editMessageState = strongSelf.presentationInterfaceState.editMessageState, case let .media(options) = editMessageState.content else {
|
||||
return
|
||||
}
|
||||
@ -6124,10 +6132,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let message = message {
|
||||
for media in message.media {
|
||||
if let image = media as? TelegramMediaImage {
|
||||
originalMediaReference = .message(message: MessageReference(message), media: image)
|
||||
originalMediaReference = .message(message: MessageReference(message._asMessage()), media: image)
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
if file.isVideo || file.isAnimated {
|
||||
originalMediaReference = .message(message: MessageReference(message), media: file)
|
||||
originalMediaReference = .message(message: MessageReference(message._asMessage()), media: file)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6884,21 +6892,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}, shareSelectedMessages: { [weak self] in
|
||||
if let strongSelf = self, let selectedIds = strongSelf.presentationInterfaceState.interfaceState.selectionState?.selectedIds, !selectedIds.isEmpty {
|
||||
strongSelf.commitPurposefulAction()
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Message] in
|
||||
var messages: [Message] = []
|
||||
for id in selectedIds {
|
||||
if let message = transaction.getMessage(id) {
|
||||
messages.append(message)
|
||||
}
|
||||
}
|
||||
return messages
|
||||
} |> deliverOnMainQueue).start(next: { messages in
|
||||
let _ = (strongSelf.context.engine.data.get(EngineDataMap(
|
||||
selectedIds.map(TelegramEngine.EngineData.Item.Messages.Message.init)
|
||||
))
|
||||
|> map { messages -> [EngineMessage] in
|
||||
return messages.values.compactMap { $0 }
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { messages in
|
||||
if let strongSelf = self, !messages.isEmpty {
|
||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) })
|
||||
|
||||
let shareController = ShareController(context: strongSelf.context, subject: .messages(messages.sorted(by: { lhs, rhs in
|
||||
return lhs.index < rhs.index
|
||||
})), externalShare: true, immediateExternalShare: true, updatedPresentationData: strongSelf.updatedPresentationData)
|
||||
}).map { $0._asMessage() }), externalShare: true, immediateExternalShare: true, updatedPresentationData: strongSelf.updatedPresentationData)
|
||||
strongSelf.chatDisplayNode.dismissInput()
|
||||
strongSelf.present(shareController, in: .window(.root))
|
||||
}
|
||||
@ -8469,14 +8475,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self?.presentChatRequestAdminInfo()
|
||||
}, displayCopyProtectionTip: { [weak self] node, save in
|
||||
if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer, let messageIds = strongSelf.presentationInterfaceState.interfaceState.selectionState?.selectedIds {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [EngineMessage] in
|
||||
var messages: [EngineMessage] = []
|
||||
for id in messageIds {
|
||||
if let message = transaction.getMessage(id) {
|
||||
messages.append(EngineMessage(message))
|
||||
}
|
||||
}
|
||||
return messages
|
||||
let _ = (strongSelf.context.engine.data.get(EngineDataMap(
|
||||
messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init)
|
||||
))
|
||||
|> map { messages -> [EngineMessage] in
|
||||
return messages.values.compactMap { $0 }
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messages in
|
||||
guard let strongSelf = self else {
|
||||
@ -13975,11 +13978,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
private func forwardMessages(messageIds: [MessageId], options: ChatInterfaceForwardOptionsState? = nil, resetCurrent: Bool = false) {
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> [Message] in
|
||||
return messageIds.compactMap(transaction.getMessage)
|
||||
}
|
||||
let _ = (self.context.engine.data.get(EngineDataMap(
|
||||
messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init)
|
||||
))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messages in
|
||||
self?.forwardMessages(messages: messages, options: options, resetCurrent: resetCurrent)
|
||||
self?.forwardMessages(messages: messages.values.compactMap { $0?._asMessage() }, options: options, resetCurrent: resetCurrent)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -324,9 +324,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
if context.sharedContext.immediateExperimentalUISettings.localTranscription {
|
||||
let appLocale = presentationData.strings.baseLanguageCode
|
||||
|
||||
let signal: Signal<String?, NoError> = context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(message.id)
|
||||
}
|
||||
let signal: Signal<String?, NoError> = context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: message.id))
|
||||
|> mapToSignal { message -> Signal<String?, NoError> in
|
||||
guard let message = message else {
|
||||
return .single(nil)
|
||||
|
@ -842,7 +842,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
}
|
||||
}
|
||||
} else {
|
||||
updatedStatusSignal = chatMessagePhotoStatus(context: context, messageId: message.id, photoReference: .message(message: MessageReference(message), media: image), displayAtSize: 600)
|
||||
updatedStatusSignal = chatMessagePhotoStatus(context: context, messageId: message.id, photoReference: .message(message: MessageReference(message), media: image), displayAtSize: nil)
|
||||
|> map { resourceStatus -> (MediaResourceStatus, MediaResourceStatus?) in
|
||||
return (resourceStatus, nil)
|
||||
}
|
||||
|
@ -995,11 +995,9 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, UIScrollViewDeleg
|
||||
let sharedData = self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings])
|
||||
|> take(1)
|
||||
if case let .peer(peer) = controller.subject, peer.id != self.context.account.peerId {
|
||||
let cachedData = self.context.account.postbox.transaction { transaction in
|
||||
return transaction.getPeerCachedData(peerId: peer.id)
|
||||
}
|
||||
initiallySelectedEmoticon = combineLatest(cachedData, sharedData)
|
||||
|> map { cachedData, sharedData -> String in
|
||||
let themeEmoticon = self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.ThemeEmoticon(id: peer.id))
|
||||
initiallySelectedEmoticon = combineLatest(themeEmoticon, sharedData)
|
||||
|> map { themeEmoticon, sharedData -> String in
|
||||
let themeSettings: PresentationThemeSettings
|
||||
if let current = sharedData.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings]?.get(PresentationThemeSettings.self) {
|
||||
themeSettings = current
|
||||
@ -1008,15 +1006,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, UIScrollViewDeleg
|
||||
}
|
||||
let currentDefaultEmoticon = themeSettings.theme.emoticon ?? defaultEmoticon
|
||||
|
||||
if let cachedData = cachedData as? CachedUserData {
|
||||
return cachedData.themeEmoticon ?? currentDefaultEmoticon
|
||||
} else if let cachedData = cachedData as? CachedGroupData {
|
||||
return cachedData.themeEmoticon ?? currentDefaultEmoticon
|
||||
} else if let cachedData = cachedData as? CachedChannelData {
|
||||
return cachedData.themeEmoticon ?? currentDefaultEmoticon
|
||||
} else {
|
||||
return currentDefaultEmoticon
|
||||
}
|
||||
return themeEmoticon ?? currentDefaultEmoticon
|
||||
}
|
||||
} else {
|
||||
initiallySelectedEmoticon = sharedData
|
||||
|
@ -129,13 +129,16 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
|
||||
|
||||
switch self.mode {
|
||||
case let .chatSelection(_, selectedChats, additionalCategories, _):
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> [Peer] in
|
||||
return selectedChats.compactMap(transaction.getPeer)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peers in
|
||||
let _ = (self.context.engine.data.get(
|
||||
EngineDataList(
|
||||
selectedChats.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 }
|
||||
if let additionalCategories = additionalCategories {
|
||||
for i in 0 ..< additionalCategories.categories.count {
|
||||
if additionalCategories.selectedCategories.contains(additionalCategories.categories[i].id) {
|
||||
@ -144,7 +147,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
|
||||
}
|
||||
}
|
||||
strongSelf.contactsNode.editableTokens.append(contentsOf: peers.map { peer -> EditableTokenListToken in
|
||||
return EditableTokenListToken(id: peer.id, title: peerTokenTitle(accountPeerId: params.context.account.peerId, peer: peer, strings: strongSelf.presentationData.strings, nameDisplayOrder: strongSelf.presentationData.nameDisplayOrder), fixedPosition: nil)
|
||||
return EditableTokenListToken(id: peer.id, title: peerTokenTitle(accountPeerId: params.context.account.peerId, peer: peer._asPeer(), strings: strongSelf.presentationData.strings, nameDisplayOrder: strongSelf.presentationData.nameDisplayOrder), fixedPosition: nil)
|
||||
})
|
||||
strongSelf._peersReady.set(.single(true))
|
||||
if strongSelf.isNodeLoaded {
|
||||
|
@ -58,11 +58,10 @@ final class OverlayAudioPlayerControllerImpl: ViewController, OverlayAudioPlayer
|
||||
self?.dismiss()
|
||||
}, requestShare: { [weak self] messageId in
|
||||
if let strongSelf = self {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
} |> deliverOnMainQueue).start(next: { message in
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { message in
|
||||
if let strongSelf = self, let message = message {
|
||||
let shareController = ShareController(context: strongSelf.context, subject: .messages([message]), showInChat: { message in
|
||||
let shareController = ShareController(context: strongSelf.context, subject: .messages([message._asMessage()]), showInChat: { message in
|
||||
if let strongSelf = self {
|
||||
strongSelf.context.sharedContext.navigateToChat(accountId: strongSelf.context.account.id, peerId: message.id.peerId, messageId: message.id)
|
||||
strongSelf.dismiss()
|
||||
@ -70,16 +69,14 @@ final class OverlayAudioPlayerControllerImpl: ViewController, OverlayAudioPlayer
|
||||
}, externalShare: true)
|
||||
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
|
||||
@ -89,14 +86,14 @@ final class OverlayAudioPlayerControllerImpl: ViewController, OverlayAudioPlayer
|
||||
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 = ""
|
||||
|
@ -1928,16 +1928,17 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
let presentationData = strongSelf.presentationData
|
||||
let peerId = strongSelf.peerId
|
||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_ContextMenuDelete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { c, _ in
|
||||
c.setItems(context.account.postbox.transaction { transaction -> ContextController.Items in
|
||||
c.setItems(context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: message.id.peerId))
|
||||
|> map { peer -> ContextController.Items in
|
||||
var items: [ContextMenuItem] = []
|
||||
let messageIds = [message.id]
|
||||
|
||||
if let peer = transaction.getPeer(message.id.peerId) {
|
||||
if let peer = peer {
|
||||
var personalPeerName: String?
|
||||
var isChannel = false
|
||||
if let user = peer as? TelegramUser {
|
||||
if case let .user(user) = peer {
|
||||
personalPeerName = EnginePeer(user).compactDisplayTitle
|
||||
} else if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
} else if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
isChannel = true
|
||||
}
|
||||
|
||||
@ -2066,16 +2067,17 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
if actions.options.contains(.deleteLocally) || actions.options.contains(.deleteGlobally) {
|
||||
items.append(.action(ContextMenuActionItem(text: strings.Conversation_ContextMenuDelete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { c, f in
|
||||
c.setItems(context.account.postbox.transaction { transaction -> ContextController.Items in
|
||||
c.setItems(context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: message.id.peerId))
|
||||
|> map { peer -> ContextController.Items in
|
||||
var items: [ContextMenuItem] = []
|
||||
let messageIds = [message.id]
|
||||
|
||||
if let peer = transaction.getPeer(message.id.peerId) {
|
||||
if let peer = peer {
|
||||
var personalPeerName: String?
|
||||
var isChannel = false
|
||||
if let user = peer as? TelegramUser {
|
||||
if case let .user(user) = peer {
|
||||
personalPeerName = EnginePeer(user).compactDisplayTitle
|
||||
} else if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
} else if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
isChannel = true
|
||||
}
|
||||
|
||||
@ -2724,9 +2726,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
let context = strongSelf.context
|
||||
|
||||
let _ = (getUserPeer(postbox: strongSelf.context.account.postbox, peerId: peer.id)
|
||||
|> mapToSignal { peer, _ -> Signal<Void, NoError> in
|
||||
guard let peer = peer as? TelegramUser, let phone = peer.phone, !phone.isEmpty else {
|
||||
let _ = (getUserPeer(engine: strongSelf.context.engine, peerId: peer.id)
|
||||
|> mapToSignal { peer -> Signal<Void, NoError> in
|
||||
guard case let .user(peer) = peer, let phone = peer.phone, !phone.isEmpty else {
|
||||
return .complete()
|
||||
}
|
||||
return (context.sharedContext.contactDataManager?.basicDataForNormalizedPhoneNumber(DeviceContactNormalizedPhoneNumber(rawValue: formatPhoneNumber(phone))) ?? .single([]))
|
||||
@ -3279,9 +3281,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
} |> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] message in
|
||||
guard let strongSelf = self, let message = message else {
|
||||
return
|
||||
}
|
||||
@ -4004,41 +4005,42 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
let shareController = ShareController(context: strongSelf.context, subject: .media(.standalone(media: contact)), updatedPresentationData: strongSelf.controller?.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)
|
||||
}
|
||||
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
|
||||
}
|
||||
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 = presentationData.strings.UserInfo_ContactForwardTooltip_SavedMessages_One
|
||||
savedMessages = true
|
||||
|
||||
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 = presentationData.strings.UserInfo_ContactForwardTooltip_SavedMessages_One
|
||||
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 = presentationData.strings.UserInfo_ContactForwardTooltip_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 : 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.UserInfo_ContactForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
|
||||
} else if let peer = peers.first {
|
||||
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.UserInfo_ContactForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
|
||||
} 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 = presentationData.strings.UserInfo_ContactForwardTooltip_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)
|
||||
text = presentationData.strings.UserInfo_ContactForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
|
||||
} else if let peer = peers.first {
|
||||
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.UserInfo_ContactForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
|
||||
} else {
|
||||
text = ""
|
||||
}
|
||||
text = ""
|
||||
}
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
}
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -4346,94 +4348,77 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
private func openStartSecretChat() {
|
||||
let peerId = self.peerId
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> (Peer?, PeerId?) in
|
||||
let peer = transaction.getPeer(peerId)
|
||||
let filteredPeerIds = Array(transaction.getAssociatedPeerIds(peerId)).filter { $0.namespace == Namespaces.Peer.SecretChat }
|
||||
var activeIndices: [ChatListIndex] = []
|
||||
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 (peer, index.messageIndex.id.peerId)
|
||||
} else {
|
||||
return (peer, nil)
|
||||
}
|
||||
}
|
||||
|
||||
let _ = (combineLatest(
|
||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId)),
|
||||
self.context.engine.peers.mostRecentSecretChat(id: self.peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, currentPeerId in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let controller = strongSelf.controller {
|
||||
let displayTitle = peer.flatMap(EnginePeer.init)?.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder) ?? ""
|
||||
controller.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.UserInfo_StartSecretChatConfirmation(displayTitle).string, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.UserInfo_StartSecretChatStart, action: {
|
||||
guard let controller = strongSelf.controller else {
|
||||
return
|
||||
}
|
||||
let displayTitle = peer?.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder) ?? ""
|
||||
controller.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.UserInfo_StartSecretChatConfirmation(displayTitle).string, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.UserInfo_StartSecretChatStart, action: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
var createSignal = strongSelf.context.engine.peers.createSecretChat(peerId: peerId)
|
||||
var cancelImpl: (() -> Void)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
if let strongSelf = self {
|
||||
let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: {
|
||||
cancelImpl?()
|
||||
}))
|
||||
strongSelf.controller?.present(statusController, in: .window(.root))
|
||||
return ActionDisposable { [weak statusController] in
|
||||
Queue.mainQueue().async() {
|
||||
statusController?.dismiss()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return EmptyDisposable
|
||||
}
|
||||
}
|
||||
|> runOn(Queue.mainQueue())
|
||||
|> delay(0.15, queue: Queue.mainQueue())
|
||||
let progressDisposable = progressSignal.start()
|
||||
|
||||
createSignal = createSignal
|
||||
|> afterDisposed {
|
||||
Queue.mainQueue().async {
|
||||
progressDisposable.dispose()
|
||||
}
|
||||
}
|
||||
let createSecretChatDisposable = MetaDisposable()
|
||||
cancelImpl = {
|
||||
createSecretChatDisposable.set(nil)
|
||||
}
|
||||
|
||||
createSecretChatDisposable.set((createSignal
|
||||
|> deliverOnMainQueue).start(next: { peerId in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
var createSignal = strongSelf.context.engine.peers.createSecretChat(peerId: peerId)
|
||||
var cancelImpl: (() -> Void)?
|
||||
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||
if let strongSelf = self {
|
||||
let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: {
|
||||
cancelImpl?()
|
||||
}))
|
||||
strongSelf.controller?.present(statusController, in: .window(.root))
|
||||
return ActionDisposable { [weak statusController] in
|
||||
Queue.mainQueue().async() {
|
||||
statusController?.dismiss()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return EmptyDisposable
|
||||
}
|
||||
if let navigationController = (strongSelf.controller?.navigationController as? NavigationController) {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
|> runOn(Queue.mainQueue())
|
||||
|> delay(0.15, queue: Queue.mainQueue())
|
||||
let progressDisposable = progressSignal.start()
|
||||
|
||||
createSignal = createSignal
|
||||
|> afterDisposed {
|
||||
Queue.mainQueue().async {
|
||||
progressDisposable.dispose()
|
||||
}
|
||||
}, error: { error in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let createSecretChatDisposable = MetaDisposable()
|
||||
cancelImpl = {
|
||||
createSecretChatDisposable.set(nil)
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
text = strongSelf.presentationData.strings.TwoStepAuth_FloodError
|
||||
default:
|
||||
text = strongSelf.presentationData.strings.Login_UnknownError
|
||||
}
|
||||
|
||||
createSecretChatDisposable.set((createSignal
|
||||
|> deliverOnMainQueue).start(next: { peerId in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let navigationController = (strongSelf.controller?.navigationController as? NavigationController) {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
}, error: { error in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
text = strongSelf.presentationData.strings.TwoStepAuth_FloodError
|
||||
default:
|
||||
text = strongSelf.presentationData.strings.Login_UnknownError
|
||||
}
|
||||
strongSelf.controller?.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
}))
|
||||
})]), in: .window(.root))
|
||||
}
|
||||
strongSelf.controller?.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
}))
|
||||
})]), in: .window(.root))
|
||||
})
|
||||
}
|
||||
|
||||
@ -4507,44 +4492,45 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
private func openUsername(value: String) {
|
||||
let shareController = ShareController(context: self.context, subject: .url("https://t.me/\(value)"), updatedPresentationData: self.controller?.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
|
||||
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 = presentationData.strings.UserInfo_LinkForwardTooltip_SavedMessages_One
|
||||
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 = presentationData.strings.UserInfo_LinkForwardTooltip_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)
|
||||
text = presentationData.strings.UserInfo_LinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
|
||||
} else if let peer = peers.first {
|
||||
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.UserInfo_LinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
|
||||
} else {
|
||||
text = ""
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.controller?.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 = presentationData.strings.UserInfo_LinkForwardTooltip_SavedMessages_One
|
||||
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 = presentationData.strings.UserInfo_LinkForwardTooltip_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 : 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.UserInfo_LinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
|
||||
} else if let peer = peers.first {
|
||||
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.UserInfo_LinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
|
||||
} else {
|
||||
text = ""
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})
|
||||
}
|
||||
shareController.actionCompleted = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
@ -4668,12 +4654,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func openPhone(value: String) {
|
||||
let _ = (getUserPeer(postbox: self.context.account.postbox, peerId: peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, _ in
|
||||
let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let peer = peer as? TelegramUser, let peerPhoneNumber = peer.phone, formatPhoneNumber(value) == formatPhoneNumber(peerPhoneNumber) {
|
||||
if case let .user(peer) = peer, let peerPhoneNumber = peer.phone, formatPhoneNumber(value) == formatPhoneNumber(peerPhoneNumber) {
|
||||
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
|
||||
let dismissAction: () -> Void = { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
@ -4704,12 +4690,13 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func editingOpenNotificationSettings() {
|
||||
let peerId = self.peerId
|
||||
let _ = (combineLatest(self.context.account.postbox.transaction { transaction -> (TelegramPeerNotificationSettings, GlobalNotificationSettings) in
|
||||
let peerSettings: TelegramPeerNotificationSettings = (transaction.getPeerNotificationSettings(peerId) as? TelegramPeerNotificationSettings) ?? TelegramPeerNotificationSettings.defaultSettings
|
||||
let globalSettings: GlobalNotificationSettings = transaction.getPreferencesEntry(key: PreferencesKeys.globalNotifications)?.get(GlobalNotificationSettings.self) ?? GlobalNotificationSettings.defaultSettings
|
||||
return (peerSettings, globalSettings)
|
||||
}, self.context.engine.peers.notificationSoundList())
|
||||
let _ = (combineLatest(
|
||||
self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: self.peerId),
|
||||
TelegramEngine.EngineData.Item.NotificationSettings.Global()
|
||||
),
|
||||
self.context.engine.peers.notificationSoundList()
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] settings, notificationSoundList in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@ -4717,11 +4704,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
let (peerSettings, globalSettings) = settings
|
||||
|
||||
let muteSettingsController = notificationMuteSettingsController(presentationData: strongSelf.presentationData, notificationSoundList: notificationSoundList, notificationSettings: globalSettings.effective.groupChats, soundSettings: nil, openSoundSettings: {
|
||||
let muteSettingsController = notificationMuteSettingsController(presentationData: strongSelf.presentationData, notificationSoundList: notificationSoundList, notificationSettings: globalSettings.groupChats._asMessageNotificationSettings(), soundSettings: nil, openSoundSettings: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let soundController = notificationSoundSelectionController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, isModal: true, currentSound: peerSettings.messageSound, defaultSound: globalSettings.effective.groupChats.sound, completion: { sound in
|
||||
let soundController = notificationSoundSelectionController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, isModal: true, currentSound: peerSettings.messageSound._asMessageSound(), defaultSound: globalSettings.groupChats.sound._asMessageSound(), completion: { sound in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -4741,18 +4728,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func editingOpenSoundSettings() {
|
||||
let peerId = self.peerId
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> (TelegramPeerNotificationSettings, GlobalNotificationSettings) in
|
||||
let peerSettings: TelegramPeerNotificationSettings = (transaction.getPeerNotificationSettings(peerId) as? TelegramPeerNotificationSettings) ?? TelegramPeerNotificationSettings.defaultSettings
|
||||
let globalSettings: GlobalNotificationSettings = transaction.getPreferencesEntry(key: PreferencesKeys.globalNotifications)?.get(GlobalNotificationSettings.self) ?? GlobalNotificationSettings.defaultSettings
|
||||
return (peerSettings, globalSettings)
|
||||
}
|
||||
let _ = (self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: self.peerId),
|
||||
TelegramEngine.EngineData.Item.NotificationSettings.Global()
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerSettings, globalSettings in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
let soundController = notificationSoundSelectionController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, isModal: true, currentSound: peerSettings.messageSound, defaultSound: globalSettings.effective.groupChats.sound, completion: { sound in
|
||||
let soundController = notificationSoundSelectionController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, isModal: true, currentSound: peerSettings.messageSound._asMessageSound(), defaultSound: globalSettings.groupChats.sound._asMessageSound(), completion: { sound in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -4763,8 +4748,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func editingToggleShowMessageText(value: Bool) {
|
||||
let _ = (getUserPeer(postbox: self.context.account.postbox, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, _ in
|
||||
let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -4784,8 +4769,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = (getUserPeer(postbox: strongSelf.context.account.postbox, peerId: strongSelf.peerId)
|
||||
|> deliverOnMainQueue).start(next: { peer, _ in
|
||||
let _ = (getUserPeer(engine: strongSelf.context.engine, peerId: strongSelf.peerId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
guard let peer = peer, let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -4885,8 +4870,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func openAddContact() {
|
||||
let _ = (getUserPeer(postbox: self.context.account.postbox, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, _ in
|
||||
let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
@ -4899,15 +4884,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func updateBlocked(block: Bool) {
|
||||
let _ = (getUserPeer(postbox: self.context.account.postbox, peerId: self.peerId)
|
||||
let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, _ in
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
|
||||
let presentationData = strongSelf.presentationData
|
||||
if let peer = peer as? TelegramUser, let _ = peer.botInfo {
|
||||
if case let .user(peer) = peer, let _ = peer.botInfo {
|
||||
strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: block).start())
|
||||
if !block {
|
||||
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: "/start", attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]).start()
|
||||
@ -4926,8 +4911,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
let deleteChat = false
|
||||
actionSheet.setItemGroups([
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetTextItem(title: presentationData.strings.UserInfo_BlockConfirmationTitle(EnginePeer(peer).compactDisplayTitle).string),
|
||||
ActionSheetButtonItem(title: presentationData.strings.UserInfo_BlockActionTitle(EnginePeer(peer).compactDisplayTitle).string, color: .destructive, action: {
|
||||
ActionSheetTextItem(title: presentationData.strings.UserInfo_BlockConfirmationTitle(peer.compactDisplayTitle).string),
|
||||
ActionSheetButtonItem(title: presentationData.strings.UserInfo_BlockActionTitle(peer.compactDisplayTitle).string, color: .destructive, action: {
|
||||
dismissAction()
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@ -4951,9 +4936,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
} else {
|
||||
let text: String
|
||||
if block {
|
||||
text = presentationData.strings.UserInfo_BlockConfirmation(EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string
|
||||
text = presentationData.strings.UserInfo_BlockConfirmation(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string
|
||||
} else {
|
||||
text = presentationData.strings.UserInfo_UnblockConfirmation(EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string
|
||||
text = presentationData.strings.UserInfo_UnblockConfirmation(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string
|
||||
}
|
||||
strongSelf.controller?.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_No, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Yes, action: {
|
||||
guard let strongSelf = self else {
|
||||
@ -5228,52 +5213,53 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func openShareBot() {
|
||||
let _ = (getUserPeer(postbox: self.context.account.postbox, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, _ in
|
||||
let _ = (getUserPeer(engine: self.context.engine, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let peer = peer as? TelegramUser, let username = peer.username {
|
||||
if case let .user(peer) = peer, let username = peer.username {
|
||||
let shareController = ShareController(context: strongSelf.context, subject: .url("https://t.me/\(username)"), updatedPresentationData: strongSelf.controller?.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
|
||||
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 = presentationData.strings.UserInfo_LinkForwardTooltip_SavedMessages_One
|
||||
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 = presentationData.strings.UserInfo_LinkForwardTooltip_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)
|
||||
text = presentationData.strings.UserInfo_LinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
|
||||
} else if let peer = peers.first {
|
||||
let peerName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.UserInfo_LinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
|
||||
} else {
|
||||
text = ""
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.controller?.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 = presentationData.strings.UserInfo_LinkForwardTooltip_SavedMessages_One
|
||||
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 = presentationData.strings.UserInfo_LinkForwardTooltip_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 : 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.UserInfo_LinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string
|
||||
} else if let peer = peers.first {
|
||||
let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
text = presentationData.strings.UserInfo_LinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string
|
||||
} else {
|
||||
text = ""
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})
|
||||
}
|
||||
shareController.actionCompleted = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
@ -5646,20 +5632,17 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func openDeletePeer() {
|
||||
let peerId = self.peerId
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(peerId)
|
||||
}
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
var isGroup = false
|
||||
if let channel = peer as? TelegramChannel {
|
||||
if case let .channel(channel) = peer {
|
||||
if case .group = channel.info {
|
||||
isGroup = true
|
||||
}
|
||||
} else if peer is TelegramGroup {
|
||||
} else if case .legacyGroup = peer {
|
||||
isGroup = true
|
||||
}
|
||||
let presentationData = strongSelf.presentationData
|
||||
@ -5683,7 +5666,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
ActionSheetTextItem(title: title),
|
||||
ActionSheetButtonItem(title: text, color: .destructive, action: {
|
||||
dismissAction()
|
||||
self?.deletePeerChat(peer: peer, globally: true)
|
||||
self?.deletePeerChat(peer: peer._asPeer(), globally: true)
|
||||
}),
|
||||
]),
|
||||
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])
|
||||
@ -5694,21 +5677,18 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
private func openLeavePeer(delete: Bool) {
|
||||
let peerId = self.peerId
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(peerId)
|
||||
}
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
|
||||
var isGroup = false
|
||||
if let channel = peer as? TelegramChannel {
|
||||
if case let .channel(channel) = peer {
|
||||
if case .group = channel.info {
|
||||
isGroup = true
|
||||
}
|
||||
} else if peer is TelegramGroup {
|
||||
} else if case .legacyGroup = peer {
|
||||
isGroup = true
|
||||
}
|
||||
|
||||
@ -5740,7 +5720,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
strongSelf.controller?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: title, text: text, actions: [
|
||||
TextAlertAction(type: .destructiveAction, title: actionText, action: {
|
||||
self?.deletePeerChat(peer: peer, globally: delete)
|
||||
self?.deletePeerChat(peer: peer._asPeer(), globally: delete)
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {
|
||||
})
|
||||
@ -7224,22 +7204,18 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
guard let strongSelf = self, let messageIds = strongSelf.state.selectedMessageIds, !messageIds.isEmpty, strongSelf.peerId.namespace != Namespaces.Peer.SecretChat else {
|
||||
return
|
||||
}
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Message] in
|
||||
var messages: [Message] = []
|
||||
for id in messageIds {
|
||||
if let message = transaction.getMessage(id) {
|
||||
messages.append(message)
|
||||
}
|
||||
}
|
||||
return messages
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { messages in
|
||||
let _ = (strongSelf.context.engine.data.get(EngineDataMap(
|
||||
messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init)
|
||||
))
|
||||
|> deliverOnMainQueue).start(next: { messageMap in
|
||||
let messages = messageMap.values.compactMap { $0 }
|
||||
|
||||
if let strongSelf = self, !messages.isEmpty {
|
||||
strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil)
|
||||
|
||||
let shareController = ShareController(context: strongSelf.context, subject: .messages(messages.sorted(by: { lhs, rhs in
|
||||
return lhs.index < rhs.index
|
||||
})), externalShare: true, immediateExternalShare: true, updatedPresentationData: strongSelf.controller?.updatedPresentationData)
|
||||
}).map({ $0._asMessage() })), externalShare: true, immediateExternalShare: true, updatedPresentationData: strongSelf.controller?.updatedPresentationData)
|
||||
strongSelf.view.endEditing(true)
|
||||
strongSelf.controller?.present(shareController, in: .window(.root))
|
||||
}
|
||||
@ -7261,19 +7237,14 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}, completion: { _, _ in }), in: .window(.root))
|
||||
}, displayCopyProtectionTip: { [weak self] node, save in
|
||||
if let strongSelf = self, let peer = strongSelf.data?.peer, let messageIds = strongSelf.state.selectedMessageIds, !messageIds.isEmpty {
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> [EngineMessage] in
|
||||
var messages: [EngineMessage] = []
|
||||
for id in messageIds {
|
||||
if let message = transaction.getMessage(id) {
|
||||
messages.append(EngineMessage(message))
|
||||
}
|
||||
}
|
||||
return messages
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messages in
|
||||
let _ = (strongSelf.context.engine.data.get(EngineDataMap(
|
||||
messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init)
|
||||
))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] messageMap in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let messages = messageMap.values.compactMap { $0 }
|
||||
enum PeerType {
|
||||
case group
|
||||
case channel
|
||||
@ -8104,19 +8075,20 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
|
||||
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.navigationBar?.backButtonNode else {
|
||||
return
|
||||
}
|
||||
let peers = peerList.compactMap { $0 }
|
||||
|
||||
let avatarSize = CGSize(width: 28.0, height: 28.0)
|
||||
|
||||
var items: [ContextMenuItem] = []
|
||||
for peer in peers {
|
||||
items.append(.action(ContextMenuActionItem(text: EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), icon: { _ in return nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: strongSelf.context.account, peer: EnginePeer(peer), size: avatarSize)), action: { _, f in
|
||||
items.append(.action(ContextMenuActionItem(text: peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), icon: { _ in return nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: strongSelf.context.account, peer: peer, size: avatarSize)), action: { _, f in
|
||||
f(.default)
|
||||
|
||||
guard let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||
@ -8212,18 +8184,17 @@ private final class SettingsTabBarContextExtractedContentSource: ContextExtracte
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
private func getUserPeer(engine: TelegramEngine, peerId: EnginePeer.Id) -> Signal<EnginePeer?, NoError> {
|
||||
return engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> mapToSignal { peer -> Signal<EnginePeer?, NoError> in
|
||||
guard let peer = peer else {
|
||||
return .single(nil)
|
||||
}
|
||||
var resultPeer: Peer?
|
||||
if let peer = peer as? TelegramSecretChat {
|
||||
resultPeer = transaction.getPeer(peer.regularPeerId)
|
||||
if case let .secretChat(secretChat) = peer {
|
||||
return engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: secretChat.regularPeerId))
|
||||
} else {
|
||||
resultPeer = peer
|
||||
return .single(peer)
|
||||
}
|
||||
return (resultPeer, resultPeer.flatMap({ transaction.getPeerCachedData(peerId: $0.id) }))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -559,35 +559,41 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
||||
case let .index(index):
|
||||
switch self.messagesLocation {
|
||||
case let .messages(chatLocation, tagMask, _):
|
||||
let inputIndex: Signal<MessageIndex?, NoError>
|
||||
var inputIndex: Signal<MessageIndex?, NoError>?
|
||||
let looping = self.looping
|
||||
switch self.order {
|
||||
case .regular, .reversed:
|
||||
inputIndex = .single(index)
|
||||
case .random:
|
||||
var playbackStack = self.playbackStack
|
||||
inputIndex = self.context.account.postbox.transaction { transaction -> MessageIndex? in
|
||||
if case let .random(previous) = navigation, previous {
|
||||
let _ = playbackStack.pop()
|
||||
while true {
|
||||
if let id = playbackStack.pop() {
|
||||
if let message = transaction.getMessage(id) {
|
||||
return message.index
|
||||
}
|
||||
} else {
|
||||
break
|
||||
|
||||
if case let .random(previous) = navigation, previous {
|
||||
let _ = playbackStack.pop()
|
||||
inner: while true {
|
||||
if let id = playbackStack.pop() {
|
||||
inputIndex = self.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: id))
|
||||
|> map { message in
|
||||
return message?.index
|
||||
}
|
||||
break inner
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if inputIndex == nil {
|
||||
if let peerId = chatLocation.peerId {
|
||||
return transaction.findRandomMessage(peerId: peerId, namespace: Namespaces.Message.Cloud, tag: tagMask, ignoreIds: (playbackStack.ids, playbackStack.set)) ?? index
|
||||
inputIndex = self.context.engine.messages.findRandomMessage(peerId: peerId, namespace: Namespaces.Message.Cloud, tag: tagMask, ignoreIds: (playbackStack.ids, playbackStack.set))
|
||||
|> map { result in
|
||||
return result ?? index
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
inputIndex = .single(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
let historySignal = inputIndex
|
||||
let historySignal = (inputIndex ?? .single(nil))
|
||||
|> mapToSignal { inputIndex -> Signal<(Message, [Message])?, NoError> in
|
||||
guard let inputIndex = inputIndex else {
|
||||
return .single(nil)
|
||||
|
@ -189,14 +189,8 @@ public final class PeerSelectionControllerImpl: ViewController, PeerSelectionCon
|
||||
|
||||
self.peerSelectionNode.requestOpenPeerFromSearch = { [weak self] peer in
|
||||
if let strongSelf = self {
|
||||
let storedPeer = strongSelf.context.account.postbox.transaction { transaction -> Void in
|
||||
if transaction.getPeer(peer.id) == nil {
|
||||
updatePeers(transaction: transaction, peers: [peer], update: { previousPeer, updatedPeer in
|
||||
return updatedPeer
|
||||
})
|
||||
}
|
||||
}
|
||||
strongSelf.openMessageFromSearchDisposable.set((storedPeer |> deliverOnMainQueue).start(completed: { [weak strongSelf] in
|
||||
strongSelf.openMessageFromSearchDisposable.set((strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: EnginePeer(peer))
|
||||
|> deliverOnMainQueue).start(completed: { [weak strongSelf] in
|
||||
if let strongSelf = strongSelf, let peerSelected = strongSelf.peerSelected {
|
||||
peerSelected(peer)
|
||||
}
|
||||
|
@ -705,11 +705,10 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
} else {
|
||||
switch peer {
|
||||
case let .peer(peer, _, _):
|
||||
let _ = (strongSelf.context.account.postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(peer.id)
|
||||
} |> deliverOnMainQueue).start(next: { peer in
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id))
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
if let strongSelf = self, let peer = peer {
|
||||
strongSelf.requestOpenPeerFromSearch?(peer)
|
||||
strongSelf.requestOpenPeerFromSearch?(peer._asPeer())
|
||||
}
|
||||
})
|
||||
case .deviceContact:
|
||||
|
@ -1183,13 +1183,12 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
// params.openPeer(peer, .info)
|
||||
})
|
||||
|
||||
let _ = ((context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(messageId)
|
||||
}) |> deliverOnMainQueue).start(next: { message in
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|
||||
|> deliverOnMainQueue).start(next: { message in
|
||||
guard let message = message else {
|
||||
return
|
||||
}
|
||||
let controller = LocationViewController(context: context, subject: message, params: controllerParams)
|
||||
let controller = LocationViewController(context: context, subject: message._asMessage(), params: controllerParams)
|
||||
controller.navigationPresentation = .modal
|
||||
navigationController.pushViewController(controller)
|
||||
})
|
||||
|
@ -517,9 +517,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
||||
}
|
||||
}
|
||||
case let .peerId(peerId):
|
||||
return context.account.postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(peerId)
|
||||
}
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> mapToSignal { peer -> Signal<ResolvedUrl?, NoError> in
|
||||
if let peer = peer {
|
||||
return .single(.peer(peer.id, .chat(textInputState: nil, subject: nil, peekData: nil)))
|
||||
@ -528,11 +526,9 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
||||
}
|
||||
}
|
||||
case let .privateMessage(messageId, threadId, timecode):
|
||||
return context.account.postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(messageId.peerId)
|
||||
}
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId))
|
||||
|> mapToSignal { peer -> Signal<ResolvedUrl?, NoError> in
|
||||
let foundPeer: Signal<Peer?, NoError>
|
||||
let foundPeer: Signal<EnginePeer?, NoError>
|
||||
if let peer = peer {
|
||||
foundPeer = .single(peer)
|
||||
} else {
|
||||
|
@ -388,18 +388,17 @@ final class WatchMediaHandler: WatchRequestHandler {
|
||||
|> take(1)
|
||||
|> mapToSignal({ context -> Signal<UIImage?, NoError> in
|
||||
if let context = context {
|
||||
return context.account.postbox.transaction { transaction -> Peer? in
|
||||
guard let peer = transaction.getPeer(peerId) else {
|
||||
return nil
|
||||
}
|
||||
if let peer = peer as? TelegramSecretChat {
|
||||
return transaction.getPeer(peer.regularPeerId)
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> mapToSignal { peer -> Signal<EnginePeer?, NoError> in
|
||||
if let peer = peer, case let .secretChat(secretChat) = peer {
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: secretChat.regularPeerId))
|
||||
} else {
|
||||
return peer
|
||||
return .single(peer)
|
||||
}
|
||||
} |> mapToSignal({ peer -> Signal<UIImage?, NoError> in
|
||||
}
|
||||
|> mapToSignal({ peer -> Signal<UIImage?, NoError> in
|
||||
if let peer = peer, let representation = peer.smallProfileImage {
|
||||
let imageData = peerAvatarImageData(account: context.account, peerReference: PeerReference(peer), authorOfMessage: nil, representation: representation, synchronousLoad: false)
|
||||
let imageData = peerAvatarImageData(account: context.account, peerReference: PeerReference(peer._asPeer()), authorOfMessage: nil, representation: representation, synchronousLoad: false)
|
||||
if let imageData = imageData {
|
||||
return imageData
|
||||
|> map { data -> UIImage? in
|
||||
@ -457,14 +456,12 @@ final class WatchMediaHandler: WatchRequestHandler {
|
||||
}
|
||||
}
|
||||
} else if args.stickerPeerId != 0, let peerId = makePeerIdFromBridgeIdentifier(args.stickerPeerId) {
|
||||
mediaSignal = context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: args.stickerMessageId))
|
||||
}
|
||||
mediaSignal = context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: args.stickerMessageId)))
|
||||
|> map { message -> (TelegramMediaFile, FileMediaReference)? in
|
||||
if let message = message {
|
||||
for media in message.media {
|
||||
if let media = media as? TelegramMediaFile {
|
||||
return (media, .message(message: MessageReference(message), media: media))
|
||||
return (media, .message(message: MessageReference(message._asMessage()), media: media))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -514,25 +511,23 @@ final class WatchMediaHandler: WatchRequestHandler {
|
||||
|> mapToSignal({ context -> Signal<UIImage?, NoError> in
|
||||
if let context = context, let peerId = makePeerIdFromBridgeIdentifier(args.peerId) {
|
||||
var roundVideo = false
|
||||
return context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: args.messageId))
|
||||
}
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: args.messageId)))
|
||||
|> mapToSignal { message -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> in
|
||||
if let message = message, !message.containsSecretMedia {
|
||||
if let message = message, !message._asMessage().containsSecretMedia {
|
||||
var imageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>?
|
||||
var updatedMediaReference: AnyMediaReference?
|
||||
var candidateMediaReference: AnyMediaReference?
|
||||
var imageDimensions: CGSize?
|
||||
for media in message.media {
|
||||
if let image = media as? TelegramMediaImage, let resource = largestImageRepresentation(image.representations)?.resource {
|
||||
self.disposable.add(messageMediaImageInteractiveFetched(context: context, message: message, image: image, resource: resource, storeToDownloadsPeerType: nil).start())
|
||||
candidateMediaReference = .message(message: MessageReference(message), media: media)
|
||||
self.disposable.add(messageMediaImageInteractiveFetched(context: context, message: message._asMessage(), image: image, resource: resource, storeToDownloadsPeerType: nil).start())
|
||||
candidateMediaReference = .message(message: MessageReference(message._asMessage()), media: media)
|
||||
break
|
||||
} else if let _ = media as? TelegramMediaFile {
|
||||
candidateMediaReference = .message(message: MessageReference(message), media: media)
|
||||
candidateMediaReference = .message(message: MessageReference(message._asMessage()), media: media)
|
||||
break
|
||||
} else if let webPage = media as? TelegramMediaWebpage, case let .Loaded(content) = webPage.content, let image = content.image, let resource = largestImageRepresentation(image.representations)?.resource {
|
||||
self.disposable.add(messageMediaImageInteractiveFetched(context: context, message: message, image: image, resource: resource, storeToDownloadsPeerType: nil).start())
|
||||
self.disposable.add(messageMediaImageInteractiveFetched(context: context, message: message._asMessage(), image: image, resource: resource, storeToDownloadsPeerType: nil).start())
|
||||
candidateMediaReference = .webPage(webPage: WebpageReference(webPage), media: image)
|
||||
break
|
||||
}
|
||||
@ -664,14 +659,12 @@ final class WatchAudioHandler: WatchRequestHandler {
|
||||
|> take(1)
|
||||
|> mapToSignal({ context -> Signal<String, NoError> in
|
||||
if let context = context, let peerId = makePeerIdFromBridgeIdentifier(args.peerId) {
|
||||
return context.account.postbox.transaction { transaction -> Message? in
|
||||
return transaction.getMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: args.messageId))
|
||||
}
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: args.messageId)))
|
||||
|> mapToSignal { message -> Signal<String, NoError> in
|
||||
if let message = message {
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile {
|
||||
self.disposable.add(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: true).start())
|
||||
self.disposable.add(messageMediaFileInteractiveFetched(context: context, message: message._asMessage(), file: file, userInitiated: true).start())
|
||||
return context.account.postbox.mediaBox.resourceData(file.resource)
|
||||
|> mapToSignal({ data -> Signal<String, NoError> in
|
||||
if let tempPath = manager.watchTemporaryStorePath, data.complete {
|
||||
|
Loading…
x
Reference in New Issue
Block a user