no message

This commit is contained in:
Peter 2018-05-20 23:10:26 +02:00
parent 1bd781669c
commit ec6c3b451d
11 changed files with 385 additions and 233 deletions

View File

@ -386,8 +386,6 @@
D08CAA881ED81DD40000FDA8 /* LocalizationInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */; }; D08CAA881ED81DD40000FDA8 /* LocalizationInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */; };
D08CAA8C1ED81EDF0000FDA8 /* Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */; }; D08CAA8C1ED81EDF0000FDA8 /* Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */; };
D08CAA8D1ED81EDF0000FDA8 /* Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */; }; D08CAA8D1ED81EDF0000FDA8 /* Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */; };
D08D7E8120A0F3E10005D80C /* GroupPeerMembers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08D7E8020A0F3E10005D80C /* GroupPeerMembers.swift */; };
D08D7E8220A0F3E10005D80C /* GroupPeerMembers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08D7E8020A0F3E10005D80C /* GroupPeerMembers.swift */; };
D08F4A661E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; }; D08F4A661E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; };
D08F4A671E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; }; D08F4A671E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; };
D08F4A691E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */; }; D08F4A691E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */; };
@ -922,7 +920,6 @@
D08CAA831ED8164B0000FDA8 /* Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localization.swift; sourceTree = "<group>"; }; D08CAA831ED8164B0000FDA8 /* Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localization.swift; sourceTree = "<group>"; };
D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizationInfo.swift; sourceTree = "<group>"; }; D08CAA861ED81DD40000FDA8 /* LocalizationInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizationInfo.swift; sourceTree = "<group>"; };
D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localizations.swift; sourceTree = "<group>"; }; D08CAA8B1ED81EDF0000FDA8 /* Localizations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localizations.swift; sourceTree = "<group>"; };
D08D7E8020A0F3E10005D80C /* GroupPeerMembers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupPeerMembers.swift; sourceTree = "<group>"; };
D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; }; D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; };
D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; }; D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; };
D093D7ED206413F600BC3599 /* SecureIdDataTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureIdDataTypes.swift; sourceTree = "<group>"; }; D093D7ED206413F600BC3599 /* SecureIdDataTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureIdDataTypes.swift; sourceTree = "<group>"; };
@ -1790,7 +1787,6 @@
D0C44B601FC616E200227BE0 /* SearchGroupMembers.swift */, D0C44B601FC616E200227BE0 /* SearchGroupMembers.swift */,
D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */, D0F8C39C20178B9B00236FC5 /* GroupFeedPeers.swift */,
D018EE042045E95000CBB130 /* CheckPeerChatServiceActions.swift */, D018EE042045E95000CBB130 /* CheckPeerChatServiceActions.swift */,
D08D7E8020A0F3E10005D80C /* GroupPeerMembers.swift */,
); );
name = Peers; name = Peers;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2092,7 +2088,6 @@
D0F3A8A21E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift in Sources */, D0F3A8A21E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift in Sources */,
D01C7ED61EF5E468008305F1 /* ProxySettings.swift in Sources */, D01C7ED61EF5E468008305F1 /* ProxySettings.swift in Sources */,
D049EAE81E44B67100A2CD3A /* RecentPeerItem.swift in Sources */, D049EAE81E44B67100A2CD3A /* RecentPeerItem.swift in Sources */,
D08D7E8120A0F3E10005D80C /* GroupPeerMembers.swift in Sources */,
D02ABC7B1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */, D02ABC7B1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
C2E064681ECEEF0A00387BB8 /* TelegramMediaInvoice.swift in Sources */, C2E064681ECEEF0A00387BB8 /* TelegramMediaInvoice.swift in Sources */,
D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */, D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */,
@ -2448,7 +2443,6 @@
D01A21A71F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */, D01A21A71F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */,
D0E68776207534CA0064BDB2 /* Api0.swift in Sources */, D0E68776207534CA0064BDB2 /* Api0.swift in Sources */,
D00C7CEC1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */, D00C7CEC1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */,
D08D7E8220A0F3E10005D80C /* GroupPeerMembers.swift in Sources */,
D048B4AD20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift in Sources */, D048B4AD20A5DA4300C79D31 /* ManagedProxyInfoUpdates.swift in Sources */,
D0B844481DAB91FD005F29E1 /* ManagedMessageHistoryHoles.swift in Sources */, D0B844481DAB91FD005F29E1 /* ManagedMessageHistoryHoles.swift in Sources */,
D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */, D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */,

