diff --git a/TelegramCore.xcodeproj/project.pbxproj b/TelegramCore.xcodeproj/project.pbxproj index f857edd945..4f3ce10231 100644 --- a/TelegramCore.xcodeproj/project.pbxproj +++ b/TelegramCore.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 9F10CE8B20613C78002DD61A /* SecretApiLayer73.swift in Sources */ = {isa = PBXBuildFile; fileRef = D018EDFF2044939F00CBB130 /* SecretApiLayer73.swift */; }; 9F10CE8C20613CDB002DD61A /* TelegramDeviceContactImportInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B2F7732052DEF700D3BFB9 /* TelegramDeviceContactImportInfo.swift */; }; + 9FAA268820D457A300D26CF3 /* RemoteStorageConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EA188120D3D2B1001AEE19 /* RemoteStorageConfiguration.swift */; }; 9FC8ADA9206BBD000094F7B4 /* SaveSecureIdValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D093D805206539D000BC3599 /* SaveSecureIdValue.swift */; }; 9FC8ADAB206BBFF10094F7B4 /* RecentWebSessions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FC8ADAA206BBFF10094F7B4 /* RecentWebSessions.swift */; }; 9FC8ADAC206BC00A0094F7B4 /* RecentWebSessions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FC8ADAA206BBFF10094F7B4 /* RecentWebSessions.swift */; }; @@ -39,6 +40,8 @@ C27982511E72C97800262BFD /* MacosLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C27982501E72C97800262BFD /* MacosLegacy.swift */; }; C28725421EF967E700613564 /* NotificationInfoMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = C28725411EF967E700613564 /* NotificationInfoMessageAttribute.swift */; }; C28725431EF967E700613564 /* NotificationInfoMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = C28725411EF967E700613564 /* NotificationInfoMessageAttribute.swift */; }; + C28D3CF020D3DA900027F4D6 /* DeepLinkInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C28D3CEF20D3DA900027F4D6 /* DeepLinkInfo.swift */; }; + C28D3CF120D3DAA30027F4D6 /* DeepLinkInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C28D3CEF20D3DA900027F4D6 /* DeepLinkInfo.swift */; }; C29340F31F5080FA0074991E /* UpdateGroupSpecificStickerset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C29340F21F5080FA0074991E /* UpdateGroupSpecificStickerset.swift */; }; C29340F41F5081280074991E /* UpdateGroupSpecificStickerset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C29340F21F5080FA0074991E /* UpdateGroupSpecificStickerset.swift */; }; C2A315C01E2E776A00D89000 /* RequestStartBot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01749581E1092BC0057C89A /* RequestStartBot.swift */; }; @@ -745,6 +748,7 @@ C251D7421E65E50500283EDE /* StickerSetInstallation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerSetInstallation.swift; sourceTree = ""; }; C27982501E72C97800262BFD /* MacosLegacy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MacosLegacy.swift; sourceTree = ""; }; C28725411EF967E700613564 /* NotificationInfoMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationInfoMessageAttribute.swift; sourceTree = ""; }; + C28D3CEF20D3DA900027F4D6 /* DeepLinkInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkInfo.swift; sourceTree = ""; }; C29340F21F5080FA0074991E /* UpdateGroupSpecificStickerset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateGroupSpecificStickerset.swift; sourceTree = ""; }; C2E064671ECEEF0A00387BB8 /* TelegramMediaInvoice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelegramMediaInvoice.swift; sourceTree = ""; }; C2E0646C1ECF171D00387BB8 /* TelegramMediaWebDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelegramMediaWebDocument.swift; sourceTree = ""; }; @@ -1271,6 +1275,7 @@ D01C06B61FBBA269001561AB /* CanSendMessagesToPeer.swift */, D0F8C39F2017AF2700236FC5 /* GlobalTelegramCoreConfiguration.swift */, D0E412E9206AD18E00BEE4A2 /* DecryptedResourceData.swift */, + C28D3CEF20D3DA900027F4D6 /* DeepLinkInfo.swift */, ); name = Utils; sourceTree = ""; @@ -2253,6 +2258,7 @@ D0BE304B20627D9800FBE6D8 /* AccessSecureId.swift in Sources */, D0BEAF5D1E54941B00BD963D /* Authorization.swift in Sources */, D0C26D6C1FE286C3004ABF18 /* FetchChatList.swift in Sources */, + C28D3CF020D3DA900027F4D6 /* DeepLinkInfo.swift in Sources */, D0B843831DA6EDB8005F29E1 /* CachedGroupData.swift in Sources */, D0E35A121DE4A25E00BC6096 /* OutgoingChatContextResultMessageAttribute.swift in Sources */, D093D806206539D000BC3599 /* SaveSecureIdValue.swift in Sources */, @@ -2379,6 +2385,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9FAA268820D457A300D26CF3 /* RemoteStorageConfiguration.swift in Sources */, + C28D3CF120D3DAA30027F4D6 /* DeepLinkInfo.swift in Sources */, 9FC8ADAC206BC00A0094F7B4 /* RecentWebSessions.swift in Sources */, 9FC8ADA9206BBD000094F7B4 /* SaveSecureIdValue.swift in Sources */, 9F10CE8C20613CDB002DD61A /* TelegramDeviceContactImportInfo.swift in Sources */, diff --git a/TelegramCore/ChannelAdmins.swift b/TelegramCore/ChannelAdmins.swift index eb66c68599..020ff331b9 100644 --- a/TelegramCore/ChannelAdmins.swift +++ b/TelegramCore/ChannelAdmins.swift @@ -55,3 +55,30 @@ public func channelAdmins(account: Account, peerId: PeerId) -> Signal<[RenderedC } } |> switchToLatest } + +public func channelAdminIds(postbox: Postbox, network: Network, peerId: PeerId, hash: Int32) -> Signal<[PeerId], Void> { + return postbox.transaction { transaction in + if let peer = transaction.getPeer(peerId) as? TelegramChannel, case .group = peer.info, let apiChannel = apiInputChannel(peer) { + let api = Api.functions.channels.getParticipants(channel: apiChannel, filter: .channelParticipantsAdmins, offset: 0, limit: 100, hash: hash) + return network.request(api) |> retryRequest |> mapToSignal { result in + switch result { + case let .channelParticipants(_, participants, users): + let users = users.filter({ user in + return participants.contains(where: { participant in + switch participant { + case let .channelParticipantAdmin(_, userId, _, _, _, _): + return user.peerId.id == userId + default: + return false + } + }) + }) + return .single(users.map({TelegramUser(user: $0).id})) + default: + return .complete() + } + } + } + return .complete() + } |> switchToLatest +} diff --git a/TelegramCore/DeepLinkInfo.swift b/TelegramCore/DeepLinkInfo.swift new file mode 100644 index 0000000000..ca71be6476 --- /dev/null +++ b/TelegramCore/DeepLinkInfo.swift @@ -0,0 +1,23 @@ +import Foundation +#if os(macOS) +import SwiftSignalKitMac +#else +import SwiftSignalKit +#endif + +public struct DeepLinkInfo { + public let message: String + public let entities: [MessageTextEntity] + public let updateApp: Bool +} + +public func getDeepLinkInfo(network: Network, path: String) -> Signal { + return network.request(Api.functions.help.getDeepLinkInfo(path: path)) |> retryRequest |> map { value -> DeepLinkInfo? in + switch value { + case .deepLinkInfoEmpty: + return nil + case let .deepLinkInfo(flags, message, entities): + return DeepLinkInfo(message: message, entities: entities != nil ? messageTextEntitiesFromApiEntities(entities!) : [], updateApp: (flags & (1 << 0)) != 0) + } + } +} diff --git a/TelegramCore/PeerPhotoUpdater.swift b/TelegramCore/PeerPhotoUpdater.swift index 1a3de3df09..bf43250782 100644 --- a/TelegramCore/PeerPhotoUpdater.swift +++ b/TelegramCore/PeerPhotoUpdater.swift @@ -191,15 +191,20 @@ public func updatePeerPhoto(account: Account, peerId: PeerId, photo: Signal Signal { - switch reference { +public func removeAccountPhoto(network: Network, reference: TelegramMediaImageReference?) -> Signal { + if let reference = reference { + switch reference { case let .cloud(imageId, accessHash): return network.request(Api.functions.photos.deletePhotos(id: [.inputPhoto(id: imageId, accessHash: accessHash)])) - |> `catch` { _ -> Signal<[Int64], NoError> in - return .single([]) - } - |> mapToSignal { _ -> Signal in - return .complete() + |> `catch` { _ -> Signal<[Int64], NoError> in + return .single([]) + } + |> mapToSignal { _ -> Signal in + return .complete() } + } + } else { + let api = Api.functions.photos.updateProfilePhoto(id: Api.InputPhoto.inputPhotoEmpty) + return network.request(api) |> map { _ in } |> retryRequest } } diff --git a/TelegramCore/RequestChatContextResults.swift b/TelegramCore/RequestChatContextResults.swift index 0edcda8ff4..5d4c0df0b6 100644 --- a/TelegramCore/RequestChatContextResults.swift +++ b/TelegramCore/RequestChatContextResults.swift @@ -9,27 +9,36 @@ import Foundation import MtProtoKitDynamic #endif -public func requestChatContextResults(account: Account, botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String) -> Signal { - return combineLatest(account.postbox.transaction { transaction -> (bot: Peer, peer: Peer)? in +public struct ChatContextGeoPoint { + let latitude: Double + let longtitude: Double + public init(latitude: Double, longtitude: Double) { + self.latitude = latitude + self.longtitude = longtitude + } +} + +public func requestChatContextResults(account: Account, botId: PeerId, peerId: PeerId, query: String, offset: String, geopoint: ChatContextGeoPoint? = nil) -> Signal { + return account.postbox.transaction { transaction -> (bot: Peer, peer: Peer)? in if let bot = transaction.getPeer(botId), let peer = transaction.getPeer(peerId) { return (bot, peer) } else { return nil } - }, location) - |> mapToSignal { botAndPeer, location -> Signal in + } + |> mapToSignal { botAndPeer -> Signal in if let (bot, peer) = botAndPeer, let inputBot = apiInputUser(bot) { var flags: Int32 = 0 var inputPeer: Api.InputPeer = .inputPeerEmpty - var geoPoint: Api.InputGeoPoint? if let actualInputPeer = apiInputPeer(peer) { inputPeer = actualInputPeer } - if let (latitude, longitude) = location { + var inputGeo: Api.InputGeoPoint? = nil + if let geopoint = geopoint { + inputGeo = Api.InputGeoPoint.inputGeoPoint(lat: geopoint.latitude, long: geopoint.longtitude) flags |= (1 << 0) - geoPoint = Api.InputGeoPoint.inputGeoPoint(lat: latitude, long: longitude) } - return account.network.request(Api.functions.messages.getInlineBotResults(flags: flags, bot: inputBot, peer: inputPeer, geoPoint: geoPoint, query: query, offset: offset)) + return account.network.request(Api.functions.messages.getInlineBotResults(flags: flags, bot: inputBot, peer: inputPeer, geoPoint: inputGeo, query: query, offset: offset)) |> map { result -> ChatContextResultCollection? in return ChatContextResultCollection(apiResults: result, botId: bot.id) } diff --git a/TelegramCore/RequestMessageActionCallback.swift b/TelegramCore/RequestMessageActionCallback.swift index eaa90199fb..b97bac49d4 100644 --- a/TelegramCore/RequestMessageActionCallback.swift +++ b/TelegramCore/RequestMessageActionCallback.swift @@ -31,7 +31,7 @@ public func requestMessageActionCallback(account: Account, messageId: MessageId, flags |= Int32(1 << 1) } return account.network.request(Api.functions.messages.getBotCallbackAnswer(flags: flags, peer: inputPeer, msgId: messageId.id, data: dataBuffer)) - |> retryRequest + |> mapError {_ in} |> map { result -> MessageActionCallbackResult in //messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer; diff --git a/TelegramCore/RequestSecureIdForm.swift b/TelegramCore/RequestSecureIdForm.swift index f4c19ec30a..eaf4161fd9 100644 --- a/TelegramCore/RequestSecureIdForm.swift +++ b/TelegramCore/RequestSecureIdForm.swift @@ -12,6 +12,7 @@ import Foundation public enum RequestSecureIdFormError { case generic case serverError(String) + case versionOutdated } private func parseSecureValueType(_ type: Api.SecureValueType, selfie: Bool) -> SecureIdRequestedFormField { @@ -238,7 +239,13 @@ public func requestSecureIdForm(postbox: Postbox, network: Network, peerId: Peer } return network.request(Api.functions.account.getAuthorizationForm(botId: peerId.id, scope: scope, publicKey: publicKey)) |> mapError { error -> RequestSecureIdFormError in - return .serverError(error.errorDescription) + switch error.errorDescription { + case "APP_VERSION_OUTDATED": + return .versionOutdated + default: + return .serverError(error.errorDescription) + } + } |> mapToSignal { result -> Signal in return postbox.transaction { transaction -> EncryptedSecureIdForm in diff --git a/TelegramCore/SearchMessages.swift b/TelegramCore/SearchMessages.swift index ce1cb4ceb3..10032a275b 100644 --- a/TelegramCore/SearchMessages.swift +++ b/TelegramCore/SearchMessages.swift @@ -95,7 +95,10 @@ public func searchMessages(account: Account, location: SearchMessagesLocation, q |> mapError { _ in } |> map(Optional.init)*/ case .general: remoteSearchResult = account.network.request(Api.functions.messages.searchGlobal(q: query, offsetDate: 0, offsetPeer: Api.InputPeer.inputPeerEmpty, offsetId: 0, limit: 64), automaticFloodWait: false) - |> mapError { _ in } |> map(Optional.init) + |> map(Optional.init) + |> `catch` { _ -> Signal in + return .single(nil) + } |> mapError {_ in} } let processedSearchResult = remoteSearchResult @@ -103,6 +106,8 @@ public func searchMessages(account: Account, location: SearchMessagesLocation, q guard let result = result else { return .single([]) } + + //assert(false) let messages: [Api.Message] let chats: [Api.Chat] let users: [Api.User] diff --git a/TelegramCore/SecureIdValue.swift b/TelegramCore/SecureIdValue.swift index 7f5530690c..95934dacb4 100644 --- a/TelegramCore/SecureIdValue.swift +++ b/TelegramCore/SecureIdValue.swift @@ -122,12 +122,12 @@ public enum SecureIdValue: Equatable { } } -struct SecureIdEncryptedValueFileMetadata: Equatable { +public struct SecureIdEncryptedValueFileMetadata: Equatable { let hash: Data let secret: Data } -struct SecureIdEncryptedValueMetadata: Equatable { +public struct SecureIdEncryptedValueMetadata: Equatable { let valueDataHash: Data let decryptedSecret: Data } diff --git a/TelegramCore/Serialization.swift b/TelegramCore/Serialization.swift index c4cfb15755..fe1f138e79 100644 --- a/TelegramCore/Serialization.swift +++ b/TelegramCore/Serialization.swift @@ -201,6 +201,8 @@ public class BoxedMessage: NSObject { } public class Serialization: NSObject, MTSerialization { + + public func currentLayer() -> UInt { return 82 } diff --git a/TelegramCore/TermsOfService.swift b/TelegramCore/TermsOfService.swift index eb02dea8ba..82df723954 100644 --- a/TelegramCore/TermsOfService.swift +++ b/TelegramCore/TermsOfService.swift @@ -48,6 +48,12 @@ public func acceptTermsOfService(account: Account, id: String) -> Signal Signal { + return network.request(Api.functions.account.deleteAccount(reason: "Decline ToS update")) + |> retryRequest + |> map {_ in return} +} + func managedTermsOfServiceUpdates(postbox: Postbox, network: Network, stateManager: AccountStateManager) -> Signal { let poll = network.request(Api.functions.help.getTermsOfServiceUpdate()) |> retryRequest diff --git a/TelegramCore/Wallpapers.swift b/TelegramCore/Wallpapers.swift index 712b363f44..b3b65eb6e1 100644 --- a/TelegramCore/Wallpapers.swift +++ b/TelegramCore/Wallpapers.swift @@ -1,36 +1,62 @@ import Foundation +#if os(macOS) +import PostboxMac +import SwiftSignalKitMac +#else import Postbox import SwiftSignalKit +#endif public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable { + case none case builtin case color(Int32) case image([TelegramMediaImageRepresentation]) - + case custom(String) public init(decoder: PostboxDecoder) { switch decoder.decodeInt32ForKey("v", orElse: 0) { - case 0: - self = .builtin - case 1: - self = .color(decoder.decodeInt32ForKey("c", orElse: 0)) - case 2: - self = .image(decoder.decodeObjectArrayWithDecoderForKey("i")) - default: - assertionFailure() - self = .builtin + case 0: + self = .builtin + case 1: + self = .color(decoder.decodeInt32ForKey("c", orElse: 0)) + case 2: + self = .image(decoder.decodeObjectArrayWithDecoderForKey("i")) + case 3: + self = .none + case 4: + self = .custom(decoder.decodeStringForKey("p", orElse: "")) + default: + assertionFailure() + self = .none + } + } + + public var hasWallpaper: Bool { + switch self { + case .none: + return false + case .color: + return false + default: + return true } } public func encode(_ encoder: PostboxEncoder) { switch self { - case .builtin: - encoder.encodeInt32(0, forKey: "v") - case let .color(color): - encoder.encodeInt32(1, forKey: "v") - encoder.encodeInt32(color, forKey: "c") - case let .image(representations): - encoder.encodeInt32(2, forKey: "v") - encoder.encodeObjectArray(representations, forKey: "i") + case .builtin: + encoder.encodeInt32(0, forKey: "v") + case let .color(color): + encoder.encodeInt32(1, forKey: "v") + encoder.encodeInt32(color, forKey: "c") + case let .image(representations): + encoder.encodeInt32(2, forKey: "v") + encoder.encodeObjectArray(representations, forKey: "i") + case .none: + encoder.encodeInt32(3, forKey: "v") + case let .custom(path): + encoder.encodeInt32(4, forKey: "v") + encoder.encodeString(path, forKey: "p") } } }