mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-10 06:27:15 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/TelegramCore
This commit is contained in:
commit
d708bd4e2b
@ -222,8 +222,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
|
dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
|
||||||
dict[-1557620115] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) }
|
dict[-1557620115] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) }
|
||||||
dict[-471670279] = { return Api.ChannelParticipant.parse_channelParticipantCreator($0) }
|
dict[-471670279] = { return Api.ChannelParticipant.parse_channelParticipantCreator($0) }
|
||||||
dict[1674301556] = { return Api.ChannelParticipant.parse_channelParticipantAdmin($0) }
|
|
||||||
dict[470789295] = { return Api.ChannelParticipant.parse_channelParticipantBanned($0) }
|
dict[470789295] = { return Api.ChannelParticipant.parse_channelParticipantBanned($0) }
|
||||||
|
dict[1571450403] = { return Api.ChannelParticipant.parse_channelParticipantAdmin($0) }
|
||||||
dict[471043349] = { return Api.contacts.Blocked.parse_blocked($0) }
|
dict[471043349] = { return Api.contacts.Blocked.parse_blocked($0) }
|
||||||
dict[-1878523231] = { return Api.contacts.Blocked.parse_blockedSlice($0) }
|
dict[-1878523231] = { return Api.contacts.Blocked.parse_blockedSlice($0) }
|
||||||
dict[-55902537] = { return Api.InputDialogPeer.parse_inputDialogPeer($0) }
|
dict[-55902537] = { return Api.InputDialogPeer.parse_inputDialogPeer($0) }
|
||||||
|
@ -5489,8 +5489,8 @@ extension Api {
|
|||||||
case channelParticipant(userId: Int32, date: Int32)
|
case channelParticipant(userId: Int32, date: Int32)
|
||||||
case channelParticipantSelf(userId: Int32, inviterId: Int32, date: Int32)
|
case channelParticipantSelf(userId: Int32, inviterId: Int32, date: Int32)
|
||||||
case channelParticipantCreator(userId: Int32)
|
case channelParticipantCreator(userId: Int32)
|
||||||
case channelParticipantAdmin(flags: Int32, userId: Int32, inviterId: Int32, promotedBy: Int32, date: Int32, adminRights: Api.ChatAdminRights)
|
|
||||||
case channelParticipantBanned(flags: Int32, userId: Int32, kickedBy: Int32, date: Int32, bannedRights: Api.ChatBannedRights)
|
case channelParticipantBanned(flags: Int32, userId: Int32, kickedBy: Int32, date: Int32, bannedRights: Api.ChatBannedRights)
|
||||||
|
case channelParticipantAdmin(flags: Int32, userId: Int32, inviterId: Int32?, promotedBy: Int32, date: Int32, adminRights: Api.ChatAdminRights)
|
||||||
|
|
||||||
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
@ -5515,17 +5515,6 @@ extension Api {
|
|||||||
}
|
}
|
||||||
serializeInt32(userId, buffer: buffer, boxed: false)
|
serializeInt32(userId, buffer: buffer, boxed: false)
|
||||||
break
|
break
|
||||||
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1674301556)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(userId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(inviterId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(promotedBy, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
|
||||||
adminRights.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .channelParticipantBanned(let flags, let userId, let kickedBy, let date, let bannedRights):
|
case .channelParticipantBanned(let flags, let userId, let kickedBy, let date, let bannedRights):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(470789295)
|
buffer.appendInt32(470789295)
|
||||||
@ -5536,6 +5525,17 @@ extension Api {
|
|||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
bannedRights.serialize(buffer, true)
|
bannedRights.serialize(buffer, true)
|
||||||
break
|
break
|
||||||
|
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1571450403)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(userId, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(inviterId!, buffer: buffer, boxed: false)}
|
||||||
|
serializeInt32(promotedBy, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
|
adminRights.serialize(buffer, true)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5547,10 +5547,10 @@ extension Api {
|
|||||||
return ("channelParticipantSelf", [("userId", userId), ("inviterId", inviterId), ("date", date)])
|
return ("channelParticipantSelf", [("userId", userId), ("inviterId", inviterId), ("date", date)])
|
||||||
case .channelParticipantCreator(let userId):
|
case .channelParticipantCreator(let userId):
|
||||||
return ("channelParticipantCreator", [("userId", userId)])
|
return ("channelParticipantCreator", [("userId", userId)])
|
||||||
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights):
|
|
||||||
return ("channelParticipantAdmin", [("flags", flags), ("userId", userId), ("inviterId", inviterId), ("promotedBy", promotedBy), ("date", date), ("adminRights", adminRights)])
|
|
||||||
case .channelParticipantBanned(let flags, let userId, let kickedBy, let date, let bannedRights):
|
case .channelParticipantBanned(let flags, let userId, let kickedBy, let date, let bannedRights):
|
||||||
return ("channelParticipantBanned", [("flags", flags), ("userId", userId), ("kickedBy", kickedBy), ("date", date), ("bannedRights", bannedRights)])
|
return ("channelParticipantBanned", [("flags", flags), ("userId", userId), ("kickedBy", kickedBy), ("date", date), ("bannedRights", bannedRights)])
|
||||||
|
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights):
|
||||||
|
return ("channelParticipantAdmin", [("flags", flags), ("userId", userId), ("inviterId", inviterId), ("promotedBy", promotedBy), ("date", date), ("adminRights", adminRights)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5596,34 +5596,6 @@ extension Api {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static func parse_channelParticipantAdmin(_ reader: BufferReader) -> ChannelParticipant? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Int32?
|
|
||||||
_2 = reader.readInt32()
|
|
||||||
var _3: Int32?
|
|
||||||
_3 = reader.readInt32()
|
|
||||||
var _4: Int32?
|
|
||||||
_4 = reader.readInt32()
|
|
||||||
var _5: Int32?
|
|
||||||
_5 = reader.readInt32()
|
|
||||||
var _6: Api.ChatAdminRights?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_6 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
let _c5 = _5 != nil
|
|
||||||
let _c6 = _6 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
|
||||||
return Api.ChannelParticipant.channelParticipantAdmin(flags: _1!, userId: _2!, inviterId: _3!, promotedBy: _4!, date: _5!, adminRights: _6!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static func parse_channelParticipantBanned(_ reader: BufferReader) -> ChannelParticipant? {
|
static func parse_channelParticipantBanned(_ reader: BufferReader) -> ChannelParticipant? {
|
||||||
var _1: Int32?
|
var _1: Int32?
|
||||||
_1 = reader.readInt32()
|
_1 = reader.readInt32()
|
||||||
@ -5649,6 +5621,34 @@ extension Api {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static func parse_channelParticipantAdmin(_ reader: BufferReader) -> ChannelParticipant? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Int32?
|
||||||
|
_2 = reader.readInt32()
|
||||||
|
var _3: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_3 = reader.readInt32() }
|
||||||
|
var _4: Int32?
|
||||||
|
_4 = reader.readInt32()
|
||||||
|
var _5: Int32?
|
||||||
|
_5 = reader.readInt32()
|
||||||
|
var _6: Api.ChatAdminRights?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_6 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
let _c5 = _5 != nil
|
||||||
|
let _c6 = _6 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||||
|
return Api.ChannelParticipant.channelParticipantAdmin(flags: _1!, userId: _2!, inviterId: _3, promotedBy: _4!, date: _5!, adminRights: _6!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
enum InputDialogPeer: TypeConstructorDescription {
|
enum InputDialogPeer: TypeConstructorDescription {
|
||||||
|
@ -1547,20 +1547,6 @@ extension Api {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static func exportChatInvite(chatId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
|
|
||||||
let buffer = Buffer()
|
|
||||||
buffer.appendInt32(2106086025)
|
|
||||||
serializeInt32(chatId, buffer: buffer, boxed: false)
|
|
||||||
return (FunctionDescription(name: "messages.exportChatInvite", parameters: [("chatId", chatId)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.ExportedChatInvite? in
|
|
||||||
let reader = BufferReader(buffer)
|
|
||||||
var result: Api.ExportedChatInvite?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
result = Api.parse(reader, signature: signature) as? Api.ExportedChatInvite
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static func checkChatInvite(hash: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ChatInvite>) {
|
static func checkChatInvite(hash: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ChatInvite>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(1051570619)
|
buffer.appendInt32(1051570619)
|
||||||
@ -2796,6 +2782,20 @@ extension Api {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func exportChatInvite(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(234312524)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
return (FunctionDescription(name: "messages.exportChatInvite", parameters: [("peer", peer)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.ExportedChatInvite? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.ExportedChatInvite?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.ExportedChatInvite
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
struct channels {
|
struct channels {
|
||||||
static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
@ -3053,20 +3053,6 @@ extension Api {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static func exportInvite(channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
|
|
||||||
let buffer = Buffer()
|
|
||||||
buffer.appendInt32(-950663035)
|
|
||||||
channel.serialize(buffer, true)
|
|
||||||
return (FunctionDescription(name: "channels.exportInvite", parameters: [("channel", channel)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.ExportedChatInvite? in
|
|
||||||
let reader = BufferReader(buffer)
|
|
||||||
var result: Api.ExportedChatInvite?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
result = Api.parse(reader, signature: signature) as? Api.ExportedChatInvite
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static func deleteChannel(channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
static func deleteChannel(channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(-1072619549)
|
buffer.appendInt32(-1072619549)
|
||||||
|
@ -36,8 +36,8 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
|
|||||||
var role: TelegramGroupRole = .member
|
var role: TelegramGroupRole = .member
|
||||||
if (flags & (1 << 0)) != 0 {
|
if (flags & (1 << 0)) != 0 {
|
||||||
role = .creator
|
role = .creator
|
||||||
} else if adminRights != nil {
|
} else if let adminRights = adminRights {
|
||||||
//role = .admin
|
role = .admin(TelegramChatAdminRights(apiAdminRights: adminRights))
|
||||||
}
|
}
|
||||||
if (flags & (1 << 5)) != 0 {
|
if (flags & (1 << 5)) != 0 {
|
||||||
groupFlags.insert(.deactivated)
|
groupFlags.insert(.deactivated)
|
||||||
|
@ -504,7 +504,7 @@ final class TelegramCloudMediaResourceFetchInfo: MediaResourceFetchInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchedMediaResource(postbox: Postbox, reference: MediaResourceReference, range: (Range<Int>, MediaBoxFetchPriority)? = nil, statsCategory: MediaResourceStatsCategory = .generic, reportResultStatus: Bool = false, preferBackgroundReferenceRevalidation: Bool = false, continueInBackground: Bool = false) -> Signal<FetchResourceSourceType, NoError> {
|
public func fetchedMediaResource(postbox: Postbox, reference: MediaResourceReference, range: (Range<Int>, MediaBoxFetchPriority)? = nil, statsCategory: MediaResourceStatsCategory = .generic, reportResultStatus: Bool = false, preferBackgroundReferenceRevalidation: Bool = false, continueInBackground: Bool = false) -> Signal<FetchResourceSourceType, FetchResourceError> {
|
||||||
if let (range, priority) = range {
|
if let (range, priority) = range {
|
||||||
return postbox.mediaBox.fetchedResourceData(reference.resource, in: range, priority: priority, parameters: MediaResourceFetchParameters(tag: TelegramMediaResourceFetchTag(statsCategory: statsCategory), info: TelegramCloudMediaResourceFetchInfo(reference: reference, preferBackgroundReferenceRevalidation: preferBackgroundReferenceRevalidation, continueInBackground: continueInBackground)))
|
return postbox.mediaBox.fetchedResourceData(reference.resource, in: range, priority: priority, parameters: MediaResourceFetchParameters(tag: TelegramMediaResourceFetchTag(statsCategory: statsCategory), info: TelegramCloudMediaResourceFetchInfo(reference: reference, preferBackgroundReferenceRevalidation: preferBackgroundReferenceRevalidation, continueInBackground: continueInBackground)))
|
||||||
|> map { _ in .local }
|
|> map { _ in .local }
|
||||||
|
@ -11,45 +11,45 @@ import Foundation
|
|||||||
|
|
||||||
public func ensuredExistingPeerExportedInvitation(account: Account, peerId: PeerId, revokeExisted: Bool = false) -> Signal<Void, NoError> {
|
public func ensuredExistingPeerExportedInvitation(account: Account, peerId: PeerId, revokeExisted: Bool = false) -> Signal<Void, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
if let peer = transaction.getPeer(peerId) {
|
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
|
||||||
if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) {
|
if let _ = peer as? TelegramChannel {
|
||||||
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, cachedData.exportedInvitation != nil && !revokeExisted {
|
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, cachedData.exportedInvitation != nil && !revokeExisted {
|
||||||
return .complete()
|
return .complete()
|
||||||
} else {
|
} else {
|
||||||
return account.network.request(Api.functions.channels.exportInvite(channel: inputChannel))
|
return account.network.request(Api.functions.messages.exportChatInvite(peer: inputPeer))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return account.postbox.transaction { transaction -> Void in
|
||||||
if let invitation = ExportedInvitation(apiExportedInvite: result) {
|
if let invitation = ExportedInvitation(apiExportedInvite: result) {
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||||
if let current = current as? CachedChannelData {
|
if let current = current as? CachedChannelData {
|
||||||
return current.withUpdatedExportedInvitation(invitation)
|
return current.withUpdatedExportedInvitation(invitation)
|
||||||
} else {
|
} else {
|
||||||
return CachedChannelData().withUpdatedExportedInvitation(invitation)
|
return CachedChannelData().withUpdatedExportedInvitation(invitation)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if let group = peer as? TelegramGroup {
|
} else if let _ = peer as? TelegramGroup {
|
||||||
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedGroupData, cachedData.exportedInvitation != nil && !revokeExisted {
|
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedGroupData, cachedData.exportedInvitation != nil && !revokeExisted {
|
||||||
return .complete()
|
return .complete()
|
||||||
} else {
|
} else {
|
||||||
return account.network.request(Api.functions.messages.exportChatInvite(chatId: group.id.id))
|
return account.network.request(Api.functions.messages.exportChatInvite(peer: inputPeer))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return account.postbox.transaction { transaction -> Void in
|
||||||
if let invitation = ExportedInvitation(apiExportedInvite: result) {
|
if let invitation = ExportedInvitation(apiExportedInvite: result) {
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||||
if let current = current as? CachedGroupData {
|
if let current = current as? CachedGroupData {
|
||||||
return current.withUpdatedExportedInvitation(invitation)
|
return current.withUpdatedExportedInvitation(invitation)
|
||||||
} else {
|
} else {
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -391,7 +391,7 @@ func multipartUpload(network: Network, postbox: Postbox, source: MultipartUpload
|
|||||||
|
|
||||||
let dataSignal: Signal<MultipartUploadData, NoError>
|
let dataSignal: Signal<MultipartUploadData, NoError>
|
||||||
let headerSize: Int32
|
let headerSize: Int32
|
||||||
let fetchedResource: Signal<Void, NoError>
|
let fetchedResource: Signal<Void, FetchResourceError>
|
||||||
switch source {
|
switch source {
|
||||||
case let .resource(resource):
|
case let .resource(resource):
|
||||||
dataSignal = postbox.mediaBox.resourceData(resource.resource, option: .incremental(waitUntilFetchStatus: true)) |> map { MultipartUploadData.resourceData($0) }
|
dataSignal = postbox.mediaBox.resourceData(resource.resource, option: .incremental(waitUntilFetchStatus: true)) |> map { MultipartUploadData.resourceData($0) }
|
||||||
@ -454,7 +454,9 @@ func multipartUpload(network: Network, postbox: Postbox, source: MultipartUpload
|
|||||||
|
|
||||||
manager.start()
|
manager.start()
|
||||||
|
|
||||||
let fetchedResourceDisposable = fetchedResource.start()
|
let fetchedResourceDisposable = fetchedResource.start(error: { _ in
|
||||||
|
subscriber.putError(.generic)
|
||||||
|
})
|
||||||
|
|
||||||
return ActionDisposable {
|
return ActionDisposable {
|
||||||
manager.cancel()
|
manager.cancel()
|
||||||
|
@ -189,7 +189,9 @@ private func maybePredownloadedImageResource(postbox: Postbox, peerId: PeerId, r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let fetched = postbox.mediaBox.fetchedResource(resource, parameters: nil).start()
|
let fetched = postbox.mediaBox.fetchedResource(resource, parameters: nil).start(error: { _ in
|
||||||
|
subscriber.putError(.generic)
|
||||||
|
})
|
||||||
|
|
||||||
return ActionDisposable {
|
return ActionDisposable {
|
||||||
data.dispose()
|
data.dispose()
|
||||||
@ -609,7 +611,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
|
|||||||
|
|
||||||
var thumbnailFile: Api.InputFile?
|
var thumbnailFile: Api.InputFile?
|
||||||
if case let .file(file) = thumbnail {
|
if case let .file(file) = thumbnail {
|
||||||
//thumbnailFile = file
|
thumbnailFile = file
|
||||||
}
|
}
|
||||||
|
|
||||||
if let _ = thumbnailFile {
|
if let _ = thumbnailFile {
|
||||||
|
@ -15,18 +15,173 @@ public enum SearchMessagesLocation: Equatable {
|
|||||||
case peer(peerId: PeerId, fromId: PeerId?, tags: MessageTags?)
|
case peer(peerId: PeerId, fromId: PeerId?, tags: MessageTags?)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func searchMessages(account: Account, location: SearchMessagesLocation, query: String, lowerBound: MessageIndex? = nil, limit: Int32 = 100) -> Signal<([Message], [PeerId : CombinedPeerReadState], Int32), NoError> {
|
private struct SearchMessagesPeerState: Equatable {
|
||||||
let remoteSearchResult: Signal<Api.messages.Messages?, NoError>
|
let messages: [Message]
|
||||||
|
let readStates: [PeerId: CombinedPeerReadState]
|
||||||
|
let totalCount: Int32
|
||||||
|
let completed: Bool
|
||||||
|
|
||||||
|
static func ==(lhs: SearchMessagesPeerState, rhs: SearchMessagesPeerState) -> Bool {
|
||||||
|
if lhs.totalCount != rhs.totalCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.completed != rhs.completed {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.messages.count != rhs.messages.count {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i in 0 ..< lhs.messages.count {
|
||||||
|
if lhs.messages[i].id != rhs.messages[i].id {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SearchMessagesResult {
|
||||||
|
public let messages: [Message]
|
||||||
|
public let readStates: [PeerId: CombinedPeerReadState]
|
||||||
|
public let totalCount: Int32
|
||||||
|
public let completed: Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SearchMessagesState: Equatable {
|
||||||
|
fileprivate let main: SearchMessagesPeerState
|
||||||
|
fileprivate let additional: SearchMessagesPeerState?
|
||||||
|
}
|
||||||
|
|
||||||
|
private func mergedState(transaction: Transaction, state: SearchMessagesPeerState?, result: Api.messages.Messages?) -> SearchMessagesPeerState? {
|
||||||
|
guard let result = result else {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
let messages: [Api.Message]
|
||||||
|
let chats: [Api.Chat]
|
||||||
|
let users: [Api.User]
|
||||||
|
let totalCount: Int32
|
||||||
|
switch result {
|
||||||
|
case let .channelMessages(_, _, count, apiMessages, apiChats, apiUsers):
|
||||||
|
messages = apiMessages
|
||||||
|
chats = apiChats
|
||||||
|
users = apiUsers
|
||||||
|
totalCount = count
|
||||||
|
case let .messages(apiMessages, apiChats, apiUsers):
|
||||||
|
messages = apiMessages
|
||||||
|
chats = apiChats
|
||||||
|
users = apiUsers
|
||||||
|
totalCount = Int32(messages.count)
|
||||||
|
case let .messagesSlice(_, count, apiMessages, apiChats, apiUsers):
|
||||||
|
messages = apiMessages
|
||||||
|
chats = apiChats
|
||||||
|
users = apiUsers
|
||||||
|
totalCount = count
|
||||||
|
case .messagesNotModified:
|
||||||
|
messages = []
|
||||||
|
chats = []
|
||||||
|
users = []
|
||||||
|
totalCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var peers: [PeerId: Peer] = [:]
|
||||||
|
|
||||||
|
for user in users {
|
||||||
|
if let user = TelegramUser.merge(transaction.getPeer(user.peerId) as? TelegramUser, rhs: user) {
|
||||||
|
peers[user.id] = user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for chat in chats {
|
||||||
|
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
||||||
|
peers[groupOrChannel.id] = groupOrChannel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var peerIdsSet: Set<PeerId> = Set()
|
||||||
|
var readStates: [PeerId: CombinedPeerReadState] = [:]
|
||||||
|
|
||||||
|
var renderedMessages: [Message] = []
|
||||||
|
for message in messages {
|
||||||
|
if let message = StoreMessage(apiMessage: message), let renderedMessage = locallyRenderedMessage(message: message, peers: peers) {
|
||||||
|
renderedMessages.append(renderedMessage)
|
||||||
|
peerIdsSet.insert(message.id.peerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for peerId in peerIdsSet {
|
||||||
|
if let readState = transaction.getCombinedPeerReadState(peerId) {
|
||||||
|
readStates[peerId] = readState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderedMessages.sort(by: { lhs, rhs in
|
||||||
|
return MessageIndex(lhs) > MessageIndex(rhs)
|
||||||
|
})
|
||||||
|
|
||||||
|
let completed = renderedMessages.isEmpty
|
||||||
|
if let previous = state {
|
||||||
|
var currentIds = Set<MessageId>()
|
||||||
|
var mergedMessages: [Message] = []
|
||||||
|
for message in previous.messages {
|
||||||
|
if currentIds.contains(message.id) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currentIds.insert(message.id)
|
||||||
|
mergedMessages.append(message)
|
||||||
|
}
|
||||||
|
for message in renderedMessages {
|
||||||
|
if currentIds.contains(message.id) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currentIds.insert(message.id)
|
||||||
|
mergedMessages.append(message)
|
||||||
|
}
|
||||||
|
mergedMessages.sort(by: { lhs, rhs in
|
||||||
|
return MessageIndex(lhs) > MessageIndex(rhs)
|
||||||
|
})
|
||||||
|
return SearchMessagesPeerState(messages: mergedMessages, readStates: readStates, totalCount: completed ? Int32(mergedMessages.count) : totalCount, completed: completed)
|
||||||
|
} else {
|
||||||
|
return SearchMessagesPeerState(messages: renderedMessages, readStates: readStates, totalCount: completed ? Int32(renderedMessages.count) : totalCount, completed: completed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func mergedResult(_ state: SearchMessagesState) -> SearchMessagesResult {
|
||||||
|
var messages: [Message] = state.main.messages
|
||||||
|
if let additional = state.additional {
|
||||||
|
if state.main.completed {
|
||||||
|
messages.append(contentsOf: additional.messages)
|
||||||
|
} else if let lastMessage = state.main.messages.last {
|
||||||
|
let earliestIndex = MessageIndex(lastMessage)
|
||||||
|
messages.append(contentsOf: additional.messages.filter({ MessageIndex($0) > earliestIndex }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
messages.sort(by: { lhs, rhs in
|
||||||
|
return MessageIndex(lhs) > MessageIndex(rhs)
|
||||||
|
})
|
||||||
|
|
||||||
|
var readStates: [PeerId: CombinedPeerReadState] = [:]
|
||||||
|
for message in messages {
|
||||||
|
let readState = state.main.readStates[message.id.peerId] ?? state.additional?.readStates[message.id.peerId]
|
||||||
|
if let readState = readState {
|
||||||
|
readStates[message.id.peerId] = readState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SearchMessagesResult(messages: messages, readStates: readStates, totalCount: state.main.totalCount + (state.additional?.totalCount ?? 0), completed: state.main.completed && (state.additional?.completed ?? true))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func searchMessages(account: Account, location: SearchMessagesLocation, query: String, state: SearchMessagesState?, limit: Int32 = 100) -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> {
|
||||||
|
let remoteSearchResult: Signal<(Api.messages.Messages?, Api.messages.Messages?), NoError>
|
||||||
switch location {
|
switch location {
|
||||||
case let .peer(peerId, fromId, tags):
|
case let .peer(peerId, fromId, tags):
|
||||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
return account.postbox.transaction { transaction -> ([Message], [PeerId : CombinedPeerReadState], Int32) in
|
return account.postbox.transaction { transaction -> (SearchMessagesResult, SearchMessagesState) in
|
||||||
var readStates: [PeerId : CombinedPeerReadState] = [:]
|
var readStates: [PeerId: CombinedPeerReadState] = [:]
|
||||||
if let readState = transaction.getCombinedPeerReadState(peerId) {
|
if let readState = transaction.getCombinedPeerReadState(peerId) {
|
||||||
readStates[peerId] = readState
|
readStates[peerId] = readState
|
||||||
}
|
}
|
||||||
let result = transaction.searchMessages(peerId: peerId, query: query, tags: tags)
|
let result = transaction.searchMessages(peerId: peerId, query: query, tags: tags)
|
||||||
return (result, readStates, Int32(result.count))
|
return (SearchMessagesResult(messages: result, readStates: readStates, totalCount: Int32(result.count), completed: true), SearchMessagesState(main: SearchMessagesPeerState(messages: [], readStates: [:], totalCount: 0, completed: true), additional: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,134 +200,114 @@ public func searchMessages(account: Account, location: SearchMessagesLocation, q
|
|||||||
} else {
|
} else {
|
||||||
filter = .inputMessagesFilterEmpty
|
filter = .inputMessagesFilterEmpty
|
||||||
}
|
}
|
||||||
|
remoteSearchResult = account.postbox.transaction { transaction -> (peer: Peer, additionalPeer: Peer?, from: Peer?)? in
|
||||||
remoteSearchResult = account.postbox.transaction { transaction -> (peer: Peer?, from: Peer?) in
|
guard let peer = transaction.getPeer(peerId) else {
|
||||||
if let fromId = fromId {
|
return nil
|
||||||
return (peer: transaction.getPeer(peerId), from: transaction.getPeer(fromId))
|
|
||||||
}
|
}
|
||||||
return (peer: transaction.getPeer(peerId), from: nil)
|
var additionalPeer: Peer?
|
||||||
|
if let _ = peer as? TelegramChannel, let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, let migrationReference = cachedData.migrationReference {
|
||||||
|
additionalPeer = transaction.getPeer(migrationReference.maxMessageId.peerId)
|
||||||
|
}
|
||||||
|
if let fromId = fromId {
|
||||||
|
return (peer: peer, additionalPeer: additionalPeer, from: transaction.getPeer(fromId))
|
||||||
|
}
|
||||||
|
return (peer: peer, additionalPeer: additionalPeer, from: nil)
|
||||||
}
|
}
|
||||||
|> mapToSignal { values -> Signal<Api.messages.Messages?, NoError> in
|
|> mapToSignal { values -> Signal<(Api.messages.Messages?, Api.messages.Messages?), NoError> in
|
||||||
if let peer = values.peer, let inputPeer = apiInputPeer(peer) {
|
guard let values = values else {
|
||||||
var fromInputUser: Api.InputUser? = nil
|
return .single((nil, nil))
|
||||||
var flags: Int32 = 0
|
}
|
||||||
if let from = values.from {
|
let peer = values.peer
|
||||||
fromInputUser = apiInputUser(from)
|
guard let inputPeer = apiInputPeer(peer) else {
|
||||||
if let _ = fromInputUser {
|
return .single((nil, nil))
|
||||||
flags |= (1 << 0)
|
}
|
||||||
}
|
var fromInputUser: Api.InputUser? = nil
|
||||||
|
var flags: Int32 = 0
|
||||||
|
if let from = values.from {
|
||||||
|
fromInputUser = apiInputUser(from)
|
||||||
|
if let _ = fromInputUser {
|
||||||
|
flags |= (1 << 0)
|
||||||
}
|
}
|
||||||
return account.network.request(Api.functions.messages.search(flags: flags, peer: inputPeer, q: query, fromId: fromInputUser, filter: filter, minDate: 0, maxDate: Int32.max - 1, offsetId: lowerBound?.id.id ?? 0, addOffset: 0, limit: limit, maxId: Int32.max - 1, minId: 0, hash: 0))
|
}
|
||||||
|
let peerMessages: Signal<Api.messages.Messages?, NoError>
|
||||||
|
if let completed = state?.main.completed, completed {
|
||||||
|
peerMessages = .single(nil)
|
||||||
|
} else {
|
||||||
|
let lowerBound = state?.main.messages.last.flatMap(MessageIndex.init)
|
||||||
|
peerMessages = account.network.request(Api.functions.messages.search(flags: flags, peer: inputPeer, q: query, fromId: fromInputUser, filter: filter, minDate: 0, maxDate: Int32.max - 1, offsetId: lowerBound?.id.id ?? 0, addOffset: 0, limit: limit, maxId: Int32.max - 1, minId: 0, hash: 0))
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<Api.messages.Messages?, NoError> in
|
|> `catch` { _ -> Signal<Api.messages.Messages?, NoError> in
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return .never()
|
|
||||||
}
|
}
|
||||||
|
let additionalPeerMessages: Signal<Api.messages.Messages?, NoError>
|
||||||
|
if let inputPeer = values.additionalPeer.flatMap(apiInputPeer) {
|
||||||
|
let mainCompleted = state?.main.completed ?? false
|
||||||
|
let hasAdditional = state?.additional != nil
|
||||||
|
if let completed = state?.additional?.completed, completed {
|
||||||
|
additionalPeerMessages = .single(nil)
|
||||||
|
} else if mainCompleted || !hasAdditional {
|
||||||
|
let lowerBound = state?.additional?.messages.last.flatMap(MessageIndex.init)
|
||||||
|
additionalPeerMessages = account.network.request(Api.functions.messages.search(flags: flags, peer: inputPeer, q: query, fromId: fromInputUser, filter: filter, minDate: 0, maxDate: Int32.max - 1, offsetId: lowerBound?.id.id ?? 0, addOffset: 0, limit: limit, maxId: Int32.max - 1, minId: 0, hash: 0))
|
||||||
|
|> map(Optional.init)
|
||||||
|
|> `catch` { _ -> Signal<Api.messages.Messages?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
additionalPeerMessages = .single(nil)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
additionalPeerMessages = .single(nil)
|
||||||
|
}
|
||||||
|
return combineLatest(peerMessages, additionalPeerMessages)
|
||||||
}
|
}
|
||||||
case let .group(groupId):
|
case let .group(groupId):
|
||||||
/*feed*/
|
/*feed*/
|
||||||
remoteSearchResult = .single(nil)
|
remoteSearchResult = .single((nil, nil))
|
||||||
/*remoteSearchResult = account.network.request(Api.functions.channels.searchFeed(feedId: groupId.rawValue, q: query, offsetDate: 0, offsetPeer: Api.InputPeer.inputPeerEmpty, offsetId: 0, limit: 64), automaticFloodWait: false)
|
/*remoteSearchResult = account.network.request(Api.functions.channels.searchFeed(feedId: groupId.rawValue, q: query, offsetDate: 0, offsetPeer: Api.InputPeer.inputPeerEmpty, offsetId: 0, limit: 64), automaticFloodWait: false)
|
||||||
|> mapError { _ in } |> map(Optional.init)*/
|
|> mapError { _ in } |> map(Optional.init)*/
|
||||||
case .general:
|
case .general:
|
||||||
remoteSearchResult = account.postbox.transaction { transaction -> Api.InputPeer in
|
remoteSearchResult = account.postbox.transaction { transaction -> (MessageIndex?, Api.InputPeer) in
|
||||||
|
var lowerBound: MessageIndex?
|
||||||
|
if let state = state, let message = state.main.messages.last {
|
||||||
|
lowerBound = MessageIndex(message)
|
||||||
|
}
|
||||||
if let lowerBound = lowerBound, let peer = transaction.getPeer(lowerBound.id.peerId), let inputPeer = apiInputPeer(peer) {
|
if let lowerBound = lowerBound, let peer = transaction.getPeer(lowerBound.id.peerId), let inputPeer = apiInputPeer(peer) {
|
||||||
return inputPeer
|
return (lowerBound, inputPeer)
|
||||||
} else {
|
} else {
|
||||||
return .inputPeerEmpty
|
return (lowerBound, .inputPeerEmpty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> mapToSignal { inputPeer in
|
|> mapToSignal { (lowerBound, inputPeer) in
|
||||||
account.network.request(Api.functions.messages.searchGlobal(q: query, offsetDate: lowerBound?.timestamp ?? 0, offsetPeer: inputPeer, offsetId: lowerBound?.id.id ?? 0, limit: limit), automaticFloodWait: false)
|
account.network.request(Api.functions.messages.searchGlobal(q: query, offsetDate: lowerBound?.timestamp ?? 0, offsetPeer: inputPeer, offsetId: lowerBound?.id.id ?? 0, limit: limit), automaticFloodWait: false)
|
||||||
|> map(Optional.init)
|
|> map { result -> (Api.messages.Messages?, Api.messages.Messages?) in
|
||||||
|> `catch` { _ -> Signal<Api.messages.Messages?, NoError> in
|
return (result, nil)
|
||||||
return .single(nil)
|
}
|
||||||
|
|> `catch` { _ -> Signal<(Api.messages.Messages?, Api.messages.Messages?), NoError> in
|
||||||
|
return .single((nil, nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let processedSearchResult = remoteSearchResult
|
return remoteSearchResult
|
||||||
|> mapToSignal { result -> Signal<([Message], [PeerId: CombinedPeerReadState], Int32), NoError> in
|
|> mapToSignal { result, additionalResult -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> in
|
||||||
guard let result = result else {
|
return account.postbox.transaction { transaction -> (SearchMessagesResult, SearchMessagesState) in
|
||||||
return .single(([], [:], 0))
|
var additional: SearchMessagesPeerState? = mergedState(transaction: transaction, state: state?.additional, result: additionalResult)
|
||||||
}
|
if state?.additional == nil, case .general = location {
|
||||||
|
|
||||||
//assert(false)
|
|
||||||
let messages: [Api.Message]
|
|
||||||
let chats: [Api.Chat]
|
|
||||||
let users: [Api.User]
|
|
||||||
let totalCount: Int32
|
|
||||||
switch result {
|
|
||||||
case let .channelMessages(_, _, count, apiMessages, apiChats, apiUsers):
|
|
||||||
messages = apiMessages
|
|
||||||
chats = apiChats
|
|
||||||
users = apiUsers
|
|
||||||
totalCount = count
|
|
||||||
case let .messages(apiMessages, apiChats, apiUsers):
|
|
||||||
messages = apiMessages
|
|
||||||
chats = apiChats
|
|
||||||
users = apiUsers
|
|
||||||
totalCount = Int32(messages.count)
|
|
||||||
case let .messagesSlice(_, count, apiMessages, apiChats, apiUsers):
|
|
||||||
messages = apiMessages
|
|
||||||
chats = apiChats
|
|
||||||
users = apiUsers
|
|
||||||
totalCount = count
|
|
||||||
case .messagesNotModified:
|
|
||||||
messages = []
|
|
||||||
chats = []
|
|
||||||
users = []
|
|
||||||
totalCount = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return account.postbox.transaction { transaction -> ([Message], [PeerId : CombinedPeerReadState], Int32) in
|
|
||||||
var peers: [PeerId: Peer] = [:]
|
|
||||||
|
|
||||||
for user in users {
|
|
||||||
if let user = TelegramUser.merge(transaction.getPeer(user.peerId) as? TelegramUser, rhs: user) {
|
|
||||||
peers[user.id] = user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for chat in chats {
|
|
||||||
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
|
||||||
peers[groupOrChannel.id] = groupOrChannel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var peerIdsSet: Set<PeerId> = Set()
|
|
||||||
var readStates:[PeerId : CombinedPeerReadState] = [:]
|
|
||||||
|
|
||||||
var renderedMessages: [Message] = []
|
|
||||||
for message in messages {
|
|
||||||
if let message = StoreMessage(apiMessage: message), let renderedMessage = locallyRenderedMessage(message: message, peers: peers) {
|
|
||||||
renderedMessages.append(renderedMessage)
|
|
||||||
peerIdsSet.insert(message.id.peerId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for peerId in peerIdsSet {
|
|
||||||
if let readState = transaction.getCombinedPeerReadState(peerId) {
|
|
||||||
readStates[peerId] = readState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if case .general = location {
|
|
||||||
let secretMessages = transaction.searchMessages(peerId: nil, query: query, tags: nil)
|
let secretMessages = transaction.searchMessages(peerId: nil, query: query, tags: nil)
|
||||||
renderedMessages.append(contentsOf: secretMessages)
|
var readStates: [PeerId: CombinedPeerReadState] = [:]
|
||||||
|
for message in secretMessages {
|
||||||
|
if let readState = transaction.getCombinedPeerReadState(message.id.peerId) {
|
||||||
|
readStates[message.id.peerId] = readState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
additional = SearchMessagesPeerState(messages: secretMessages, readStates: readStates, totalCount: Int32(secretMessages.count), completed: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderedMessages.sort(by: { lhs, rhs in
|
let updatedState = SearchMessagesState(main: mergedState(transaction: transaction, state: state?.main, result: result) ?? SearchMessagesPeerState(messages: [], readStates: [:], totalCount: 0, completed: true), additional: additional)
|
||||||
return MessageIndex(lhs) > MessageIndex(rhs)
|
return (mergedResult(updatedState), updatedState)
|
||||||
})
|
|
||||||
|
|
||||||
return (renderedMessages, readStates, totalCount)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return processedSearchResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func downloadMessage(postbox: Postbox, network: Network, messageId: MessageId) -> Signal<Message?, NoError> {
|
public func downloadMessage(postbox: Postbox, network: Network, messageId: MessageId) -> Signal<Message?, NoError> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user