no message

This commit is contained in:
Peter Iakovlev 2018-01-19 00:39:08 +04:00
parent 4a58158d99
commit 50c0158683
5 changed files with 249 additions and 526 deletions

View File

@ -151,7 +151,6 @@
D033FEB61E61F3F900644997 /* BlockedPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB51E61F3F900644997 /* BlockedPeers.swift */; };
D033FEB71E61F3F900644997 /* BlockedPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB51E61F3F900644997 /* BlockedPeers.swift */; };
D03B0CB91D62233400955575 /* Either.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CB81D62233400955575 /* Either.swift */; };
D03B0CBB1D62233C00955575 /* MergeLists.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CBA1D62233C00955575 /* MergeLists.swift */; };
D03B0CBD1D62234300955575 /* Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CBC1D62234300955575 /* Regex.swift */; };
D03B0CBF1D62234A00955575 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CBE1D62234A00955575 /* Log.swift */; };
D03B0CC11D62235000955575 /* StringFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CC01D62235000955575 /* StringFormat.swift */; };
@ -454,7 +453,6 @@
D0B8440D1DAB91CD005F29E1 /* ImageRepresentationsUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0C901D81A857008AEB01 /* ImageRepresentationsUtils.swift */; };
D0B8440E1DAB91CD005F29E1 /* MessageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0C921D81AD09008AEB01 /* MessageUtils.swift */; };
D0B8440F1DAB91CD005F29E1 /* Either.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CB81D62233400955575 /* Either.swift */; };
D0B844101DAB91CD005F29E1 /* MergeLists.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CBA1D62233C00955575 /* MergeLists.swift */; };
D0B844111DAB91CD005F29E1 /* Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CBC1D62234300955575 /* Regex.swift */; };
D0B844121DAB91CD005F29E1 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CBE1D62234A00955575 /* Log.swift */; };
D0B844131DAB91CD005F29E1 /* StringFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CC01D62235000955575 /* StringFormat.swift */; };
@ -556,6 +554,8 @@
D0E35A151DE4C6A200BC6096 /* OutgoingMessageWithChatContextResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E35A0F1DE49E1C00BC6096 /* OutgoingMessageWithChatContextResult.swift */; };
D0E6521F1E3A364A004EEA91 /* UpdateAccountPeerName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E6521E1E3A364A004EEA91 /* UpdateAccountPeerName.swift */; };
D0E652201E3A364A004EEA91 /* UpdateAccountPeerName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E6521E1E3A364A004EEA91 /* UpdateAccountPeerName.swift */; };
D0E817492010E7E300B82BBB /* ChannelAdminEventLogContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E817482010E7E300B82BBB /* ChannelAdminEventLogContext.swift */; };
D0E8174A2010E7E300B82BBB /* ChannelAdminEventLogContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E817482010E7E300B82BBB /* ChannelAdminEventLogContext.swift */; };
D0F02CE51E9926C40065DEE2 /* ManagedConfigurationUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F02CE41E9926C40065DEE2 /* ManagedConfigurationUpdates.swift */; };
D0F02CE61E9926C50065DEE2 /* ManagedConfigurationUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F02CE41E9926C40065DEE2 /* ManagedConfigurationUpdates.swift */; };
D0F3A89F1E82C65400B4C64C /* SynchronizeChatInputStateOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3A89E1E82C65400B4C64C /* SynchronizeChatInputStateOperation.swift */; };
@ -694,7 +694,6 @@
D033FEB21E61F3C000644997 /* ReportPeer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReportPeer.swift; sourceTree = "<group>"; };
D033FEB51E61F3F900644997 /* BlockedPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockedPeers.swift; sourceTree = "<group>"; };
D03B0CB81D62233400955575 /* Either.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Either.swift; sourceTree = "<group>"; };
D03B0CBA1D62233C00955575 /* MergeLists.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MergeLists.swift; sourceTree = "<group>"; };
D03B0CBC1D62234300955575 /* Regex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Regex.swift; sourceTree = "<group>"; };
D03B0CBE1D62234A00955575 /* Log.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
D03B0CC01D62235000955575 /* StringFormat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringFormat.swift; sourceTree = "<group>"; };
@ -930,6 +929,7 @@
D0E35A0F1DE49E1C00BC6096 /* OutgoingMessageWithChatContextResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutgoingMessageWithChatContextResult.swift; sourceTree = "<group>"; };
D0E35A111DE4A25E00BC6096 /* OutgoingChatContextResultMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutgoingChatContextResultMessageAttribute.swift; sourceTree = "<group>"; };
D0E6521E1E3A364A004EEA91 /* UpdateAccountPeerName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateAccountPeerName.swift; sourceTree = "<group>"; };
D0E817482010E7E300B82BBB /* ChannelAdminEventLogContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelAdminEventLogContext.swift; sourceTree = "<group>"; };
D0F02CE41E9926C40065DEE2 /* ManagedConfigurationUpdates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedConfigurationUpdates.swift; sourceTree = "<group>"; };
D0F3A89E1E82C65400B4C64C /* SynchronizeChatInputStateOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeChatInputStateOperation.swift; sourceTree = "<group>"; };
D0F3A8A11E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeChatInputStateOperations.swift; sourceTree = "<group>"; };
@ -1090,7 +1090,6 @@
D0DF0C901D81A857008AEB01 /* ImageRepresentationsUtils.swift */,
D0DF0C921D81AD09008AEB01 /* MessageUtils.swift */,
D03B0CB81D62233400955575 /* Either.swift */,
D03B0CBA1D62233C00955575 /* MergeLists.swift */,
D03B0CBC1D62234300955575 /* Regex.swift */,
D03B0CBE1D62234A00955575 /* Log.swift */,
D03B0CC01D62235000955575 /* StringFormat.swift */,
@ -1575,6 +1574,7 @@
C23BC3861E9BE3CA00D79F92 /* ImportContact.swift */,
C205FEA71EB3B75900455808 /* ExportMessageLink.swift */,
C230BEB51EE9A3760029586C /* ChannelAdminEventLogs.swift */,
D0E817482010E7E300B82BBB /* ChannelAdminEventLogContext.swift */,
D0A472B51F4CBE8B00E0EEDA /* LoadedPeer.swift */,
D0DA1D311F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift */,
D02395D51F8D09A50070F5C2 /* ChannelHistoryAvailabilitySettings.swift */,
@ -1950,6 +1950,7 @@
D0561DE31E5737FC00E6B9E9 /* UpdatePeerInfo.swift in Sources */,
D0DF0C8A1D819C7E008AEB01 /* JoinChannel.swift in Sources */,
D04CAA5A1E83310D0047E51F /* MD5.swift in Sources */,
D0E817492010E7E300B82BBB /* ChannelAdminEventLogContext.swift in Sources */,
D05452071E7B5093006EEF19 /* LoadedStickerPack.swift in Sources */,
D01C7F041EFC1C49008305F1 /* DeviceContact.swift in Sources */,
D0F7AB2F1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */,
@ -2040,7 +2041,6 @@
D0528E651E65C82400E2FEF5 /* UpdateContactName.swift in Sources */,
D03121021DA57E93006A2A60 /* TelegramPeerNotificationSettings.swift in Sources */,
D0C48F391E8138DF0075317D /* ArchivedStickerPacksInfo.swift in Sources */,
D03B0CBB1D62233C00955575 /* MergeLists.swift in Sources */,
C239BE971E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift in Sources */,
D03B0CC11D62235000955575 /* StringFormat.swift in Sources */,
D0B85AC51F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */,
@ -2289,6 +2289,7 @@
D050F2621E4A5AE700988324 /* GlobalNotificationSettings.swift in Sources */,
D0DFD5E01FCDBCFD0039B3B1 /* CachedSentMediaReferences.swift in Sources */,
D0B418991D7E0580004562A4 /* TelegramMediaMap.swift in Sources */,
D0E8174A2010E7E300B82BBB /* ChannelAdminEventLogContext.swift in Sources */,
D0561DEB1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */,
D0AD02E41FFFA14800C1DCFF /* PeerLiveLocationsContext.swift in Sources */,
D0613FCB1E60440600202CDB /* InvitationLinks.swift in Sources */,
@ -2324,7 +2325,6 @@
D033FEB41E61F3C000644997 /* ReportPeer.swift in Sources */,
D0FA8BAE1E1FD6E2001E855B /* MemoryBufferExtensions.swift in Sources */,
D0FA8BB41E201B02001E855B /* ProcessSecretChatIncomingEncryptedOperations.swift in Sources */,
D0B844101DAB91CD005F29E1 /* MergeLists.swift in Sources */,
D0F3A8A31E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift in Sources */,
D0448CA61E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */,
D001F3F11E128A1C007A8C60 /* SynchronizePeerReadState.swift in Sources */,

