Youtube player fixes

This commit is contained in:
Ilya Laktyushin 2020-10-06 09:23:16 +04:00
parent 7fb0b48ded
commit c899d1dfa7
25 changed files with 1301 additions and 1183 deletions

View File

@ -4098,7 +4098,7 @@ Unused sets are archived when you add more.";
"GroupPermission.PermissionGloballyDisabled" = "This permission is disabled in this group.";
"ChannelInfo.Stats" = "Statistics";
"ChannelInfo.Stats" = "View Statistics";
"Conversation.PressVolumeButtonForSound" = "Press volume button\nto unmute the video";
@ -5813,3 +5813,5 @@ Any member of this group will be able to see messages in the channel.";
"Channel.CommentsGroup.HeaderGroupSet" = "%@ is linking the group as it's discussion board.";
"RepliesChat.DescriptionText" = "This chat helps you keep track of replies to your comments in Channels.";
"Conversation.ContextViewStats" = "View Statistics";

View File

@ -1494,6 +1494,18 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
if let strongSelf = self {
strongSelf.presentationData = presentationData
strongSelf.presentationDataPromise.set(.single(ChatListPresentationData(theme: presentationData.theme, fontSize: presentationData.listsFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: presentationData.disableAnimations)))
strongSelf.listNode.forEachItemHeaderNode({ itemHeaderNode in
if let itemHeaderNode = itemHeaderNode as? ChatListSearchItemHeaderNode {
itemHeaderNode.updateTheme(theme: presentationData.theme)
}
})
strongSelf.recentListNode.forEachItemHeaderNode({ itemHeaderNode in
if let itemHeaderNode = itemHeaderNode as? ChatListSearchItemHeaderNode {
itemHeaderNode.updateTheme(theme: presentationData.theme)
}
})
}
})

View File

@ -210,7 +210,9 @@ public func galleryItemForEntry(context: AccountContext, presentationData: Prese
content = SystemVideoContent(url: embedUrl, imageReference: .webPage(webPage: WebpageReference(webpage), media: image), dimensions: webpageContent.embedSize?.cgSize ?? CGSize(width: 640.0, height: 640.0), duration: Int32(webpageContent.duration ?? 0))
}
}
if content == nil, let webEmbedContent = WebEmbedVideoContent(webPage: webpage, webpageContent: webpageContent, forcedTimestamp: timecode.flatMap(Int.init)) {
if content == nil, let webEmbedContent = WebEmbedVideoContent(webPage: webpage, webpageContent: webpageContent, forcedTimestamp: timecode.flatMap(Int.init), openUrl: { url in
performAction(.url(url: url.absoluteString, concealed: false))
}) {
content = webEmbedContent
}
}

View File

