no message

This commit is contained in:
Peter
2018-01-09 13:14:59 +04:00
parent 12dac67c0b
commit ecec26abd6
14 changed files with 321 additions and 235 deletions

View File

@@ -380,6 +380,8 @@
D0AB0B941D662ECE002C78E7 /* ManagedMessageHistoryHoles.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B931D662ECE002C78E7 /* ManagedMessageHistoryHoles.swift */; };
D0AB0B961D662F0B002C78E7 /* ManagedChatListHoles.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B951D662F0B002C78E7 /* ManagedChatListHoles.swift */; };
D0AB0B9A1D666520002C78E7 /* ManagedSynchronizePeerReadStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B991D666520002C78E7 /* ManagedSynchronizePeerReadStates.swift */; };
D0AD02E31FFFA14800C1DCFF /* PeerLiveLocationsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AD02E21FFFA14800C1DCFF /* PeerLiveLocationsContext.swift */; };
D0AD02E41FFFA14800C1DCFF /* PeerLiveLocationsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AD02E21FFFA14800C1DCFF /* PeerLiveLocationsContext.swift */; };
D0AF32221FAC95C20097362B /* StandaloneUploadedMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AF32211FAC95C20097362B /* StandaloneUploadedMedia.swift */; };
D0AF32231FAC95C20097362B /* StandaloneUploadedMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AF32211FAC95C20097362B /* StandaloneUploadedMedia.swift */; };
D0AF32311FACEDEC0097362B /* CoreSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AF32301FACEDEC0097362B /* CoreSettings.swift */; };
@@ -836,6 +838,7 @@
D0AB0B951D662F0B002C78E7 /* ManagedChatListHoles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedChatListHoles.swift; sourceTree = "<group>"; };
D0AB0B991D666520002C78E7 /* ManagedSynchronizePeerReadStates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizePeerReadStates.swift; sourceTree = "<group>"; };
D0AC49491D7097A400AA55DA /* SSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0AD02E21FFFA14800C1DCFF /* PeerLiveLocationsContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerLiveLocationsContext.swift; sourceTree = "<group>"; };
D0AF32211FAC95C20097362B /* StandaloneUploadedMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandaloneUploadedMedia.swift; sourceTree = "<group>"; };
D0AF32301FACEDEC0097362B /* CoreSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreSettings.swift; sourceTree = "<group>"; };
D0AF32341FAE8C6B0097362B /* MultipeerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipeerManager.swift; sourceTree = "<group>"; };
@@ -1476,6 +1479,7 @@
D021E0E01DB5400200C6B04F /* Sticker Management */,
D05A32DF1E6F096B002760B4 /* Settings */,
D08CAA8A1ED81EA10000FDA8 /* Localization */,
D0AD02E61FFFA15C00C1DCFF /* Live Location */,
D0AF32331FAE8C540097362B /* Multipeer */,
D03B0E3A1D631E4400955575 /* Supporting Files */,
D09D8C041D4FAB1D0081DBEC /* TelegramCore.h */,
@@ -1493,6 +1497,14 @@
path = TelegramCoreTests;
sourceTree = "<group>";
};
D0AD02E61FFFA15C00C1DCFF /* Live Location */ = {
isa = PBXGroup;
children = (
D0AD02E21FFFA14800C1DCFF /* PeerLiveLocationsContext.swift */,
);
name = "Live Location";
sourceTree = "<group>";
};
D0AF32331FAE8C540097362B /* Multipeer */ = {
isa = PBXGroup;
children = (
@@ -1941,6 +1953,7 @@
D05452071E7B5093006EEF19 /* LoadedStickerPack.swift in Sources */,
D01C7F041EFC1C49008305F1 /* DeviceContact.swift in Sources */,
D0F7AB2F1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */,
D0AD02E31FFFA14800C1DCFF /* PeerLiveLocationsContext.swift in Sources */,
D0B843971DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift in Sources */,
D0448CA21E291B14005A61A7 /* FetchSecretFileResource.swift in Sources */,
D08CAA871ED81DD40000FDA8 /* LocalizationInfo.swift in Sources */,
@@ -2277,6 +2290,7 @@
D0DFD5E01FCDBCFD0039B3B1 /* CachedSentMediaReferences.swift in Sources */,
D0B418991D7E0580004562A4 /* TelegramMediaMap.swift in Sources */,
D0561DEB1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */,
D0AD02E41FFFA14800C1DCFF /* PeerLiveLocationsContext.swift in Sources */,
D0613FCB1E60440600202CDB /* InvitationLinks.swift in Sources */,
D0B844471DAB91FD005F29E1 /* ManagedServiceViews.swift in Sources */,
D0F3A8A91E82CD7D00B4C64C /* UpdatePeerChatInterfaceState.swift in Sources */,

View File

@@ -566,21 +566,11 @@ public class Account {
}
}
let appVersionString = "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "") (\(Bundle.main.infoDictionary?["CFBundleVersion"] ?? ""))"
#if os(macOS)
let pInfo = ProcessInfo.processInfo
let systemVersion = pInfo.operatingSystemVersionString
#else
let systemVersion = UIDevice.current.systemVersion
#endif
var appSandbox: Api.Bool = .boolFalse
#if DEBUG
appSandbox = .boolTrue
#endif
return network.request(Api.functions.account.registerDevice(tokenType: 1, token: tokenString, deviceModel: "iPhone", systemVersion: systemVersion, appVersion: appVersionString, appSandbox: appSandbox))
return network.request(Api.functions.account.registerDevice(tokenType: 1, token: tokenString, appSandbox: appSandbox, otherUids: []))
|> retryRequest
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
@@ -599,21 +589,12 @@ public class Account {
}
}
let appVersionString = "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "") (\(Bundle.main.infoDictionary?["CFBundleVersion"] ?? ""))"
#if os(macOS)
let pInfo = ProcessInfo.processInfo
let systemVersion = pInfo.operatingSystemVersionString
#else
let systemVersion = UIDevice.current.systemVersion
#endif
var appSandbox: Api.Bool = .boolFalse
#if DEBUG
appSandbox = .boolTrue
#endif
return network.request(Api.functions.account.registerDevice(tokenType: 9, token: tokenString, deviceModel: "iPhone", systemVersion: systemVersion, appVersion: appVersionString, appSandbox: appSandbox))
return network.request(Api.functions.account.registerDevice(tokenType: 9, token: tokenString, appSandbox: appSandbox, otherUids: []))
|> retryRequest
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()