View File

@ -1031,30 +1031,6 @@ public extension Api {
}) })
} }
public static func editMessage(flags: Int32, peer: Api.InputPeer, id: Int32, message: String?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, geoPoint: Api.InputGeoPoint?) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Updates?) {
let buffer = Buffer()
buffer.appendInt32(97630429)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(id, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 11) != 0 {serializeString(message!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {replyMarkup!.serialize(buffer, true)}
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(entities!.count))
for item in entities! {
item.serialize(buffer, true)
}}
if Int(flags) & Int(1 << 13) != 0 {geoPoint!.serialize(buffer, true)}
return (FunctionDescription({return "(messages.editMessage flags: \(flags), peer: \(peer), id: \(id), message: \(String(describing: message)), replyMarkup: \(String(describing: replyMarkup)), entities: \(String(describing: entities)), geoPoint: \(String(describing: geoPoint)))"}), buffer, { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
public static func editInlineBotMessage(flags: Int32, id: Api.InputBotInlineMessageID, message: String?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) { public static func editInlineBotMessage(flags: Int32, id: Api.InputBotInlineMessageID, message: String?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(319564933) buffer.appendInt32(319564933)
@ -1800,6 +1776,31 @@ public extension Api {
}) })
} }
public static func editMessage(flags: Int32, peer: Api.InputPeer, id: Int32, message: String?, media: Api.InputMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, geoPoint: Api.InputGeoPoint?) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Updates?) {
let buffer = Buffer()
buffer.appendInt32(-1073683256)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(id, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 11) != 0 {serializeString(message!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 14) != 0 {media!.serialize(buffer, true)}
if Int(flags) & Int(1 << 2) != 0 {replyMarkup!.serialize(buffer, true)}
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(entities!.count))
for item in entities! {
item.serialize(buffer, true)
}}
if Int(flags) & Int(1 << 13) != 0 {geoPoint!.serialize(buffer, true)}
return (FunctionDescription({return "(messages.editMessage flags: \(flags), peer: \(peer), id: \(id), message: \(String(describing: message)), media: \(String(describing: media)), replyMarkup: \(String(describing: replyMarkup)), entities: \(String(describing: entities)), geoPoint: \(String(describing: geoPoint)))"}), buffer, { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
public static func getStickers(emoticon: String, hash: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Stickers?) { public static func getStickers(emoticon: String, hash: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Stickers?) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(71126828) buffer.appendInt32(71126828)

View File

@ -132,15 +132,36 @@ public func channelBlacklistParticipants(account: Account, peerId: PeerId) -> Si
} }
} }
public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, memberId: PeerId, rights: TelegramChannelBannedRights) -> Signal<Void, NoError> { public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, memberId: PeerId, rights: TelegramChannelBannedRights?) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), NoError> {
return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId) return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId)
|> mapToSignal { currentParticipant -> Signal<Void, NoError> in |> mapToSignal { currentParticipant -> Signal<(ChannelParticipant?, RenderedChannelParticipant), NoError> in
return account.postbox.modify { modifier -> Signal<Void, NoError> in return account.postbox.modify { modifier -> Signal<(ChannelParticipant?, RenderedChannelParticipant), NoError> in
if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer), let memberPeer = modifier.getPeer(memberId), let inputUser = apiInputUser(memberPeer) { if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer), let _ = modifier.getPeer(account.peerId), let memberPeer = modifier.getPeer(memberId), let inputUser = apiInputUser(memberPeer) {
return account.network.request(Api.functions.channels.editBanned(channel: inputChannel, userId: inputUser, bannedRights: rights.apiBannedRights)) let updatedParticipant: ChannelParticipant
if let currentParticipant = currentParticipant, case let .member(_, invitedAt, _, currentBanInfo) = currentParticipant {
let banInfo: ChannelParticipantBannedInfo?
if let rights = rights, !rights.flags.isEmpty {
banInfo = ChannelParticipantBannedInfo(rights: rights, restrictedBy: currentBanInfo?.restrictedBy ?? account.peerId, isMember: currentBanInfo?.isMember ?? true)
} else {
banInfo = nil
}
updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: invitedAt, adminInfo: nil, banInfo: banInfo)
} else {
let banInfo: ChannelParticipantBannedInfo?
if let rights = rights, !rights.flags.isEmpty {
banInfo = ChannelParticipantBannedInfo(rights: rights, restrictedBy: account.peerId, isMember: false)
} else {
banInfo = nil
}
updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: nil, banInfo: banInfo)
}
let effectiveRights: TelegramChannelBannedRights = rights ?? TelegramChannelBannedRights(flags: [], untilDate: 0)
return account.network.request(Api.functions.channels.editBanned(channel: inputChannel, userId: inputUser, bannedRights: effectiveRights.apiBannedRights))
|> retryRequest |> retryRequest
|> mapToSignal { result -> Signal<Void, NoError> in |> mapToSignal { result -> Signal<(ChannelParticipant?, RenderedChannelParticipant), NoError> in
return account.postbox.modify { modifier -> Void in return account.postbox.modify { modifier -> (ChannelParticipant?, RenderedChannelParticipant) in
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
if let cachedData = cachedData as? CachedChannelData { if let cachedData = cachedData as? CachedChannelData {
var updatedData = cachedData var updatedData = cachedData
@ -166,13 +187,13 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me
var isKicked = false var isKicked = false
var isBanned = false var isBanned = false
if rights.flags.contains(.banReadMessages) { if effectiveRights.flags.contains(.banReadMessages) {
isKicked = true isKicked = true
} else if !rights.flags.isEmpty { } else if !effectiveRights.flags.isEmpty {
isBanned = true isBanned = true
} }
let isMember = !wasKicked && !rights.flags.contains(.banReadMessages) let isMember = !wasKicked && !effectiveRights.flags.contains(.banReadMessages)
if isKicked != wasKicked { if isKicked != wasKicked {
if let kickedCount = updatedData.participantsSummary.kickedCount { if let kickedCount = updatedData.participantsSummary.kickedCount {
@ -206,6 +227,18 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me
return cachedData return cachedData
} }
}) })
var peers: [PeerId: Peer] = [:]
var presences: [PeerId: PeerPresence] = [:]
peers[memberPeer.id] = memberPeer
if let presence = modifier.getPeerPresence(peerId: memberPeer.id) {
presences[memberPeer.id] = presence
}
if case let .member(_, _, _, maybeBanInfo) = updatedParticipant, let banInfo = maybeBanInfo {
if let peer = modifier.getPeer(banInfo.restrictedBy) {
peers[peer.id] = peer
}
}
return (currentParticipant, RenderedChannelParticipant(participant: updatedParticipant, peer: memberPeer, peers: peers, presences: presences))
} }
} }
} else { } else {

View File

@ -9,24 +9,51 @@ import Foundation
import MtProtoKitDynamic import MtProtoKitDynamic
#endif #endif
public enum ChannelMembersFilter { public enum ChannelMembersCategoryFilter {
case none case all
case search(String) case search(String)
} }
public func channelMembers(postbox: Postbox, network: Network, peerId: PeerId, filter: ChannelMembersFilter = .none) -> Signal<[RenderedChannelParticipant], NoError> { public enum ChannelMembersCategory {
case recent(ChannelMembersCategoryFilter)
case admins
case restricted(ChannelMembersCategoryFilter)
case banned(ChannelMembersCategoryFilter)
}
public func channelMembers(postbox: Postbox, network: Network, peerId: PeerId, category: ChannelMembersCategory = .recent(.all), offset: Int32 = 0, limit: Int32 = 64) -> Signal<[RenderedChannelParticipant], NoError> {
return postbox.modify { modifier -> Signal<[RenderedChannelParticipant], NoError> in return postbox.modify { modifier -> Signal<[RenderedChannelParticipant], NoError> in
if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer) { if let peer = modifier.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
let apiFilter: Api.ChannelParticipantsFilter let apiFilter: Api.ChannelParticipantsFilter
switch category {
case let .recent(filter):
switch filter { switch filter {
case .none: case .all:
apiFilter = .channelParticipantsRecent apiFilter = .channelParticipantsRecent
case let .search(query): case let .search(query):
apiFilter = .channelParticipantsSearch(q: query) apiFilter = .channelParticipantsSearch(q: query)
} }
return network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: apiFilter, offset: 0, limit: 100, hash: 0)) case .admins:
apiFilter = .channelParticipantsAdmins
case let .restricted(filter):
switch filter {
case .all:
apiFilter = .channelParticipantsBanned(q: "")
case let .search(query):
apiFilter = .channelParticipantsBanned(q: query)
}
case let .banned(filter):
switch filter {
case .all:
apiFilter = .channelParticipantsKicked(q: "")
case let .search(query):
apiFilter = .channelParticipantsKicked(q: query)
}
}
return network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: apiFilter, offset: offset, limit: limit, hash: 0))
|> retryRequest |> retryRequest
|> map { result -> [RenderedChannelParticipant] in |> mapToSignal { result -> Signal<[RenderedChannelParticipant], NoError> in
return postbox.modify { modifier -> [RenderedChannelParticipant] in
var items: [RenderedChannelParticipant] = [] var items: [RenderedChannelParticipant] = []
switch result { switch result {
case let .channelParticipants(_, participants, users): case let .channelParticipants(_, participants, users):
@ -39,6 +66,10 @@ public func channelMembers(postbox: Postbox, network: Network, peerId: PeerId, f
presences[peer.id] = presence presences[peer.id] = presence
} }
} }
updatePeers(modifier: modifier, peers: Array(peers.values), update: { _, updated in
return updated
})
modifier.updatePeerPresences(presences)
for participant in CachedChannelParticipants(apiParticipants: participants).participants { for participant in CachedChannelParticipants(apiParticipants: participants).participants {
if let peer = peers[participant.peerId] { if let peer = peers[participant.peerId] {
@ -51,6 +82,7 @@ public func channelMembers(postbox: Postbox, network: Network, peerId: PeerId, f
} }
return items return items
} }
}
} else { } else {
return .single([]) return .single([])
} }

View File

@ -1,20 +0,0 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
public final class GroupPeerMembersContext {
private let postbox: Postbox
private let network: Network
private let peerId: PeerId
public init(postbox: Postbox, network: Network, peerId: PeerId) {
self.postbox = postbox
self.network = network
self.peerId = peerId
}
}

View File

@ -225,15 +225,34 @@ public func fetchChannelParticipant(account: Account, peerId: PeerId, participan
} |> switchToLatest } |> switchToLatest
} }
public func updatePeerAdminRights(account: Account, peerId: PeerId, adminId: PeerId, rights: TelegramChannelAdminRights) -> Signal<Void, UpdatePeerAdminRightsError> { public func updatePeerAdminRights(account: Account, peerId: PeerId, adminId: PeerId, rights: TelegramChannelAdminRights) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdatePeerAdminRightsError> {
return fetchChannelParticipant(account: account, peerId: peerId, participantId: adminId) return fetchChannelParticipant(account: account, peerId: peerId, participantId: adminId)
|> mapError { error -> UpdatePeerAdminRightsError in |> mapError { error -> UpdatePeerAdminRightsError in
return .generic return .generic
} }
|> mapToSignal { currentParticipant -> Signal<Void, UpdatePeerAdminRightsError> in |> mapToSignal { currentParticipant -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdatePeerAdminRightsError> in
return account.postbox.modify { modifier -> Signal<Void, UpdatePeerAdminRightsError> in return account.postbox.modify { modifier -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdatePeerAdminRightsError> in
if let peer = modifier.getPeer(peerId), let adminPeer = modifier.getPeer(adminId), let inputUser = apiInputUser(adminPeer) { if let peer = modifier.getPeer(peerId), let adminPeer = modifier.getPeer(adminId), let inputUser = apiInputUser(adminPeer) {
if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) { if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) {
let updatedParticipant: ChannelParticipant
if let currentParticipant = currentParticipant, case let .member(_, invitedAt, currentAdminInfo, _) = currentParticipant {
let adminInfo: ChannelParticipantAdminInfo?
if !rights.flags.isEmpty {
adminInfo = ChannelParticipantAdminInfo(rights: rights, promotedBy: currentAdminInfo?.promotedBy ?? account.peerId, canBeEditedByAccountPeer: true)
} else {
adminInfo = nil
}
updatedParticipant = ChannelParticipant.member(id: adminId, invitedAt: invitedAt, adminInfo: adminInfo, banInfo: nil)
} else {
let adminInfo: ChannelParticipantAdminInfo?
if !rights.flags.isEmpty {
adminInfo = ChannelParticipantAdminInfo(rights: rights, promotedBy: account.peerId, canBeEditedByAccountPeer: true)
} else {
adminInfo = nil
}
updatedParticipant = ChannelParticipant.member(id: adminId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: adminInfo, banInfo: nil)
}
return account.network.request(Api.functions.channels.editAdmin(channel: inputChannel, userId: inputUser, adminRights: rights.apiAdminRights)) return account.network.request(Api.functions.channels.editAdmin(channel: inputChannel, userId: inputUser, adminRights: rights.apiAdminRights))
|> map { [$0] } |> map { [$0] }
|> `catch` { error -> Signal<[Api.Updates], UpdatePeerAdminRightsError> in |> `catch` { error -> Signal<[Api.Updates], UpdatePeerAdminRightsError> in
@ -253,11 +272,11 @@ public func updatePeerAdminRights(account: Account, peerId: PeerId, adminId: Pee
} }
return .fail(.generic) return .fail(.generic)
} }
|> mapToSignal { result -> Signal<Void, UpdatePeerAdminRightsError> in |> mapToSignal { result -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdatePeerAdminRightsError> in
for updates in result { for updates in result {
account.stateManager.addUpdates(updates) account.stateManager.addUpdates(updates)
} }
return account.postbox.modify { modifier -> Void in return account.postbox.modify { modifier -> (ChannelParticipant?, RenderedChannelParticipant) in
modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in modifier.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
if let cachedData = cachedData as? CachedChannelData, let adminCount = cachedData.participantsSummary.adminCount { if let cachedData = cachedData as? CachedChannelData, let adminCount = cachedData.participantsSummary.adminCount {
var updatedAdminCount = adminCount var updatedAdminCount = adminCount
@ -283,6 +302,18 @@ public func updatePeerAdminRights(account: Account, peerId: PeerId, adminId: Pee
return cachedData return cachedData
} }
}) })
var peers: [PeerId: Peer] = [:]
var presences: [PeerId: PeerPresence] = [:]
peers[adminPeer.id] = adminPeer
if let presence = modifier.getPeerPresence(peerId: adminPeer.id) {
presences[adminPeer.id] = presence
}
if case let .member(_, _, maybeAdminInfo, _) = updatedParticipant, let adminInfo = maybeAdminInfo {
if let peer = modifier.getPeer(adminInfo.promotedBy) {
peers[peer.id] = peer
}
}
return (currentParticipant, RenderedChannelParticipant(participant: updatedParticipant, peer: adminPeer, peers: peers, presences: presences))
} |> mapError { _ -> UpdatePeerAdminRightsError in return .generic } } |> mapError { _ -> UpdatePeerAdminRightsError in return .generic }
} }
} else { } else {

View File

@ -65,7 +65,14 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
return .ready(.forward(forwardInfo)) return .ready(.forward(forwardInfo))
} else if let contextResult = contextResult { } else if let contextResult = contextResult {
return .ready(.chatContextResult(contextResult)) return .ready(.chatContextResult(contextResult))
} else if let media = media.first { } else if let media = media.first, let mediaResult = mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, peerId: peerId, media: media, text: text, autoremoveAttribute: autoremoveAttribute, messageId: messageId, attributes: attributes) {
return mediaResult
} else {
return .ready(.text(text))
}
}
func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, peerId: PeerId, media: Media, text: String, autoremoveAttribute: AutoremoveTimeoutMessageAttribute?, messageId: MessageId?, attributes: [MessageAttribute]) -> PendingMessageUploadContent? {
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) { if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
if let reference = image.reference, case let .cloud(id, accessHash) = reference { if let reference = image.reference, case let .cloud(id, accessHash) = reference {
return .ready(.media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash), ttlSeconds: nil), text)) return .ready(.media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash), ttlSeconds: nil), text))
@ -96,10 +103,7 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
} }
return .ready(.media(input, text)) return .ready(.media(input, text))
} else { } else {
return .ready(.text(text)) return nil
}
} else {
return .ready(.text(text))
} }
} }

