Merge commit 'fd63e83d6e5471546fc0922d97508fa4d921d13c'

This commit is contained in:
Isaac 2024-07-26 20:36:42 +08:00
commit 807608a44a
7 changed files with 122 additions and 28 deletions

View File

@ -12653,5 +12653,6 @@ Sorry for the inconvenience.";
"Story.Cover" = "Story Cover"; "Story.Cover" = "Story Cover";
"Story.SaveCover" = "Save Cover"; "Story.SaveCover" = "Save Cover";
"WebBrowser.CopyLink" = "Copy Link";
"WebBrowser.DeleteBookmark" = "Delete Bookmark"; "WebBrowser.DeleteBookmark" = "Delete Bookmark";
"WebBrowser.RemoveRecent" = "Remove from Recent"; "WebBrowser.RemoveRecent" = "Remove from Recent";

View File

@ -9,6 +9,7 @@ import TelegramCore
import AccountContext import AccountContext
import TelegramPresentationData import TelegramPresentationData
import ContextUI import ContextUI
import UndoUI
final class BrowserAddressListComponent: Component { final class BrowserAddressListComponent: Component {
let context: AccountContext let context: AccountContext
@ -336,13 +337,23 @@ final class BrowserAddressListComponent: Component {
} }
}, },
contextAction: { [weak self] webPage, message, sourceView, gesture in contextAction: { [weak self] webPage, message, sourceView, gesture in
guard let self, let component = self.component else { guard let self, let component = self.component, let url = webPage.content.url else {
return return
} }
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 } let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
var itemList: [ContextMenuItem] = [] var itemList: [ContextMenuItem] = []
itemList.append(.action(ContextMenuActionItem(text: presentationData.strings.WebBrowser_CopyLink, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, f in
f(.default)
UIPasteboard.general.string = url
if let self, let component = self.component {
component.presentInGlobalOverlay(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }))
}
})))
if let message { if let message {
itemList.append(.action(ContextMenuActionItem(text: presentationData.strings.WebBrowser_DeleteBookmark, textColor: .destructive, icon: { theme in itemList.append(.action(ContextMenuActionItem(text: presentationData.strings.WebBrowser_DeleteBookmark, textColor: .destructive, icon: { theme in

View File

@ -186,6 +186,7 @@ final class BrowserAddressListItemComponent: Component {
} }
address = address.replacingOccurrences(of: "https://www.", with: "") address = address.replacingOccurrences(of: "https://www.", with: "")
address = address.replacingOccurrences(of: "https://", with: "") address = address.replacingOccurrences(of: "https://", with: "")
address = address.replacingOccurrences(of: "tonsite://", with: "")
address = address.trimmingCharacters(in: CharacterSet(charactersIn: "/")) address = address.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
subtitle = address subtitle = address

View File

@ -16,6 +16,8 @@ import UrlWhitelist
import SearchUI import SearchUI
import SearchBarNode import SearchBarNode
import ChatHistorySearchContainerNode import ChatHistorySearchContainerNode
import ContextUI
import UndoUI
public final class BrowserBookmarksScreen: ViewController { public final class BrowserBookmarksScreen: ViewController {
final class Node: ViewControllerTracingNode, ASScrollViewDelegate { final class Node: ViewControllerTracingNode, ASScrollViewDelegate {
@ -39,6 +41,7 @@ public final class BrowserBookmarksScreen: ViewController {
self.presentationData = presentationData self.presentationData = presentationData
var openMessageImpl: ((Message) -> Bool)? var openMessageImpl: ((Message) -> Bool)?
var openContextMenuImpl: ((Message, ASDisplayNode, CGRect, UIGestureRecognizer?) -> Void)?
self.controllerInteraction = ChatControllerInteraction(openMessage: { message, _ in self.controllerInteraction = ChatControllerInteraction(openMessage: { message, _ in
if let openMessageImpl = openMessageImpl { if let openMessageImpl = openMessageImpl {
return openMessageImpl(message) return openMessageImpl(message)
@ -47,7 +50,8 @@ public final class BrowserBookmarksScreen: ViewController {
} }
}, openPeer: { _, _, _, _ in }, openPeer: { _, _, _, _ in
}, openPeerMention: { _, _ in }, openPeerMention: { _, _ in
}, openMessageContextMenu: { _, _, _, _, _, _ in }, openMessageContextMenu: { message, _, sourceView, rect, gesture, _ in
openContextMenuImpl?(message, sourceView, rect, gesture)
}, openMessageReactionContextMenu: { _, _, _, _ in }, openMessageReactionContextMenu: { _, _, _, _ in
}, updateMessageReaction: { _, _, _, _ in }, updateMessageReaction: { _, _, _, _ in
}, activateMessagePinch: { _ in }, activateMessagePinch: { _ in
@ -220,6 +224,47 @@ public final class BrowserBookmarksScreen: ViewController {
self.containerLayoutUpdated(layout: layout, navigationBarHeight: navigationBarHeight, actualNavigationBarHeight: actualNavigationBarHeight, transition: .animated(duration: 0.4, curve: .spring)) self.containerLayoutUpdated(layout: layout, navigationBarHeight: navigationBarHeight, actualNavigationBarHeight: actualNavigationBarHeight, transition: .animated(duration: 0.4, curve: .spring))
} }
} }
openContextMenuImpl = { [weak self] message, sourceNode, rect, gesture in
guard let self, let sourceNode = sourceNode as? ContextExtractedContentContainingNode else {
return
}
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
var itemList: [ContextMenuItem] = []
if let webPage = message.media.first(where: { $0 is TelegramMediaWebpage }) as? TelegramMediaWebpage, let url = webPage.content.url {
itemList.append(.action(ContextMenuActionItem(text: presentationData.strings.WebBrowser_CopyLink, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, f in
f(.default)
UIPasteboard.general.string = url
if let self {
self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
}
})))
}
itemList.append(.action(ContextMenuActionItem(text: presentationData.strings.WebBrowser_DeleteBookmark, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor)
}, action: { [weak self] _, f in
f(.dismissWithoutContent)
if let self {
let _ = self.context.engine.messages.deleteMessagesInteractively(messageIds: [message.id], type: .forEveryone).startStandalone()
}
})))
let items = ContextController.Items(content: .list(itemList))
let controller = ContextController(
presentationData: presentationData,
source: .extracted(BrowserBookmarksContextExtractedContentSource(contentNode: sourceNode)),
items: .single(items),
recognizer: nil,
gesture: gesture as? ContextGesture
)
self.controller?.presentInGlobalOverlay(controller)
}
} }
func activateSearch(placeholderNode: SearchBarPlaceholderNode) { func activateSearch(placeholderNode: SearchBarPlaceholderNode) {
@ -515,3 +560,23 @@ private class BottomPanelNode: ASDisplayNode {
} }
} }
final class BrowserBookmarksContextExtractedContentSource: ContextExtractedContentSource {
let keepInPlace: Bool = false
let ignoreContentTouches: Bool = false
let blurBackground: Bool = true
private let contentNode: ContextExtractedContentContainingNode
init(contentNode: ContextExtractedContentContainingNode) {
self.contentNode = contentNode
}
func takeView() -> ContextControllerTakeViewInfo? {
return ContextControllerTakeViewInfo(containingItem: .node(self.contentNode), contentAreaInScreenSpace: UIScreen.main.bounds)
}
func putBack() -> ContextControllerPutBackViewInfo? {
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
}
}

View File

@ -261,6 +261,8 @@ final class BrowserNavigationBarComponent: CombinedComponent {
availableWidth -= itemSpacing * CGFloat(max(0, leftItemList.count - 1)) + itemSpacing * CGFloat(max(0, rightItemList.count - 1)) + 30.0 availableWidth -= itemSpacing * CGFloat(max(0, leftItemList.count - 1)) + itemSpacing * CGFloat(max(0, rightItemList.count - 1)) + 30.0
} }
availableWidth -= context.component.sideInset * 2.0 availableWidth -= context.component.sideInset * 2.0
let canCenter = availableWidth > 660.0
availableWidth = min(660.0, availableWidth) availableWidth = min(660.0, availableWidth)
let environment = BrowserNavigationBarEnvironment(fraction: context.component.collapseFraction) let environment = BrowserNavigationBarEnvironment(fraction: context.component.collapseFraction)
@ -276,7 +278,11 @@ final class BrowserNavigationBarComponent: CombinedComponent {
var centerX = maxCenterInset + (context.availableSize.width - maxCenterInset * 2.0) / 2.0 var centerX = maxCenterInset + (context.availableSize.width - maxCenterInset * 2.0) / 2.0
if "".isEmpty { if "".isEmpty {
centerX = centerLeftInset + (context.availableSize.width - centerLeftInset - centerRightInset) / 2.0 if canCenter {
centerX = context.availableSize.width / 2.0
} else {
centerX = centerLeftInset + (context.availableSize.width - centerLeftInset - centerRightInset) / 2.0
}
} }
if let centerItem = centerItem { if let centerItem = centerItem {
let centerItemPosition = CGPoint(x: centerX, y: context.component.topInset + contentHeight / 2.0 + verticalOffset) let centerItemPosition = CGPoint(x: centerX, y: context.component.topInset + contentHeight / 2.0 + verticalOffset)

View File

@ -153,24 +153,24 @@ private final class BrowserScreenComponent: CombinedComponent {
] ]
if isTablet { if isTablet {
navigationLeftItems.append( // navigationLeftItems.append(
AnyComponentWithIdentity( // AnyComponentWithIdentity(
id: "minimize", // id: "minimize",
component: AnyComponent( // component: AnyComponent(
Button( // Button(
content: AnyComponent( // content: AnyComponent(
BundleIconComponent( // BundleIconComponent(
name: "Media Gallery/PictureInPictureButton", // name: "Media Gallery/PictureInPictureButton",
tintColor: environment.theme.rootController.navigationBar.accentTextColor // tintColor: environment.theme.rootController.navigationBar.accentTextColor
) // )
), // ),
action: { // action: {
performAction.invoke(.close) // performAction.invoke(.close)
} // }
) // )
) // )
) // )
) // )
let canGoBack = context.component.contentState?.canGoBack ?? false let canGoBack = context.component.contentState?.canGoBack ?? false
let canGoForward = context.component.contentState?.canGoForward ?? false let canGoForward = context.component.contentState?.canGoForward ?? false

View File

@ -348,7 +348,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
} }
address = address.trimmingCharacters(in: CharacterSet(charactersIn: "/")) address = address.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
let plainUrlString = NSAttributedString(string: address.replacingOccurrences(of: "https://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor) let plainUrlString = NSAttributedString(string: address.replacingOccurrences(of: "https://", with: "").replacingOccurrences(of: "tonsite://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor)
let urlString = NSMutableAttributedString() let urlString = NSMutableAttributedString()
urlString.append(plainUrlString) urlString.append(plainUrlString)
urlString.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: content.url, range: NSMakeRange(0, urlString.length)) urlString.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: content.url, range: NSMakeRange(0, urlString.length))
@ -412,8 +412,13 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
let rawUrlString = urlString let rawUrlString = urlString
var parsedUrl = URL(string: urlString) var parsedUrl = URL(string: urlString)
if (parsedUrl == nil || parsedUrl!.host == nil || parsedUrl!.host!.isEmpty) && !urlString.contains("@") { if (parsedUrl == nil || parsedUrl!.host == nil || parsedUrl!.host!.isEmpty) && !urlString.contains("@") {
urlString = "http://" + urlString if let mappedURL = URL(string: "https://\(urlString)"), let host = mappedURL.host, host.lowercased().hasSuffix(".ton") {
parsedUrl = URL(string: urlString) urlString = "tonsite://" + urlString
parsedUrl = URL(string: urlString)
} else {
urlString = "http://" + urlString
parsedUrl = URL(string: urlString)
}
} }
var host: String? = concealed ? urlString : parsedUrl?.host var host: String? = concealed ? urlString : parsedUrl?.host
if host == nil { if host == nil {
@ -463,7 +468,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
urlString = address urlString = address
let urlAttributedString = NSMutableAttributedString() let urlAttributedString = NSMutableAttributedString()
urlAttributedString.append(NSAttributedString(string: urlString.replacingOccurrences(of: "https://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor)) urlAttributedString.append(NSAttributedString(string: urlString.replacingOccurrences(of: "https://", with: "").replacingOccurrences(of: "tonsite://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor))
if item.presentationData.theme.theme.list.itemAccentColor.isEqual(item.presentationData.theme.theme.list.itemPrimaryTextColor) { if item.presentationData.theme.theme.list.itemAccentColor.isEqual(item.presentationData.theme.theme.list.itemPrimaryTextColor) {
urlAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length)) urlAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length))
} }
@ -495,8 +500,13 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
let rawUrlString = urlString let rawUrlString = urlString
var parsedUrl = URL(string: urlString) var parsedUrl = URL(string: urlString)
if (parsedUrl == nil || parsedUrl!.host == nil || parsedUrl!.host!.isEmpty) && !urlString.contains("@") { if (parsedUrl == nil || parsedUrl!.host == nil || parsedUrl!.host!.isEmpty) && !urlString.contains("@") {
urlString = "http://" + urlString if let mappedURL = URL(string: "https://\(urlString)"), let host = mappedURL.host, host.lowercased().hasSuffix(".ton") {
parsedUrl = URL(string: urlString) urlString = "tonsite://" + urlString
parsedUrl = URL(string: urlString)
} else {
urlString = "http://" + urlString
parsedUrl = URL(string: urlString)
}
} }
let host: String? = concealed ? urlString : parsedUrl?.host let host: String? = concealed ? urlString : parsedUrl?.host
if let url = parsedUrl, let host = host { if let url = parsedUrl, let host = host {
@ -533,7 +543,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
urlString = address urlString = address
let urlAttributedString = NSMutableAttributedString() let urlAttributedString = NSMutableAttributedString()
urlAttributedString.append(NSAttributedString(string: urlString.replacingOccurrences(of: "https://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor)) urlAttributedString.append(NSAttributedString(string: urlString.replacingOccurrences(of: "https://", with: "").replacingOccurrences(of: "tonsite://", with: ""), font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor))
if item.presentationData.theme.theme.list.itemAccentColor.isEqual(item.presentationData.theme.theme.list.itemPrimaryTextColor) { if item.presentationData.theme.theme.list.itemAccentColor.isEqual(item.presentationData.theme.theme.list.itemPrimaryTextColor) {
urlAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length)) urlAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length))
} }