diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index cb7c80f259..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"; 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/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 c40f70ffbd..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 } 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/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 }