View File

@@ -13,18 +13,18 @@ final class AccountInitialState {
let state: AuthorizedAccountState.State
let peerIds: Set<PeerId>
let messageIds: Set<MessageId>
let channelStates: [PeerId: ChannelState]
let chatStates: [PeerId: PeerChatState]
//let topCloudMessageIds: [PeerId: MessageId]
let peerNotificationSettings: [PeerId: PeerNotificationSettings]
let peerIdsWithNewMessages: Set<PeerId>
let locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]
let cloudReadStates: [PeerId: PeerReadState]
init(state: AuthorizedAccountState.State, peerIds: Set<PeerId>, messageIds: Set<MessageId>, peerIdsWithNewMessages: Set<PeerId>, channelStates: [PeerId: ChannelState], peerNotificationSettings: [PeerId: PeerNotificationSettings], locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]], cloudReadStates: [PeerId: PeerReadState]) {
init(state: AuthorizedAccountState.State, peerIds: Set<PeerId>, messageIds: Set<MessageId>, peerIdsWithNewMessages: Set<PeerId>, chatStates: [PeerId: PeerChatState], peerNotificationSettings: [PeerId: PeerNotificationSettings], locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]], cloudReadStates: [PeerId: PeerReadState]) {
self.state = state
self.peerIds = peerIds
self.messageIds = messageIds
self.channelStates = channelStates
self.chatStates = chatStates
self.peerIdsWithNewMessages = peerIdsWithNewMessages
self.peerNotificationSettings = peerNotificationSettings
self.locallyGeneratedMessageTimestamps = locallyGeneratedMessageTimestamps
@@ -98,7 +98,7 @@ struct AccountMutableState {
var state: AuthorizedAccountState.State
var peers: [PeerId: Peer]
var channelStates: [PeerId: ChannelState]
var chatStates: [PeerId: PeerChatState]
var peerNotificationSettings: [PeerId: PeerNotificationSettings]
var storedMessages: Set<MessageId>
var readInboxMaxIds: [PeerId: MessageId]
@@ -115,18 +115,18 @@ struct AccountMutableState {
self.peers = initialPeers
self.storedMessages = initialStoredMessages
self.readInboxMaxIds = initialReadInboxMaxIds
self.channelStates = initialState.channelStates
self.chatStates = initialState.chatStates
self.peerNotificationSettings = initialState.peerNotificationSettings
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
self.branchOperationIndex = 0
}
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], channelStates: [PeerId: ChannelState], peerNotificationSettings: [PeerId: PeerNotificationSettings], storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], branchOperationIndex: Int) {
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], chatStates: [PeerId: PeerChatState], peerNotificationSettings: [PeerId: PeerNotificationSettings], storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], branchOperationIndex: Int) {
self.initialState = initialState
self.operations = operations
self.state = state
self.peers = peers
self.channelStates = channelStates
self.chatStates = chatStates
self.storedMessages = storedMessages
self.peerNotificationSettings = peerNotificationSettings
self.readInboxMaxIds = readInboxMaxIds
@@ -135,7 +135,7 @@ struct AccountMutableState {
}
func branch() -> AccountMutableState {
return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, channelStates: self.channelStates, peerNotificationSettings: self.peerNotificationSettings, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, branchOperationIndex: self.operations.count)
return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, chatStates: self.chatStates, peerNotificationSettings: self.peerNotificationSettings, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, branchOperationIndex: self.operations.count)
}
mutating func merge(_ other: AccountMutableState) {
@@ -313,7 +313,7 @@ struct AccountMutableState {
case let .UpdateState(state):
self.state = state
case let .UpdateChannelState(peerId, channelState):
self.channelStates[peerId] = channelState
self.chatStates[peerId] = channelState
case let .UpdateNotificationSettings(subject, notificationSettings):
if case let .peer(peerId) = subject {
self.peerNotificationSettings[peerId] = notificationSettings

View File

@@ -258,7 +258,7 @@ private func locallyGeneratedMessageTimestampsFromDifference(_ difference: Api.u
private func initialStateWithPeerIds(_ modifier: Modifier, peerIds: Set<PeerId>, associatedMessageIds: Set<MessageId>, peerIdsWithNewMessages: Set<PeerId>, locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]) -> AccountMutableState {
var peers: [PeerId: Peer] = [:]
var channelStates: [PeerId: ChannelState] = [:]
var chatStates: [PeerId: PeerChatState] = [:]
for peerId in peerIds {
if let peer = modifier.getPeer(peerId) {
@@ -267,7 +267,11 @@ private func initialStateWithPeerIds(_ modifier: Modifier, peerIds: Set<PeerId>,
if peerId.namespace == Namespaces.Peer.CloudChannel {
if let channelState = modifier.getPeerChatState(peerId) as? ChannelState {
channelStates[peerId] = channelState
chatStates[peerId] = channelState
}
} else if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup {
if let chatState = modifier.getPeerChatState(peerId) as? RegularChatState {
chatStates[peerId] = chatState
}
}
}
@@ -312,7 +316,7 @@ private func initialStateWithPeerIds(_ modifier: Modifier, peerIds: Set<PeerId>,
}
}
return AccountMutableState(initialState: AccountInitialState(state: (modifier.getState() as? AuthorizedAccountState)!.state!, peerIds: peerIds, messageIds: associatedMessageIds, peerIdsWithNewMessages: peerIdsWithNewMessages, channelStates: channelStates, peerNotificationSettings: peerNotificationSettings, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestamps, cloudReadStates: cloudReadStates), initialPeers: peers, initialStoredMessages: storedMessages, initialReadInboxMaxIds: readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: storedMessagesByPeerIdAndTimestamp)
return AccountMutableState(initialState: AccountInitialState(state: (modifier.getState() as? AuthorizedAccountState)!.state!, peerIds: peerIds, messageIds: associatedMessageIds, peerIdsWithNewMessages: peerIdsWithNewMessages, chatStates: chatStates, peerNotificationSettings: peerNotificationSettings, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestamps, cloudReadStates: cloudReadStates), initialPeers: peers, initialStoredMessages: storedMessages, initialReadInboxMaxIds: readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: storedMessagesByPeerIdAndTimestamp)
}
func initialStateWithUpdateGroups(_ account: Account, groups: [UpdateGroup]) -> Signal<AccountMutableState, NoError> {
@@ -629,7 +633,7 @@ private func finalStateWithUpdates(account: Account, state: AccountMutableState,
case let .updateChannelTooLong(_, channelId, channelPts):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
if !channelsToPoll.contains(peerId) {
if let channelPts = channelPts, let channelState = state.channelStates[peerId], channelState.pts >= channelPts {
if let channelPts = channelPts, let channelState = state.chatStates[peerId] as? ChannelState, channelState.pts >= channelPts {
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip updateChannelTooLong by pts")
} else {
channelsToPoll.insert(peerId)
@@ -637,7 +641,7 @@ private func finalStateWithUpdates(account: Account, state: AccountMutableState,
}
case let .updateDeleteChannelMessages(channelId, messages, pts: pts, ptsCount):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
if let previousState = updatedState.channelStates[peerId] {
if let previousState = updatedState.chatStates[peerId] as? ChannelState {
if previousState.pts >= pts {
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip old delete update")
} else if previousState.pts + ptsCount == pts {
@@ -659,7 +663,7 @@ private func finalStateWithUpdates(account: Account, state: AccountMutableState,
case let .updateEditChannelMessage(apiMessage, pts, ptsCount):
if let message = StoreMessage(apiMessage: apiMessage), case let .Id(messageId) = message.id {
let peerId = messageId.peerId
if let previousState = updatedState.channelStates[peerId] {
if let previousState = updatedState.chatStates[peerId] as? ChannelState {
if previousState.pts >= pts {
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip old edit update")
} else if previousState.pts + ptsCount == pts {
@@ -690,7 +694,7 @@ private func finalStateWithUpdates(account: Account, state: AccountMutableState,
}
case let .updateChannelWebPage(channelId, apiWebpage, pts, ptsCount):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
if let previousState = updatedState.channelStates[peerId] {
if let previousState = updatedState.chatStates[peerId] as? ChannelState {
if previousState.pts >= pts {
} else if previousState.pts + ptsCount == pts {
switch apiWebpage {
@@ -730,7 +734,7 @@ private func finalStateWithUpdates(account: Account, state: AccountMutableState,
}
case let .updateNewChannelMessage(apiMessage, pts, ptsCount):
if let message = StoreMessage(apiMessage: apiMessage) {
if let previousState = updatedState.channelStates[message.id.peerId] {
if let previousState = updatedState.chatStates[message.id.peerId] as? ChannelState {
if previousState.pts >= pts {
Logger.shared.log("State", "channel \(message.id.peerId) (\((updatedState.peers[message.id.peerId] as? TelegramChannel)?.title ?? "nil")) skip old message \(message.id) (\(message.text))")
} else if previousState.pts + ptsCount == pts {
@@ -1274,16 +1278,16 @@ private func resolveMissingPeerCloudReadStates(account: Account, state: AccountM
func keepPollingChannel(account: Account, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Signal<Void, NoError> in
if let accountState = (modifier.getState() as? AuthorizedAccountState)?.state, let peer = modifier.getPeer(peerId) {
var channelStates: [PeerId: ChannelState] = [:]
var chatStates: [PeerId: PeerChatState] = [:]
if let channelState = modifier.getPeerChatState(peerId) as? ChannelState {
channelStates[peerId] = channelState
chatStates[peerId] = channelState
}
let initialPeers: [PeerId: Peer] = [peerId: peer]
var peerNotificationSettings: [PeerId: TelegramPeerNotificationSettings] = [:]
if let notificationSettings = modifier.getPeerNotificationSettings(peerId) as? TelegramPeerNotificationSettings {
peerNotificationSettings[peerId] = notificationSettings
}
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), messageIds: Set(), peerIdsWithNewMessages: Set(), channelStates: channelStates, peerNotificationSettings: peerNotificationSettings, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:]), initialPeers: initialPeers, initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), messageIds: Set(), peerIdsWithNewMessages: Set(), chatStates: chatStates, peerNotificationSettings: peerNotificationSettings, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:]), initialPeers: initialPeers, initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
return pollChannel(account, peer: peer, state: initialState)
|> mapToSignal { (finalState, _, timeout) -> Signal<Void, NoError> in
return resolveAssociatedMessages(account: account, state: finalState)
@@ -1444,7 +1448,13 @@ private func pollChannel(_ account: Account, peer: Peer, state: AccountMutableSt
#if (arch(i386) || arch(x86_64)) && os(iOS)
limit = 3
#endif
return (account.network.request(Api.functions.updates.getChannelDifference(flags: 0, channel: inputChannel, filter: .channelMessagesFilterEmpty, pts: state.channelStates[peer.id]?.pts ?? 1, limit: limit))
let pollPts: Int32
if let channelState = state.chatStates[peer.id] as? ChannelState {
pollPts = channelState.pts
} else {
pollPts = 1
}
return (account.network.request(Api.functions.updates.getChannelDifference(flags: 0, channel: inputChannel, filter: .channelMessagesFilterEmpty, pts: pollPts, limit: limit))
|> map { Optional($0) }
|> `catch` { error -> Signal<Api.updates.ChannelDifference?, MTRpcError> in
if error.errorDescription == "CHANNEL_PRIVATE" {
@@ -1462,7 +1472,7 @@ private func pollChannel(_ account: Account, peer: Peer, state: AccountMutableSt
case let .channelDifference(_, pts, timeout, newMessages, otherUpdates, chats, users):
apiTimeout = timeout
let channelState: ChannelState
if let previousState = updatedState.channelStates[peer.id] {
if let previousState = updatedState.chatStates[peer.id] as? ChannelState {
channelState = previousState.withUpdatedPts(pts)
} else {
channelState = ChannelState(pts: pts, invalidatedPts: nil)
@@ -1543,7 +1553,7 @@ private func pollChannel(_ account: Account, peer: Peer, state: AccountMutableSt
apiTimeout = timeout
let channelState: ChannelState
if let previousState = updatedState.channelStates[peer.id] {
if let previousState = updatedState.chatStates[peer.id] as? ChannelState {
channelState = previousState.withUpdatedPts(pts)
} else {
channelState = ChannelState(pts: pts, invalidatedPts: nil)
@@ -1639,7 +1649,7 @@ private func verifyTransaction(_ modifier: Modifier, finalState: AccountMutableS
for peerId in channelsWithUpdatedStates {
let currentState = modifier.getPeerChatState(peerId)
var previousStateMatches = false
let previousState = finalState.initialState.channelStates[peerId]
let previousState = finalState.initialState.chatStates[peerId] as? ChannelState
if let currentState = currentState, let previousState = previousState {
if currentState.equals(previousState) {
previousStateMatches = true

View File

@@ -118,7 +118,7 @@ func accountStateReset(postbox: Postbox, network: Network) -> Signal<Void, NoErr
if let apiChannelPts = apiChannelPts {
chatStates[peerId] = ChannelState(pts: apiChannelPts, invalidatedPts: apiChannelPts)
} else {
} else if peerId.namespace == Namespaces.Peer.CloudGroup || peerId.namespace == Namespaces.Peer.CloudUser {
switch state {
case let .state(pts, _, _, _, _):
chatStates[peerId] = RegularChatState(invalidatedPts: pts)

View File

@@ -283,7 +283,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[410618194] = { return Api.InputDocument.parse_inputDocument($0) }
dict[2131196633] = { return Api.contacts.ResolvedPeer.parse_resolvedPeer($0) }
dict[-1771768449] = { return Api.InputMedia.parse_inputMediaEmpty($0) }
dict[-373312269] = { return Api.InputMedia.parse_inputMediaPhoto($0) }
dict[-104578748] = { return Api.InputMedia.parse_inputMediaGeoPoint($0) }
dict[-1494984313] = { return Api.InputMedia.parse_inputMediaContact($0) }
dict[444068508] = { return Api.InputMedia.parse_inputMediaDocument($0) }
@@ -295,13 +294,13 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-476700163] = { return Api.InputMedia.parse_inputMediaUploadedDocument($0) }
dict[2065305999] = { return Api.InputMedia.parse_inputMediaGeoLive($0) }
dict[-1052959727] = { return Api.InputMedia.parse_inputMediaVenue($0) }
dict[-2114308294] = { return Api.InputMedia.parse_inputMediaPhoto($0) }
dict[-186607933] = { return Api.InputMedia.parse_inputMediaInvoice($0) }
dict[2134579434] = { return Api.InputPeer.parse_inputPeerEmpty($0) }
dict[2107670217] = { return Api.InputPeer.parse_inputPeerSelf($0) }
dict[396093539] = { return Api.InputPeer.parse_inputPeerChat($0) }
dict[2072935910] = { return Api.InputPeer.parse_inputPeerUser($0) }
dict[548253432] = { return Api.InputPeer.parse_inputPeerChannel($0) }
dict[888128301] = { return Api.InputPeer.parse_inputPeerFeed($0) }
dict[568808380] = { return Api.upload.WebFile.parse_webFile($0) }
dict[-116274796] = { return Api.Contact.parse_contact($0) }
dict[-1679053127] = { return Api.BotInlineResult.parse_botInlineResult($0) }
@@ -8458,7 +8457,6 @@ public struct Api {
public enum InputMedia {
case inputMediaEmpty
case inputMediaPhoto(id: Api.InputPhoto, caption: String)
case inputMediaGeoPoint(geoPoint: Api.InputGeoPoint)
case inputMediaContact(phoneNumber: String, firstName: String, lastName: String)
case inputMediaDocument(id: Api.InputDocument, caption: String)
@@ -8470,6 +8468,7 @@ public struct Api {
case inputMediaUploadedDocument(flags: Int32, file: Api.InputFile, thumb: Api.InputFile?, mimeType: String, attributes: [Api.DocumentAttribute], caption: String, stickers: [Api.InputDocument]?, ttlSeconds: Int32?)
case inputMediaGeoLive(geoPoint: Api.InputGeoPoint, period: Int32)
case inputMediaVenue(geoPoint: Api.InputGeoPoint, title: String, address: String, provider: String, venueId: String, venueType: String)
case inputMediaPhoto(flags: Int32, id: Api.InputPhoto, caption: String, ttlSeconds: Int32?)
case inputMediaInvoice(flags: Int32, title: String, description: String, photo: Api.InputWebDocument?, invoice: Api.Invoice, payload: Buffer, provider: String, providerData: Api.DataJSON, startParam: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
@@ -8479,13 +8478,6 @@ public struct Api {
buffer.appendInt32(-1771768449)
}
break
case .inputMediaPhoto(let id, let caption):
if boxed {
buffer.appendInt32(-373312269)
}
id.serialize(buffer, true)
serializeString(caption, buffer: buffer, boxed: false)
break
case .inputMediaGeoPoint(let geoPoint):
if boxed {
@@ -8588,6 +8580,15 @@ public struct Api {
serializeString(venueId, buffer: buffer, boxed: false)
serializeString(venueType, buffer: buffer, boxed: false)
break
case .inputMediaPhoto(let flags, let id, let caption, let ttlSeconds):
if boxed {
buffer.appendInt32(-2114308294)
}
serializeInt32(flags, buffer: buffer, boxed: false)
id.serialize(buffer, true)
serializeString(caption, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
break
case .inputMediaInvoice(let flags, let title, let description, let photo, let invoice, let payload, let provider, let providerData, let startParam):
if boxed {
buffer.appendInt32(-186607933)
@@ -8608,22 +8609,6 @@ public struct Api {
fileprivate static func parse_inputMediaEmpty(_ reader: BufferReader) -> InputMedia? {
return Api.InputMedia.inputMediaEmpty
}
fileprivate static func parse_inputMediaPhoto(_ reader: BufferReader) -> InputMedia? {
var _1: Api.InputPhoto?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.InputPhoto
}
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.InputMedia.inputMediaPhoto(id: _1!, caption: _2!)
}
else {
return nil
}
}
fileprivate static func parse_inputMediaGeoPoint(_ reader: BufferReader) -> InputMedia? {
var _1: Api.InputGeoPoint?
if let signature = reader.readInt32() {
@@ -8836,6 +8821,28 @@ public struct Api {
return nil
}
}
fileprivate static func parse_inputMediaPhoto(_ reader: BufferReader) -> InputMedia? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.InputPhoto?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.InputPhoto
}
var _3: String?
_3 = parseString(reader)
var _4: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_4 = reader.readInt32() }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.InputMedia.inputMediaPhoto(flags: _1!, id: _2!, caption: _3!, ttlSeconds: _4)
}
else {
return nil
}
}
fileprivate static func parse_inputMediaInvoice(_ reader: BufferReader) -> InputMedia? {
var _1: Int32?
_1 = reader.readInt32()
@@ -8886,7 +8893,6 @@ public struct Api {
case inputPeerChat(chatId: Int32)
case inputPeerUser(userId: Int32, accessHash: Int64)
case inputPeerChannel(channelId: Int32, accessHash: Int64)
case inputPeerFeed(feedId: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@@ -8922,12 +8928,6 @@ public struct Api {
serializeInt32(channelId, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
break
case .inputPeerFeed(let feedId):
if boxed {
buffer.appendInt32(888128301)
}
serializeInt32(feedId, buffer: buffer, boxed: false)
break
}
}
@@ -8976,17 +8976,6 @@ public struct Api {
return nil
}
}
fileprivate static func parse_inputPeerFeed(_ reader: BufferReader) -> InputPeer? {
var _1: Int32?
_1 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.InputPeer.inputPeerFeed(feedId: _1!)
}
else {
return nil
}
}
}
@@ -20135,6 +20124,25 @@ public struct Api {
})
}
public static func getDialogs(flags: Int32, feedId: Int32?, offsetDate: Int32, offsetId: Int32, offsetPeer: Api.InputPeer, limit: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Dialogs?) {
let buffer = Buffer()
buffer.appendInt32(96533218)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(feedId!, buffer: buffer, boxed: false)}
serializeInt32(offsetDate, buffer: buffer, boxed: false)
serializeInt32(offsetId, buffer: buffer, boxed: false)
offsetPeer.serialize(buffer, true)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription({return "(messages.getDialogs flags: \(flags), feedId: \(String(describing: feedId)), offsetDate: \(offsetDate), offsetId: \(offsetId), offsetPeer: \(offsetPeer), limit: \(limit))"}), buffer, { (buffer: Buffer) -> Api.messages.Dialogs? in
let reader = BufferReader(buffer)
var result: Api.messages.Dialogs?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Dialogs
}
return result
})
}
public static func toggleDialogPin(flags: Int32, peer: Api.InputDialogPeer) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(-1489903017)
@@ -20186,25 +20194,6 @@ public struct Api {
return result
})
}
public static func getDialogs(flags: Int32, feedId: Int32?, offsetDate: Int32, offsetId: Int32, offsetPeer: Api.InputPeer, limit: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Dialogs?) {
let buffer = Buffer()
buffer.appendInt32(96533218)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(feedId!, buffer: buffer, boxed: false)}
serializeInt32(offsetDate, buffer: buffer, boxed: false)
serializeInt32(offsetId, buffer: buffer, boxed: false)
offsetPeer.serialize(buffer, true)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription({return "(messages.getDialogs flags: \(flags), feedId: \(String(describing: feedId)), offsetDate: \(offsetDate), offsetId: \(offsetId), offsetPeer: \(offsetPeer), limit: \(limit))"}), buffer, { (buffer: Buffer) -> Api.messages.Dialogs? in
let reader = BufferReader(buffer)
var result: Api.messages.Dialogs?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Dialogs
}
return result
})
}
}
public struct channels {
public static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
@@ -20539,21 +20528,6 @@ public struct Api {
})
}
public static func exportMessageLink(channel: Api.InputChannel, id: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.ExportedMessageLink?) {
let buffer = Buffer()
buffer.appendInt32(-934882771)
channel.serialize(buffer, true)
serializeInt32(id, buffer: buffer, boxed: false)
return (FunctionDescription({return "(channels.exportMessageLink channel: \(channel), id: \(id))"}), buffer, { (buffer: Buffer) -> Api.ExportedMessageLink? in
let reader = BufferReader(buffer)
var result: Api.ExportedMessageLink?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.ExportedMessageLink
}
return result
})
}
public static func toggleSignatures(channel: Api.InputChannel, enabled: Api.Bool) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Updates?) {
let buffer = Buffer()
buffer.appendInt32(527021574)
@@ -20738,6 +20712,22 @@ public struct Api {
})
}
public static func exportMessageLink(channel: Api.InputChannel, id: Int32, grouped: Api.Bool) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.ExportedMessageLink?) {
let buffer = Buffer()
buffer.appendInt32(-826838685)
channel.serialize(buffer, true)
serializeInt32(id, buffer: buffer, boxed: false)
grouped.serialize(buffer, true)
return (FunctionDescription({return "(channels.exportMessageLink channel: \(channel), id: \(id), grouped: \(grouped))"}), buffer, { (buffer: Buffer) -> Api.ExportedMessageLink? in
let reader = BufferReader(buffer)
var result: Api.ExportedMessageLink?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.ExportedMessageLink
}
return result
})
}
public static func getFeed(flags: Int32, feedId: Int32, offsetPosition: Api.FeedPosition?, addOffset: Int32, limit: Int32, maxPosition: Api.FeedPosition?, minPosition: Api.FeedPosition?, sourcesHash: Int32, hash: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.FeedMessages?) {
let buffer = Buffer()
buffer.appendInt32(403799538)
@@ -20760,6 +20750,25 @@ public struct Api {
})
}
public static func searchFeed(feedId: Int32, q: String, offsetDate: Int32, offsetPeer: Api.InputPeer, offsetId: Int32, limit: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Messages?) {
let buffer = Buffer()
buffer.appendInt32(-2009967767)
serializeInt32(feedId, buffer: buffer, boxed: false)
serializeString(q, buffer: buffer, boxed: false)
serializeInt32(offsetDate, buffer: buffer, boxed: false)
offsetPeer.serialize(buffer, true)
serializeInt32(offsetId, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription({return "(channels.searchFeed feedId: \(feedId), q: \(q), offsetDate: \(offsetDate), offsetPeer: \(offsetPeer), offsetId: \(offsetId), limit: \(limit))"}), buffer, { (buffer: Buffer) -> Api.messages.Messages? in
let reader = BufferReader(buffer)
var result: Api.messages.Messages?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Messages
}
return result
})
}
public static func getFeedSources(flags: Int32, feedId: Int32?, hash: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.channels.FeedSources?) {
let buffer = Buffer()
buffer.appendInt32(-657579154)
@@ -20826,25 +20835,6 @@ public struct Api {
return result
})
}
public static func searchFeed(feedId: Int32, q: String, offsetDate: Int32, offsetPeer: Api.InputPeer, offsetId: Int32, limit: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Messages?) {
let buffer = Buffer()
buffer.appendInt32(-2009967767)
serializeInt32(feedId, buffer: buffer, boxed: false)
serializeString(q, buffer: buffer, boxed: false)
serializeInt32(offsetDate, buffer: buffer, boxed: false)
offsetPeer.serialize(buffer, true)
serializeInt32(offsetId, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription({return "(channels.searchFeed feedId: \(feedId), q: \(q), offsetDate: \(offsetDate), offsetPeer: \(offsetPeer), offsetId: \(offsetId), limit: \(limit))"}), buffer, { (buffer: Buffer) -> Api.messages.Messages? in
let reader = BufferReader(buffer)
var result: Api.messages.Messages?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Messages
}
return result
})
}
}
public struct payments {
public static func getPaymentForm(msgId: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.payments.PaymentForm?) {
@@ -21835,40 +21825,6 @@ public struct Api {
}
}
public struct account {
public static func registerDevice(tokenType: Int32, token: String, deviceModel: String, systemVersion: String, appVersion: String, appSandbox: Api.Bool) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(-1568319572)
serializeInt32(tokenType, buffer: buffer, boxed: false)
serializeString(token, buffer: buffer, boxed: false)
serializeString(deviceModel, buffer: buffer, boxed: false)
serializeString(systemVersion, buffer: buffer, boxed: false)
serializeString(appVersion, buffer: buffer, boxed: false)
appSandbox.serialize(buffer, true)
return (FunctionDescription({return "(account.registerDevice tokenType: \(tokenType), token: \(token), deviceModel: \(deviceModel), systemVersion: \(systemVersion), appVersion: \(appVersion), appSandbox: \(appSandbox))"}), buffer, { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
public static func unregisterDevice(tokenType: Int32, token: String) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(1707432768)
serializeInt32(tokenType, buffer: buffer, boxed: false)
serializeString(token, buffer: buffer, boxed: false)
return (FunctionDescription({return "(account.unregisterDevice tokenType: \(tokenType), token: \(token))"}), buffer, { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
public static func updateNotifySettings(peer: Api.InputNotifyPeer, settings: Api.InputPeerNotifySettings) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(-2067899501)
@@ -22237,6 +22193,47 @@ public struct Api {
return result
})
}
public static func registerDevice(tokenType: Int32, token: String, appSandbox: Api.Bool, otherUids: [Int32]) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(1280460)
serializeInt32(tokenType, buffer: buffer, boxed: false)
serializeString(token, buffer: buffer, boxed: false)
appSandbox.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(otherUids.count))
for item in otherUids {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription({return "(account.registerDevice tokenType: \(tokenType), token: \(token), appSandbox: \(appSandbox), otherUids: \(otherUids))"}), buffer, { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
public static func unregisterDevice(tokenType: Int32, token: String, otherUids: [Int32]) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(813089983)
serializeInt32(tokenType, buffer: buffer, boxed: false)
serializeString(token, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(otherUids.count))
for item in otherUids {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription({return "(account.unregisterDevice tokenType: \(tokenType), token: \(token), otherUids: \(otherUids))"}), buffer, { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public struct langpack {
public static func getLangPack(langCode: String) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.LangPackDifference?) {

View File

@@ -13,7 +13,7 @@ public func exportMessageLink(account:Account, peerId:PeerId, messageId:MessageI
return modifier.getPeer(peerId)
} |> mapToSignal { peer -> Signal<String?, Void> in
if let peer = peer, let input = apiInputChannel(peer) {
return account.network.request(Api.functions.channels.exportMessageLink(channel: input, id: messageId.id)) |> mapError {_ in return } |> map { res in
return account.network.request(Api.functions.channels.exportMessageLink(channel: input, id: messageId.id, grouped: .boolTrue)) |> mapError {_ in return } |> map { res in
switch res {
case let .exportedMessageLink(link, _):
return link

View File

@@ -81,8 +81,9 @@ public extension MessageTags {
static let webPage = MessageTags(rawValue: 1 << 3)
static let voiceOrInstantVideo = MessageTags(rawValue: 1 << 4)
static let unseenPersonalMessage = MessageTags(rawValue: 1 << 5)
static let liveLocation = MessageTags(rawValue: 1 << 6)
static let all: MessageTags = [.photoOrVideo, .file, .music, .webPage, .voiceOrInstantVideo, .unseenPersonalMessage]
static let all: MessageTags = [.photoOrVideo, .file, .music, .webPage, .voiceOrInstantVideo, .unseenPersonalMessage, .liveLocation]
}
public extension GlobalMessageTags {

View File

@@ -0,0 +1,30 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
public func topPeerActiveLiveLocationMessages(account: Account, peerId: PeerId) -> Signal<[Message], NoError> {
return account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId), index: .upperBound, anchorIndex: .upperBound, count: 100, fixedCombinedReadStates: nil, tagMask: .liveLocation, orderStatistics: [])
|> map { (view, _, _) -> [Message] in
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
var result: [Message] = []
for entry in view.entries {
if case let .MessageEntry(message, _, _, _) = entry {
for media in message.media {
if let location = media as? TelegramMediaMap, let liveBroadcastingTimeout = location.liveBroadcastingTimeout {
if message.timestamp + liveBroadcastingTimeout > timestamp {
result.append(message)
}
} else {
assertionFailure()
}
}
}
}
return result
}
}

View File

@@ -64,7 +64,7 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
} else if let media = media.first {
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
if let reference = image.reference, case let .cloud(id, accessHash) = reference {
return .ready(.media(Api.InputMedia.inputMediaPhoto(id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash), caption: text)))
return .ready(.media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash), caption: text, ttlSeconds: nil)))
} else {
return .upload(uploadedMediaImageContent(network: network, postbox: postbox, peerId: peerId, image: image, text: text, autoremoveAttribute: autoremoveAttribute))
}
@@ -179,19 +179,20 @@ private func maybeCacheUploadedResource(postbox: Postbox, key: CachedSentMediaRe
private func uploadedMediaImageContent(network: Network, postbox: Postbox, peerId: PeerId, image: TelegramMediaImage, text: String, autoremoveAttribute: AutoremoveTimeoutMessageAttribute?) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> {
if let largestRepresentation = largestImageRepresentation(image.representations) {
let predownloadedResource: Signal<PredownloadedResource, PendingMessageUploadError>
if autoremoveAttribute == nil {
predownloadedResource = maybePredownloadedImageResource(postbox: postbox, resource: largestRepresentation.resource)
} else {
predownloadedResource = .single(.none)
}
let predownloadedResource: Signal<PredownloadedResource, PendingMessageUploadError> = maybePredownloadedImageResource(postbox: postbox, resource: largestRepresentation.resource)
return predownloadedResource
|> mapToSignal { result -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
var referenceKey: CachedSentMediaReferenceKey?
switch result {
case let .media(media):
if let image = media as? TelegramMediaImage, let reference = image.reference, case let .cloud(id, accessHash) = reference {
return .single(.progress(1.0)) |> then(.single(.content(.media(.inputMediaPhoto(id: .inputPhoto(id: id, accessHash: accessHash), caption: text)))))
var flags: Int32 = 0
var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute {
flags |= 1 << 1
ttlSeconds = autoremoveAttribute.timeout
}
return .single(.progress(1.0)) |> then(.single(.content(.media(.inputMediaPhoto(flags: flags, id: .inputPhoto(id: id, accessHash: accessHash), caption: text, ttlSeconds: ttlSeconds)))))
}
case let .localReference(key):
referenceKey = key
@@ -227,7 +228,13 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, peerI
switch result {
case let .messageMediaPhoto(_, photo, _, _):
if let photo = photo, let mediaImage = telegramMediaImageFromApiPhoto(photo), let reference = mediaImage.reference, case let .cloud(id, accessHash) = reference {
return maybeCacheUploadedResource(postbox: postbox, key: referenceKey, result: .content(.media(.inputMediaPhoto(id: .inputPhoto(id: id, accessHash: accessHash), caption: text))), media: mediaImage)
var flags: Int32 = 0
var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute {
flags |= 1 << 1
ttlSeconds = autoremoveAttribute.timeout
}
return maybeCacheUploadedResource(postbox: postbox, key: referenceKey, result: .content(.media(.inputMediaPhoto(flags: flags, id: .inputPhoto(id: id, accessHash: accessHash), caption: text, ttlSeconds: ttlSeconds))), media: mediaImage)
}
default:
break

View File

@@ -7,26 +7,38 @@ import Foundation
import SwiftSignalKit
#endif
public func searchGroupMembers(postbox: Postbox, network: Network, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
if peerId.namespace == Namespaces.Peer.CloudChannel && !query.isEmpty {
return channelMembers(postbox: postbox, network: network, peerId: peerId, filter: .search(query))
|> map { participants -> [Peer] in
return participants.map { $0.peer }
private func searchLocalGroupMembers(postbox: Postbox, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
return peerParticipants(postbox: postbox, id: peerId)
|> map { peers -> [Peer] in
let normalizedQuery = query.lowercased()
return peers.filter { peer in
if peer.indexName.matchesByTokens(normalizedQuery) {
return true
}
} else {
return peerParticipants(postbox: postbox, id: peerId)
|> map { peers -> [Peer] in
let normalizedQuery = query.lowercased()
return peers.filter { peer in
if peer.indexName.matchesByTokens(normalizedQuery) {
return true
}
if let addressName = peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
return true
}
return false
}
if let addressName = peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
return true
}
return false
}
}
}
public func searchGroupMembers(postbox: Postbox, network: Network, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
if peerId.namespace == Namespaces.Peer.CloudChannel && !query.isEmpty {
return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query)
|> mapToSignal { local -> Signal<[Peer], NoError> in
return .single(local)
|> then(channelMembers(postbox: postbox, network: network, peerId: peerId, filter: .search(query))
|> map { participants -> [Peer] in
var result: [Peer] = local
let existingIds = Set(local.map { $0.id })
let filtered = participants.map({ $0.peer }).filter({ !existingIds.contains($0.id) })
result.append(contentsOf: filtered)
return result
})
}
} else {
return searchLocalGroupMembers(postbox: postbox, peerId: peerId, query: query)
}
}

View File

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

View File

@@ -81,6 +81,8 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
default:
break
}
} else if let location = attachment as? TelegramMediaMap, location.liveBroadcastingTimeout != nil {
tags.insert(.liveLocation)
}
}
if let textEntities = textEntities, !textEntities.isEmpty && !tags.contains(.webPage) {
@@ -492,6 +494,25 @@ extension StoreMessage {
let attribute = TextEntitiesMessageAttribute(entities: messageTextEntitiesFromApiEntities(entities))
entitiesAttribute = attribute
attributes.append(attribute)
} else {
var noEntities = false
loop: for media in medias {
switch media {
case _ as TelegramMediaImage,
_ as TelegramMediaFile,
_ as TelegramMediaContact,
_ as TelegramMediaMap:
noEntities = true
break loop
default:
break
}
}
if !noEntities {
let attribute = TextEntitiesMessageAttribute(entities: [])
entitiesAttribute = attribute
attributes.append(attribute)
}
}
var storeFlags = StoreMessageFlags()

View File

@@ -18,6 +18,7 @@ public enum MessageTextEntityType: Equatable {
case Pre
case TextUrl(url: String)
case TextMention(peerId: PeerId)
case PhoneNumber
public static func ==(lhs: MessageTextEntityType, rhs: MessageTextEntityType) -> Bool {
switch lhs {
@@ -93,6 +94,12 @@ public enum MessageTextEntityType: Equatable {
} else {
return false
}
case .PhoneNumber:
if case .PhoneNumber = rhs {
return true
} else {
return false
}
}
}
}
@@ -132,6 +139,8 @@ public struct MessageTextEntity: PostboxCoding, Equatable {
self.type = .TextUrl(url: decoder.decodeStringForKey("url", orElse: ""))
case 11:
self.type = .TextMention(peerId: PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0)))
case 12:
self.type = .PhoneNumber
default:
self.type = .Unknown
}
@@ -167,6 +176,8 @@ public struct MessageTextEntity: PostboxCoding, Equatable {
case let .TextMention(peerId):
encoder.encodeInt32(11, forKey: "_rawValue")
encoder.encodeInt64(peerId.toInt64(), forKey: "peerId")
case .PhoneNumber:
encoder.encodeInt32(12, forKey: "_rawValue")
}
}
@@ -209,39 +220,41 @@ public class TextEntitiesMessageAttribute: MessageAttribute, Equatable {
}
func apiTextAttributeEntities(_ attribute: TextEntitiesMessageAttribute, associatedPeers:SimpleDictionary<PeerId, Peer>) -> [Api.MessageEntity] {
func apiTextAttributeEntities(_ attribute: TextEntitiesMessageAttribute, associatedPeers: SimpleDictionary<PeerId, Peer>) -> [Api.MessageEntity] {
var entities:[Api.MessageEntity] = []
for entity in attribute.entities {
let offset:Int32 = Int32(entity.range.lowerBound)
let length:Int32 = Int32(entity.range.upperBound - entity.range.lowerBound)
switch entity.type {
case .Unknown:
break
case .Mention:
entities.append(.messageEntityMention(offset: offset, length: length))
case .Hashtag:
entities.append(.messageEntityHashtag(offset: offset, length: length))
case .BotCommand:
entities.append(.messageEntityBotCommand(offset: offset, length: length))
case .Url:
entities.append(.messageEntityUrl(offset: offset, length: length))
case .Email:
entities.append(.messageEntityEmail(offset: offset, length: length))
case .Bold:
entities.append(.messageEntityBold(offset: offset, length: length))
case .Italic:
entities.append(.messageEntityItalic(offset: offset, length: length))
case .Code:
entities.append(.messageEntityCode(offset: offset, length: length))
case .Pre:
entities.append(.messageEntityPre(offset: offset, length: length, language: ""))
case let .TextUrl(url):
entities.append(.messageEntityTextUrl(offset: offset, length: length, url: url))
case let .TextMention(peerId):
if let peer = associatedPeers[peerId], let inputUser = apiInputUser(peer) {
entities.append(.inputMessageEntityMentionName(offset: offset, length: length, userId: inputUser))
}
case .Unknown:
break
case .Mention:
entities.append(.messageEntityMention(offset: offset, length: length))
case .Hashtag:
entities.append(.messageEntityHashtag(offset: offset, length: length))
case .BotCommand:
entities.append(.messageEntityBotCommand(offset: offset, length: length))
case .Url:
entities.append(.messageEntityUrl(offset: offset, length: length))
case .Email:
entities.append(.messageEntityEmail(offset: offset, length: length))
case .Bold:
entities.append(.messageEntityBold(offset: offset, length: length))
case .Italic:
entities.append(.messageEntityItalic(offset: offset, length: length))
case .Code:
entities.append(.messageEntityCode(offset: offset, length: length))
case .Pre:
entities.append(.messageEntityPre(offset: offset, length: length, language: ""))
case let .TextUrl(url):
entities.append(.messageEntityTextUrl(offset: offset, length: length, url: url))
case let .TextMention(peerId):
if let peer = associatedPeers[peerId], let inputUser = apiInputUser(peer) {
entities.append(.inputMessageEntityMentionName(offset: offset, length: length, userId: inputUser))
}
case .PhoneNumber:
break
}
}
return entities