View File

@ -13,6 +13,9 @@ public func removePeerMember(account: Account, peerId: PeerId, memberId: PeerId)
if peerId.namespace == Namespaces.Peer.CloudChannel { if peerId.namespace == Namespaces.Peer.CloudChannel {
return updateChannelMemberBannedRights(account: account, peerId: peerId, memberId: memberId, rights: TelegramChannelBannedRights(flags: [.banReadMessages], untilDate: 0)) return updateChannelMemberBannedRights(account: account, peerId: peerId, memberId: memberId, rights: TelegramChannelBannedRights(flags: [.banReadMessages], untilDate: 0))
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
} }
return account.postbox.modify { modifier -> Signal<Void, NoError> in return account.postbox.modify { modifier -> Signal<Void, NoError> in

View File

@ -9,7 +9,55 @@ import Foundation
import MtProtoKitDynamic import MtProtoKitDynamic
#endif #endif
public func requestEditMessage(account: Account, messageId: MessageId, text: String, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false) -> Signal<Bool, NoError> { public enum RequestEditMessageMedia {
case keep
case update(Media)
}
public enum RequestEditMessageResult {
case progress(Float)
case done(Bool)
}
public func requestEditMessage(account: Account, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false) -> Signal<RequestEditMessageResult, NoError> {
let uploadedMedia: Signal<PendingMessageUploadedContentResult?, NoError>
switch media {
case .keep:
uploadedMedia = .single(.progress(0.0)) |> then(.single(nil))
case let .update(media):
if let uploadData = mediaContentToUpload(network: account.network, postbox: account.postbox, auxiliaryMethods: account.auxiliaryMethods, transformOutgoingMessageMedia: account.transformOutgoingMessageMedia, messageMediaPreuploadManager: account.messageMediaPreuploadManager, peerId: messageId.peerId, media: media, text: "", autoremoveAttribute: nil, messageId: nil, attributes: []) {
switch uploadData {
case let .ready(content):
uploadedMedia = .single(.content(content))
case let .upload(upload):
uploadedMedia = .single(.progress(0.027)) |> then(upload)
|> map { result -> PendingMessageUploadedContentResult? in
switch result {
case let .progress(value):
return .progress(max(value, 0.027))
case let .content(content):
return .content(content)
}
}
|> `catch` { _ -> Signal<PendingMessageUploadedContentResult?, NoError> in
return .single(nil)
}
}
} else {
uploadedMedia = .single(nil)
}
}
return uploadedMedia
|> mapToSignal { uploadedMediaResult -> Signal<RequestEditMessageResult, NoError> in
var pendingMediaContent: PendingMessageUploadedContent?
if let uploadedMediaResult = uploadedMediaResult {
switch uploadedMediaResult {
case let .progress(value):
return .single(.progress(value))
case let .content(content):
pendingMediaContent = content
}
}
return account.postbox.modify { modifier -> (Peer?, SimpleDictionary<PeerId, Peer>) in return account.postbox.modify { modifier -> (Peer?, SimpleDictionary<PeerId, Peer>) in
guard let message = modifier.getMessage(messageId) else { guard let message = modifier.getMessage(messageId) else {
return (nil, SimpleDictionary()) return (nil, SimpleDictionary())
@ -37,7 +85,7 @@ public func requestEditMessage(account: Account, messageId: MessageId, text: Str
} }
return (modifier.getPeer(messageId.peerId), peers) return (modifier.getPeer(messageId.peerId), peers)
} }
|> mapToSignal { peer, associatedPeers in |> mapToSignal { peer, associatedPeers -> Signal<RequestEditMessageResult, NoError> in
if let peer = peer, let inputPeer = apiInputPeer(peer) { if let peer = peer, let inputPeer = apiInputPeer(peer) {
var flags: Int32 = 1 << 11 var flags: Int32 = 1 << 11
@ -51,7 +99,20 @@ public func requestEditMessage(account: Account, messageId: MessageId, text: Str
flags |= Int32(1 << 1) flags |= Int32(1 << 1)
} }
return account.network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, replyMarkup: nil, entities: apiEntities, geoPoint: nil)) var inputMedia: Api.InputMedia? = nil
if let pendingMediaContent = pendingMediaContent {
switch pendingMediaContent {
case let .media(media, _):
inputMedia = media
default:
break
}
}
if let _ = inputMedia {
flags |= Int32(1 << 14)
}
return account.network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, media: inputMedia, replyMarkup: nil, entities: apiEntities, geoPoint: nil))
|> map { result -> Api.Updates? in |> map { result -> Api.Updates? in
return result return result
} }
@ -65,16 +126,29 @@ public func requestEditMessage(account: Account, messageId: MessageId, text: Str
|> mapError { _ -> NoError in |> mapError { _ -> NoError in
return NoError() return NoError()
} }
|> mapToSignal { result -> Signal<Bool, NoError> in |> mapToSignal { result -> Signal<RequestEditMessageResult, NoError> in
if let result = result { if let result = result {
return account.postbox.modify { modifier -> RequestEditMessageResult in
var toMedia: Media?
if let message = result.messages.first.flatMap(StoreMessage.init(apiMessage:)) {
toMedia = message.media.first
}
if case let .update(fromMedia) = media, let toMedia = toMedia {
applyMediaResourceChanges(from: fromMedia, to: toMedia, postbox: account.postbox)
}
account.stateManager.addUpdates(result) account.stateManager.addUpdates(result)
return .single(true)
return .done(true)
}
} else { } else {
return .single(false) return .single(.done(false))
} }
} }
} else { } else {
return .single(false) return .single(.done(false))
}
} }
} }
} }
@ -91,7 +165,7 @@ public func requestEditLiveLocation(postbox: Postbox, network: Network, stateMan
} else { } else {
flags |= 1 << 12 flags |= 1 << 12
} }
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, replyMarkup: nil, entities: nil, geoPoint: coordinate.flatMap { Api.InputGeoPoint.inputGeoPoint(lat: $0.latitude, long: $0.longitude) })) return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: nil, replyMarkup: nil, entities: nil, geoPoint: coordinate.flatMap { Api.InputGeoPoint.inputGeoPoint(lat: $0.latitude, long: $0.longitude) }))
|> map(Optional.init) |> map(Optional.init)
|> `catch` { _ -> Signal<Api.Updates?, NoError> in |> `catch` { _ -> Signal<Api.Updates?, NoError> in
return .single(nil) return .single(nil)

View File

@ -33,7 +33,7 @@ public func searchGroupMembers(postbox: Postbox, network: Network, peerId: PeerI
return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query) return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query)
|> mapToSignal { local -> Signal<[Peer], NoError> in |> mapToSignal { local -> Signal<[Peer], NoError> in
return .single(local) return .single(local)
|> then(channelMembers(postbox: postbox, network: network, peerId: peerId, filter: .search(query)) |> then(channelMembers(postbox: postbox, network: network, peerId: peerId, category: .recent(.search(query)))
|> map { participants -> [Peer] in |> map { participants -> [Peer] in
var result: [Peer] = local var result: [Peer] = local
let existingIds = Set(local.map { $0.id }) let existingIds = Set(local.map { $0.id })