Skip to content

Commit

Permalink
add "View All YouTube Videos (Experimental)" context-menu action to U…
Browse files Browse the repository at this point in the history
…nread category

Right click on Unread and choose "View All YouTube Videos" and it will open up
a custom/local html file that plays all of the videos back to back.
  • Loading branch information
d3fault committed Sep 26, 2024
1 parent a672609 commit e88ba27
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 0 deletions.
1 change: 1 addition & 0 deletions QuiteRSS.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<file alias="newspaper_description">html/newspaper_description.html</file>
<file alias="newspaper_head">html/newspaper_head.html</file>
<file alias="newspaper_description_rtl">html/newspaper_description_rtl.html</file>
<file alias="sequential_youtube_player">html/sequential_youtube_player.html</file>
</qresource>
<qresource prefix="/flags">
<file alias="flag_AR">images/flags/flag_arab.png</file>
Expand Down
114 changes: 114 additions & 0 deletions html/sequential_youtube_player.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>YouTube Sequential Player</title>
<style>
body {
background-color: black;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100vh;
margin: 0;
color: white;
}
#controls {
margin-top: 20px;
}
.disabled {
color: grey;
pointer-events: none;
}
a {
color: white;
margin: 0 15px;
cursor: pointer;
text-decoration: none;
}
</style>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var videoIds = [%1];

var currentIndex = 0;
var player;

function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: videoIds[currentIndex],
playerVars: {
'autoplay': 1,
'controls': 1,
'rel': 0, // Prevents showing related videos at the end
'modestbranding': 1 // Minimizes YouTube branding
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}

function onPlayerReady() {
refocusPlayer();
updateControls();
}

function onPlayerStateChange(event) {
if (event.data === YT.PlayerState.ENDED) {
loadNextVideo();
}
}

function loadPreviousVideo() {
if (currentIndex > 0) {
currentIndex--;
player.loadVideoById(videoIds[currentIndex]);
updateControls();
refocusPlayer();
}
}

function loadNextVideo() {
if (currentIndex < videoIds.length - 1) {
currentIndex++;
player.loadVideoById(videoIds[currentIndex]);
updateControls();
refocusPlayer();
}
}

function refocusPlayer() {
var iframe = document.getElementById('player');
if (iframe) {
iframe.focus();
}
}

function updateControls() {
var prevLink = document.getElementById('prev');
var nextLink = document.getElementById('next');

prevLink.classList.toggle('disabled', currentIndex === 0);
nextLink.classList.toggle('disabled', currentIndex === videoIds.length - 1);
}
</script>
</head>
<body>
<div id="player"></div>

<div id="controls">
<a id="prev" class="disabled" onclick="loadPreviousVideo()">Previous</a>
<a id="next" onclick="loadNextVideo()">Next</a>
</div>
</body>
</html>
7 changes: 7 additions & 0 deletions src/application/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ void MainWindow::createFeedsWidget()
this, SLOT(clearDeleted()));
connect(categoriesTree_, SIGNAL(signalMarkRead(QTreeWidgetItem*)),
this, SLOT(slotMarkReadCategory(QTreeWidgetItem*)));
connect(categoriesTree_, SIGNAL(signalViewAllYoutubeVideos()),
this, SLOT(viewAllYoutubeVideos()));
connect(showCategoriesButton_, SIGNAL(clicked()),
this, SLOT(showNewsCategoriesTree()));
connect(feedsSplitter_, SIGNAL(splitterMoved(int,int)),
Expand Down Expand Up @@ -7585,6 +7587,11 @@ void MainWindow::slotMarkReadCategory(QTreeWidgetItem *item)
}
}

void MainWindow::viewAllYoutubeVideos()
{
currentNewsTab->viewAllYoutubeVideos();
}

/** @brief Show/Hide categories tree
*---------------------------------------------------------------------------*/
void MainWindow::showNewsCategoriesTree()
Expand Down
1 change: 1 addition & 0 deletions src/application/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ private slots:
void slotCategoriesClicked(QTreeWidgetItem *item, int, bool createTab = false);
void clearDeleted();
void slotMarkReadCategory(QTreeWidgetItem *item);
void viewAllYoutubeVideos();
void showNewsCategoriesTree();
void feedsSplitterMoved(int pos, int);