@ -493,6 +493,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
var disablePictureInPicture = false
var disablePlayerControls = false
var forceEnablePiP = false
var forceEnableUserInteraction = false
var isAnimated = false
if let content = item.content as? NativeVideoContent {
isAnimated = content.fileReference.media.isAnimated
@ -503,6 +504,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
let type = webEmbedType(content: content.webpageContent)
switch type {
case .youtube:
forceEnableUserInteraction = true
disablePictureInPicture = !(item.configuration?.youtubePictureInPictureEnabled ?? false)
self.videoFramePreview = YoutubeEmbedFramePreview(context: item.context, content: content)
case .iframe:
@ -527,7 +529,14 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
let mediaManager = item.context.sharedContext.mediaManager
let videoNode = UniversalVideoNode(postbox: item.context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: GalleryVideoDecoration(), content: item.content, priority: .gallery)
let videoSize = CGSize(width: item.content.dimensions.width * 2.0, height: item.content.dimensions.height * 2.0)
let videoScale: CGFloat
if item.content is WebEmbedVideoContent {
videoScale = 1.0
} else {
videoScale = 2.0
}
let videoSize = CGSize(width: item.content.dimensions.width * videoScale, height: item.content.dimensions.height * videoScale)
videoNode.updateLayout(size: videoSize, transition: .immediate)
videoNode.ownsContentNodeUpdated = { [weak self] value in
if let strongSelf = self {
@ -546,7 +555,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
}
self.videoNode = videoNode
videoNode.isUserInteractionEnabled = disablePlayerControls
videoNode.isUserInteractionEnabled = disablePlayerControls || forceEnableUserInteraction
videoNode.backgroundColor = videoNode.ownsContentNode ? UIColor.black : UIColor(rgb: 0x333335)
if item.fromPlayingVideo {
videoNode.canAttachContent = false

View File

@ -44,6 +44,15 @@ public class BaseLinesChartController: BaseChartController {
self.setBackButtonVisibilityClosure?(isZoomed, animated)
updateChartRangeTitle(animated: animated)
let initial = initialChartsCollection
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
if let lastDate = initial.axisValues.last {
TimeInterval.animationDurationMultipler = 0.00001
self.didTapZoomIn(date: lastDate, pointIndex: initial.axisValues.count - 1)
TimeInterval.animationDurationMultipler = 1.0
}
}
}
func updateChartRangeTitle(animated: Bool) {

View File

@ -137,7 +137,9 @@ public struct InstantPageGalleryEntry: Equatable {
}))
}), caption: NSAttributedString(string: ""), fromPlayingVideo: fromPlayingVideo, landscape: landscape, performAction: { _ in }, openActionOptions: { _ in }, storeMediaPlaybackState: { _, _ in }, present: { _, _ in })
} else {
if let content = WebEmbedVideoContent(webPage: embedWebpage, webpageContent: webpageContent) {
if let content = WebEmbedVideoContent(webPage: embedWebpage, webpageContent: webpageContent, openUrl: { url in
}) {
return UniversalVideoGalleryItem(context: context, presentationData: presentationData, content: content, originData: nil, indexData: nil, contentInfo: .webPage(webPage, embedWebpage, nil), caption: NSAttributedString(string: ""), fromPlayingVideo: fromPlayingVideo, landscape: landscape, performAction: { _ in }, openActionOptions: { _ in }, storeMediaPlaybackState: { _, _ in }, present: { _, _ in })
} else {
preconditionFailure()

View File

@ -39,7 +39,7 @@ private enum StatsEntry: ItemListNodeEntry {
case overview(PresentationTheme, MessageStats, Int32?)
case interactionsTitle(PresentationTheme, String)
case interactionsGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType)
case interactionsGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, StatsGraph?, ChartType)
case publicForwardsTitle(PresentationTheme, String)
case publicForward(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Message)
@ -92,8 +92,8 @@ private enum StatsEntry: ItemListNodeEntry {
} else {
return false
}
case let .interactionsGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsGraph, lhsType):
if case let .interactionsGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsGraph, rhsType) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsGraph == rhsGraph, lhsType == rhsType {
case let .interactionsGraph(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsGraph, lhsDetailedGraph, lhsType):
if case let .interactionsGraph(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsGraph, rhsDetailedGraph, rhsType) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsGraph == rhsGraph, lhsDetailedGraph == rhsDetailedGraph, lhsType == rhsType {
return true
} else {
return false
@ -126,13 +126,17 @@ private enum StatsEntry: ItemListNodeEntry {
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .overview(_, stats, publicShares):
return MessageStatsOverviewItem(presentationData: presentationData, stats: stats, publicShares: publicShares, sectionId: self.section, style: .blocks)
case let .interactionsGraph(_, _, _, graph, type):
case let .interactionsGraph(_, _, _, graph, detailedGraph, type):
return StatsGraphItem(presentationData: presentationData, graph: graph, type: type, getDetailsData: { date, completion in
if let detailedGraph = detailedGraph, case let .Loaded(_, data) = detailedGraph {
completion(data)
} else {
let _ = arguments.loadDetailedGraph(graph, Int64(date.timeIntervalSince1970) * 1000).start(next: { graph in
if let graph = graph, case let .Loaded(_, data) = graph {
completion(data)
}
})
}
}, sectionId: self.section, style: .blocks)
case let .publicForward(_, _, _, _, message):
var views: Int = 0
@ -148,9 +152,6 @@ private enum StatsEntry: ItemListNodeEntry {
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: PresentationDateTimeFormat(timeFormat: .military, dateFormat: .dayFirst, dateSeparator: ".", decimalSeparator: ",", groupingSeparator: ""), nameDisplayOrder: .firstLast, context: arguments.context, peer: message.peers[message.id.peerId]!, height: .generic, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .text(text), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: nil), revealOptions: nil, switchValue: nil, enabled: true, highlighted: false, selectable: true, sectionId: self.section, action: {
arguments.openMessage(message.id)
}, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, contextAction: nil)
// return StatsMessageItem(context: arguments.context, presentationData: presentationData, message: message, views: 0, forwards: 0, sectionId: self.section, style: .blocks, action: {
// arguments.openMessage(message.id)
// })
}
}
}
@ -164,7 +165,7 @@ private func messageStatsControllerEntries(data: MessageStats?, messages: Search
if !data.interactionsGraph.isEmpty {
entries.append(.interactionsTitle(presentationData.theme, presentationData.strings.Stats_MessageInteractionsTitle.uppercased()))
entries.append(.interactionsGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.interactionsGraph, .twoAxisStep))
entries.append(.interactionsGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.interactionsGraph, data.detailedInteractionsGraph, .twoAxisStep))
}
if let messages = messages, !messages.messages.isEmpty {

View File

@ -9,11 +9,13 @@ public struct MessageStats: Equatable {
public let views: Int
public let forwards: Int
public let interactionsGraph: StatsGraph
public let detailedInteractionsGraph: StatsGraph?
init(views: Int, forwards: Int, interactionsGraph: StatsGraph) {
init(views: Int, forwards: Int, interactionsGraph: StatsGraph, detailedInteractionsGraph: StatsGraph?) {
self.views = views
self.forwards = forwards
self.interactionsGraph = interactionsGraph
self.detailedInteractionsGraph = detailedInteractionsGraph
}
public static func == (lhs: MessageStats, rhs: MessageStats) -> Bool {
@ -26,11 +28,14 @@ public struct MessageStats: Equatable {
if lhs.interactionsGraph != rhs.interactionsGraph {
return false
}
if lhs.detailedInteractionsGraph != rhs.detailedInteractionsGraph {
return false
}
return true
}
public func withUpdatedInteractionsGraph(_ interactionsGraph: StatsGraph) -> MessageStats {
return MessageStats(views: self.views, forwards: self.forwards, interactionsGraph: self.interactionsGraph)
return MessageStats(views: self.views, forwards: self.forwards, interactionsGraph: interactionsGraph, detailedInteractionsGraph: self.detailedInteractionsGraph)
}
}
@ -39,8 +44,7 @@ public struct MessageStatsContextState: Equatable {
}
private func requestMessageStats(postbox: Postbox, network: Network, datacenterId: Int32, messageId: MessageId, dark: Bool = false) -> Signal<MessageStats?, NoError> {
return .single(nil)
/*return postbox.transaction { transaction -> (Peer, Message)? in
return postbox.transaction { transaction -> (Peer, Message)? in
if let peer = transaction.getPeer(messageId.peerId), let message = transaction.getMessage(messageId) {
return (peer, message)
} else {
@ -79,15 +83,25 @@ private func requestMessageStats(postbox: Postbox, network: Network, datacenterI
}
return signal
|> map { result -> MessageStats? in
|> mapToSignal { result -> Signal<MessageStats?, MTRpcError> in
if case let .messageStats(apiViewsGraph) = result {
return MessageStats(views: views, forwards: forwards, interactionsGraph: StatsGraph(apiStatsGraph: apiViewsGraph))
let interactionsGraph = StatsGraph(apiStatsGraph: apiViewsGraph)
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
if case let .Loaded(tokenValue, _) = interactionsGraph, let token = tokenValue, Int64(message.timestamp + 60 * 60 * 24 * 2) > Int64(timestamp) {
return requestGraph(network: network, datacenterId: datacenterId, token: token, x: 1601596800000)
|> castError(MTRpcError.self)
|> map { detailedGraph -> MessageStats? in
return MessageStats(views: views, forwards: forwards, interactionsGraph: interactionsGraph, detailedInteractionsGraph: detailedGraph)
}
} else {
return nil
return .single(MessageStats(views: views, forwards: forwards, interactionsGraph: interactionsGraph, detailedInteractionsGraph: nil))
}
} else {
return .single(nil)
}
}
|> retryRequest
}*/
}
}
private final class MessageStatsContextImpl {

View File

@ -345,15 +345,32 @@ public func searchMessages(account: Account, location: SearchMessagesLocation, q
|> mapToSignal { result, additionalResult -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> in
return account.postbox.transaction { transaction -> (SearchMessagesResult, SearchMessagesState) in
var additional: SearchMessagesPeerState? = mergedState(transaction: transaction, state: state?.additional, result: additionalResult)
if state?.additional == nil, case let .general(tags, _, _) = location {
if state?.additional == nil {
switch location {
case let .general(tags, minDate, maxDate), let .group(_, tags, minDate, maxDate):
let secretMessages = transaction.searchMessages(peerId: nil, query: query, tags: tags)
var filteredMessages: [Message] = []
var readStates: [PeerId: CombinedPeerReadState] = [:]
for message in secretMessages {
var match = true
if let minDate = minDate, message.timestamp < minDate {
match = false
}
if let maxDate = maxDate, message.timestamp > maxDate {
match = false
}
if match {
filteredMessages.append(message)
if let readState = transaction.getCombinedPeerReadState(message.id.peerId) {
readStates[message.id.peerId] = readState
}
}
additional = SearchMessagesPeerState(messages: secretMessages, readStates: readStates, totalCount: Int32(secretMessages.count), completed: true, nextRate: nil)
}
additional = SearchMessagesPeerState(messages: filteredMessages, readStates: readStates, totalCount: Int32(filteredMessages.count), completed: true, nextRate: nil)
default:
break
}
}
let updatedState = SearchMessagesState(main: mergedState(transaction: transaction, state: state?.main, result: result) ?? SearchMessagesPeerState(messages: [], readStates: [:], totalCount: 0, completed: true, nextRate: nil), additional: additional)

View File

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 119
return 120
}
public func parseMessage(_ data: Data!) -> Any! {

View File

@ -38,7 +38,7 @@
function getCurrentTime() {
downloadProgress = player.getVideoLoadedFraction();
position = player.getCurrentTime();
storyboardSpec = player.getStoryboardFormat();
//storyboardSpec = player.getStoryboardFormat();
updateState();
invoke("tick");
@ -67,6 +67,7 @@
function onReady(event) {
window.location.href = "embed://onReady?data=" + event.data;
iframe = document.getElementById("player");
iframe.referrerPolicy = "origin";
duration = player.getDuration();
invoke("tick");
}

View File

@ -16,56 +16,56 @@ function initialize() {
function tick() {
var watermark = document.getElementsByClassName("ytp-watermark")[0];
if (watermark != null) {
watermark.style.display = "none";
// watermark.style.display = "none";
}
var button = document.getElementsByClassName("ytp-large-play-button")[0];
if (button != null) {
button.style.display = "none";
button.style.opacity = "0";
// button.style.display = "none";
// button.style.opacity = "0";
}
var progress = document.getElementsByClassName("ytp-spinner-container")[0];
if (progress != null) {
progress.style.display = "none";
progress.style.opacity = "0";
// progress.style.display = "none";
// progress.style.opacity = "0";
}
var pause = document.getElementsByClassName("ytp-pause-overlay")[0];
if (pause != null) {
pause.style.display = "none";
pause.style.opacity = "0";
// pause.style.display = "none";
// pause.style.opacity = "0";
}
var chrome = document.getElementsByClassName("ytp-chrome-top")[0];
if (chrome != null) {
chrome.style.display = "none";
chrome.style.opacity = "0";
// chrome.style.display = "none";
// chrome.style.opacity = "0";
}
var paid = document.getElementsByClassName("ytp-paid-content-overlay")[0];
if (paid != null) {
paid.style.display = "none";
paid.style.opacity = "0";
// paid.style.display = "none";
// paid.style.opacity = "0";
}
var gradient = document.getElementsByClassName("ytp-gradient-top")[0];
if (gradient != null) {
gradient.style.display = "none";
gradient.style.opacity = "0";
// gradient.style.display = "none";
// gradient.style.opacity = "0";
}
var end = document.getElementsByClassName("html5-endscreen")[0];
if (end != null) {
end.style.display = "none";
end.style.opacity = "0";
// end.style.display = "none";
// end.style.opacity = "0";
}
var elements = document.getElementsByClassName("ytp-ce-element");
for (var i = 0; i < elements.length; i++) {
var element = elements[i]
element.style.display = "none";
element.style.opacity = "0";
// element.style.display = "none";
// element.style.opacity = "0";
}
var video = document.getElementsByTagName("video")[0];

View File

@ -2219,6 +2219,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
break
}
}
}, openMessageStats: { [weak self] id in
let _ = (context.account.postbox.transaction { transaction -> CachedPeerData? in
return transaction.getPeerCachedData(peerId: id.peerId)
} |> deliverOnMainQueue).start(next: { [weak self] cachedPeerData in
guard let strongSelf = self, let cachedPeerData = cachedPeerData else {
return
}
strongSelf.push(messageStatsController(context: context, messageId: id, cachedPeerData: cachedPeerData))
})
}, requestMessageUpdate: { [weak self] id in
if let strongSelf = self {
strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(id)

View File

@ -114,6 +114,7 @@ public final class ChatControllerInteraction {
let openPeerContextMenu: (Peer, ASDisplayNode, CGRect, ContextGesture?) -> Void
let openMessageReplies: (MessageId, Bool, Bool) -> Void
let openReplyThreadOriginalMessage: (Message) -> Void
let openMessageStats: (MessageId) -> Void
let requestMessageUpdate: (MessageId) -> Void
let cancelInteractiveKeyboardGestures: () -> Void
@ -199,6 +200,7 @@ public final class ChatControllerInteraction {
openPeerContextMenu: @escaping (Peer, ASDisplayNode, CGRect, ContextGesture?) -> Void,
openMessageReplies: @escaping (MessageId, Bool, Bool) -> Void,
openReplyThreadOriginalMessage: @escaping (Message) -> Void,
openMessageStats: @escaping (MessageId) -> Void,
requestMessageUpdate: @escaping (MessageId) -> Void,
cancelInteractiveKeyboardGestures: @escaping () -> Void,
automaticMediaDownloadSettings: MediaAutoDownloadSettings,
@ -271,6 +273,7 @@ public final class ChatControllerInteraction {
self.openPeerContextMenu = openPeerContextMenu
self.openMessageReplies = openMessageReplies
self.openReplyThreadOriginalMessage = openReplyThreadOriginalMessage
self.openMessageStats = openMessageStats
self.requestMessageUpdate = requestMessageUpdate
self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures
@ -321,6 +324,7 @@ public final class ChatControllerInteraction {
}, openPeerContextMenu: { _, _, _, _ in
}, openMessageReplies: { _, _, _ in
}, openReplyThreadOriginalMessage: { _ in
}, openMessageStats: { _ in
}, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,

View File

@ -808,9 +808,26 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
}
var clearCacheAsDelete = false
if let _ = message.peers[message.id.peerId] as? TelegramChannel {
if message.id.peerId.namespace == Namespaces.Peer.CloudChannel {
var views: Int = 0
for attribute in message.attributes {
if let attribute = attribute as? ViewCountMessageAttribute {
views = attribute.count
}
}
if views >= 100 {
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextViewStats, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Statistics"), color: theme.actionSheet.primaryTextColor)
}, action: { c, _ in
c.dismiss(completion: {
controllerInteraction.openMessageStats(messages[0].id)
})
})))
}
clearCacheAsDelete = true
}
if !isReplyThreadHead, (!data.messageActions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty || clearCacheAsDelete) && !isAction {
let title: String
var isSending = false

View File

@ -453,6 +453,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}, openPeerContextMenu: { _, _, _, _ in
}, openMessageReplies: { _, _, _ in
}, openReplyThreadOriginalMessage: { _ in
}, openMessageStats: { _ in
}, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,

View File

@ -146,6 +146,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
}, openPeerContextMenu: { _, _, _, _ in
}, openMessageReplies: { _, _, _ in
}, openReplyThreadOriginalMessage: { _ in
}, openMessageStats: { _ in
}, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,

View File

@ -136,6 +136,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu
}, openPeerContextMenu: { _, _, _, _ in
}, openMessageReplies: { _, _, _ in
}, openReplyThreadOriginalMessage: { _ in
}, openMessageStats: { _ in
}, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false))

View File

@ -1961,6 +1961,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
}, openPeerContextMenu: { _, _, _, _ in
}, openMessageReplies: { _, _, _ in
}, openReplyThreadOriginalMessage: { _ in
}, openMessageStats: { _ in
}, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,

View File

@ -1200,6 +1200,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
}, openPeerContextMenu: { _, _, _, _ in
}, openMessageReplies: { _, _, _ in
}, openReplyThreadOriginalMessage: { _ in
}, openMessageStats: { _ in
}, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,

View File

@ -75,18 +75,24 @@ final class WebEmbedPlayerNode: ASDisplayNode, WKNavigationDelegate {
let impl: WebEmbedImplementation
private let openUrl: (URL) -> Void
private let intrinsicDimensions: CGSize
private let webView: WKWebView
private let semaphore = DispatchSemaphore(value: 0)
private let queue = Queue()
init(impl: WebEmbedImplementation, intrinsicDimensions: CGSize) {
init(impl: WebEmbedImplementation, intrinsicDimensions: CGSize, openUrl: @escaping (URL) -> Void) {
self.impl = impl
self.intrinsicDimensions = intrinsicDimensions
self.openUrl = openUrl
let userContentController = WKUserContentController()
if impl is YoutubeEmbedImplementation {
} else {
userContentController.addUserScript(WKUserScript(source: "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta)", injectionTime: .atDocumentEnd, forMainFrameOnly: true))
}
let configuration = WKWebViewConfiguration()
configuration.allowsInlineMediaPlayback = true
@ -112,6 +118,8 @@ final class WebEmbedPlayerNode: ASDisplayNode, WKNavigationDelegate {
self.webView.navigationDelegate = self
self.webView.scrollView.isScrollEnabled = false
self.webView.allowsLinkPreview = false
self.webView.allowsBackForwardNavigationGestures = false
if #available(iOSApplicationExtension 11.0, iOS 11.0, *) {
self.webView.accessibilityIgnoresInvertColors = true
self.webView.scrollView.contentInsetAdjustmentBehavior = .never
@ -159,7 +167,7 @@ final class WebEmbedPlayerNode: ASDisplayNode, WKNavigationDelegate {
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("w")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
@ -179,6 +187,9 @@ final class WebEmbedPlayerNode: ASDisplayNode, WKNavigationDelegate {
} else if let _ = navigationAction.targetFrame {
decisionHandler(.allow)
} else {
if let url = navigationAction.request.url, url.absoluteString.contains("youtube") {
self.openUrl(url)
}
decisionHandler(.cancel)
}
}

View File

@ -19,8 +19,9 @@ public final class WebEmbedVideoContent: UniversalVideoContent {
public let dimensions: CGSize
public let duration: Int32
let forcedTimestamp: Int?
let openUrl: (URL) -> Void
public init?(webPage: TelegramMediaWebpage, webpageContent: TelegramMediaWebpageLoadedContent, forcedTimestamp: Int? = nil) {
public init?(webPage: TelegramMediaWebpage, webpageContent: TelegramMediaWebpageLoadedContent, forcedTimestamp: Int? = nil, openUrl: @escaping (URL) -> Void) {
guard let embedUrl = webpageContent.embedUrl else {
return nil
}
@ -30,10 +31,11 @@ public final class WebEmbedVideoContent: UniversalVideoContent {
self.dimensions = webpageContent.embedSize?.cgSize ?? CGSize(width: 128.0, height: 128.0)
self.duration = Int32(webpageContent.duration ?? (0 as Int))
self.forcedTimestamp = forcedTimestamp
self.openUrl = openUrl
}
public func makeContentNode(postbox: Postbox, audioSession: ManagedAudioSession) -> UniversalVideoContentNode & ASDisplayNode {
return WebEmbedVideoContentNode(postbox: postbox, audioSessionManager: audioSession, webPage: self.webPage, webpageContent: self.webpageContent, forcedTimestamp: self.forcedTimestamp)
return WebEmbedVideoContentNode(postbox: postbox, audioSessionManager: audioSession, webPage: self.webPage, webpageContent: self.webpageContent, forcedTimestamp: self.forcedTimestamp, openUrl: self.openUrl)
}
}
@ -70,7 +72,7 @@ final class WebEmbedVideoContentNode: ASDisplayNode, UniversalVideoContentNode {
private var readyDisposable = MetaDisposable()
init(postbox: Postbox, audioSessionManager: ManagedAudioSession, webPage: TelegramMediaWebpage, webpageContent: TelegramMediaWebpageLoadedContent, forcedTimestamp: Int? = nil) {
init(postbox: Postbox, audioSessionManager: ManagedAudioSession, webPage: TelegramMediaWebpage, webpageContent: TelegramMediaWebpageLoadedContent, forcedTimestamp: Int? = nil, openUrl: @escaping (URL) -> Void) {
self.webpageContent = webpageContent
if let embedSize = webpageContent.embedSize {
@ -83,7 +85,7 @@ final class WebEmbedVideoContentNode: ASDisplayNode, UniversalVideoContentNode {
let embedType = webEmbedType(content: webpageContent, forcedTimestamp: forcedTimestamp)
let embedImpl = webEmbedImplementation(for: embedType)
self.playerNode = WebEmbedPlayerNode(impl: embedImpl, intrinsicDimensions: self.intrinsicDimensions)
self.playerNode = WebEmbedPlayerNode(impl: embedImpl, intrinsicDimensions: self.intrinsicDimensions, openUrl: openUrl)
super.init()

View File

@ -174,8 +174,8 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
updateStatus(self.status)
let html = String(format: htmlTemplate, paramsJson)
webView.loadHTMLString(html, baseURL: URL(string: "https://youtube.com/"))
webView.isUserInteractionEnabled = false
webView.loadHTMLString(html, baseURL: URL(string: "https://messenger.telegram.org"))
// webView.isUserInteractionEnabled = false
userContentController.addUserScript(WKUserScript(source: userScript, injectionTime: .atDocumentEnd, forMainFrameOnly: false))
}