diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 8eb9165453..accd40bc2e 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -12548,6 +12548,11 @@ Sorry for the inconvenience."; "WebBrowser.LinkForwardTooltip.ManyChats.One" = "Link forwarded to **%@** and %@ others"; "WebBrowser.LinkForwardTooltip.SavedMessages.One" = "Link forwarded to **Saved Messages**"; +"WebBrowser.FileForwardTooltip.Chat.One" = "Document forwarded to **%@**"; +"WebBrowser.FileForwardTooltip.TwoChats.One" = "Document forwarded to **%@** and **%@**"; +"WebBrowser.FileForwardTooltip.ManyChats.One" = "Document forwarded to **%@** and %@ others"; +"WebBrowser.FileForwardTooltip.SavedMessages.One" = "Document forwarded to **Saved Messages**"; + "Stars.Intro.StarsSent_1" = "%@ Star sent."; "Stars.Intro.StarsSent_any" = "%@ Stars sent."; "Stars.Intro.StarsSent.ViewChat" = "View Chat"; @@ -12753,6 +12758,10 @@ Sorry for the inconvenience."; "SensitiveContent.ViewAnyway" = "View Anyway"; "SensitiveContent.SettingsInfo" = "You can update the visibility of sensitive media in [Data and Storage > Show 18+ Content]()."; +"SensitiveContent.Enable.Title" = "18+ Content"; +"SensitiveContent.Enable.Text" = "Confirm that you are over 18 years old and update settings to see potentially explicit and sensitive content."; +"SensitiveContent.Enable.Confirm" = "Confirm"; + "Notification.Refund" = "You received a refund of {amount} from {name}"; "InviteLink.SubscriptionFee.Title" = "SUBSCRIPTION FEE"; diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 58145b36b1..0168008557 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -1006,8 +1006,8 @@ public protocol SharedAccountContext: AnyObject { func makeStarsTransactionsScreen(context: AccountContext, starsContext: StarsContext) -> ViewController func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [Any], purpose: StarsPurchasePurpose, completion: @escaping (Int64) -> Void) -> ViewController - func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController - func makeStarsSubscriptionTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, link: String, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void) -> ViewController + func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController + func makeStarsSubscriptionTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, link: String, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void) -> ViewController func makeStarsTransactionScreen(context: AccountContext, transaction: StarsContext.State.Transaction, peer: EnginePeer) -> ViewController func makeStarsReceiptScreen(context: AccountContext, receipt: BotPaymentReceipt) -> ViewController func makeStarsSubscriptionScreen(context: AccountContext, subscription: StarsContext.State.Subscription, update: @escaping (Bool) -> Void) -> ViewController diff --git a/submodules/BrowserUI/Sources/BrowserDocumentContent.swift b/submodules/BrowserUI/Sources/BrowserDocumentContent.swift index c84adeee08..065eb5180d 100644 --- a/submodules/BrowserUI/Sources/BrowserDocumentContent.swift +++ b/submodules/BrowserUI/Sources/BrowserDocumentContent.swift @@ -20,6 +20,7 @@ import UrlEscaping final class BrowserDocumentContent: UIView, BrowserContent, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate { private let context: AccountContext private var presentationData: PresentationData + let file: TelegramMediaFile private let webView: WKWebView @@ -50,6 +51,7 @@ final class BrowserDocumentContent: UIView, BrowserContent, WKNavigationDelegate self.context = context self.uuid = UUID() self.presentationData = presentationData + self.file = file let configuration = WKWebViewConfiguration() self.webView = WKWebView(frame: CGRect(), configuration: configuration) diff --git a/submodules/BrowserUI/Sources/BrowserPdfContent.swift b/submodules/BrowserUI/Sources/BrowserPdfContent.swift index ce4d5b7b89..780678c4d6 100644 --- a/submodules/BrowserUI/Sources/BrowserPdfContent.swift +++ b/submodules/BrowserUI/Sources/BrowserPdfContent.swift @@ -20,6 +20,7 @@ import PDFKit final class BrowserPdfContent: UIView, BrowserContent, UIScrollViewDelegate, PDFDocumentDelegate { private let context: AccountContext private var presentationData: PresentationData + let file: TelegramMediaFile private let pdfView: PDFView private let scrollView: UIScrollView! @@ -51,6 +52,7 @@ final class BrowserPdfContent: UIView, BrowserContent, UIScrollViewDelegate, PDF self.context = context self.uuid = UUID() self.presentationData = presentationData + self.file = file self.pdfView = PDFView() diff --git a/submodules/BrowserUI/Sources/BrowserScreen.swift b/submodules/BrowserUI/Sources/BrowserScreen.swift index e551a654e9..16bd42554c 100644 --- a/submodules/BrowserUI/Sources/BrowserScreen.swift +++ b/submodules/BrowserUI/Sources/BrowserScreen.swift @@ -562,7 +562,22 @@ public class BrowserScreen: ViewController, MinimizableController { content.navigateForward() case .share: let presentationData = self.presentationData - let shareController = ShareController(context: self.context, subject: .url(url)) + let subject: ShareControllerSubject + var isDocument = false + if let content = self.content.last { + if let documentContent = content as? BrowserDocumentContent { + subject = .media(.standalone(media: documentContent.file)) + isDocument = true + } else if let documentContent = content as? BrowserPdfContent { + subject = .media(.standalone(media: documentContent.file)) + isDocument = true + } else { + subject = .url(url) + } + } else { + subject = .url(url) + } + let shareController = ShareController(context: self.context, subject: subject) shareController.completed = { [weak self] peerIds in guard let strongSelf = self else { return @@ -582,20 +597,21 @@ public class BrowserScreen: ViewController, MinimizableController { let text: String var savedMessages = false - if peerIds.count == 1, let peerId = peerIds.first, peerId == strongSelf.context.account.peerId { + if peerIds.count == 1, let peerId = peerIds.first, peerId == strongSelf.context.account.peerId && !isDocument { text = presentationData.strings.WebBrowser_LinkAddedToBookmarks savedMessages = true } else { if peers.count == 1, let peer = peers.first { let peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) - text = presentationData.strings.WebBrowser_LinkForwardTooltip_Chat_One(peerName).string + text = isDocument ? presentationData.strings.WebBrowser_FileForwardTooltip_Chat_One(peerName).string : presentationData.strings.WebBrowser_LinkForwardTooltip_Chat_One(peerName).string + savedMessages = peer.id == strongSelf.context.account.peerId } else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last { let firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) let secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) - text = presentationData.strings.WebBrowser_LinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string + text = isDocument ? presentationData.strings.WebBrowser_FileForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.WebBrowser_LinkForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string } else if let peer = peers.first { let peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) - text = presentationData.strings.WebBrowser_LinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string + text = isDocument ? presentationData.strings.WebBrowser_FileForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string : presentationData.strings.WebBrowser_LinkForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string } else { text = "" } @@ -1444,6 +1460,17 @@ public class BrowserScreen: ViewController, MinimizableController { "application/vnd.openxmlformats-officedocument.presentationml.presentation" ] + public static let supportedDocumentExtensions: [String] = [ + "txt", + "rtf", + "pdf", + "doc", + "docx", + "xls", + "xlsx", + "pptx" + ] + public init(context: AccountContext, subject: Subject, preferredConfiguration: WKWebViewConfiguration? = nil, openPreviousOnClose: Bool = false) { var subject = subject if case let .webPage(url) = subject, let parsedUrl = URL(string: url) { diff --git a/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift b/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift index abb4d86c6c..cdafe9a37c 100644 --- a/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift +++ b/submodules/PlatformRestrictionMatching/Sources/PlatformRestrictionMatching.swift @@ -20,7 +20,7 @@ public extension Message { public extension RestrictedContentMessageAttribute { func platformText(platform: String, contentSettings: ContentSettings) -> String? { for rule in self.rules { - if rule.isSensitive { + if rule.reason == "sensitive" { continue } if rule.platform == "all" || rule.platform == "ios" || contentSettings.addContentRestrictionReasons.contains(rule.platform) { diff --git a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift index 72496f4c82..8ab3cdc71c 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift @@ -13,6 +13,7 @@ import AccountContext import OpenInExternalAppUI import ItemListPeerActionItem import StorageUsageScreen +import PresentationDataUtils public enum AutomaticSaveIncomingPeerType { case privateChats @@ -35,7 +36,6 @@ private final class DataAndStorageControllerArguments { let openBrowserSelection: () -> Void let openIntents: () -> Void let toggleSensitiveContent: (Bool) -> Void - let toggleOtherSensitiveContent: (Bool) -> Void init( openStorageUsage: @escaping () -> Void, @@ -51,8 +51,7 @@ private final class DataAndStorageControllerArguments { toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, - toggleSensitiveContent: @escaping (Bool) -> Void, - toggleOtherSensitiveContent: @escaping (Bool) -> Void + toggleSensitiveContent: @escaping (Bool) -> Void ) { self.openStorageUsage = openStorageUsage self.openNetworkUsage = openNetworkUsage @@ -68,7 +67,6 @@ private final class DataAndStorageControllerArguments { self.openBrowserSelection = openBrowserSelection self.openIntents = openIntents self.toggleSensitiveContent = toggleSensitiveContent - self.toggleOtherSensitiveContent = toggleOtherSensitiveContent } } @@ -81,7 +79,6 @@ private enum DataAndStorageSection: Int32 { case other case connection case sensitiveContent - case otherSensitiveContent } public enum DataAndStorageEntryTag: ItemListItemTag, Equatable { @@ -132,7 +129,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry { case connectionHeader(PresentationTheme, String) case connectionProxy(PresentationTheme, String, String) - case otherSensitiveContent(String, Bool) var section: ItemListSectionId { switch self { @@ -152,8 +148,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return DataAndStorageSection.sensitiveContent.rawValue case .connectionHeader, .connectionProxy: return DataAndStorageSection.connection.rawValue - case .otherSensitiveContent: - return DataAndStorageSection.otherSensitiveContent.rawValue } } @@ -207,8 +201,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return 38 case .connectionProxy: return 39 - case .otherSensitiveContent: - return 40 } } @@ -358,12 +350,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry { } else { return false } - case let .otherSensitiveContent(text, value): - if case .otherSensitiveContent(text, value) = rhs { - return true - } else { - return false - } } } @@ -450,7 +436,7 @@ private enum DataAndStorageEntry: ItemListNodeEntry { case let .raiseToListenInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section) case let .sensitiveContent(text, value): - return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in + return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: false, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleSensitiveContent(value) }, tag: DataAndStorageEntryTag.sensitiveContent) case let .sensitiveContentInfo(text): @@ -467,10 +453,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openProxy() }) - case let .otherSensitiveContent(text, value): - return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in - arguments.toggleOtherSensitiveContent(value) - }, tag: nil) } } } @@ -674,8 +656,10 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat entries.append(.raiseToListen(presentationData.theme, presentationData.strings.Settings_RaiseToListen, data.mediaInputSettings.enableRaiseToSpeak)) entries.append(.raiseToListenInfo(presentationData.theme, presentationData.strings.Settings_RaiseToListenInfo)) - entries.append(.sensitiveContent(presentationData.strings.Settings_SensitiveContent, mediaSettings.showSensitiveContent)) - entries.append(.sensitiveContentInfo(presentationData.strings.Settings_SensitiveContentInfo)) + if let contentSettingsConfiguration = contentSettingsConfiguration, contentSettingsConfiguration.canAdjustSensitiveContent { + entries.append(.sensitiveContent(presentationData.strings.Settings_SensitiveContent, contentSettingsConfiguration.sensitiveContentEnabled)) + entries.append(.sensitiveContentInfo(presentationData.strings.Settings_SensitiveContentInfo)) + } let proxyValue: String if let proxySettings = data.proxySettings, let activeServer = proxySettings.activeServer, proxySettings.enabled { @@ -690,13 +674,7 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat } entries.append(.connectionHeader(presentationData.theme, presentationData.strings.ChatSettings_ConnectionType_Title.uppercased())) entries.append(.connectionProxy(presentationData.theme, presentationData.strings.SocksProxySetup_Title, proxyValue)) - - #if DEBUG - if let contentSettingsConfiguration = contentSettingsConfiguration, contentSettingsConfiguration.canAdjustSensitiveContent { - entries.append(.otherSensitiveContent("Display Sensitive Content", contentSettingsConfiguration.sensitiveContentEnabled)) - } - #endif - + return entries } @@ -923,19 +901,29 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da let controller = intentsSettingsController(context: context) pushControllerImpl?(controller) }, toggleSensitiveContent: { value in - let _ = updateMediaDisplaySettingsInteractively(accountManager: context.sharedContext.accountManager, { - $0.withUpdatedShowSensitiveContent(value) - }).startStandalone() - }, toggleOtherSensitiveContent: { value in - let _ = (contentSettingsConfiguration.get() - |> take(1) - |> deliverOnMainQueue).start(next: { [weak contentSettingsConfiguration] settings in - if var settings = settings { - settings.sensitiveContentEnabled = value - contentSettingsConfiguration?.set(.single(settings)) - } - }) - updateSensitiveContentDisposable.set(updateRemoteContentSettingsConfiguration(postbox: context.account.postbox, network: context.account.network, sensitiveContentEnabled: value).start()) + let update = { + let _ = (contentSettingsConfiguration.get() + |> take(1) + |> deliverOnMainQueue).start(next: { [weak contentSettingsConfiguration] settings in + if var settings = settings { + settings.sensitiveContentEnabled = value + contentSettingsConfiguration?.set(.single(settings)) + } + }) + updateSensitiveContentDisposable.set(updateRemoteContentSettingsConfiguration(postbox: context.account.postbox, network: context.account.network, sensitiveContentEnabled: value).start()) + } + if value { + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + let alertController = textAlertController(context: context, title: presentationData.strings.SensitiveContent_Enable_Title, text: presentationData.strings.SensitiveContent_Enable_Text, actions: [ + TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), + TextAlertAction(type: .defaultAction, title: presentationData.strings.SensitiveContent_Enable_Confirm, action: { + update() + }) + ]) + presentControllerImpl?(alertController, nil) + } else { + update() + } }) let preferencesKey: PostboxViewKey = .preferences(keys: Set([ApplicationSpecificPreferencesKeys.mediaAutoSaveSettings])) @@ -955,6 +943,8 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da )) } + let sensitiveContent = Atomic(value: nil) + let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), @@ -979,8 +969,14 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da defaultWebBrowser = presentationData.strings.WebBrowser_Telegram } + let previousSensitiveContent = sensitiveContent.swap(contentSettingsConfiguration?.sensitiveContentEnabled) + var animateChanges = false + if previousSensitiveContent != contentSettingsConfiguration?.sensitiveContentEnabled { + animateChanges = true + } + let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.ChatSettings_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: dataAndStorageControllerEntries(state: state, data: dataAndStorageData, presentationData: presentationData, defaultWebBrowser: defaultWebBrowser, contentSettingsConfiguration: contentSettingsConfiguration, networkUsage: usageSignal.network, storageUsage: usageSignal.storage, mediaAutoSaveSettings: mediaAutoSaveSettings, autosaveExceptionPeers: autosaveExceptionPeers, mediaSettings: mediaSettings), style: .blocks, ensureVisibleItemTag: focusOnItemTag, emptyStateItem: nil, animateChanges: false) + let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: dataAndStorageControllerEntries(state: state, data: dataAndStorageData, presentationData: presentationData, defaultWebBrowser: defaultWebBrowser, contentSettingsConfiguration: contentSettingsConfiguration, networkUsage: usageSignal.network, storageUsage: usageSignal.storage, mediaAutoSaveSettings: mediaAutoSaveSettings, autosaveExceptionPeers: autosaveExceptionPeers, mediaSettings: mediaSettings), style: .blocks, ensureVisibleItemTag: focusOnItemTag, emptyStateItem: nil, animateChanges: animateChanges) return (controllerState, (listState, arguments)) } |> afterDisposed { diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 1483814ea2..0eeb02d587 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -803,7 +803,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1929860175] = { return Api.RequestedPeer.parse_requestedPeerChat($0) } dict[-701500310] = { return Api.RequestedPeer.parse_requestedPeerUser($0) } dict[-797791052] = { return Api.RestrictionReason.parse_restrictionReason($0) } - dict[2007669447] = { return Api.RestrictionReason.parse_restrictionReasonSensitive($0) } dict[894777186] = { return Api.RichText.parse_textAnchor($0) } dict[1730456516] = { return Api.RichText.parse_textBold($0) } dict[2120376535] = { return Api.RichText.parse_textConcat($0) } diff --git a/submodules/TelegramApi/Sources/Api21.swift b/submodules/TelegramApi/Sources/Api21.swift index f7bb2d7515..73eedd5544 100644 --- a/submodules/TelegramApi/Sources/Api21.swift +++ b/submodules/TelegramApi/Sources/Api21.swift @@ -397,7 +397,6 @@ public extension Api { public extension Api { enum RestrictionReason: TypeConstructorDescription { case restrictionReason(platform: String, reason: String, text: String) - case restrictionReasonSensitive(platform: String) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -409,12 +408,6 @@ public extension Api { serializeString(reason, buffer: buffer, boxed: false) serializeString(text, buffer: buffer, boxed: false) break - case .restrictionReasonSensitive(let platform): - if boxed { - buffer.appendInt32(2007669447) - } - serializeString(platform, buffer: buffer, boxed: false) - break } } @@ -422,8 +415,6 @@ public extension Api { switch self { case .restrictionReason(let platform, let reason, let text): return ("restrictionReason", [("platform", platform as Any), ("reason", reason as Any), ("text", text as Any)]) - case .restrictionReasonSensitive(let platform): - return ("restrictionReasonSensitive", [("platform", platform as Any)]) } } @@ -444,17 +435,6 @@ public extension Api { return nil } } - public static func parse_restrictionReasonSensitive(_ reader: BufferReader) -> RestrictionReason? { - var _1: String? - _1 = parseString(reader) - let _c1 = _1 != nil - if _c1 { - return Api.RestrictionReason.restrictionReasonSensitive(platform: _1!) - } - else { - return nil - } - } } } diff --git a/submodules/TelegramCore/Sources/ApiUtils/PeerAccessRestrictionInfo.swift b/submodules/TelegramCore/Sources/ApiUtils/PeerAccessRestrictionInfo.swift index 69c164dcab..ec42c80376 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/PeerAccessRestrictionInfo.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/PeerAccessRestrictionInfo.swift @@ -8,8 +8,6 @@ extension RestrictionRule { switch apiReason { case let .restrictionReason(platform, reason, text): self.init(platform: platform, reason: reason, text: text) - case let .restrictionReasonSensitive(platform): - self.init(platform: platform) } } } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_PeerAccessRestrictionInfo.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_PeerAccessRestrictionInfo.swift index a7de5ef3ee..509aa85c8d 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_PeerAccessRestrictionInfo.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_PeerAccessRestrictionInfo.swift @@ -4,34 +4,29 @@ public final class RestrictionRule: PostboxCoding, Equatable { public let platform: String public let reason: String public let text: String - public let isSensitive: Bool public init(platform: String, reason: String, text: String) { self.platform = platform self.reason = reason self.text = text - self.isSensitive = false } public init(platform: String) { self.platform = platform self.reason = "" self.text = "" - self.isSensitive = true } public init(decoder: PostboxDecoder) { self.platform = decoder.decodeStringForKey("p", orElse: "all") self.reason = decoder.decodeStringForKey("r", orElse: "") self.text = decoder.decodeStringForKey("t", orElse: "") - self.isSensitive = decoder.decodeBoolForKey("s", orElse: false) } public func encode(_ encoder: PostboxEncoder) { encoder.encodeString(self.platform, forKey: "p") encoder.encodeString(self.reason, forKey: "r") encoder.encodeString(self.text, forKey: "t") - encoder.encodeBool(self.isSensitive, forKey: "s") } public static func ==(lhs: RestrictionRule, rhs: RestrictionRule) -> Bool { @@ -44,9 +39,6 @@ public final class RestrictionRule: PostboxCoding, Equatable { if lhs.text != rhs.text { return false } - if lhs.isSensitive != rhs.isSensitive { - return false - } return true } } diff --git a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift index 11f798d64b..acc484da19 100644 --- a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift @@ -380,7 +380,7 @@ public extension Message { } func isSensitiveContent(platform: String) -> Bool { - if let rule = self.restrictedContentAttribute?.rules.first(where: { $0.isSensitive }) { + if let rule = self.restrictedContentAttribute?.rules.first(where: { $0.reason == "sensitive" }) { if rule.platform == "all" || rule.platform == platform { return true } diff --git a/submodules/TelegramCore/Sources/Utils/PeerUtils.swift b/submodules/TelegramCore/Sources/Utils/PeerUtils.swift index 8357dc2e8a..d993fc3d4c 100644 --- a/submodules/TelegramCore/Sources/Utils/PeerUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/PeerUtils.swift @@ -30,7 +30,7 @@ public extension Peer { if let restrictionInfo = restrictionInfo { for rule in restrictionInfo.rules { - if rule.isSensitive { + if rule.reason == "sensitive" { continue } if rule.platform == "all" || rule.platform == platform || contentSettings.addContentRestrictionReasons.contains(rule.platform) { @@ -234,7 +234,7 @@ public extension Peer { break } - if let restrictionInfo, let rule = restrictionInfo.rules.first(where: { $0.isSensitive }) { + if let restrictionInfo, let rule = restrictionInfo.rules.first(where: { $0.reason == "sensitive" }) { if rule.platform == "all" || rule.platform == platform { return true } diff --git a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift index 44b575595d..d6384438a6 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift @@ -28,7 +28,7 @@ private final class SheetContent: CombinedComponent { let invoice: TelegramMediaInvoice let source: BotPaymentInvoiceSource let extendedMedia: [TelegramExtendedMedia] - let inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError> + let inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError> let navigateToPeer: (EnginePeer) -> Void let dismiss: () -> Void @@ -38,7 +38,7 @@ private final class SheetContent: CombinedComponent { invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], - inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, + inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void, dismiss: @escaping () -> Void ) { @@ -101,7 +101,7 @@ private final class SheetContent: CombinedComponent { source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], invoice: TelegramMediaInvoice, - inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, + inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void ) { self.context = context @@ -132,6 +132,7 @@ private final class SheetContent: CombinedComponent { self.form = inputData?.1 self.botPeer = inputData?.2 self.chatPeer = chatPeer + self.authorPeer = inputData?.3 self.updated(transition: .immediate) if self.optionsDisposable == nil, let balance = self.balance, balance < self.invoice.totalAmount { @@ -404,7 +405,13 @@ private final class SheetContent: CombinedComponent { } } - if let botPeerName = state.botPeer?.compactDisplayTitle { + if let authorPeerName = state.authorPeer?.compactDisplayTitle { + infoText = strings.Stars_Transfer_UnlockBotInfo( + description, + authorPeerName, + strings.Stars_Transfer_Info_Stars(Int32(amount)) + ).string + } else if let botPeerName = state.botPeer?.compactDisplayTitle { infoText = strings.Stars_Transfer_UnlockBotInfo( description, botPeerName, @@ -664,7 +671,7 @@ private final class StarsTransferSheetComponent: CombinedComponent { private let invoice: TelegramMediaInvoice private let source: BotPaymentInvoiceSource private let extendedMedia: [TelegramExtendedMedia] - private let inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError> + private let inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError> private let navigateToPeer: (EnginePeer) -> Void init( @@ -673,7 +680,7 @@ private final class StarsTransferSheetComponent: CombinedComponent { invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], - inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, + inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void ) { self.context = context @@ -776,7 +783,7 @@ public final class StarsTransferScreen: ViewControllerComponentContainer { invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia] = [], - inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, + inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void = { _ in }, completion: @escaping (Bool) -> Void ) { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 67fcd3ba70..e6bf3d31f7 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -2808,9 +2808,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G inputData.get(), starsContext.state ) - |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?)? in + |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)? in if let data, let state { - return (state, data.form, data.botPeer) + return (state, data.form, data.botPeer, message.forwardInfo?.sourceMessageId == nil ? message.author : nil) } else { return nil } @@ -2856,9 +2856,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G inputData.get(), starsContext.state ) - |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?)? in + |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)? in if let data, let state { - return (state, data.form, data.botPeer) + return (state, data.form, data.botPeer, nil) } else { return nil } @@ -4423,9 +4423,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } if alwaysShow { - let _ = updateMediaDisplaySettingsInteractively(accountManager: context.sharedContext.accountManager, { - $0.withUpdatedShowSensitiveContent(true) - }).startStandalone() + let _ = updateRemoteContentSettingsConfiguration(postbox: context.account.postbox, network: context.account.network, sensitiveContentEnabled: true).start() self.present(UndoOverlayController(presentationData: self.presentationData, content: .info(title: nil, text: self.presentationData.strings.SensitiveContent_SettingsInfo, timeout: nil, customUndoText: nil), elevatedLayout: false, position: .top, action: { [weak self] action in if case .info = action, let self { diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 169d643d1d..bd5bef6587 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -1558,7 +1558,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto self.allAdMessagesPromise.get() ) - let sharedData = self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.mediaDisplaySettings]) + let contentSettings = self.context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.ContentSettings()) let maxReadStoryId: Signal if let peerId = self.chatLocation.peerId, peerId.namespace == Namespaces.Peer.CloudUser { @@ -1636,10 +1636,9 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto audioTranscriptionTrial, chatThemes, deviceContactsNumbers, - sharedData - ).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, sharedData 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 - let mediaSettings = sharedData.entries[ApplicationSpecificSharedDataKeys.mediaDisplaySettings]?.get(MediaDisplaySettings.self) ?? MediaDisplaySettings.defaultSettings func applyHole() { Queue.mainQueue().async { @@ -1857,7 +1856,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto translateToLanguage = 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: mediaSettings.showSensitiveContent) + 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 { diff --git a/submodules/TelegramUI/Sources/OpenChatMessage.swift b/submodules/TelegramUI/Sources/OpenChatMessage.swift index 2aa1886294..4ad460d22e 100644 --- a/submodules/TelegramUI/Sources/OpenChatMessage.swift +++ b/submodules/TelegramUI/Sources/OpenChatMessage.swift @@ -232,7 +232,13 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool { } else if let rootController = params.navigationController?.view.window?.rootViewController { let proceed = { let canShare = !params.message.isCopyProtected() + var useBrowserScreen = false if BrowserScreen.supportedDocumentMimeTypes.contains(file.mimeType) { + useBrowserScreen = true + } else if let fileName = file.fileName as? NSString, BrowserScreen.supportedDocumentExtensions.contains(fileName.pathExtension.lowercased()) { + useBrowserScreen = true + } + if useBrowserScreen { let subject: BrowserScreen.Subject if file.mimeType == "application/pdf" { subject = .pdfDocument(file: file, canShare: canShare) diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 82e296a34b..980473852c 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -315,9 +315,9 @@ func openResolvedUrlImpl( inputData.get(), starsContext.state ) - |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?)? in + |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)? in if let data, let state { - return (state, data.form, data.botPeer) + return (state, data.form, data.botPeer, nil) } else { return nil } @@ -916,9 +916,9 @@ func openResolvedUrlImpl( inputData.get(), starsContext.state ) - |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?)? in + |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)? in if let data, let state { - return (state, data.form, data.botPeer) + return (state, data.form, data.botPeer, nil) } else { return nil } diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index 73ff9ae237..c1c4bdc591 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -2743,11 +2743,11 @@ public final class SharedAccountContextImpl: SharedAccountContext { return StarsPurchaseScreen(context: context, starsContext: starsContext, options: options, purpose: purpose, completion: completion) } - public func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController { + public func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController { return StarsTransferScreen(context: context, starsContext: starsContext, invoice: invoice, source: source, extendedMedia: extendedMedia, inputData: inputData, completion: completion) } - public func makeStarsSubscriptionTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, link: String, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void) -> ViewController { + public func makeStarsSubscriptionTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, link: String, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void) -> ViewController { return StarsTransferScreen(context: context, starsContext: starsContext, invoice: invoice, source: .starsChatSubscription(hash: link), extendedMedia: [], inputData: inputData, navigateToPeer: navigateToPeer, completion: { _ in }) } diff --git a/submodules/TelegramUIPreferences/Sources/MediaDisplaySettings.swift b/submodules/TelegramUIPreferences/Sources/MediaDisplaySettings.swift index 2573f6d518..7532462dea 100644 --- a/submodules/TelegramUIPreferences/Sources/MediaDisplaySettings.swift +++ b/submodules/TelegramUIPreferences/Sources/MediaDisplaySettings.swift @@ -4,41 +4,33 @@ import SwiftSignalKit public struct MediaDisplaySettings: Codable, Equatable { public let showNextMediaOnTap: Bool - public let showSensitiveContent: Bool public static var defaultSettings: MediaDisplaySettings { - return MediaDisplaySettings(showNextMediaOnTap: true, showSensitiveContent: false) + return MediaDisplaySettings(showNextMediaOnTap: true) } - public init(showNextMediaOnTap: Bool, showSensitiveContent: Bool) { + public init(showNextMediaOnTap: Bool) { self.showNextMediaOnTap = showNextMediaOnTap - self.showSensitiveContent = showSensitiveContent } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StringCodingKey.self) self.showNextMediaOnTap = (try container.decode(Int32.self, forKey: "showNextMediaOnTap")) != 0 - self.showSensitiveContent = (try container.decode(Int32.self, forKey: "showSensitiveContent")) != 0 } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: StringCodingKey.self) try container.encode((self.showNextMediaOnTap ? 1 : 0) as Int32, forKey: "showNextMediaOnTap") - try container.encode((self.showSensitiveContent ? 1 : 0) as Int32, forKey: "showSensitiveContent") } public static func ==(lhs: MediaDisplaySettings, rhs: MediaDisplaySettings) -> Bool { - return lhs.showNextMediaOnTap == rhs.showNextMediaOnTap && lhs.showSensitiveContent == rhs.showSensitiveContent + return lhs.showNextMediaOnTap == rhs.showNextMediaOnTap } public func withUpdatedShowNextMediaOnTap(_ showNextMediaOnTap: Bool) -> MediaDisplaySettings { - return MediaDisplaySettings(showNextMediaOnTap: showNextMediaOnTap, showSensitiveContent: self.showSensitiveContent) - } - - public func withUpdatedShowSensitiveContent(_ showSensitiveContent: Bool) -> MediaDisplaySettings { - return MediaDisplaySettings(showNextMediaOnTap: self.showNextMediaOnTap, showSensitiveContent: showSensitiveContent) + return MediaDisplaySettings(showNextMediaOnTap: showNextMediaOnTap) } } diff --git a/submodules/WebUI/Sources/WebAppController.swift b/submodules/WebUI/Sources/WebAppController.swift index 9318c7d072..c54a03079b 100644 --- a/submodules/WebUI/Sources/WebAppController.swift +++ b/submodules/WebUI/Sources/WebAppController.swift @@ -767,9 +767,9 @@ public final class WebAppController: ViewController, AttachmentContainable { inputData.get(), starsContext.state ) - |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?)? in + |> map { data, state -> (StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)? in if let data, let state { - return (state, data.form, data.botPeer) + return (state, data.form, data.botPeer, nil) } else { return nil }