View File

@ -0,0 +1,124 @@
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
public struct ChannelAdminEventLogEntry: Comparable {
public let event: AdminLogEvent
public let peers: [PeerId: Peer]
public static func ==(lhs: ChannelAdminEventLogEntry, rhs: ChannelAdminEventLogEntry) -> Bool {
return lhs.event == rhs.event
}
public static func <(lhs: ChannelAdminEventLogEntry, rhs: ChannelAdminEventLogEntry) -> Bool {
return lhs.event < rhs.event
}
}
public enum ChannelAdminEventLogUpdateType {
case initial
case generic
case load
}
public final class ChannelAdminEventLogContext {
private let queue: Queue = Queue.mainQueue()
private let postbox: Postbox
private let network: Network
private let peerId: PeerId
private var entries: [ChannelAdminEventLogEntry] = []
private var hasEarlier: Bool = true
private var loadingMoreEarlier: Bool = false
private var subscribers = Bag<([ChannelAdminEventLogEntry], Bool, ChannelAdminEventLogUpdateType) -> Void>()
private let loadMoreDisposable = MetaDisposable()
public init(postbox: Postbox, network: Network, peerId: PeerId) {
self.postbox = postbox
self.network = network
self.peerId = peerId
}
deinit {
self.loadMoreDisposable.dispose()
}
public func get() -> Signal<([ChannelAdminEventLogEntry], Bool, ChannelAdminEventLogUpdateType), NoError> {
let queue = self.queue
return Signal { [weak self] subscriber in
if let strongSelf = self {
subscriber.putNext((strongSelf.entries, strongSelf.hasEarlier, .initial))
let index = strongSelf.subscribers.add({ entries, hasEarlier, type in
subscriber.putNext((strongSelf.entries, strongSelf.hasEarlier, type))
})
return ActionDisposable {
queue.async {
if let strongSelf = self {
strongSelf.subscribers.remove(index)
}
}
}
} else {
return EmptyDisposable
}
} |> runOn(queue)
}
public func loadMoreEntries() {
assert(self.queue.isCurrent())
if self.loadingMoreEarlier {
return
}
let maxId: AdminLogEventId
if let last = self.entries.last {
maxId = last.event.id
} else {
maxId = AdminLogEventId.max
}
self.loadingMoreEarlier = true
self.loadMoreDisposable.set((channelAdminLogEvents(postbox: self.postbox, network: self.network, peerId: self.peerId, maxId: maxId, minId: AdminLogEventId.min, limit: 10, query: nil, filter: nil, admins: nil)
|> deliverOn(self.queue)).start(next: { [weak self] result in
if let strongSelf = self {
var events = result.events.sorted()
if let first = strongSelf.entries.first {
var clipIndex = events.count
for i in (0 ..< events.count).reversed() {
if events[i] >= first.event {
clipIndex = i - 1
}
}
if clipIndex < events.count {
events.removeSubrange(clipIndex ..< events.count)
}
}
strongSelf.hasEarlier = !events.isEmpty
var entries: [ChannelAdminEventLogEntry] = events.map { event in
return ChannelAdminEventLogEntry(event: event, peers: result.peers)
}
entries.append(contentsOf: strongSelf.entries)
strongSelf.entries = entries
strongSelf.loadingMoreEarlier = false
for subscriber in strongSelf.subscribers.copyItems() {
subscriber(strongSelf.entries, strongSelf.hasEarlier, .load)
}
}
}))
}
}

