mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Merge branch 'youtube-integration' into super-cut
This commit is contained in:
@@ -40,10 +40,10 @@ class ArticleExtractor: Logging {
|
||||
|
||||
let clientURL = "https://extract.feedbin.com/parser"
|
||||
let username = SecretsManager.provider.mercuryClientId
|
||||
let signiture = articleLink.hmacUsingSHA1(key: SecretsManager.provider.mercuryClientSecret)
|
||||
let signature = articleLink.hmacUsingSHA1(key: SecretsManager.provider.mercuryClientSecret)
|
||||
|
||||
if let base64URL = articleLink.data(using: .utf8)?.base64EncodedString() {
|
||||
let fullURL = "\(clientURL)/\(username)/\(signiture)?base64_url=\(base64URL)"
|
||||
let fullURL = "\(clientURL)/\(username)/\(signature)?base64_url=\(base64URL)"
|
||||
if let url = URL(string: fullURL) {
|
||||
self.url = url
|
||||
return
|
||||
|
||||
44
Shared/Article Rendering/inject.js
Normal file
44
Shared/Article Rendering/inject.js
Normal file
@@ -0,0 +1,44 @@
|
||||
function fixYouTube() {
|
||||
var checkForVideoTimer = null;
|
||||
|
||||
function callback(event) {
|
||||
var fullScreenButtonOld = document.querySelector("button.ytp-fullscreen-button");
|
||||
var fullScreenButton = fullScreenButtonOld.cloneNode(true);
|
||||
fullScreenButton.style = false;
|
||||
fullScreenButton.setAttribute("aria-disabled", "false");
|
||||
fullScreenButton.onclick = function() {
|
||||
var player = document.querySelector("video");
|
||||
player.webkitRequestFullScreen();
|
||||
};
|
||||
fullScreenButtonOld.parentNode.replaceChild(fullScreenButton, fullScreenButtonOld);
|
||||
}
|
||||
|
||||
function checkForVideo() {
|
||||
var video = document.querySelector("video");
|
||||
if (video) {
|
||||
clearInterval(checkForVideoTimer);
|
||||
|
||||
var goFullScreen = function() {
|
||||
video.webkitRequestFullScreen();
|
||||
};
|
||||
|
||||
var fullScreenButtonOld = document.querySelector("button.ytp-fullscreen-button");
|
||||
var fullScreenButton = fullScreenButtonOld.cloneNode(true);
|
||||
fullScreenButton.style = false;
|
||||
fullScreenButton.setAttribute("aria-disabled", "false");
|
||||
fullScreenButton.onclick = goFullScreen;
|
||||
fullScreenButtonOld.parentNode.replaceChild(fullScreenButton, fullScreenButtonOld);
|
||||
}
|
||||
}
|
||||
|
||||
const hostname = window.location.hostname;
|
||||
if (hostname.endsWith(".youtube.com") || hostname.endsWith(".youtube-nocookie.com")) {
|
||||
checkForVideoTimer = setInterval(checkForVideo, 100);
|
||||
}
|
||||
|
||||
document.addEventListener('webkitfullscreenchange', fullScreenChange, true);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
fixYouTube();
|
||||
});
|
||||
@@ -156,19 +156,18 @@ function removeWpSmiley() {
|
||||
}
|
||||
}
|
||||
|
||||
function addYouTubeVideos() {
|
||||
function addYouTubeVideo() {
|
||||
const titleURL = document.querySelector(".articleTitle A").getAttribute("href")
|
||||
const youTubeLink = "https://www.youtube.com/watch?v="
|
||||
if (!titleURL.startsWith(youTubeLink)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dynamically add the YouTube frame
|
||||
|
||||
const bodyContainer = document.querySelector("#bodyContainer");
|
||||
bodyContainer.setAttribute("style", "position: relative; padding-bottom: 56.25%; height: 100%; max-width: 100% !important; overflow: hidden;")
|
||||
|
||||
|
||||
var youTubeFrame = document.createElement("iFrame");
|
||||
youTubeFrame.setAttribute("src", "https://www.youtube.com/embed/" + titleURL.substring(youTubeLink.length));
|
||||
youTubeFrame.setAttribute("src", "https://www.youtube.com/embed/" + titleURL.substring(youTubeLink.length) + "?fs=0&rel=0");
|
||||
youTubeFrame.setAttribute("style", "position: absolute; top: 0; left: 0; width: 100%; height: 100%;");
|
||||
youTubeFrame.setAttribute("title", "YouTube video player");
|
||||
youTubeFrame.setAttribute("frameborder", "0");
|
||||
@@ -186,6 +185,6 @@ function processPage() {
|
||||
flattenPreElements();
|
||||
styleLocalFootnotes();
|
||||
removeWpSmiley();
|
||||
addYouTubeVideos();
|
||||
addYouTubeVideo();
|
||||
postRenderProcessing();
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import Foundation
|
||||
import Account
|
||||
import RSCore
|
||||
|
||||
struct OPMLExporter {
|
||||
@MainActor struct OPMLExporter {
|
||||
|
||||
static func OPMLString(with account: Account, title: String) -> String {
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import Foundation
|
||||
import RSWeb
|
||||
import RSCore
|
||||
|
||||
struct CacheCleaner: Logging {
|
||||
@MainActor struct CacheCleaner: Logging {
|
||||
|
||||
static func purgeIfNecessary() {
|
||||
|
||||
|
||||
21
Shared/Extensions/WKUserContentController-Extensions.swift
Normal file
21
Shared/Extensions/WKUserContentController-Extensions.swift
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// WKUserContentController-Extensions.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 4/5/23.
|
||||
// Copyright © 2023 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import WebKit
|
||||
|
||||
extension WKUserContentController {
|
||||
|
||||
func addUserScript(forResource res: String, withExtension ext: String) {
|
||||
if let url = Bundle.main.url(forResource: res, withExtension: ext), let source = try? String(contentsOf: url) {
|
||||
let userScript = WKUserScript(source: source, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false)
|
||||
addUserScript(userScript)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,12 +5,17 @@
|
||||
</head>
|
||||
<body>
|
||||
<outline text="BBC News - World" title="BBC News - World" type="rss" version="RSS" htmlUrl="https://www.bbc.com/news" xmlUrl="https://feeds.bbci.co.uk/news/world/rss.xml"/>
|
||||
<outline text="Allen Pike" title="Allen Pike" type="rss" version="RSS" htmlUrl="https://www.allenpike.com/" xmlUrl="https://feeds.allenpike.com/feed/"/>
|
||||
<outline text="Becky Hansmeyer" title="Becky Hansmeyer" type="rss" version="RSS" htmlUrl="https://beckyhansmeyer.com" xmlUrl="https://beckyhansmeyer.com/feed/"/>
|
||||
<outline text="Colossal" title="Colossal" type="rss" version="RSS" htmlUrl="https://www.thisiscolossal.com/" xmlUrl="https://www.thisiscolossal.com/feed/"/>
|
||||
<outline text="Craig Hockenberry" title="Craig Hockenberry" type="rss" version="RSS" htmlUrl="https://furbo.org/" xmlUrl="https://furbo.org/feed/json"/>
|
||||
<outline text="Daring Fireball" title="Daring Fireball" type="rss" version="RSS" htmlUrl="https://daringfireball.net/" xmlUrl="https://daringfireball.net/feeds/json"/>
|
||||
<outline text="inessential" title="inessential" type="rss" version="RSS" htmlUrl="https://inessential.com/" xmlUrl="https://inessential.com/feed.json"/>
|
||||
<outline text="Jason Kottke" title="Jason Kottke" type="rss" version="RSS" htmlUrl="https://kottke.org/" xmlUrl="http://feeds.kottke.org/json"/>
|
||||
<outline text="Julia Evans" title="Julia Evans" type="rss" version="RSS" htmlUrl="https://jvns.ca/" xmlUrl="https://jvns.ca/atom.xml"/>
|
||||
<outline text="Manton Reece" title="Manton Reece" type="rss" version="RSS" htmlUrl="https://manton.org/" xmlUrl="https://www.manton.org/feed/json"/>
|
||||
<outline text="Maurice Parker" title="Maurice Parker" type="rss" version="RSS" htmlUrl="https://vincode.io/" xmlUrl="https://vincode.io/feed.xml"/>
|
||||
<outline text="Michael Tsai" title="Michael Tsai" type="rss" version="RSS" htmlUrl="https://mjtsai.com/blog/" xmlUrl="https://mjtsai.com/blog/feed/"/>
|
||||
<outline text="NetNewsWire Blog" title="NetNewsWire Blog" type="rss" version="RSS" htmlUrl="https://nnw.ranchero.com/" xmlUrl="https://nnw.ranchero.com/feed.json"/>
|
||||
<outline text="One Foot Tsunami" title="One Foot Tsunami" type="rss" version="RSS" htmlUrl="https://onefoottsunami.com/" xmlUrl="https://onefoottsunami.com/feed/json/"/>
|
||||
<outline text="Six Colors" title="Six Colors" type="rss" version="RSS" htmlUrl="https://sixcolors.com/" xmlUrl="https://feedpress.me/sixcolors?type=xml"/>
|
||||
|
||||
@@ -10,7 +10,7 @@ import Foundation
|
||||
import Account
|
||||
import RSCore
|
||||
|
||||
struct DefaultFeedsImporter {
|
||||
@MainActor struct DefaultFeedsImporter {
|
||||
|
||||
static func importDefaultFeeds(account: Account) {
|
||||
let defaultFeedsURL = Bundle.main.url(forResource: "DefaultFeeds", withExtension: "opml")!
|
||||
|
||||
Reference in New Issue
Block a user