From 9b90e94ab8fefe63ce52b86c05e1dbbcc97c2ed7 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Thu, 24 Sep 2020 23:23:28 +0400 Subject: [PATCH] Comment updates --- .../Sources/LegacyAttachmentMenu.swift | 8 +- .../Sources/LegacyMediaPickers.swift | 4 +- .../Sources/LegacySuggestionContext.swift | 5 +- .../LocalizedPeerData/Sources/PeerTitle.swift | 3 + .../Sources/ChannelInfoController.swift | 2 +- .../Sources/GroupInfoController.swift | 2 +- .../Sources/SearchPeerMembers.swift | 6 +- .../Sources/SettingsController.swift | 2 +- submodules/TelegramApi/Sources/Api0.swift | 2 +- submodules/TelegramApi/Sources/Api1.swift | 80 +++++++++---------- submodules/TelegramApi/Sources/Api3.swift | 15 ++++ .../Sources/AccountViewTracker.swift | 16 +++- .../TelegramCore/Sources/ReportPeer.swift | 27 +++++++ .../Sources/ApplicationContext.swift | 6 +- .../TelegramUI/Sources/ChatController.swift | 32 ++++---- .../ChatInterfaceStateContextMenus.swift | 46 +---------- .../ChatInterfaceStateContextQueries.swift | 8 +- .../Sources/ChatMediaInputNode.swift | 2 +- .../ChatMessageCommentFooterContentNode.swift | 4 +- .../ChatMessageInstantVideoItemNode.swift | 6 +- .../Sources/ChatMessageNotificationItem.swift | 12 ++- .../Sources/ChatMessageStickerItemNode.swift | 2 +- .../ChatRecentActionsHistoryTransition.swift | 1 + .../Sources/CreateChannelController.swift | 2 +- .../Sources/CreateGroupController.swift | 2 +- .../TelegramUI/Sources/LegacyCamera.swift | 4 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 2 +- .../Sources/LegacyWebSearchGallery.swift | 6 +- .../Sources/WebSearchController.swift | 6 +- .../Sources/WebSearchControllerNode.swift | 6 +- 30 files changed, 174 insertions(+), 145 deletions(-) diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift index 33615c4158..12c55fbd7e 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift @@ -59,7 +59,7 @@ public enum LegacyAttachmentMenuMediaEditing { case file } -public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, presentationData: PresentationData, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, present: @escaping (ViewController, Any?) -> Void) -> TGMenuSheetController { +public func legacyAttachmentMenu(context: AccountContext, peer: Peer, chatLocation: ChatLocation, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, presentationData: PresentationData, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, present: @escaping (ViewController, Any?) -> Void) -> TGMenuSheetController { let defaultVideoPreset = defaultVideoPresetForContext(context) UserDefaults.standard.set(defaultVideoPreset.rawValue as NSNumber, forKey: "TG_preferredVideoPreset_v0") @@ -119,7 +119,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO let carouselItem = TGAttachmentCarouselItemView(context: parentController.context, camera: PGCamera.cameraAvailable(), selfPortrait: false, forProfilePhoto: false, assetType: TGMediaAssetAnyType, saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: editMediaOptions == nil && allowGrouping, allowSelection: editMediaOptions == nil, allowEditing: true, document: false, selectionLimit: selectionLimit)! carouselItemView = carouselItem carouselItem.stickersContext = paintStickersContext - carouselItem.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id) + carouselItem.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation) carouselItem.recipientName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) carouselItem.cameraPressed = { [weak controller, weak parentController] cameraView in if let controller = controller { @@ -367,7 +367,7 @@ public func legacyMenuPaletteFromTheme(_ theme: PresentationTheme) -> TGMenuShee return TGMenuSheetPallete(dark: theme.overallDarkAppearance, backgroundColor: sheetTheme.opaqueItemBackgroundColor, selectionColor: sheetTheme.opaqueItemHighlightedBackgroundColor, separatorColor: sheetTheme.opaqueItemSeparatorColor, accentColor: sheetTheme.controlAccentColor, destructiveColor: sheetTheme.destructiveActionTextColor, textColor: sheetTheme.primaryTextColor, secondaryTextColor: sheetTheme.secondaryTextColor, spinnerColor: sheetTheme.secondaryTextColor, badgeTextColor: sheetTheme.controlAccentColor, badgeImage: nil, cornersImage: generateStretchableFilledCircleImage(diameter: 11.0, color: nil, strokeColor: nil, strokeWidth: nil, backgroundColor: sheetTheme.opaqueItemBackgroundColor)) } -public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, saveEditedPhotos: Bool, allowGrouping: Bool, presentationData: PresentationData, images: [UIImage], sendMessagesWithSignals: @escaping ([Any]?) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, present: (ViewController, Any?) -> Void, initialLayout: ContainerViewLayout? = nil) -> ViewController { +public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, chatLocation: ChatLocation, saveEditedPhotos: Bool, allowGrouping: Bool, presentationData: PresentationData, images: [UIImage], sendMessagesWithSignals: @escaping ([Any]?) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, present: (ViewController, Any?) -> Void, initialLayout: ContainerViewLayout? = nil) -> ViewController { let defaultVideoPreset = defaultVideoPresetForContext(context) UserDefaults.standard.set(defaultVideoPreset.rawValue as NSNumber, forKey: "TG_preferredVideoPreset_v0") @@ -394,7 +394,7 @@ public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, saveEdit legacyController.enableSizeClassSignal = true - let suggestionContext = legacySuggestionContext(context: context, peerId: peer.id) + let suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation) let paintStickersContext = LegacyPaintStickersContext(context: context) paintStickersContext.presentStickersController = { completion in diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift index a3c9729106..72377a327e 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift @@ -19,7 +19,7 @@ public func guessMimeTypeByFileExtension(_ ext: String) -> String { return TGMimeTypeMap.mimeType(forExtension: ext) ?? "application/binary" } -public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, hasSchedule: Bool, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?) { +public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, chatLocation: ChatLocation, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, hasSchedule: Bool, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?) { let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat let paintStickersContext = LegacyPaintStickersContext(context: context) @@ -34,7 +34,7 @@ public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, co controller.captionsEnabled = captionsEnabled controller.inhibitDocumentCaptions = false controller.stickersContext = paintStickersContext - controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id) + controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation) if peer.id != context.account.peerId { if peer is TelegramUser { controller.hasTimer = hasSchedule diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacySuggestionContext.swift b/submodules/LegacyMediaPickerUI/Sources/LegacySuggestionContext.swift index 9b6bd9ace1..4580ff3d45 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacySuggestionContext.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacySuggestionContext.swift @@ -9,13 +9,12 @@ import LegacyUI import SearchPeerMembers import AccountContext -public func legacySuggestionContext(context: AccountContext, peerId: PeerId) -> TGSuggestionContext { +public func legacySuggestionContext(context: AccountContext, peerId: PeerId, chatLocation: ChatLocation) -> TGSuggestionContext { let suggestionContext = TGSuggestionContext() suggestionContext.userListSignal = { query in return SSignal { subscriber in if let query = query { - let normalizedQuery = query.lowercased() - let disposable = searchPeerMembers(context: context, peerId: peerId, query: query).start(next: { peers in + let disposable = searchPeerMembers(context: context, peerId: peerId, chatLocation: chatLocation, query: query).start(next: { peers in let users = NSMutableArray() for peer in peers { let user = TGUser() diff --git a/submodules/LocalizedPeerData/Sources/PeerTitle.swift b/submodules/LocalizedPeerData/Sources/PeerTitle.swift index 80f6fc719f..eab176ceb2 100644 --- a/submodules/LocalizedPeerData/Sources/PeerTitle.swift +++ b/submodules/LocalizedPeerData/Sources/PeerTitle.swift @@ -31,6 +31,9 @@ public extension Peer { func displayTitle(strings: PresentationStrings, displayOrder: PresentationPersonNameOrder) -> String { switch self { case let user as TelegramUser: + if user.id.isReplies { + return strings.DialogList_Replies + } if let firstName = user.firstName, !firstName.isEmpty { if let lastName = user.lastName, !lastName.isEmpty { switch displayOrder { diff --git a/submodules/PeerInfoUI/Sources/ChannelInfoController.swift b/submodules/PeerInfoUI/Sources/ChannelInfoController.swift index a8d2e5aa20..3efed590b4 100644 --- a/submodules/PeerInfoUI/Sources/ChannelInfoController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelInfoController.swift @@ -757,7 +757,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: hasPhotos, hasViewButton: false, personalPhoto: false, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: true)! let _ = currentAvatarMixin.swap(mixin) mixin.requestSearchController = { assetsController in - let controller = WebSearchController(context: context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), completion: { result in + let controller = WebSearchController(context: context, peer: peer, chatLocation: nil, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), completion: { result in assetsController?.dismiss() completedImpl(result) })) diff --git a/submodules/PeerInfoUI/Sources/GroupInfoController.swift b/submodules/PeerInfoUI/Sources/GroupInfoController.swift index 14daf3c79a..d93f87178e 100644 --- a/submodules/PeerInfoUI/Sources/GroupInfoController.swift +++ b/submodules/PeerInfoUI/Sources/GroupInfoController.swift @@ -1482,7 +1482,7 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId: let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: hasPhotos, hasViewButton: false, personalPhoto: false, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: true)! let _ = currentAvatarMixin.swap(mixin) mixin.requestSearchController = { assetsController in - let controller = WebSearchController(context: context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), completion: { result in + let controller = WebSearchController(context: context, peer: peer, chatLocation: nil, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), completion: { result in assetsController?.dismiss() completedImpl(result) })) diff --git a/submodules/SearchPeerMembers/Sources/SearchPeerMembers.swift b/submodules/SearchPeerMembers/Sources/SearchPeerMembers.swift index 6bf47f54c3..a7b38b0465 100644 --- a/submodules/SearchPeerMembers/Sources/SearchPeerMembers.swift +++ b/submodules/SearchPeerMembers/Sources/SearchPeerMembers.swift @@ -5,8 +5,10 @@ import SyncCore import SwiftSignalKit import AccountContext -public func searchPeerMembers(context: AccountContext, peerId: PeerId, query: String) -> Signal<[Peer], NoError> { - if peerId.namespace == Namespaces.Peer.CloudChannel { +public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocation: ChatLocation, query: String) -> Signal<[Peer], NoError> { + if case .replyThread = chatLocation { + return .single([]) + } else if peerId.namespace == Namespaces.Peer.CloudChannel { return context.account.postbox.transaction { transaction -> CachedChannelData? in return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData } diff --git a/submodules/SettingsUI/Sources/SettingsController.swift b/submodules/SettingsUI/Sources/SettingsController.swift index 66ec64ff69..7b7a26f31a 100644 --- a/submodules/SettingsUI/Sources/SettingsController.swift +++ b/submodules/SettingsUI/Sources/SettingsController.swift @@ -1400,7 +1400,7 @@ public func settingsController(context: AccountContext, accountManager: AccountM let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: hasPhotos, hasViewButton: false, personalPhoto: true, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: false)! let _ = currentAvatarMixin.swap(mixin) mixin.requestSearchController = { assetsController in - let controller = WebSearchController(context: context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: nil, completion: { result in + let controller = WebSearchController(context: context, peer: peer, chatLocation: nil, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: nil, completion: { result in assetsController?.dismiss() completedProfilePhotoImpl(result) })) diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index aabe82ab8b..8a137c3a69 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -701,9 +701,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1449145777] = { return Api.upload.CdnFile.parse_cdnFile($0) } dict[1984136919] = { return Api.wallet.LiteResponse.parse_liteResponse($0) } dict[415997816] = { return Api.help.InviteText.parse_inviteText($0) } - dict[1984755728] = { return Api.BotInlineMessage.parse_botInlineMessageMediaAuto($0) } dict[-1937807902] = { return Api.BotInlineMessage.parse_botInlineMessageText($0) } dict[-1222451611] = { return Api.BotInlineMessage.parse_botInlineMessageMediaGeo($0) } + dict[1984755728] = { return Api.BotInlineMessage.parse_botInlineMessageMediaAuto($0) } dict[-1970903652] = { return Api.BotInlineMessage.parse_botInlineMessageMediaVenue($0) } dict[416402882] = { return Api.BotInlineMessage.parse_botInlineMessageMediaContact($0) } dict[-1673717362] = { return Api.InputPeerNotifySettings.parse_inputPeerNotifySettings($0) } diff --git a/submodules/TelegramApi/Sources/Api1.swift b/submodules/TelegramApi/Sources/Api1.swift index e12df7433c..5a1cdb630c 100644 --- a/submodules/TelegramApi/Sources/Api1.swift +++ b/submodules/TelegramApi/Sources/Api1.swift @@ -19856,27 +19856,14 @@ public extension Api { } public enum BotInlineMessage: TypeConstructorDescription { - case botInlineMessageMediaAuto(flags: Int32, message: String, entities: [Api.MessageEntity]?, replyMarkup: Api.ReplyMarkup?) case botInlineMessageText(flags: Int32, message: String, entities: [Api.MessageEntity]?, replyMarkup: Api.ReplyMarkup?) case botInlineMessageMediaGeo(flags: Int32, geo: Api.GeoPoint, period: Int32, replyMarkup: Api.ReplyMarkup?) + case botInlineMessageMediaAuto(flags: Int32, message: String, entities: [Api.MessageEntity]?, replyMarkup: Api.ReplyMarkup?) case botInlineMessageMediaVenue(flags: Int32, geo: Api.GeoPoint, title: String, address: String, provider: String, venueId: String, venueType: String, replyMarkup: Api.ReplyMarkup?) case botInlineMessageMediaContact(flags: Int32, phoneNumber: String, firstName: String, lastName: String, vcard: String, replyMarkup: Api.ReplyMarkup?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .botInlineMessageMediaAuto(let flags, let message, let entities, let replyMarkup): - if boxed { - buffer.appendInt32(1984755728) - } - serializeInt32(flags, buffer: buffer, boxed: false) - serializeString(message, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261) - buffer.appendInt32(Int32(entities!.count)) - for item in entities! { - item.serialize(buffer, true) - }} - if Int(flags) & Int(1 << 2) != 0 {replyMarkup!.serialize(buffer, true)} - break case .botInlineMessageText(let flags, let message, let entities, let replyMarkup): if boxed { buffer.appendInt32(-1937807902) @@ -19899,6 +19886,19 @@ public extension Api { serializeInt32(period, buffer: buffer, boxed: false) if Int(flags) & Int(1 << 2) != 0 {replyMarkup!.serialize(buffer, true)} break + case .botInlineMessageMediaAuto(let flags, let message, let entities, let replyMarkup): + if boxed { + buffer.appendInt32(1984755728) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeString(message, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261) + buffer.appendInt32(Int32(entities!.count)) + for item in entities! { + item.serialize(buffer, true) + }} + if Int(flags) & Int(1 << 2) != 0 {replyMarkup!.serialize(buffer, true)} + break case .botInlineMessageMediaVenue(let flags, let geo, let title, let address, let provider, let venueId, let venueType, let replyMarkup): if boxed { buffer.appendInt32(-1970903652) @@ -19928,12 +19928,12 @@ public extension Api { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .botInlineMessageMediaAuto(let flags, let message, let entities, let replyMarkup): - return ("botInlineMessageMediaAuto", [("flags", flags), ("message", message), ("entities", entities), ("replyMarkup", replyMarkup)]) case .botInlineMessageText(let flags, let message, let entities, let replyMarkup): return ("botInlineMessageText", [("flags", flags), ("message", message), ("entities", entities), ("replyMarkup", replyMarkup)]) case .botInlineMessageMediaGeo(let flags, let geo, let period, let replyMarkup): return ("botInlineMessageMediaGeo", [("flags", flags), ("geo", geo), ("period", period), ("replyMarkup", replyMarkup)]) + case .botInlineMessageMediaAuto(let flags, let message, let entities, let replyMarkup): + return ("botInlineMessageMediaAuto", [("flags", flags), ("message", message), ("entities", entities), ("replyMarkup", replyMarkup)]) case .botInlineMessageMediaVenue(let flags, let geo, let title, let address, let provider, let venueId, let venueType, let replyMarkup): return ("botInlineMessageMediaVenue", [("flags", flags), ("geo", geo), ("title", title), ("address", address), ("provider", provider), ("venueId", venueId), ("venueType", venueType), ("replyMarkup", replyMarkup)]) case .botInlineMessageMediaContact(let flags, let phoneNumber, let firstName, let lastName, let vcard, let replyMarkup): @@ -19941,30 +19941,6 @@ public extension Api { } } - public static func parse_botInlineMessageMediaAuto(_ reader: BufferReader) -> BotInlineMessage? { - var _1: Int32? - _1 = reader.readInt32() - var _2: String? - _2 = parseString(reader) - var _3: [Api.MessageEntity]? - if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() { - _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self) - } } - var _4: Api.ReplyMarkup? - if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() { - _4 = Api.parse(reader, signature: signature) as? Api.ReplyMarkup - } } - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil - let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil - if _c1 && _c2 && _c3 && _c4 { - return Api.BotInlineMessage.botInlineMessageMediaAuto(flags: _1!, message: _2!, entities: _3, replyMarkup: _4) - } - else { - return nil - } - } public static func parse_botInlineMessageText(_ reader: BufferReader) -> BotInlineMessage? { var _1: Int32? _1 = reader.readInt32() @@ -20013,6 +19989,30 @@ public extension Api { return nil } } + public static func parse_botInlineMessageMediaAuto(_ reader: BufferReader) -> BotInlineMessage? { + var _1: Int32? + _1 = reader.readInt32() + var _2: String? + _2 = parseString(reader) + var _3: [Api.MessageEntity]? + if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() { + _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self) + } } + var _4: Api.ReplyMarkup? + if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() { + _4 = Api.parse(reader, signature: signature) as? Api.ReplyMarkup + } } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil + let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil + if _c1 && _c2 && _c3 && _c4 { + return Api.BotInlineMessage.botInlineMessageMediaAuto(flags: _1!, message: _2!, entities: _3, replyMarkup: _4) + } + else { + return nil + } + } public static func parse_botInlineMessageMediaVenue(_ reader: BufferReader) -> BotInlineMessage? { var _1: Int32? _1 = reader.readInt32() diff --git a/submodules/TelegramApi/Sources/Api3.swift b/submodules/TelegramApi/Sources/Api3.swift index 309ddc9c45..330dc0faa3 100644 --- a/submodules/TelegramApi/Sources/Api3.swift +++ b/submodules/TelegramApi/Sources/Api3.swift @@ -5235,6 +5235,21 @@ public extension Api { return result }) } + + public static func blockFromReplies(flags: Int32, msgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(698914348) + serializeInt32(flags, buffer: buffer, boxed: false) + serializeInt32(msgId, buffer: buffer, boxed: false) + return (FunctionDescription(name: "contacts.blockFromReplies", parameters: [("flags", flags), ("msgId", msgId)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in + let reader = BufferReader(buffer) + var result: Api.Updates? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.Updates + } + return result + }) + } } public struct help { public static func getConfig() -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { diff --git a/submodules/TelegramCore/Sources/AccountViewTracker.swift b/submodules/TelegramCore/Sources/AccountViewTracker.swift index 126b543857..a85ca8bf9e 100644 --- a/submodules/TelegramCore/Sources/AccountViewTracker.swift +++ b/submodules/TelegramCore/Sources/AccountViewTracker.swift @@ -726,7 +726,6 @@ public final class AccountViewTracker { maxMessageId = MessageId(peerId: commentsChannelId, namespace: Namespaces.Message.Cloud, id: repliesMaxId) } } - resultStates[messageIds[i]] = ViewCountContextState(timestamp: Int32(CFAbsoluteTimeGetCurrent()), clientId: clientId, result: ViewCountContextState.ReplyInfo(commentsPeerId: commentsChannelId, maxReadIncomingMessageId: maxReadIncomingMessageId, maxMessageId: maxMessageId)) loop: for j in 0 ..< attributes.count { if let attribute = attributes[j] as? ViewCountMessageAttribute { if let views = views { @@ -736,13 +735,24 @@ public final class AccountViewTracker { if let forwards = forwards { attributes[j] = ForwardCountMessageAttribute(count: Int(forwards)) } - } else if let _ = attributes[j] as? ReplyThreadMessageAttribute { + } else if let attribute = attributes[j] as? ReplyThreadMessageAttribute { foundReplies = true if let repliesCount = repliesCount { - attributes[j] = ReplyThreadMessageAttribute(count: repliesCount, latestUsers: recentRepliersPeerIds ?? [], commentsPeerId: commentsChannelId, maxMessageId: repliesMaxId, maxReadMessageId: repliesReadMaxId) + var resolvedMaxReadMessageId: MessageId.Id? + if previousMaxReadMessageId = attribute.maxReadMessageId, let repliesReadMaxId = repliesReadMaxId { + resolvedMaxReadMessageId = max(previousMaxReadMessageId, repliesReadMaxId) + maxReadIncomingMessageId = resolvedMaxReadMessageId + } else if let repliesReadMaxId = repliesReadMaxId { + resolvedMaxReadMessageId = repliesReadMaxId + maxReadIncomingMessageId = resolvedMaxReadMessageId + } else { + resolvedMaxReadMessageId = attribute.maxReadMessageId + } + attributes[j] = ReplyThreadMessageAttribute(count: repliesCount, latestUsers: recentRepliersPeerIds ?? [], commentsPeerId: commentsChannelId, maxMessageId: repliesMaxId, maxReadMessageId: resolvedMaxReadMessageId) } } } + resultStates[messageIds[i]] = ViewCountContextState(timestamp: Int32(CFAbsoluteTimeGetCurrent()), clientId: clientId, result: ViewCountContextState.ReplyInfo(commentsPeerId: commentsChannelId, maxReadIncomingMessageId: maxReadIncomingMessageId, maxMessageId: maxMessageId)) if !foundReplies, let repliesCount = repliesCount { attributes.append(ReplyThreadMessageAttribute(count: repliesCount, latestUsers: recentRepliersPeerIds ?? [], commentsPeerId: commentsChannelId, maxMessageId: repliesMaxId, maxReadMessageId: repliesReadMaxId)) } diff --git a/submodules/TelegramCore/Sources/ReportPeer.swift b/submodules/TelegramCore/Sources/ReportPeer.swift index b28ea9821f..41652f8bfa 100644 --- a/submodules/TelegramCore/Sources/ReportPeer.swift +++ b/submodules/TelegramCore/Sources/ReportPeer.swift @@ -199,3 +199,30 @@ public func dismissPeerStatusOptions(account: Account, peerId: PeerId) -> Signal } } |> switchToLatest } + +public func reportRepliesMessage(account: Account, messageId: MessageId, deleteMessage: Bool, deleteHistory: Bool, reportSpam: Bool) -> Signal { + if messageId.namespace != Namespaces.Message.Cloud { + return .complete() + } + var flags: Int32 = 0 + if deleteMessage { + flags |= 1 << 0 + } + if deleteHistory { + flags |= 1 << 1 + } + if reportSpam { + flags |= 1 << 2 + } + return account.network.request(Api.functions.contacts.blockFromReplies(flags: flags, msgId: messageId.id)) + |> map(Optional.init) + |> `catch` { _ -> Signal in + return .single(nil) + } + |> mapToSignal { updates -> Signal in + if let updates = updates { + account.stateManager.addUpdates(updates) + } + return .complete() + } +} diff --git a/submodules/TelegramUI/Sources/ApplicationContext.swift b/submodules/TelegramUI/Sources/ApplicationContext.swift index eec674cc7e..0c08fc926f 100644 --- a/submodules/TelegramUI/Sources/ApplicationContext.swift +++ b/submodules/TelegramUI/Sources/ApplicationContext.swift @@ -264,11 +264,9 @@ final class AuthorizedApplicationContext { if UIApplication.shared.applicationState == .active { var chatIsVisible = false if let topController = strongSelf.rootController.topViewController as? ChatControllerImpl, topController.traceVisibility() { - if case .peer(firstMessage.id.peerId) = topController.chatLocation { + if topController.chatLocation.peerId == firstMessage.id.peerId { chatIsVisible = true - }/* else if case let .group(topGroupId) = topController.chatLocation, topGroupId == groupId { - chatIsVisible = true - }*/ + } } if !notify { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index f54f7fd6bf..b067ac674e 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -3957,9 +3957,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (strongSelf.context.account.postbox.transaction { transasction -> Void in deleteAllMessagesWithForwardAuthor(transaction: transasction, mediaBox: account.postbox.mediaBox, peerId: message.id.peerId, forwardAuthorId: peer.id, namespace: Namespaces.Message.Cloud) }).start() - if reportSpam { - let _ = TelegramCore.reportPeer(account: strongSelf.context.account, peerId: peer.id, reason: .spam).start() - } + let _ = reportRepliesMessage(account: strongSelf.context.account, messageId: message.id, deleteMessage: true, deleteHistory: true, reportSpam: reportSpam).start() }) ] as [ActionSheetItem]) @@ -6703,7 +6701,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G slowModeEnabled = true } - let controller = legacyAttachmentMenu(context: strongSelf.context, peer: peer, editMediaOptions: menuEditMediaOptions, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, canSendPolls: canSendPolls, presentationData: strongSelf.presentationData, parentController: legacyController, recentlyUsedInlineBots: strongSelf.recentlyUsedInlineBotsValue, initialCaption: inputText.string, openGallery: { + let controller = legacyAttachmentMenu(context: strongSelf.context, peer: peer, chatLocation: strongSelf.chatLocation, editMediaOptions: menuEditMediaOptions, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, canSendPolls: canSendPolls, presentationData: strongSelf.presentationData, parentController: legacyController, recentlyUsedInlineBots: strongSelf.recentlyUsedInlineBotsValue, initialCaption: inputText.string, openGallery: { self?.presentMediaPicker(fileMode: false, editingMedia: editMediaOptions != nil, completion: { signals, silentPosting, scheduleTime in if !inputText.string.isEmpty { //strongSelf.clearInputText() @@ -6716,7 +6714,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) }, openCamera: { [weak self] cameraView, menuController in if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer { - presentedLegacyCamera(context: strongSelf.context, peer: peer, cameraView: cameraView, menuController: menuController, parentController: strongSelf, editingMedia: editMediaOptions != nil, saveCapturedPhotos: settings.storeEditedPhotos, mediaGrouping: true, initialCaption: inputText.string, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, sendMessagesWithSignals: { [weak self] signals, silentPosting, scheduleTime in + presentedLegacyCamera(context: strongSelf.context, peer: peer, chatLocation: strongSelf.chatLocation, cameraView: cameraView, menuController: menuController, parentController: strongSelf, editingMedia: editMediaOptions != nil, saveCapturedPhotos: settings.storeEditedPhotos, mediaGrouping: true, initialCaption: inputText.string, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, sendMessagesWithSignals: { [weak self] signals, silentPosting, scheduleTime in if let strongSelf = self { if editMediaOptions != nil { strongSelf.editMessageMediaWithLegacySignals(signals!) @@ -6967,9 +6965,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G legacyController.bind(controller: controller) legacyController.deferScreenEdgeGestures = [.top] - configureLegacyAssetPicker(controller, context: strongSelf.context, peer: peer, initialCaption: inputText.string, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, presentWebSearch: editingMedia ? nil : { [weak self, weak legacyController] in + configureLegacyAssetPicker(controller, context: strongSelf.context, peer: peer, chatLocation: strongSelf.chatLocation, initialCaption: inputText.string, hasSchedule: !strongSelf.presentationInterfaceState.isScheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, presentWebSearch: editingMedia ? nil : { [weak self, weak legacyController] in if let strongSelf = self { - let controller = WebSearchController(context: strongSelf.context, peer: peer, configuration: searchBotsConfiguration, mode: .media(completion: { results, selectionState, editingState, silentPosting in + let controller = WebSearchController(context: strongSelf.context, peer: peer, chatLocation: strongSelf.chatLocation, configuration: searchBotsConfiguration, mode: .media(completion: { results, selectionState, editingState, silentPosting in if let legacyController = legacyController { legacyController.dismiss() } @@ -7064,7 +7062,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } |> deliverOnMainQueue).start(next: { [weak self] configuration in if let strongSelf = self { - let controller = WebSearchController(context: strongSelf.context, peer: peer, configuration: configuration, mode: .media(completion: { [weak self] results, selectionState, editingState, silentPosting in + let controller = WebSearchController(context: strongSelf.context, peer: peer, chatLocation: strongSelf.chatLocation, configuration: configuration, mode: .media(completion: { [weak self] results, selectionState, editingState, silentPosting in legacyEnqueueWebSearchMessages(selectionState, editingState, enqueueChatContextResult: { [weak self] result in if let strongSelf = self { strongSelf.enqueueChatContextResult(results, result, hideVia: true) @@ -7668,7 +7666,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> deliverOnMainQueue).start(next: { [weak self] settings in if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer { strongSelf.chatDisplayNode.dismissInput() - let _ = presentLegacyPasteMenu(context: strongSelf.context, peer: peer, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, presentationData: strongSelf.presentationData, images: images, sendMessagesWithSignals: { signals in + let _ = presentLegacyPasteMenu(context: strongSelf.context, peer: peer, chatLocation: strongSelf.chatLocation, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, presentationData: strongSelf.presentationData, images: images, sendMessagesWithSignals: { signals in self?.enqueueMediaMessages(signals: signals, silentPosting: false) }, presentStickers: { [weak self] completion in if let strongSelf = self { @@ -8325,16 +8323,22 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } + if self.controllerInteraction?.currentMessageWithLoadingReplyThread == messageId { + return + } + let progressSignal: Signal = Signal { [weak self] _ in guard let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction else { return EmptyDisposable } - let previousId = controllerInteraction.currentMessageWithLoadingReplyThread - controllerInteraction.currentMessageWithLoadingReplyThread = messageId - strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(messageId) - if let previousId = previousId { - strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(previousId) + if controllerInteraction.currentMessageWithLoadingReplyThread != messageId { + let previousId = controllerInteraction.currentMessageWithLoadingReplyThread + controllerInteraction.currentMessageWithLoadingReplyThread = messageId + strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(messageId) + if let previousId = previousId { + strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(previousId) + } } return ActionDisposable { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 8d7c8e9709..8f0163fc67 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -273,7 +273,6 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState: var loadCopyMediaResource: MediaResource? var isAction = false var diceEmoji: String? - var canDiscuss = false if messages.count == 1 { for media in messages[0].media { if let file = media as? TelegramMediaFile { @@ -309,17 +308,6 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState: if let channel = messages[0].peers[messages[0].id.peerId] as? TelegramChannel { if !isAction { canPin = channel.hasPermission(.pinMessages) - - if messages[0].id.namespace == Namespaces.Message.Cloud { - switch channel.info { - case let .broadcast(info): - if info.flags.contains(.hasDiscussionGroup) { - canDiscuss = true - } - case .group: - break - } - } } } else if let group = messages[0].peers[messages[0].id.peerId] as? TelegramGroup { if !isAction { @@ -602,8 +590,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState: } } - if let threadId = threadId { - let replyThreadId = makeThreadIdMessageId(peerId: messages[0].id.peerId, threadId: threadId) + if let _ = threadId { let text: String if threadMessageCount != 0 { text = chatPresentationInterfaceState.strings.Conversation_ContextViewReplies(Int32(threadMessageCount)) @@ -613,37 +600,8 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState: actions.append(.action(ContextMenuActionItem(text: text, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Replies"), color: theme.actionSheet.primaryTextColor) }, action: { c, _ in - let foundIndex = Promise() - if let channel = messages[0].peers[messages[0].id.peerId] as? TelegramChannel { - foundIndex.set(fetchChannelReplyThreadMessage(account: context.account, messageId: messages[0].id, atMessageId: nil) - |> map(Optional.init) - |> `catch` { _ -> Signal in - return .single(nil) - }) - } c.dismiss(completion: { - if let channel = messages[0].peers[messages[0].id.peerId] as? TelegramChannel { - var cancelImpl: (() -> Void)? - let statusController = OverlayStatusController(theme: chatPresentationInterfaceState.theme, type: .loading(cancelled: { - cancelImpl?() - })) - controllerInteraction.presentController(statusController, nil) - - let disposable = (foundIndex.get() - |> take(1) - |> deliverOnMainQueue).start(next: { [weak statusController] result in - statusController?.dismiss() - - if let result = result { - interfaceInteraction.viewReplies(nil, result) - } - }) - - cancelImpl = { [weak statusController] in - disposable.dispose() - statusController?.dismiss() - } - } + controllerInteraction.openMessageReplies(messages[0].id, true) }) }))) } diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextQueries.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextQueries.swift index 333a91aeb9..1fc95214f1 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextQueries.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextQueries.swift @@ -43,7 +43,7 @@ func contextQueryResultStateForChatInterfacePresentationState(_ chatPresentation for query in inputQueries { let previousQuery = currentQueryStates[query.kind]?.0 if previousQuery != query { - let signal = updatedContextQueryResultStateForQuery(context: context, peer: peer, inputQuery: query, previousQuery: previousQuery) + let signal = updatedContextQueryResultStateForQuery(context: context, peer: peer, chatLocation: chatPresentationInterfaceState.chatLocation, inputQuery: query, previousQuery: previousQuery) updates[query.kind] = .update(query, signal) } } @@ -64,7 +64,7 @@ func contextQueryResultStateForChatInterfacePresentationState(_ chatPresentation return updates } -private func updatedContextQueryResultStateForQuery(context: AccountContext, peer: Peer, inputQuery: ChatPresentationInputQuery, previousQuery: ChatPresentationInputQuery?) -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> { +private func updatedContextQueryResultStateForQuery(context: AccountContext, peer: Peer, chatLocation: ChatLocation, inputQuery: ChatPresentationInputQuery, previousQuery: ChatPresentationInputQuery?) -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> { switch inputQuery { case let .emoji(query): var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .complete() @@ -145,7 +145,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee } let inlineBots: Signal<[(Peer, Double)], NoError> = types.contains(.contextBots) ? recentlyUsedInlineBots(postbox: context.account.postbox) : .single([]) - let participants = combineLatest(inlineBots, searchPeerMembers(context: context, peerId: peer.id, query: query)) + let participants = combineLatest(inlineBots, searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatLocation, query: query)) |> map { inlineBots, peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in let filteredInlineBots = inlineBots.sorted(by: { $0.1 > $1.1 }).filter { peer, rating in if rating < 0.14 { @@ -347,7 +347,7 @@ func searchQuerySuggestionResultStateForChatInterfacePresentationState(_ chatPre } } - let participants = searchPeerMembers(context: context, peerId: peer.id, query: query) + let participants = searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatPresentationInterfaceState.chatLocation, query: query) |> map { peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in let filteredPeers = peers var sortedPeers: [Peer] = [] diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index 076c0acc6f..00601fe12a 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -753,7 +753,7 @@ final class ChatMediaInputNode: ChatInputNode { let inputNodeInteraction = self.inputNodeInteraction! let peerSpecificPack: Signal<(PeerSpecificPackData?, CanInstallPeerSpecificPack), NoError> - if let peerId = peerId, case .peer = chatLocation { + if let peerId = peerId { self.dismissedPeerSpecificStickerPack.set(context.account.postbox.transaction { transaction -> Bool in guard let state = transaction.getPeerChatInterfaceState(peerId) as? ChatInterfaceState else { return false diff --git a/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift index cab139ee7a..93b68b4646 100644 --- a/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift @@ -278,10 +278,10 @@ final class ChatMessageCommentFooterContentNode: ChatMessageBubbleContentNode { strongSelf.arrowNode.isHidden = false if let statusNode = strongSelf.statusNode { strongSelf.statusNode = nil - statusNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak statusNode] _ in + statusNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, delay: 0.3, removeOnCompletion: false, completion: { [weak statusNode] _ in statusNode?.removeFromSupernode() }) - strongSelf.arrowNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + strongSelf.arrowNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, delay: 0.3) } } diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index cb89ccbe66..dbd9a0be95 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -292,7 +292,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { var ignoreSource = false if let forwardInfo = item.message.forwardInfo { - if item.message.id.peerId != item.context.account.peerId { + if !item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.message.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { if attribute.messageId.peerId == forwardInfo.author?.id { @@ -303,6 +303,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { break } } + } else { + ignoreForward = true } } @@ -326,7 +328,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { } } - if !ignoreSource, item.message.id.peerId != item.context.account.peerId { + if !ignoreSource, !item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.message.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { if let sourcePeer = item.message.peers[attribute.messageId.peerId] { diff --git a/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift b/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift index 882ebf425a..e5aa07c7fa 100644 --- a/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift +++ b/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift @@ -115,7 +115,9 @@ final class ChatMessageNotificationItemNode: NotificationItemNode { if let channel = peer as? TelegramChannel, case .broadcast = channel.info { title = peer.displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder) } else if let author = firstMessage.author { - if author.id != peer.id { + if firstMessage.id.peerId.isReplies, let _ = firstMessage.sourceReference, let effectiveAuthor = firstMessage.forwardInfo?.author { + title = effectiveAuthor.displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder) + "@" + peer.displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder) + } else if author.id != peer.id { if author.id == item.context.account.peerId { title = presentationData.strings.DialogList_You + "@" + peer.displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder) } else { @@ -136,14 +138,18 @@ final class ChatMessageNotificationItemNode: NotificationItemNode { title = peer.displayTitle(strings: item.strings, displayOrder: item.nameDisplayOrder) } - if let text = title, firstMessage.flags.contains(.WasScheduled) { + if let _ = title, firstMessage.flags.contains(.WasScheduled) { if let author = firstMessage.author, author.id == peer.id, author.id == item.context.account.peerId { isReminder = true } else { isScheduled = true } } - self.avatarNode.setPeer(context: item.context, theme: presentationData.theme, peer: peer, overrideImage: peer.id == item.context.account.peerId ? .savedMessagesIcon : nil, emptyColor: presentationData.theme.list.mediaPlaceholderColor) + var avatarPeer = peer + if firstMessage.id.peerId.isReplies, let author = firstMessage.forwardInfo?.author { + avatarPeer = author + } + self.avatarNode.setPeer(context: item.context, theme: presentationData.theme, peer: avatarPeer, overrideImage: peer.id == item.context.account.peerId ? .savedMessagesIcon : nil, emptyColor: presentationData.theme.list.mediaPlaceholderColor) } var titleIcon: UIImage? diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 094f051f5b..0ad94dbe65 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -235,7 +235,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { switch item.chatLocation { case let .peer(peerId): - if peerId != item.context.account.peerId { + if !peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { if peerId.isGroupOrChannel && item.message.author != nil { var isBroadcastChannel = false if let peer = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = peer.info { diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift index e070ab91db..42e7e08dd7 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift @@ -685,6 +685,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { (.canBanUsers, self.presentationData.strings.Channel_AdminLog_CanBanUsers), (.canInviteUsers, self.presentationData.strings.Channel_AdminLog_CanInviteUsers), (.canPinMessages, self.presentationData.strings.Channel_AdminLog_CanPinMessages), + (.canBeAnonymous, self.presentationData.strings.Channel_AdminLog_CanBeAnonymous), (.canAddAdmins, self.presentationData.strings.Channel_AdminLog_CanAddAdmins) ] } diff --git a/submodules/TelegramUI/Sources/CreateChannelController.swift b/submodules/TelegramUI/Sources/CreateChannelController.swift index c1ac7433e0..8d31c1539e 100644 --- a/submodules/TelegramUI/Sources/CreateChannelController.swift +++ b/submodules/TelegramUI/Sources/CreateChannelController.swift @@ -445,7 +445,7 @@ public func createChannelController(context: AccountContext) -> ViewController { let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: stateValue.with({ $0.avatar }) != nil, hasViewButton: false, personalPhoto: false, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: false)! let _ = currentAvatarMixin.swap(mixin) mixin.requestSearchController = { assetsController in - let controller = WebSearchController(context: context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: title, completion: { result in + let controller = WebSearchController(context: context, peer: peer, chatLocation: nil, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: title, completion: { result in assetsController?.dismiss() completedChannelPhotoImpl(result) })) diff --git a/submodules/TelegramUI/Sources/CreateGroupController.swift b/submodules/TelegramUI/Sources/CreateGroupController.swift index 52caf3fc28..3fe9f78ff9 100644 --- a/submodules/TelegramUI/Sources/CreateGroupController.swift +++ b/submodules/TelegramUI/Sources/CreateGroupController.swift @@ -704,7 +704,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: stateValue.with({ $0.avatar }) != nil, hasViewButton: false, personalPhoto: false, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: false)! let _ = currentAvatarMixin.swap(mixin) mixin.requestSearchController = { assetsController in - let controller = WebSearchController(context: context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: title, completion: { result in + let controller = WebSearchController(context: context, peer: peer, chatLocation: nil, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: title, completion: { result in assetsController?.dismiss() completedGroupPhotoImpl(result) })) diff --git a/submodules/TelegramUI/Sources/LegacyCamera.swift b/submodules/TelegramUI/Sources/LegacyCamera.swift index 3a087c72eb..e2e7938699 100644 --- a/submodules/TelegramUI/Sources/LegacyCamera.swift +++ b/submodules/TelegramUI/Sources/LegacyCamera.swift @@ -11,7 +11,7 @@ import ShareController import LegacyUI import LegacyMediaPickerUI -func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: String, hasSchedule: Bool, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?) { +func presentedLegacyCamera(context: AccountContext, peer: Peer, chatLocation: ChatLocation, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: String, hasSchedule: Bool, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme) legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait) @@ -79,7 +79,7 @@ func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAt controller.allowCaptionEntities = true controller.allowGrouping = mediaGrouping controller.inhibitDocumentCaptions = false - controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id) + controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation) controller.recipientName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) if peer.id != context.account.peerId { if peer is TelegramUser { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 44ae82c9a5..a6d54776cb 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -4138,7 +4138,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD guard let strongSelf = self else { return } - let controller = WebSearchController(context: strongSelf.context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: strongSelf.isSettings ? nil : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), completion: { [weak self] result in + let controller = WebSearchController(context: strongSelf.context, peer: peer, chatLocation: nil, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: strongSelf.isSettings ? nil : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), completion: { [weak self] result in assetsController?.dismiss() self?.updateProfilePhoto(result) })) diff --git a/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift b/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift index fd93f84bab..f30273f4a3 100644 --- a/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift +++ b/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift @@ -313,7 +313,7 @@ private func galleryItems(account: Account, results: [ChatContextResult], curren return (galleryItems, focusItem) } -func presentLegacyWebSearchGallery(context: AccountContext, peer: Peer?, presentationData: PresentationData, results: [ChatContextResult], current: ChatContextResult, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext, updateHiddenMedia: @escaping (String?) -> Void, initialLayout: ContainerViewLayout?, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (ChatContextResult) -> Void, presentStickers: ((@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?)?, present: (ViewController, Any?) -> Void) { +func presentLegacyWebSearchGallery(context: AccountContext, peer: Peer?, chatLocation: ChatLocation?, presentationData: PresentationData, results: [ChatContextResult], current: ChatContextResult, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext, updateHiddenMedia: @escaping (String?) -> Void, initialLayout: ContainerViewLayout?, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (ChatContextResult) -> Void, presentStickers: ((@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?)?, present: (ViewController, Any?) -> Void) { let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme, initialLayout: nil) legacyController.statusBar.statusBarStyle = presentationData.theme.rootController.statusBarStyle.style @@ -338,8 +338,8 @@ func presentLegacyWebSearchGallery(context: AccountContext, peer: Peer?, present let model = TGMediaPickerGalleryModel(context: legacyController.context, items: items, focus: focusItem, selectionContext: selectionContext, editingContext: editingContext, hasCaptions: false, allowCaptionEntities: true, hasTimer: false, onlyCrop: false, inhibitDocumentCaptions: false, hasSelectionPanel: false, hasCamera: false, recipientName: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))! model.stickersContext = paintStickersContext - if let peer = peer { - model.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id) + if let peer = peer, let chatLocation = chatLocation { + model.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation) } controller.model = model model.controller = controller diff --git a/submodules/WebSearchUI/Sources/WebSearchController.swift b/submodules/WebSearchUI/Sources/WebSearchController.swift index 140e9fba8e..d15c663dc4 100644 --- a/submodules/WebSearchUI/Sources/WebSearchController.swift +++ b/submodules/WebSearchUI/Sources/WebSearchController.swift @@ -126,6 +126,7 @@ public final class WebSearchController: ViewController { private let context: AccountContext private let mode: WebSearchControllerMode private let peer: Peer? + private let chatLocation: ChatLocation? private let configuration: SearchBotsConfiguration private var controllerNode: WebSearchControllerNode { @@ -155,10 +156,11 @@ public final class WebSearchController: ViewController { } } - public init(context: AccountContext, peer: Peer?, configuration: SearchBotsConfiguration, mode: WebSearchControllerMode) { + public init(context: AccountContext, peer: Peer?, chatLocation: ChatLocation?, configuration: SearchBotsConfiguration, mode: WebSearchControllerMode) { self.context = context self.mode = mode self.peer = peer + self.chatLocation = chatLocation self.configuration = configuration let presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -319,7 +321,7 @@ public final class WebSearchController: ViewController { } override public func loadDisplayNode() { - self.displayNode = WebSearchControllerNode(context: self.context, presentationData: self.interfaceState.presentationData, controllerInteraction: self.controllerInteraction!, peer: self.peer, mode: self.mode.mode) + self.displayNode = WebSearchControllerNode(context: self.context, presentationData: self.interfaceState.presentationData, controllerInteraction: self.controllerInteraction!, peer: self.peer, chatLocation: self.chatLocation, mode: self.mode.mode) self.controllerNode.requestUpdateInterfaceState = { [weak self] animated, f in if let strongSelf = self { strongSelf.updateInterfaceState(f) diff --git a/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift b/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift index acfa1d974b..024cf62559 100644 --- a/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift +++ b/submodules/WebSearchUI/Sources/WebSearchControllerNode.swift @@ -128,6 +128,7 @@ private func preparedWebSearchRecentTransition(from fromEntries: [WebSearchRecen class WebSearchControllerNode: ASDisplayNode { private let context: AccountContext private let peer: Peer? + private let chatLocation: ChatLocation? private var theme: PresentationTheme private var strings: PresentationStrings private var presentationData: PresentationData @@ -180,13 +181,14 @@ class WebSearchControllerNode: ASDisplayNode { var presentStickers: ((@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?)? - init(context: AccountContext, presentationData: PresentationData, controllerInteraction: WebSearchControllerInteraction, peer: Peer?, mode: WebSearchMode) { + init(context: AccountContext, presentationData: PresentationData, controllerInteraction: WebSearchControllerInteraction, peer: Peer?, chatLocation: ChatLocation?, mode: WebSearchMode) { self.context = context self.theme = presentationData.theme self.strings = presentationData.strings self.presentationData = presentationData self.controllerInteraction = controllerInteraction self.peer = peer + self.chatLocation = chatLocation self.mode = mode self.webSearchInterfaceState = WebSearchInterfaceState(presentationData: context.sharedContext.currentPresentationData.with { $0 }) @@ -694,7 +696,7 @@ class WebSearchControllerNode: ASDisplayNode { if self.controllerInteraction.selectionState != nil { if let state = self.webSearchInterfaceState.state, state.scope == .images { if let results = self.currentProcessedResults?.results { - presentLegacyWebSearchGallery(context: self.context, peer: self.peer, presentationData: self.presentationData, results: results, current: currentResult, selectionContext: self.controllerInteraction.selectionState, editingContext: self.controllerInteraction.editingState, updateHiddenMedia: { [weak self] id in + presentLegacyWebSearchGallery(context: self.context, peer: self.peer, chatLocation: self.chatLocation, presentationData: self.presentationData, results: results, current: currentResult, selectionContext: self.controllerInteraction.selectionState, editingContext: self.controllerInteraction.editingState, updateHiddenMedia: { [weak self] id in self?.hiddenMediaId.set(.single(id)) }, initialLayout: self.containerLayout?.0, transitionHostView: { [weak self] in return self?.gridNode.view