View File

@ -8,11 +8,23 @@
public typealias AdminLogEventId = Int64
public struct AdminLogEvent {
public struct AdminLogEvent: Comparable {
public let id: AdminLogEventId
public let peerId: PeerId
public let date: Int32
public let action: AdminLogEventAction
public static func ==(lhs: AdminLogEvent, rhs: AdminLogEvent) -> Bool {
return lhs.id == rhs.id
}
public static func <(lhs: AdminLogEvent, rhs: AdminLogEvent) -> Bool {
if lhs.date != rhs.date {
return lhs.date < rhs.date
} else {
return lhs.id < rhs.id
}
}
}
public struct AdminLogEventsResult {
@ -86,112 +98,112 @@ private func boolFromApiValue(_ value: Api.Bool) -> Bool {
}
}
public func channelAdminLogEvents(_ account:Account, peerId:PeerId, maxId: AdminLogEventId, minId: AdminLogEventId, limit: Int32 = 100, query: String? = nil, filter: AdminLogEventsFlags? = nil, admins: [PeerId]? = nil) -> Signal<AdminLogEventsResult, ChannelAdminLogEventError> {
return account.postbox.modify { modifier -> (Peer?, [Peer]?) in
return (modifier.getPeer(peerId), admins?.flatMap {modifier.getPeer($0)})
} |> mapError {return .generic} |> mapToSignal { (peer, admins) -> Signal<AdminLogEventsResult, ChannelAdminLogEventError> in
public func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: PeerId, maxId: AdminLogEventId, minId: AdminLogEventId, limit: Int32 = 100, query: String? = nil, filter: AdminLogEventsFlags? = nil, admins: [PeerId]? = nil) -> Signal<AdminLogEventsResult, ChannelAdminLogEventError> {
return postbox.modify { modifier -> (Peer?, [Peer]?) in
return (modifier.getPeer(peerId), admins?.flatMap { modifier.getPeer($0) })
}
|> mapError { return .generic }
|> mapToSignal { (peer, admins) -> Signal<AdminLogEventsResult, ChannelAdminLogEventError> in
if let peer = peer, let inputChannel = apiInputChannel(peer) {
let inputAdmins = admins?.flatMap {apiInputUser($0)}
if let peer = peer, let inputChannel = apiInputChannel(peer) {
let inputAdmins = admins?.flatMap {apiInputUser($0)}
var flags:Int32 = 0
var eventsFilter:Api.ChannelAdminLogEventsFilter? = nil
if let filter = filter {
flags += Int32(1 << 0)
eventsFilter = Api.ChannelAdminLogEventsFilter.channelAdminLogEventsFilter(flags: Int32(filter.rawValue))
}
if let _ = inputAdmins {
flags += Int32(1 << 1)
}
return account.network.request(Api.functions.channels.getAdminLog(flags: flags, channel: inputChannel, q: query ?? "", eventsFilter: eventsFilter, admins: inputAdmins, maxId: maxId, minId: minId, limit: limit)) |> map { result in
switch result {
case let .adminLogResults(apiEvents, apiChats, apiUsers):
let peers = (apiChats.flatMap {parseTelegramGroupOrChannel(chat: $0)} + apiUsers.flatMap { TelegramUser(user: $0) } + Array(arrayLiteral: peer)).reduce([:], { current, peer -> [PeerId : Peer] in
var current = current
current[peer.id] = peer
return current
})
var events: [AdminLogEvent] = []
for event in apiEvents {
switch event {
case let .channelAdminLogEvent(id, date, userId, apiAction):
var action: AdminLogEventAction?
switch apiAction {
case let .channelAdminLogEventActionChangeTitle(prev, new):
action = .changeTitle(prev: prev, new: new)
case let .channelAdminLogEventActionChangeAbout(prev, new):
action = .changeAbout(prev: prev, new: new)
case let .channelAdminLogEventActionChangeUsername(prev, new):
action = .changeUsername(prev: prev, new: new)
case let .channelAdminLogEventActionChangePhoto(prev, new):
action = .changePhoto(prev: imageRepresentationsForApiChatPhoto(prev), new: imageRepresentationsForApiChatPhoto(new))
case let .channelAdminLogEventActionToggleInvites(new):
action = .toggleInvites(boolFromApiValue(new))
case let .channelAdminLogEventActionToggleSignatures(new):
action = .toggleSignatures(boolFromApiValue(new))
case let .channelAdminLogEventActionUpdatePinned(new):
switch new {
case .messageEmpty:
action = .updatePinned(nil)
default:
if let message = StoreMessage(apiMessage: new), let rendered = locallyRenderedMessage(message: message, peers: peers) {
action = .updatePinned(rendered)
}
}
case let .channelAdminLogEventActionEditMessage(prev, new):
if let prev = StoreMessage(apiMessage: prev), let prevRendered = locallyRenderedMessage(message: prev, peers: peers), let new = StoreMessage(apiMessage: new), let newRendered = locallyRenderedMessage(message: new, peers: peers) {
action = .editMessage(prev: prevRendered, new: newRendered)
}
case let .channelAdminLogEventActionDeleteMessage(message):
if let message = StoreMessage(apiMessage: message), let rendered = locallyRenderedMessage(message: message, peers: peers) {
action = .deleteMessage(rendered)
}
case .channelAdminLogEventActionParticipantJoin:
action = .participantJoin
case .channelAdminLogEventActionParticipantLeave:
action = .participantLeave
case let .channelAdminLogEventActionParticipantInvite(participant):
let participant = ChannelParticipant(apiParticipant: participant)
if let peer = peers[participant.peerId] {
action = .participantInvite(RenderedChannelParticipant(participant: participant, peer: peer))
}
case let .channelAdminLogEventActionParticipantToggleBan(prev, new):
let prevParticipant = ChannelParticipant(apiParticipant: prev)
let newParticipant = ChannelParticipant(apiParticipant: new)
if let prevPeer = peers[prevParticipant.peerId], let newPeer = peers[newParticipant.peerId] {
action = .participantToggleBan(prev: RenderedChannelParticipant(participant: prevParticipant, peer: prevPeer), new: RenderedChannelParticipant(participant: newParticipant, peer: newPeer))
}
case let .channelAdminLogEventActionParticipantToggleAdmin(prev, new):
let prevParticipant = ChannelParticipant(apiParticipant: prev)
let newParticipant = ChannelParticipant(apiParticipant: new)
if let prevPeer = peers[prevParticipant.peerId], let newPeer = peers[newParticipant.peerId] {
action = .participantToggleAdmin(prev: RenderedChannelParticipant(participant: prevParticipant, peer: prevPeer), new: RenderedChannelParticipant(participant: newParticipant, peer: newPeer))
}
case let .channelAdminLogEventActionChangeStickerSet(prevStickerset, newStickerset):
action = .changeStickerPack(prev: StickerPackReference(apiInputSet: prevStickerset), new: StickerPackReference(apiInputSet: newStickerset))
case let .channelAdminLogEventActionTogglePreHistoryHidden(value):
action = .togglePreHistoryHidden(value == .boolTrue)
}
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
if let action = action {
events.append(AdminLogEvent(id: id, peerId: peerId, date: date, action: action))
}
}
}
return AdminLogEventsResult(peerId: peerId, peers: peers, events: events)
}
} |> mapError {_ in return .generic}
var flags: Int32 = 0
var eventsFilter: Api.ChannelAdminLogEventsFilter? = nil
if let filter = filter {
flags += Int32(1 << 0)
eventsFilter = Api.ChannelAdminLogEventsFilter.channelAdminLogEventsFilter(flags: Int32(filter.rawValue))
}
return .complete()
if let _ = inputAdmins {
flags += Int32(1 << 1)
}
return network.request(Api.functions.channels.getAdminLog(flags: flags, channel: inputChannel, q: query ?? "", eventsFilter: eventsFilter, admins: inputAdmins, maxId: maxId, minId: minId, limit: limit)) |> map { result in
switch result {
case let .adminLogResults(apiEvents, apiChats, apiUsers):
let peers = (apiChats.flatMap {parseTelegramGroupOrChannel(chat: $0)} + apiUsers.flatMap { TelegramUser(user: $0) } + Array(arrayLiteral: peer)).reduce([:], { current, peer -> [PeerId : Peer] in
var current = current
current[peer.id] = peer
return current
})
var events: [AdminLogEvent] = []
for event in apiEvents {
switch event {
case let .channelAdminLogEvent(id, date, userId, apiAction):
var action: AdminLogEventAction?
switch apiAction {
case let .channelAdminLogEventActionChangeTitle(prev, new):
action = .changeTitle(prev: prev, new: new)
case let .channelAdminLogEventActionChangeAbout(prev, new):
action = .changeAbout(prev: prev, new: new)
case let .channelAdminLogEventActionChangeUsername(prev, new):
action = .changeUsername(prev: prev, new: new)
case let .channelAdminLogEventActionChangePhoto(prev, new):
action = .changePhoto(prev: imageRepresentationsForApiChatPhoto(prev), new: imageRepresentationsForApiChatPhoto(new))
case let .channelAdminLogEventActionToggleInvites(new):
action = .toggleInvites(boolFromApiValue(new))
case let .channelAdminLogEventActionToggleSignatures(new):
action = .toggleSignatures(boolFromApiValue(new))
case let .channelAdminLogEventActionUpdatePinned(new):
switch new {
case .messageEmpty:
action = .updatePinned(nil)
default:
if let message = StoreMessage(apiMessage: new), let rendered = locallyRenderedMessage(message: message, peers: peers) {
action = .updatePinned(rendered)
}
}
case let .channelAdminLogEventActionEditMessage(prev, new):
if let prev = StoreMessage(apiMessage: prev), let prevRendered = locallyRenderedMessage(message: prev, peers: peers), let new = StoreMessage(apiMessage: new), let newRendered = locallyRenderedMessage(message: new, peers: peers) {
action = .editMessage(prev: prevRendered, new: newRendered)
}
case let .channelAdminLogEventActionDeleteMessage(message):
if let message = StoreMessage(apiMessage: message), let rendered = locallyRenderedMessage(message: message, peers: peers) {
action = .deleteMessage(rendered)
}
case .channelAdminLogEventActionParticipantJoin:
action = .participantJoin
case .channelAdminLogEventActionParticipantLeave:
action = .participantLeave
case let .channelAdminLogEventActionParticipantInvite(participant):
let participant = ChannelParticipant(apiParticipant: participant)
if let peer = peers[participant.peerId] {
action = .participantInvite(RenderedChannelParticipant(participant: participant, peer: peer))
}
case let .channelAdminLogEventActionParticipantToggleBan(prev, new):
let prevParticipant = ChannelParticipant(apiParticipant: prev)
let newParticipant = ChannelParticipant(apiParticipant: new)
if let prevPeer = peers[prevParticipant.peerId], let newPeer = peers[newParticipant.peerId] {
action = .participantToggleBan(prev: RenderedChannelParticipant(participant: prevParticipant, peer: prevPeer), new: RenderedChannelParticipant(participant: newParticipant, peer: newPeer))
}
case let .channelAdminLogEventActionParticipantToggleAdmin(prev, new):
let prevParticipant = ChannelParticipant(apiParticipant: prev)
let newParticipant = ChannelParticipant(apiParticipant: new)
if let prevPeer = peers[prevParticipant.peerId], let newPeer = peers[newParticipant.peerId] {
action = .participantToggleAdmin(prev: RenderedChannelParticipant(participant: prevParticipant, peer: prevPeer), new: RenderedChannelParticipant(participant: newParticipant, peer: newPeer))
}
case let .channelAdminLogEventActionChangeStickerSet(prevStickerset, newStickerset):
action = .changeStickerPack(prev: StickerPackReference(apiInputSet: prevStickerset), new: StickerPackReference(apiInputSet: newStickerset))
case let .channelAdminLogEventActionTogglePreHistoryHidden(value):
action = .togglePreHistoryHidden(value == .boolTrue)
}
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
if let action = action {
events.append(AdminLogEvent(id: id, peerId: peerId, date: date, action: action))
}
}
}
return AdminLogEventsResult(peerId: peerId, peers: peers, events: events)
}
} |> mapError {_ in return .generic}
}
return .complete()
}
}

View File

@ -1,413 +0,0 @@
import Foundation
public protocol Identifiable {
associatedtype T: Hashable
var stableId: T { get }
}
public func mergeListsStable<T>(leftList: [T], rightList: [T]) -> ([Int], [(Int, T, Int?)]) where T: Comparable, T: Identifiable {
var removeIndices: [Int] = []
var insertItems: [(Int, T, Int?)] = []
var currentList = leftList
var i = 0
var j = 0
while true {
let left: T? = i < currentList.count ? currentList[i] : nil
let right: T? = j < rightList.count ? rightList[j] : nil
if let left = left, let right = right {
if left == right {
i += 1
j += 1
} else if left < right {
removeIndices.append(i)
i += 1
} else {
j += 1
}
} else if let _ = left {
removeIndices.append(i)
i += 1
} else if let _ = right {
j += 1
} else {
break
}
}
for index in removeIndices.reversed() {
currentList.remove(at: index)
}
var previousIndices: [T.T: Int] = [:]
i = 0
for left in leftList {
previousIndices[left.stableId] = i
i += 1
}
i = 0
j = 0
while true {
let left: T? = i < currentList.count ? currentList[i] : nil
let right: T? = j < rightList.count ? rightList[j] : nil
if let left = left, let right = right {
if left == right {
i += 1
j += 1
} else if left > right {
let previousIndex = previousIndices[right.stableId]
insertItems.append((i, right, previousIndex))
currentList.insert(right, at: i)
i += 1
j += 1
} else {
i += 1
}
} else if let _ = left {
i += 1
} else if let right = right {
let previousIndex = previousIndices[right.stableId]
insertItems.append((i, right, previousIndex))
currentList.insert(right, at: i)
i += 1
j += 1
} else {
break
}
}
assert(currentList == rightList, "currentList == rightList")
return (removeIndices, insertItems)
}
public func mergeListsStableWithUpdates<T>(leftList: [T], rightList: [T]) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) where T: Comparable, T: Identifiable {
var removeIndices: [Int] = []
var insertItems: [(Int, T, Int?)] = []
var updatedIndices: [(Int, T, Int)] = []
#if (arch(i386) || arch(x86_64)) && os(iOS)
var existingStableIds: [T.T: T] = [:]
for item in leftList {
if let _ = existingStableIds[item.stableId] {
assertionFailure()
} else {
existingStableIds[item.stableId] = item
}
}
existingStableIds.removeAll()
for item in rightList {
if let other = existingStableIds[item.stableId] {
print("\(other) has the same stableId as \(item): \(item.stableId)")
assertionFailure()
} else {
existingStableIds[item.stableId] = item
}
}
#endif
var currentList = leftList
var i = 0
var previousIndices: [T.T: Int] = [:]
for left in leftList {
previousIndices[left.stableId] = i
i += 1
}
i = 0
var j = 0
while true {
let left: T? = i < currentList.count ? currentList[i] : nil
let right: T? = j < rightList.count ? rightList[j] : nil
if let left = left, let right = right {
if left.stableId == right.stableId && left != right {
updatedIndices.append((i, right, previousIndices[left.stableId]!))
i += 1
j += 1
} else {
if left == right {
i += 1
j += 1
} else if left < right {
removeIndices.append(i)
i += 1
} else if !(left > right) {
removeIndices.append(i)
i += 1
} else {
j += 1
}
}
} else if let _ = left {
removeIndices.append(i)
i += 1
} else if let _ = right {
j += 1
} else {
break
}
}
//print("remove:\n\(removeIndices)")
for index in removeIndices.reversed() {
currentList.remove(at: index)
for i in 0 ..< updatedIndices.count {
if updatedIndices[i].0 >= index {
updatedIndices[i].0 -= 1
}
}
}
/*print("\n current after removes:\n")
m = 0
for right in currentList {
print("\(m): \(right.stableId)")
m += 1
}
print("update:\n\(updatedIndices.map({ "\($0.0), \($0.1.stableId) (was \($0.2)))" }))")*/
i = 0
j = 0
var k = 0
while true {
let left: T?
//print("i=\(i), j=\(j), k=\(k)")
if k < updatedIndices.count && updatedIndices[k].0 < i {
//print("updated[k=\(k)]=\(updatedIndices[k].0)<i=\(i), k++")
k += 1
}
if k < updatedIndices.count {
if updatedIndices[k].0 == i {
left = updatedIndices[k].1
//print("override left = \(updatedIndices[k].1.stableId)")
} else {
left = i < currentList.count ? currentList[i] : nil
}
} else {
left = i < currentList.count ? currentList[i] : nil
}
let right: T? = j < rightList.count ? rightList[j] : nil
if let left = left, let right = right {
if left == right {
//print("\(left.stableId)==\(right.stableId)")
//print("i++, j++")
i += 1
j += 1
} else if left > right {
//print("\(left.stableId)>\(right.stableId)")
//print("insert \(right.stableId) at \(i)")
//print("i++, j++")
let previousIndex = previousIndices[right.stableId]
insertItems.append((i, right, previousIndex))
currentList.insert(right, at: i)
if k < updatedIndices.count {
for l in k ..< updatedIndices.count {
updatedIndices[l] = (updatedIndices[l].0 + 1, updatedIndices[l].1, updatedIndices[l].2)
}
}
i += 1
j += 1
} else {
//print("\(left.stableId)<\(right.stableId)")
//print("i++")
i += 1
}
} else if let _ = left {
//print("\(left!.stableId)>nil")
//print("i++")
i += 1
} else if let right = right {
//print("nil<\(right.stableId)")
//print("insert \(right.stableId) at \(i)")
//print("i++")
//print("j++")
let previousIndex = previousIndices[right.stableId]
insertItems.append((i, right, previousIndex))
currentList.insert(right, at: i)
if k < updatedIndices.count {
for l in k ..< updatedIndices.count {
updatedIndices[l] = (updatedIndices[l].0 + 1, updatedIndices[l].1, updatedIndices[l].2)
}
}
i += 1
j += 1
} else {
break
}
}
for (index, item, _) in updatedIndices {
currentList[index] = item
}
assert(currentList == rightList, "currentList == rightList")
return (removeIndices, insertItems, updatedIndices)
}
public func mergeListsStableWithUpdatesReversed<T>(leftList: [T], rightList: [T]) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) where T: Comparable, T: Identifiable {
var removeIndices: [Int] = []
var insertItems: [(Int, T, Int?)] = []
var updatedIndices: [(Int, T, Int)] = []
#if (arch(i386) || arch(x86_64)) && os(iOS)
var existingStableIds: [T.T: T] = [:]
for item in leftList {
if let _ = existingStableIds[item.stableId] {
assertionFailure()
} else {
existingStableIds[item.stableId] = item
}
}
existingStableIds.removeAll()
for item in rightList {
if let other = existingStableIds[item.stableId] {
print("\(other) has the same stableId as \(item): \(item.stableId)")
assertionFailure()
} else {
existingStableIds[item.stableId] = item
}
}
#endif
var currentList = leftList
var i = 0
var previousIndices: [T.T: Int] = [:]
for left in leftList {
previousIndices[left.stableId] = i
i += 1
}
i = 0
var j = 0
while true {
let left: T? = i < currentList.count ? currentList[i] : nil
let right: T? = j < rightList.count ? rightList[j] : nil
if let left = left, let right = right {
if left.stableId == right.stableId && left != right {
updatedIndices.append((i, right, previousIndices[left.stableId]!))
i += 1
j += 1
} else {
if left == right {
i += 1
j += 1
} else if left > right {
removeIndices.append(i)
i += 1
} else if !(left < right) {
removeIndices.append(i)
i += 1
} else {
j += 1
}
}
} else if let _ = left {
removeIndices.append(i)
i += 1
} else if let _ = right {
j += 1
} else {
break
}
}
//print("remove:\n\(removeIndices)")
for index in removeIndices.reversed() {
currentList.remove(at: index)
for i in 0 ..< updatedIndices.count {
if updatedIndices[i].0 >= index {
updatedIndices[i].0 -= 1
}
}
}
i = 0
j = 0
var k = 0
while true {
let left: T?
if k < updatedIndices.count && updatedIndices[k].0 < i {
k += 1
}
if k < updatedIndices.count {
if updatedIndices[k].0 == i {
left = updatedIndices[k].1
} else {
left = i < currentList.count ? currentList[i] : nil
}
} else {
left = i < currentList.count ? currentList[i] : nil
}
let right: T? = j < rightList.count ? rightList[j] : nil
if let left = left, let right = right {
if left == right {
i += 1
j += 1
} else if left < right {
let previousIndex = previousIndices[right.stableId]
insertItems.append((i, right, previousIndex))
currentList.insert(right, at: i)
if k < updatedIndices.count {
for l in k ..< updatedIndices.count {
updatedIndices[l] = (updatedIndices[l].0 + 1, updatedIndices[l].1, updatedIndices[l].2)
}
}
i += 1
j += 1
} else {
i += 1
}
} else if let _ = left {
i += 1
} else if let right = right {
let previousIndex = previousIndices[right.stableId]
insertItems.append((i, right, previousIndex))
currentList.insert(right, at: i)
if k < updatedIndices.count {
for l in k ..< updatedIndices.count {
updatedIndices[l] = (updatedIndices[l].0 + 1, updatedIndices[l].1, updatedIndices[l].2)
}
}
i += 1
j += 1
} else {
break
}
}
for (index, item, _) in updatedIndices {
currentList[index] = item
}
assert(currentList == rightList, "currentList == rightList")
return (removeIndices, insertItems, updatedIndices)
}

View File

@ -20,7 +20,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 75
return 76
}
public func parseMessage(_ data: Data!) -> Any! {