diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 5c42773db3..5d7e5dbc9b 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -13006,6 +13006,9 @@ Sorry for the inconvenience."; "Gift.View.Convert.Stars_1" = "%@ Star"; "Gift.View.Convert.Stars_any" = "%@ Stars"; +"Gift.View.NameHidden" = "Only you can see the senders's name."; +"Gift.View.NameAndMessageHidden" = "Only you can see the senders's name and message."; + "Gift.View.DisplayedInfo" = "The gift is visible on your Page. [View >]()"; "Gift.View.HiddenInfo" = "This gift is hidden. Only you can see it."; diff --git a/submodules/AccountContext/Sources/ChatController.swift b/submodules/AccountContext/Sources/ChatController.swift index e25e234b27..05ab49c8b2 100644 --- a/submodules/AccountContext/Sources/ChatController.swift +++ b/submodules/AccountContext/Sources/ChatController.swift @@ -63,7 +63,6 @@ public final class ChatMessageItemAssociatedData: Equatable { public let isStandalone: Bool public let isInline: Bool public let showSensitiveContent: Bool - public let starGifts: [Int64: TelegramMediaFile] public init( automaticDownloadPeerType: MediaAutoDownloadPeerType, @@ -97,8 +96,7 @@ public final class ChatMessageItemAssociatedData: Equatable { deviceContactsNumbers: Set = Set(), isStandalone: Bool = false, isInline: Bool = false, - showSensitiveContent: Bool = false, - starGifts: [Int64: TelegramMediaFile] = [:] + showSensitiveContent: Bool = false ) { self.automaticDownloadPeerType = automaticDownloadPeerType self.automaticDownloadPeerId = automaticDownloadPeerId @@ -132,7 +130,6 @@ public final class ChatMessageItemAssociatedData: Equatable { self.isStandalone = isStandalone self.isInline = isInline self.showSensitiveContent = showSensitiveContent - self.starGifts = starGifts } public static func == (lhs: ChatMessageItemAssociatedData, rhs: ChatMessageItemAssociatedData) -> Bool { @@ -226,9 +223,6 @@ public final class ChatMessageItemAssociatedData: Equatable { if lhs.showSensitiveContent != rhs.showSensitiveContent { return false } - if lhs.starGifts != rhs.starGifts { - return false - } return true } } diff --git a/submodules/TabBarUI/Sources/TabBarController.swift b/submodules/TabBarUI/Sources/TabBarController.swift index d614adeeec..a2438aab2c 100644 --- a/submodules/TabBarUI/Sources/TabBarController.swift +++ b/submodules/TabBarUI/Sources/TabBarController.swift @@ -340,8 +340,8 @@ open class TabBarControllerImpl: ViewController, TabBarController { public func updateBackgroundAlpha(_ alpha: CGFloat, transition: ContainedViewLayoutTransition) { let alpha = max(0.0, min(1.0, alpha)) - transition.updateAlpha(node: self.tabBarControllerNode.tabBarNode.backgroundNode, alpha: alpha, delay: 0.15) - transition.updateAlpha(node: self.tabBarControllerNode.tabBarNode.separatorNode, alpha: alpha, delay: 0.15) + transition.updateAlpha(node: self.tabBarControllerNode.tabBarNode.backgroundNode, alpha: alpha, delay: 0.1) + transition.updateAlpha(node: self.tabBarControllerNode.tabBarNode.separatorNode, alpha: alpha, delay: 0.1) } private func updateSelectedIndex(animated: Bool = false) { diff --git a/submodules/TelegramApi/Sources/Api36.swift b/submodules/TelegramApi/Sources/Api36.swift index f8b1794b5c..0a6196d7bb 100644 --- a/submodules/TelegramApi/Sources/Api36.swift +++ b/submodules/TelegramApi/Sources/Api36.swift @@ -2607,23 +2607,6 @@ public extension Api.functions.channels { }) } } -public extension Api.functions.channels { - static func clickSponsoredMessage(flags: Int32, channel: Api.InputChannel, randomId: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(21257589) - serializeInt32(flags, buffer: buffer, boxed: false) - channel.serialize(buffer, true) - serializeBytes(randomId, buffer: buffer, boxed: false) - return (FunctionDescription(name: "channels.clickSponsoredMessage", parameters: [("flags", String(describing: flags)), ("channel", String(describing: channel)), ("randomId", String(describing: randomId))]), buffer, DeserializeFunctionResponse { (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 extension Api.functions.channels { static func convertToGigagroup(channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -3165,21 +3148,6 @@ public extension Api.functions.channels { }) } } -public extension Api.functions.channels { - static func getSponsoredMessages(channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(-333377601) - channel.serialize(buffer, true) - return (FunctionDescription(name: "channels.getSponsoredMessages", parameters: [("channel", String(describing: channel))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.SponsoredMessages? in - let reader = BufferReader(buffer) - var result: Api.messages.SponsoredMessages? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.messages.SponsoredMessages - } - return result - }) - } -} public extension Api.functions.channels { static func inviteToChannel(channel: Api.InputChannel, users: [Api.InputUser]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -3344,23 +3312,6 @@ public extension Api.functions.channels { }) } } -public extension Api.functions.channels { - static func reportSponsoredMessage(channel: Api.InputChannel, randomId: Buffer, option: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(-1349519687) - channel.serialize(buffer, true) - serializeBytes(randomId, buffer: buffer, boxed: false) - serializeBytes(option, buffer: buffer, boxed: false) - return (FunctionDescription(name: "channels.reportSponsoredMessage", parameters: [("channel", String(describing: channel)), ("randomId", String(describing: randomId)), ("option", String(describing: option))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.channels.SponsoredMessageReportResult? in - let reader = BufferReader(buffer) - var result: Api.channels.SponsoredMessageReportResult? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.channels.SponsoredMessageReportResult - } - return result - }) - } -} public extension Api.functions.channels { static func restrictSponsoredMessages(channel: Api.InputChannel, restricted: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -3688,22 +3639,6 @@ public extension Api.functions.channels { }) } } -public extension Api.functions.channels { - static func viewSponsoredMessage(channel: Api.InputChannel, randomId: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(-1095836780) - channel.serialize(buffer, true) - serializeBytes(randomId, buffer: buffer, boxed: false) - return (FunctionDescription(name: "channels.viewSponsoredMessage", parameters: [("channel", String(describing: channel)), ("randomId", String(describing: randomId))]), buffer, DeserializeFunctionResponse { (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 extension Api.functions.chatlists { static func checkChatlistInvite(slug: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -5007,6 +4942,23 @@ public extension Api.functions.messages { }) } } +public extension Api.functions.messages { + static func clickSponsoredMessage(flags: Int32, peer: Api.InputPeer, randomId: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(252261477) + serializeInt32(flags, buffer: buffer, boxed: false) + peer.serialize(buffer, true) + serializeBytes(randomId, buffer: buffer, boxed: false) + return (FunctionDescription(name: "messages.clickSponsoredMessage", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("randomId", String(describing: randomId))]), buffer, DeserializeFunctionResponse { (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 extension Api.functions.messages { static func createChat(flags: Int32, users: [Api.InputUser], title: String, ttlPeriod: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -6838,6 +6790,21 @@ public extension Api.functions.messages { }) } } +public extension Api.functions.messages { + static func getSponsoredMessages(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(-1680673735) + peer.serialize(buffer, true) + return (FunctionDescription(name: "messages.getSponsoredMessages", parameters: [("peer", String(describing: peer))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.SponsoredMessages? in + let reader = BufferReader(buffer) + var result: Api.messages.SponsoredMessages? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.messages.SponsoredMessages + } + return result + }) + } +} public extension Api.functions.messages { static func getStickerSet(stickerset: Api.InputStickerSet, hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -7448,6 +7415,23 @@ public extension Api.functions.messages { }) } } +public extension Api.functions.messages { + static func reportSponsoredMessage(peer: Api.InputPeer, randomId: Buffer, option: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(452189112) + peer.serialize(buffer, true) + serializeBytes(randomId, buffer: buffer, boxed: false) + serializeBytes(option, buffer: buffer, boxed: false) + return (FunctionDescription(name: "messages.reportSponsoredMessage", parameters: [("peer", String(describing: peer)), ("randomId", String(describing: randomId)), ("option", String(describing: option))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.channels.SponsoredMessageReportResult? in + let reader = BufferReader(buffer) + var result: Api.channels.SponsoredMessageReportResult? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.channels.SponsoredMessageReportResult + } + return result + }) + } +} public extension Api.functions.messages { static func requestAppWebView(flags: Int32, peer: Api.InputPeer, app: Api.InputBotApp, startParam: String?, themeParams: Api.DataJSON?, platform: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -8728,6 +8712,22 @@ public extension Api.functions.messages { }) } } +public extension Api.functions.messages { + static func viewSponsoredMessage(peer: Api.InputPeer, randomId: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(1731909873) + peer.serialize(buffer, true) + serializeBytes(randomId, buffer: buffer, boxed: false) + return (FunctionDescription(name: "messages.viewSponsoredMessage", parameters: [("peer", String(describing: peer)), ("randomId", String(describing: randomId))]), buffer, DeserializeFunctionResponse { (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 extension Api.functions.payments { static func applyGiftCode(slug: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -10103,12 +10103,12 @@ public extension Api.functions.smsjobs { } } public extension Api.functions.stats { - static func getBroadcastRevenueStats(flags: Int32, channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getBroadcastRevenueStats(flags: Int32, peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(1977595505) + buffer.appendInt32(-142021095) serializeInt32(flags, buffer: buffer, boxed: false) - channel.serialize(buffer, true) - return (FunctionDescription(name: "stats.getBroadcastRevenueStats", parameters: [("flags", String(describing: flags)), ("channel", String(describing: channel))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueStats? in + peer.serialize(buffer, true) + return (FunctionDescription(name: "stats.getBroadcastRevenueStats", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueStats? in let reader = BufferReader(buffer) var result: Api.stats.BroadcastRevenueStats? if let signature = reader.readInt32() { @@ -10119,13 +10119,13 @@ public extension Api.functions.stats { } } public extension Api.functions.stats { - static func getBroadcastRevenueTransactions(channel: Api.InputChannel, offset: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getBroadcastRevenueTransactions(peer: Api.InputPeer, offset: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(6891535) - channel.serialize(buffer, true) + buffer.appendInt32(1889078125) + peer.serialize(buffer, true) serializeInt32(offset, buffer: buffer, boxed: false) serializeInt32(limit, buffer: buffer, boxed: false) - return (FunctionDescription(name: "stats.getBroadcastRevenueTransactions", parameters: [("channel", String(describing: channel)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueTransactions? in + return (FunctionDescription(name: "stats.getBroadcastRevenueTransactions", parameters: [("peer", String(describing: peer)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueTransactions? in let reader = BufferReader(buffer) var result: Api.stats.BroadcastRevenueTransactions? if let signature = reader.readInt32() { @@ -10136,12 +10136,12 @@ public extension Api.functions.stats { } } public extension Api.functions.stats { - static func getBroadcastRevenueWithdrawalUrl(channel: Api.InputChannel, password: Api.InputCheckPasswordSRP) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getBroadcastRevenueWithdrawalUrl(peer: Api.InputPeer, password: Api.InputCheckPasswordSRP) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(711323507) - channel.serialize(buffer, true) + buffer.appendInt32(-1644889427) + peer.serialize(buffer, true) password.serialize(buffer, true) - return (FunctionDescription(name: "stats.getBroadcastRevenueWithdrawalUrl", parameters: [("channel", String(describing: channel)), ("password", String(describing: password))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueWithdrawalUrl? in + return (FunctionDescription(name: "stats.getBroadcastRevenueWithdrawalUrl", parameters: [("peer", String(describing: peer)), ("password", String(describing: password))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueWithdrawalUrl? in let reader = BufferReader(buffer) var result: Api.stats.BroadcastRevenueWithdrawalUrl? if let signature = reader.readInt32() { diff --git a/submodules/TelegramCore/Sources/Statistics/RevenueStatistics.swift b/submodules/TelegramCore/Sources/Statistics/RevenueStatistics.swift index 90ad669f1c..7fafc906bc 100644 --- a/submodules/TelegramCore/Sources/Statistics/RevenueStatistics.swift +++ b/submodules/TelegramCore/Sources/Statistics/RevenueStatistics.swift @@ -145,7 +145,7 @@ private func requestRevenueStats(postbox: Postbox, network: Network, peerId: Pee } return nil } |> mapToSignal { peer -> Signal in - guard let peer, let inputChannel = apiInputChannel(peer) else { + guard let peer, let inputPeer = apiInputPeer(peer) else { return .never() } @@ -154,7 +154,7 @@ private func requestRevenueStats(postbox: Postbox, network: Network, peerId: Pee flags |= (1 << 1) } - return network.request(Api.functions.stats.getBroadcastRevenueStats(flags: flags, channel: inputChannel)) + return network.request(Api.functions.stats.getBroadcastRevenueStats(flags: flags, peer: inputPeer)) |> map { result -> RevenueStats? in return RevenueStats(apiRevenueStats: result, peerId: peerId) } @@ -354,13 +354,13 @@ private final class RevenueStatsTransactionsContextImpl { } |> mapToSignal { peer -> Signal<([RevenueStatsTransactionsContext.State.Transaction], Int32, Int32?), NoError> in if let peer { - guard let inputChannel = apiInputChannel(peer) else { + guard let inputPeer = apiInputPeer(peer) else { return .complete() } let offset = lastOffset ?? 0 let limit: Int32 = lastOffset == nil ? 25 : 50 - return account.network.request(Api.functions.stats.getBroadcastRevenueTransactions(channel: inputChannel, offset: offset, limit: limit), automaticFloodWait: false) + return account.network.request(Api.functions.stats.getBroadcastRevenueTransactions(peer: inputPeer, offset: offset, limit: limit), automaticFloodWait: false) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) @@ -502,7 +502,7 @@ public enum RequestRevenueWithdrawalError : Equatable { } func _internal_checkChannelRevenueWithdrawalAvailability(account: Account) -> Signal { - return account.network.request(Api.functions.stats.getBroadcastRevenueWithdrawalUrl(channel: .inputChannelEmpty, password: .inputCheckPasswordEmpty)) + return account.network.request(Api.functions.stats.getBroadcastRevenueWithdrawalUrl(peer: .inputPeerEmpty, password: .inputCheckPasswordEmpty)) |> mapError { error -> RequestRevenueWithdrawalError in if error.errorDescription == "PASSWORD_HASH_INVALID" { return .requestPassword @@ -530,7 +530,7 @@ func _internal_requestChannelRevenueWithdrawalUrl(account: Account, peerId: Peer } return account.postbox.transaction { transaction -> Signal in - guard let channel = transaction.getPeer(peerId) as? TelegramChannel, let inputChannel = apiInputChannel(channel) else { + guard let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) else { return .fail(.generic) } @@ -555,7 +555,7 @@ func _internal_requestChannelRevenueWithdrawalUrl(account: Account, peerId: Peer return checkPassword |> mapToSignal { password -> Signal in - return account.network.request(Api.functions.stats.getBroadcastRevenueWithdrawalUrl(channel: inputChannel, password: password), automaticFloodWait: false) + return account.network.request(Api.functions.stats.getBroadcastRevenueWithdrawalUrl(peer: inputPeer, password: password), automaticFloodWait: false) |> mapError { error -> RequestRevenueWithdrawalError in if error.errorDescription.hasPrefix("FLOOD_WAIT") { return .limitExceeded diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift index 0cf834f0db..3e5616334f 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift @@ -298,6 +298,7 @@ public struct CachedUserFlags: OptionSet { public static let readDatesPrivate = CachedUserFlags(rawValue: 1 << 2) public static let premiumRequired = CachedUserFlags(rawValue: 1 << 3) public static let adsEnabled = CachedUserFlags(rawValue: 1 << 4) + public static let canViewRevenue = CachedUserFlags(rawValue: 1 << 5) } public final class EditableBotInfo: PostboxCoding, Equatable { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift index ee9351f768..20c87296ea 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift @@ -420,14 +420,14 @@ private class AdMessagesHistoryContextImpl { } }) - let signal: Signal<(interPostInterval: Int32?, messages: [Message]), NoError> = account.postbox.transaction { transaction -> Api.InputChannel? in - return transaction.getPeer(peerId).flatMap(apiInputChannel) + let signal: Signal<(interPostInterval: Int32?, messages: [Message]), NoError> = account.postbox.transaction { transaction -> Api.InputPeer? in + return transaction.getPeer(peerId).flatMap(apiInputPeer) } - |> mapToSignal { inputChannel -> Signal<(interPostInterval: Int32?, messages: [Message]), NoError> in - guard let inputChannel = inputChannel else { + |> mapToSignal { inputPeer -> Signal<(interPostInterval: Int32?, messages: [Message]), NoError> in + guard let inputPeer else { return .single((nil, [])) } - return account.network.request(Api.functions.channels.getSponsoredMessages(channel: inputChannel)) + return account.network.request(Api.functions.messages.getSponsoredMessages(peer: inputPeer)) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) @@ -515,14 +515,14 @@ private class AdMessagesHistoryContextImpl { } func markAsSeen(opaqueId: Data) { - let signal: Signal = account.postbox.transaction { transaction -> Api.InputChannel? in - return transaction.getPeer(self.peerId).flatMap(apiInputChannel) + let signal: Signal = account.postbox.transaction { transaction -> Api.InputPeer? in + return transaction.getPeer(self.peerId).flatMap(apiInputPeer) } - |> mapToSignal { inputChannel -> Signal in - guard let inputChannel = inputChannel else { + |> mapToSignal { inputPeer -> Signal in + guard let inputPeer else { return .complete() } - return self.account.network.request(Api.functions.channels.viewSponsoredMessage(channel: inputChannel, randomId: Buffer(data: opaqueId))) + return self.account.network.request(Api.functions.messages.viewSponsoredMessage(peer: inputPeer, randomId: Buffer(data: opaqueId))) |> `catch` { _ -> Signal in return .single(.boolFalse) } @@ -608,11 +608,11 @@ public class AdMessagesHistoryContext { func _internal_markAdAction(account: Account, peerId: EnginePeer.Id, opaqueId: Data, media: Bool, fullscreen: Bool) { - let signal: Signal = account.postbox.transaction { transaction -> Api.InputChannel? in - return transaction.getPeer(peerId).flatMap(apiInputChannel) + let signal: Signal = account.postbox.transaction { transaction -> Api.InputPeer? in + return transaction.getPeer(peerId).flatMap(apiInputPeer) } - |> mapToSignal { inputChannel -> Signal in - guard let inputChannel = inputChannel else { + |> mapToSignal { inputPeer -> Signal in + guard let inputPeer else { return .complete() } var flags: Int32 = 0 @@ -622,7 +622,7 @@ func _internal_markAdAction(account: Account, peerId: EnginePeer.Id, opaqueId: D if fullscreen { flags |= (1 << 1) } - return account.network.request(Api.functions.channels.clickSponsoredMessage(flags: flags, channel: inputChannel, randomId: Buffer(data: opaqueId))) + return account.network.request(Api.functions.messages.clickSponsoredMessage(flags: flags, peer: inputPeer, randomId: Buffer(data: opaqueId))) |> `catch` { _ -> Signal in return .single(.boolFalse) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ReportAds.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ReportAds.swift index ae07cda8da..61fb824b75 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/ReportAds.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ReportAds.swift @@ -21,10 +21,10 @@ public enum ReportAdMessageError { func _internal_reportAdMessage(account: Account, peerId: EnginePeer.Id, opaqueId: Data, option: Data?) -> Signal { return account.postbox.transaction { transaction -> Signal in - guard let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) else { + guard let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) else { return .fail(.generic) } - return account.network.request(Api.functions.channels.reportSponsoredMessage(channel: inputChannel, randomId: Buffer(data: opaqueId), option: Buffer(data: option))) + return account.network.request(Api.functions.messages.reportSponsoredMessage(peer: inputPeer, randomId: Buffer(data: opaqueId), option: Buffer(data: option))) |> mapError { error -> ReportAdMessageError in if error.errorDescription == "PREMIUM_ACCOUNT_REQUIRED" { return .premiumRequired diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift index 349401e213..85a0117c97 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift @@ -288,6 +288,8 @@ func _internal_updateStarGiftAddedToProfile(account: Account, messageId: EngineM } } +private var cachedAccountGifts: [EnginePeer.Id: [ProfileGiftsContext.State.StarGift]] = [:] + private final class ProfileGiftsContextImpl { private let queue: Queue private let account: Account @@ -320,7 +322,11 @@ private final class ProfileGiftsContextImpl { } func loadMore() { - if case let .ready(true, nextOffset) = self.dataState { + if case let .ready(true, initialNextOffset) = self.dataState { + if self.gifts.isEmpty, self.peerId == self.account.peerId, let cachedGifts = cachedAccountGifts[self.peerId] { + self.gifts = cachedGifts + } + self.dataState = .loading self.pushState() @@ -335,7 +341,7 @@ private final class ProfileGiftsContextImpl { guard let inputUser else { return .single(([], 0, nil)) } - return network.request(Api.functions.payments.getUserStarGifts(userId: inputUser, offset: nextOffset ?? "", limit: 32)) + return network.request(Api.functions.payments.getUserStarGifts(userId: inputUser, offset: initialNextOffset ?? "", limit: 32)) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) @@ -362,8 +368,13 @@ private final class ProfileGiftsContextImpl { guard let strongSelf = self else { return } - for gift in gifts { - strongSelf.gifts.append(gift) + if initialNextOffset == nil, strongSelf.peerId == strongSelf.account.peerId { + cachedAccountGifts[strongSelf.peerId] = gifts + strongSelf.gifts = gifts + } else { + for gift in gifts { + strongSelf.gifts.append(gift) + } } let updatedCount = max(Int32(strongSelf.gifts.count), count) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift index b2e538e6bb..9121a3cbee 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift @@ -281,6 +281,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee let premiumRequired = (userFullFlags & (1 << 29)) != 0 let translationsDisabled = (userFullFlags & (1 << 23)) != 0 let adsEnabled = (userFullFlags2 & (1 << 7)) != 0 + let canViewRevenue = (userFullFlags2 & (1 << 9)) != 0 var flags: CachedUserFlags = previous.flags if premiumRequired { @@ -303,6 +304,11 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee } else { flags.remove(.adsEnabled) } + if canViewRevenue { + flags.insert(.canViewRevenue) + } else { + flags.remove(.canViewRevenue) + } let callsPrivate = (userFullFlags & (1 << 5)) != 0 let canPinMessages = (userFullFlags & (1 << 7)) != 0 diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift index 49171ab6e8..3396ef3132 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift @@ -91,17 +91,16 @@ private final class GiftViewSheetContent: CombinedComponent { if let arguments = subject.arguments { var peerIds: [EnginePeer.Id] = [arguments.peerId, context.account.peerId] - if let fromPeerId = arguments.fromPeerId { + if let fromPeerId = arguments.fromPeerId, !peerIds.contains(fromPeerId) { peerIds.append(fromPeerId) } - self.disposable = combineLatest(queue: Queue.mainQueue(), context.engine.data.get(EngineDataMap( peerIds.map { peerId -> TelegramEngine.EngineData.Item.Peer.Peer in return TelegramEngine.EngineData.Item.Peer.Peer(id: peerId) } )), - context.engine.payments.cachedStarGifts() + .single(nil) |> then(context.engine.payments.cachedStarGifts()) ).startStrict(next: { [weak self] peers, starGifts in if let strongSelf = self { var peersMap: [EnginePeer.Id: EnginePeer] = [:] @@ -142,6 +141,7 @@ private final class GiftViewSheetContent: CombinedComponent { let animation = Child(GiftAnimationComponent.self) let title = Child(MultilineTextComponent.self) let description = Child(MultilineTextComponent.self) + let hiddenText = Child(MultilineTextComponent.self) let table = Child(TableComponent.self) let additionalText = Child(MultilineTextComponent.self) let button = Child(SolidRoundedButtonComponent.self) @@ -192,6 +192,7 @@ private final class GiftViewSheetContent: CombinedComponent { var giftId: Int64 = 0 var date: Int32? var soldOut = false + var nameHidden = false if case let .soldOutGift(gift) = component.subject { animationFile = gift.file stars = gift.price @@ -214,6 +215,7 @@ private final class GiftViewSheetContent: CombinedComponent { giftId = arguments.gift.id date = arguments.date titleString = incoming ? strings.Gift_View_ReceivedTitle : strings.Gift_View_Title + nameHidden = arguments.nameHidden } else { animationFile = nil stars = 0 @@ -270,7 +272,101 @@ private final class GiftViewSheetContent: CombinedComponent { availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 60.0, height: CGFloat.greatestFiniteMagnitude), transition: .immediate ) - + context.add(title + .position(CGPoint(x: context.availableSize.width / 2.0, y: 177.0)) + ) + + var originY: CGFloat = 0.0 + if let animationFile { + let animation = animation.update( + component: GiftAnimationComponent( + context: component.context, + theme: environment.theme, + file: animationFile + ), + availableSize: CGSize(width: 128.0, height: 128.0), + transition: .immediate + ) + context.add(animation + .position(CGPoint(x: context.availableSize.width / 2.0, y: animation.size.height / 2.0 + 25.0)) + ) + originY += animation.size.height + } + originY += 80.0 + if soldOut { + originY -= 12.0 + } + + let linkColor = theme.actionSheet.controlAccentColor + if !descriptionText.isEmpty { + if state.cachedChevronImage == nil || state.cachedChevronImage?.1 !== environment.theme { + state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: linkColor)!, theme) + } + + let textFont = soldOut ? Font.medium(15.0) : Font.regular(15.0) + let textColor = soldOut ? theme.list.itemDestructiveColor : theme.list.itemPrimaryTextColor + let markdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: textFont, textColor: textColor), link: MarkdownAttributeSet(font: textFont, textColor: linkColor), linkAttribute: { contents in + return (TelegramTextAttributes.URL, contents) + }) + let attributedString = parseMarkdownIntoAttributedString(descriptionText, attributes: markdownAttributes, textAlignment: .center).mutableCopy() as! NSMutableAttributedString + if let range = attributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 { + attributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: attributedString.string)) + } + let description = description.update( + component: MultilineTextComponent( + text: .plain(attributedString), + horizontalAlignment: .center, + maximumNumberOfLines: 5, + lineSpacing: 0.2, + highlightColor: linkColor.withAlphaComponent(0.1), + highlightInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: -8.0), + highlightAction: { attributes in + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) + } else { + return nil + } + }, + tapAction: { _, _ in + component.openStarsIntro() + } + ), + availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 60.0, height: CGFloat.greatestFiniteMagnitude), + transition: .immediate + ) + context.add(description + .position(CGPoint(x: context.availableSize.width / 2.0, y: originY + description.size.height / 2.0)) + ) + originY += description.size.height + 21.0 + if soldOut { + originY -= 7.0 + } + } else { + originY += 21.0 + } + + if nameHidden { + let textFont = Font.regular(13.0) + let textColor = theme.list.itemSecondaryTextColor + + let hiddenText = hiddenText.update( + component: MultilineTextComponent( + text: .plain(NSAttributedString(string: text != nil ? strings.Gift_View_NameAndMessageHidden : strings.Gift_View_NameHidden, font: textFont, textColor: textColor)), + horizontalAlignment: .center, + maximumNumberOfLines: 2, + lineSpacing: 0.2 + ), + availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 60.0, height: CGFloat.greatestFiniteMagnitude), + transition: .immediate + ) + context.add(hiddenText + .position(CGPoint(x: context.availableSize.width / 2.0, y: originY)) + ) + + originY += hiddenText.size.height + originY += 11.0 + } + let tableFont = Font.regular(15.0) let tableBoldFont = Font.semibold(15.0) let tableItalicFont = Font.italic(15.0) @@ -489,82 +585,6 @@ private final class GiftViewSheetContent: CombinedComponent { availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: .greatestFiniteMagnitude), transition: .immediate ) - - let linkColor = theme.actionSheet.controlAccentColor - - context.add(title - .position(CGPoint(x: context.availableSize.width / 2.0, y: 177.0)) - ) - - var originY: CGFloat = 0.0 - if let animationFile { - let animation = animation.update( - component: GiftAnimationComponent( - context: component.context, - theme: environment.theme, - file: animationFile - ), - availableSize: CGSize(width: 128.0, height: 128.0), - transition: .immediate - ) - context.add(animation - .position(CGPoint(x: context.availableSize.width / 2.0, y: animation.size.height / 2.0 + 25.0)) - ) - originY += animation.size.height - } - originY += 80.0 - - if soldOut { - originY -= 12.0 - } - - if !descriptionText.isEmpty { - if state.cachedChevronImage == nil || state.cachedChevronImage?.1 !== environment.theme { - state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: linkColor)!, theme) - } - - let textFont = soldOut ? Font.medium(15.0) : Font.regular(15.0) - let textColor = soldOut ? theme.list.itemDestructiveColor : theme.list.itemPrimaryTextColor - let markdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: textFont, textColor: textColor), link: MarkdownAttributeSet(font: textFont, textColor: linkColor), linkAttribute: { contents in - return (TelegramTextAttributes.URL, contents) - }) - let attributedString = parseMarkdownIntoAttributedString(descriptionText, attributes: markdownAttributes, textAlignment: .center).mutableCopy() as! NSMutableAttributedString - if let range = attributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 { - attributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: attributedString.string)) - } - let description = description.update( - component: MultilineTextComponent( - text: .plain(attributedString), - horizontalAlignment: .center, - maximumNumberOfLines: 5, - lineSpacing: 0.2, - highlightColor: linkColor.withAlphaComponent(0.1), - highlightInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: -8.0), - highlightAction: { attributes in - if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { - return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) - } else { - return nil - } - }, - tapAction: { _, _ in - component.openStarsIntro() - } - ), - availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 60.0, height: CGFloat.greatestFiniteMagnitude), - transition: .immediate - ) - context.add(description - .position(CGPoint(x: context.availableSize.width / 2.0, y: originY + description.size.height / 2.0)) - ) - originY += description.size.height + 21.0 - if soldOut { - originY -= 7.0 - } - } else { - originY += 21.0 - } - context.add(table .position(CGPoint(x: context.availableSize.width / 2.0, y: originY + table.size.height / 2.0)) ) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 0338d54c7e..515a0fa010 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -12709,7 +12709,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc self.controllerNode.resetHeaderExpansion() } } else { - self.controllerNode.updateNavigation(transition: .immediate, additive: false, animateHeader: false) + self.controllerNode.updateNavigation(transition: .animated(duration: 0.15, curve: .easeInOut), additive: false, animateHeader: false) } } } diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsStatisticsScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsStatisticsScreen.swift index ee82996b1c..fe094d65b1 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsStatisticsScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsStatisticsScreen.swift @@ -181,8 +181,8 @@ final class StarsStatisticsScreenComponent: Component { super.init(frame: frame) - self.scrollView.delaysContentTouches = true - self.scrollView.canCancelContentTouches = true + self.scrollView.delaysContentTouches = false +// self.scrollView.canCancelContentTouches = true self.scrollView.clipsToBounds = false if #available(iOSApplicationExtension 11.0, iOS 11.0, *) { self.scrollView.contentInsetAdjustmentBehavior = .never @@ -217,6 +217,28 @@ final class StarsStatisticsScreenComponent: Component { self.stateDisposable?.dispose() } + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + guard let result = super.hitTest(point, with: event) else { + return nil + } + var currentParent: UIView? = result + while true { + if currentParent == nil || currentParent === self { + break + } + if let scrollView = currentParent as? UIScrollView { + if scrollView === self.scrollView { + break + } + if scrollView.isDecelerating && scrollView.contentOffset.y < -scrollView.contentInset.top { + return self.scrollView + } + } + currentParent = currentParent?.superview + } + return result + } + func scrollToTop() { self.scrollView.setContentOffset(CGPoint(x: 0.0, y: -self.scrollView.contentInset.top), animated: true) } diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsListPanelComponent.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsListPanelComponent.swift index 23aa277d0f..713d2533f1 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsListPanelComponent.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsListPanelComponent.swift @@ -136,8 +136,8 @@ final class StarsTransactionsListPanelComponent: Component { super.init(frame: frame) - self.scrollView.delaysContentTouches = true - self.scrollView.canCancelContentTouches = true + self.scrollView.delaysContentTouches = false +// self.scrollView.canCancelContentTouches = true self.scrollView.clipsToBounds = false if #available(iOSApplicationExtension 11.0, iOS 11.0, *) { self.scrollView.contentInsetAdjustmentBehavior = .never @@ -164,6 +164,15 @@ final class StarsTransactionsListPanelComponent: Component { self.itemsDisposable?.dispose() } + func scrollToTop() -> Bool { + if self.scrollView.contentOffset.y > 0.0 { + self.scrollView.setContentOffset(CGPoint(), animated: true) + return true + } else { + return false + } + } + func scrollViewDidScroll(_ scrollView: UIScrollView) { if !self.ignoreScrolling { self.updateScrolling(transition: .immediate) diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsPanelContainerComponent.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsPanelContainerComponent.swift index c35e7e9619..89f1e91ccb 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsPanelContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsPanelContainerComponent.swift @@ -610,6 +610,13 @@ final class StarsTransactionsPanelContainerComponent: Component { } } + func scrollToTop() -> Bool { + if let currentPanelView = self.currentPanelView as? StarsTransactionsListPanelComponent.View { + return currentPanelView.scrollToTop() + } + return false + } + func update(component: StarsTransactionsPanelContainerComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { let environment = environment[StarsTransactionsPanelContainerEnvironment.self].value diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift index 870009686b..276716b6cb 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift @@ -152,8 +152,8 @@ final class StarsTransactionsScreenComponent: Component { super.init(frame: frame) - self.scrollView.delaysContentTouches = true - self.scrollView.canCancelContentTouches = true + self.scrollView.delaysContentTouches = false +// self.scrollView.canCancelContentTouches = true self.scrollView.clipsToBounds = false if #available(iOSApplicationExtension 11.0, iOS 11.0, *) { self.scrollView.contentInsetAdjustmentBehavior = .never @@ -185,21 +185,44 @@ final class StarsTransactionsScreenComponent: Component { self.stateDisposable?.dispose() } + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + guard let result = super.hitTest(point, with: event) else { + return nil + } + var currentParent: UIView? = result + while true { + if currentParent == nil || currentParent === self { + break + } + if let scrollView = currentParent as? UIScrollView { + if scrollView === self.scrollView { + break + } + if scrollView.isDecelerating && scrollView.contentOffset.y < -scrollView.contentInset.top { + return self.scrollView + } + } + currentParent = currentParent?.superview + } + return result + } + func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { self.enableVelocityTracking = true } func scrollViewDidScroll(_ scrollView: UIScrollView) { - if !self.ignoreScrolling { - if self.enableVelocityTracking { - self.previousVelocityM1 = self.previousVelocity - if let value = (scrollView.value(forKey: (["_", "verticalVelocity"] as [String]).joined()) as? NSNumber)?.doubleValue { - self.previousVelocity = CGFloat(value) - } - } - - self.updateScrolling(transition: .immediate) + guard !self.ignoreScrolling else { + return } + if self.enableVelocityTracking { + self.previousVelocityM1 = self.previousVelocity + if let value = (scrollView.value(forKey: (["_", "verticalVelocity"] as [String]).joined()) as? NSNumber)?.doubleValue { + self.previousVelocity = CGFloat(value) + } + } + + self.updateScrolling(transition: .immediate) } func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { @@ -229,6 +252,12 @@ final class StarsTransactionsScreenComponent: Component { self.previousVelocityM1 = 0.0 } } + + func scrollToTop() { + if let panelContainerView = self.panelContainer.view as? StarsTransactionsPanelContainerComponent.View, !panelContainerView.scrollToTop() { + self.scrollView.setContentOffset(.zero, animated: true) + } + } private func updateScrolling(transition: ComponentTransition) { let scrollBounds = self.scrollView.bounds @@ -1124,6 +1153,15 @@ public final class StarsTransactionsScreen: ViewControllerComponentContainer { self.starsContext.load(force: false) self.subscriptionsContext.loadMore() + + self.scrollToTop = { [weak self] in + guard let self else { + return + } + if let componentView = self.node.hostView.componentView as? StarsTransactionsScreenComponent.View { + componentView.scrollToTop() + } + } } required public init(coder aDecoder: NSCoder) { diff --git a/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift b/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift index 45352322e2..53130d45e0 100644 --- a/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift +++ b/submodules/TelegramUI/Components/StorageUsageScreen/Sources/StorageUsageScreen.swift @@ -865,6 +865,28 @@ final class StorageUsageScreenComponent: Component { self.keepScreenActiveDisposable?.dispose() } + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + guard let result = super.hitTest(point, with: event) else { + return nil + } + var currentParent: UIView? = result + while true { + if currentParent == nil || currentParent === self { + break + } + if let scrollView = currentParent as? UIScrollView { + if scrollView === self.scrollView { + break + } + if scrollView.isDecelerating && scrollView.contentOffset.y < -scrollView.contentInset.top { + return self.scrollView + } + } + currentParent = currentParent?.superview + } + return result + } + func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { self.enableVelocityTracking = true } diff --git a/submodules/TelegramUI/Sources/ChatAdPanelNode.swift b/submodules/TelegramUI/Sources/ChatAdPanelNode.swift index 7c4de5a295..9005f206b8 100644 --- a/submodules/TelegramUI/Sources/ChatAdPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatAdPanelNode.swift @@ -124,19 +124,31 @@ final class ChatAdPanelNode: ASDisplayNode { self.tapButton.highligthedChanged = { [weak self] highlighted in if let strongSelf = self { if highlighted { + strongSelf.adNode.layer.removeAnimation(forKey: "opacity") + strongSelf.adNode.alpha = 0.4 strongSelf.titleNode.layer.removeAnimation(forKey: "opacity") strongSelf.titleNode.alpha = 0.4 strongSelf.textNode.textNode.layer.removeAnimation(forKey: "opacity") strongSelf.textNode.textNode.alpha = 0.4 strongSelf.imageNode.layer.removeAnimation(forKey: "opacity") strongSelf.imageNode.alpha = 0.4 + strongSelf.removeTextNode.layer.removeAnimation(forKey: "opacity") + strongSelf.removeTextNode.alpha = 0.4 + strongSelf.removeBackgroundNode.layer.removeAnimation(forKey: "opacity") + strongSelf.removeBackgroundNode.alpha = 0.4 } else { + strongSelf.adNode.alpha = 1.0 + strongSelf.adNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) strongSelf.titleNode.alpha = 1.0 strongSelf.titleNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) strongSelf.textNode.textNode.alpha = 1.0 strongSelf.textNode.textNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) strongSelf.imageNode.alpha = 1.0 strongSelf.imageNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) + strongSelf.removeTextNode.alpha = 1.0 + strongSelf.removeTextNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) + strongSelf.removeBackgroundNode.alpha = 1.0 + strongSelf.removeBackgroundNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) } } } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index d2c6cec8d4..0abb065708 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -4279,6 +4279,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G adOpaqueId = adAttribute.opaqueId } } + if adOpaqueId == nil, let panelMessage = self.chatDisplayNode.adPanelNode?.message, let adAttribute = panelMessage.adAttribute { + adOpaqueId = adAttribute.opaqueId + } let _ = self.context.engine.accountData.updateAdMessagesEnabled(enabled: false).start() if let adOpaqueId { self.removeAd(opaqueId: adOpaqueId) @@ -5542,7 +5545,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G adMessage ).startStrict(next: { [weak self] peerView, globalNotificationSettings, onlineMemberCount, hasScheduledMessages, peerReportNotice, pinnedCount, threadInfo, hasSearchTags, hasSavedChats, isPremiumRequiredForMessaging, managingBot, adMessage in if let strongSelf = self { - if strongSelf.peerView === peerView && strongSelf.reportIrrelvantGeoNotice == peerReportNotice && strongSelf.hasScheduledMessages == hasScheduledMessages && strongSelf.threadInfo == threadInfo && strongSelf.presentationInterfaceState.hasSearchTags == hasSearchTags && strongSelf.presentationInterfaceState.hasSavedChats == hasSavedChats && strongSelf.presentationInterfaceState.isPremiumRequiredForMessaging == isPremiumRequiredForMessaging && managingBot == strongSelf.presentationInterfaceState.contactStatus?.managingBot { + if strongSelf.peerView === peerView && strongSelf.reportIrrelvantGeoNotice == peerReportNotice && strongSelf.hasScheduledMessages == hasScheduledMessages && strongSelf.threadInfo == threadInfo && strongSelf.presentationInterfaceState.hasSearchTags == hasSearchTags && strongSelf.presentationInterfaceState.hasSavedChats == hasSavedChats && strongSelf.presentationInterfaceState.isPremiumRequiredForMessaging == isPremiumRequiredForMessaging && managingBot == strongSelf.presentationInterfaceState.contactStatus?.managingBot && adMessage?.id == strongSelf.presentationInterfaceState.adMessage?.id { return } @@ -5828,11 +5831,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } var adMessage = adMessage - if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramUser, peer.botInfo != nil { + if let peer = peerView.peers[peerView.peerId] as? TelegramUser, peer.botInfo != nil { } else { adMessage = nil } + if strongSelf.presentationInterfaceState.adMessage?.id != adMessage?.id { + animated = true + } + strongSelf.updateChatPresentationInterfaceState(animated: animated, interactive: false, { return $0.updatedPeer { _ in return renderedPeer diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 48edaa17be..0b8f034d5e 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -1432,21 +1432,32 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { var dismissedAdPanelNode: ChatAdPanelNode? var adPanelHeight: CGFloat? if let _ = self.chatPresentationInterfaceState.adMessage { + var animateAppearance = false let adPanelNode: ChatAdPanelNode if let current = self.adPanelNode { adPanelNode = current } else { adPanelNode = ChatAdPanelNode(context: self.context, animationCache: self.controllerInteraction.presentationContext.animationCache, animationRenderer: self.controllerInteraction.presentationContext.animationRenderer) adPanelNode.controllerInteraction = self.controllerInteraction + adPanelNode.clipsToBounds = true + animateAppearance = true } if self.adPanelNode != adPanelNode { dismissedAdPanelNode = self.adPanelNode self.adPanelNode = adPanelNode - self.contentContainerNode.contentNode.addSubnode(adPanelNode) + self.titleAccessoryPanelContainer.addSubnode(adPanelNode) + + adPanelNode.clipsToBounds = true } - adPanelHeight = adPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: transition, interfaceState: self.chatPresentationInterfaceState) + let height = adPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: transition, interfaceState: self.chatPresentationInterfaceState) + adPanelHeight = height + if transition.isAnimated && animateAppearance { + adPanelNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + adPanelNode.subnodeTransform = CATransform3DMakeTranslation(0.0, -height, 0.0) + transition.updateSublayerTransformOffset(layer: adPanelNode.layer, offset: CGPoint()) + } } else if let adPanelNode = self.adPanelNode { dismissedAdPanelNode = adPanelNode self.adPanelNode = nil @@ -1759,7 +1770,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { var adPanelFrame: CGRect? if let _ = self.adPanelNode, let panelHeight = adPanelHeight { - adPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: panelHeight)) + adPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: extraNavigationBarHeight), size: CGSize(width: layout.size.width, height: panelHeight)) insets.top += panelHeight extraNavigationBarHeight += panelHeight } @@ -2212,12 +2223,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { } if let adPanelNode = self.adPanelNode, let adPanelFrame, !adPanelNode.frame.equalTo(adPanelFrame) { - if adPanelNode.frame.width.isZero { - adPanelNode.frame = adPanelFrame - transition.animatePositionAdditive(node: adPanelNode, offset: CGPoint(x: 0.0, y: -adPanelFrame.height)) - } else { - transition.updateFrame(node: adPanelNode, frame: adPanelFrame) - } + adPanelNode.frame = adPanelFrame } if let secondaryInputPanelNode = self.secondaryInputPanelNode, let apparentSecondaryInputPanelFrame = apparentSecondaryInputPanelFrame, !secondaryInputPanelNode.frame.equalTo(apparentSecondaryInputPanelFrame) { @@ -2339,6 +2345,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { if let dismissedAdPanelNode { var dismissedPanelFrame = dismissedAdPanelNode.frame dismissedPanelFrame.origin.y = -dismissedPanelFrame.size.height + transition.updateAlpha(node: dismissedAdPanelNode, alpha: 0.0) transition.updateFrame(node: dismissedAdPanelNode, frame: dismissedPanelFrame, completion: { [weak dismissedAdPanelNode] _ in dismissedAdPanelNode?.removeFromSupernode() }) diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 00a8b74b8b..5d53b73751 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -351,8 +351,7 @@ private func extractAssociatedData( chatThemes: [TelegramTheme], deviceContactsNumbers: Set, isInline: Bool, - showSensitiveContent: Bool, - starGifts: [Int64 : TelegramMediaFile] + showSensitiveContent: Bool ) -> ChatMessageItemAssociatedData { var automaticDownloadPeerId: EnginePeer.Id? var automaticMediaDownloadPeerType: MediaAutoDownloadPeerType = .channel @@ -407,7 +406,7 @@ private func extractAssociatedData( automaticDownloadPeerId = message.peerId } - return ChatMessageItemAssociatedData(automaticDownloadPeerType: automaticMediaDownloadPeerType, automaticDownloadPeerId: automaticDownloadPeerId, automaticDownloadNetworkType: automaticDownloadNetworkType, preferredStoryHighQuality: preferredStoryHighQuality, isRecentActions: false, subject: subject, contactsPeerIds: contactsPeerIds, channelDiscussionGroup: channelDiscussionGroup, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, currentlyPlayingMessageId: currentlyPlayingMessageId, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, availableMessageEffects: availableMessageEffects, savedMessageTags: savedMessageTags, defaultReaction: defaultReaction, isPremium: isPremium, accountPeer: accountPeer, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, topicAuthorId: topicAuthorId, hasBots: hasBots, translateToLanguage: translateToLanguage, maxReadStoryId: maxReadStoryId, recommendedChannels: recommendedChannels, audioTranscriptionTrial: audioTranscriptionTrial, chatThemes: chatThemes, deviceContactsNumbers: deviceContactsNumbers, isInline: isInline, showSensitiveContent: showSensitiveContent, starGifts: starGifts) + return ChatMessageItemAssociatedData(automaticDownloadPeerType: automaticMediaDownloadPeerType, automaticDownloadPeerId: automaticDownloadPeerId, automaticDownloadNetworkType: automaticDownloadNetworkType, preferredStoryHighQuality: preferredStoryHighQuality, isRecentActions: false, subject: subject, contactsPeerIds: contactsPeerIds, channelDiscussionGroup: channelDiscussionGroup, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, currentlyPlayingMessageId: currentlyPlayingMessageId, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, availableMessageEffects: availableMessageEffects, savedMessageTags: savedMessageTags, defaultReaction: defaultReaction, isPremium: isPremium, accountPeer: accountPeer, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, topicAuthorId: topicAuthorId, hasBots: hasBots, translateToLanguage: translateToLanguage, maxReadStoryId: maxReadStoryId, recommendedChannels: recommendedChannels, audioTranscriptionTrial: audioTranscriptionTrial, chatThemes: chatThemes, deviceContactsNumbers: deviceContactsNumbers, isInline: isInline, showSensitiveContent: showSensitiveContent) } private extension ChatHistoryLocationInput { @@ -777,13 +776,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto } var adMessages: Signal<(interPostInterval: Int32?, messages: [Message]), NoError> if case .bubbles = mode, let peerId = displayAdPeer { - var effectivePeerId = peerId -#if DEBUG - if peerId.namespace == Namespaces.Peer.CloudUser && peerId.id._internalGetInt64Value() == 784496 { - effectivePeerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(8000911878)) - } -#endif - let adMessagesContext = context.engine.messages.adMessages(peerId: effectivePeerId) + let adMessagesContext = context.engine.messages.adMessages(peerId: peerId) self.adMessagesContext = adMessagesContext if peerId.namespace == Namespaces.Peer.CloudUser { adMessages = .single((nil, [])) @@ -1621,17 +1614,6 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto } |> distinctUntilChanged - let starGifts: Signal<[Int64 : TelegramMediaFile], NoError> = context.engine.payments.cachedStarGifts() - |> map { gifts in - var files: [Int64 : TelegramMediaFile] = [:] - if let gifts { - for gift in gifts { - files[gift.id] = gift.file - } - } - return files - } - let messageViewQueue = Queue.mainQueue() let historyViewTransitionDisposable = combineLatest(queue: messageViewQueue, historyViewUpdate, @@ -1658,9 +1640,8 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto audioTranscriptionTrial, chatThemes, deviceContactsNumbers, - contentSettings, - starGifts - ).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, preferredStoryHighQuality, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, availableMessageEffects, savedMessageTags, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, translationState, maxReadStoryId, recommendedChannels, audioTranscriptionTrial, chatThemes, deviceContactsNumbers, contentSettings, starGifts in + contentSettings + ).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, preferredStoryHighQuality, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, availableMessageEffects, savedMessageTags, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, translationState, maxReadStoryId, recommendedChannels, audioTranscriptionTrial, chatThemes, deviceContactsNumbers, contentSettings in let (historyAppearsCleared, pendingUnpinnedAllMessages, pendingRemovedMessages, currentlyPlayingMessageIdAndType, scrollToMessageId, chatHasBots, allAdMessages) = promises func applyHole() { @@ -1874,7 +1855,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto translateToLanguage = normalizeTranslationLanguage(languageCode) } - let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType, preferredStoryHighQuality: preferredStoryHighQuality, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, subject: subject, currentlyPlayingMessageId: currentlyPlayingMessageIdAndType?.0, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, availableMessageEffects: availableMessageEffects, savedMessageTags: savedMessageTags, defaultReaction: defaultReaction, isPremium: isPremium, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, accountPeer: accountPeer, topicAuthorId: topicAuthorId, hasBots: chatHasBots, translateToLanguage: translateToLanguage, maxReadStoryId: maxReadStoryId, recommendedChannels: recommendedChannels, audioTranscriptionTrial: audioTranscriptionTrial, chatThemes: chatThemes, deviceContactsNumbers: deviceContactsNumbers, isInline: !rotated, showSensitiveContent: contentSettings.ignoreContentRestrictionReasons.contains("sensitive"), starGifts: starGifts) + let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType, preferredStoryHighQuality: preferredStoryHighQuality, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, subject: subject, currentlyPlayingMessageId: currentlyPlayingMessageIdAndType?.0, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, availableMessageEffects: availableMessageEffects, savedMessageTags: savedMessageTags, defaultReaction: defaultReaction, isPremium: isPremium, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, accountPeer: accountPeer, topicAuthorId: topicAuthorId, hasBots: chatHasBots, translateToLanguage: translateToLanguage, maxReadStoryId: maxReadStoryId, recommendedChannels: recommendedChannels, audioTranscriptionTrial: audioTranscriptionTrial, chatThemes: chatThemes, deviceContactsNumbers: deviceContactsNumbers, isInline: !rotated, showSensitiveContent: contentSettings.ignoreContentRestrictionReasons.contains("sensitive")) var includeEmbeddedSavedChatInfo = false if case let .replyThread(message) = chatLocation, message.peerId == context.account.peerId, !rotated {