Expand Down
4 changes: 4 additions & 0 deletions src/categoriestreewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ void CategoriesTreeWidget::showContextMenuCategory(const QPoint &pos)
menu.addSeparator();
menu.addAction(tr("Mark Read"), this, SLOT(slotMarkRead()));
}
if (itemClicked_ == topLevelItem(UnreadItem)) {
menu.addSeparator();
menu.addAction(tr("View All Youtube Videos (Experimental)"), this, SIGNAL(signalViewAllYoutubeVideos()));
}
menu.exec(viewport()->mapToGlobal(pos));
}
}
Expand Down
1 change: 1 addition & 0 deletions src/categoriestreewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class CategoriesTreeWidget : public QTreeWidget
void signalMiddleClicked();
void signalClearDeleted();
void signalMarkRead(QTreeWidgetItem *item);
void signalViewAllYoutubeVideos();
// void pressKeyUp();
// void pressKeyDown();

Expand Down
49 changes: 49 additions & 0 deletions src/newstabwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,55 @@ void NewsTabWidget::markAllNewsRead()
mainWindow_->recountCategoryCounts();
}

void NewsTabWidget::viewAllYoutubeVideos()
{
if (type_ != TabTypeUnread) return;
int cnt = newsModel_->rowCount();
if (cnt == 0) return;
QList<QString> allYoutubeVideoIDs;
for (int i = cnt-1; i > -1; --i) {
bool read = (newsModel_->dataField(i, "read").toInt() > 0);
if (read) continue; //they might still be in the Unread category but just recently read moments ago
QUrl htmlUrl = QUrl::fromEncoded(getLinkNews(i).toUtf8());
QString host = htmlUrl.host();
if (host == "youtube.com" || host == "www.youtube.com") {
QUrlQuery query(htmlUrl);
QString videoId = query.queryItemValue("v");
if (!videoId.isEmpty()) {
allYoutubeVideoIDs.append(videoId);
}
}
}
if (allYoutubeVideoIDs.isEmpty()) return;
QFile sequentialYoutubePlayerHtmlFile;
sequentialYoutubePlayerHtmlFile.setFileName(":/html/sequential_youtube_player");
sequentialYoutubePlayerHtmlFile.open(QFile::ReadOnly);
QString sequentialYoutubePlayerHtml = QString::fromUtf8(sequentialYoutubePlayerHtmlFile.readAll());
sequentialYoutubePlayerHtmlFile.close();

QString youtubeIdsAsJavascriptArray;
bool first = true;
foreach (const QString &ytId, allYoutubeVideoIDs) {
if (!first) {
youtubeIdsAsJavascriptArray += ",\n";
}
first = false;
youtubeIdsAsJavascriptArray += "'" + ytId + "'";
}

sequentialYoutubePlayerHtml = sequentialYoutubePlayerHtml.arg(youtubeIdsAsJavascriptArray);

QTemporaryFile tempFile(QDir::tempPath() + "/sequential-youtube-player-XXXXXX.html");
if (tempFile.open()) {
tempFile.setAutoRemove(false);
QTextStream tempFileStream(&tempFile);
tempFileStream << sequentialYoutubePlayerHtml;
tempFile.close();
QUrl tempFileUrl = "file://" + tempFile.fileName();
openUrl(tempFileUrl);
}
}

/** @brief Mark selected news Starred
*----------------------------------------------------------------------------*/
void NewsTabWidget::markNewsStar()
Expand Down
1 change: 1 addition & 0 deletions src/newstabwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class NewsTabWidget : public QWidget
void setBrowserPosition();
void markNewsRead();
void markAllNewsRead();
void viewAllYoutubeVideos();
void markNewsStar();
void setLabelNews(int labelId);
void deleteNews();
Expand Down

0 comments on commit e88ba27

Please sign in to comment.