This commit is contained in:
syeopite 2025-01-22 23:27:58 +01:00 committed by GitHub
commit e01422dd21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 262 additions and 61 deletions

View File

@ -158,6 +158,8 @@ body a.pure-button {
} }
button.pure-button-primary, button.pure-button-primary,
summary.pure-button-primary,
#share-widget > summary,
body a.pure-button-primary, body a.pure-button-primary,
.channel-owner:hover, .channel-owner:hover,
.channel-owner:focus { .channel-owner:focus {
@ -534,13 +536,15 @@ span > select {
background-color: #fff2; background-color: #fff2;
} }
.light-theme a { .light-theme a,
.light-theme summary {
color: #335d7a; color: #335d7a;
text-decoration: none; text-decoration: none;
} }
/* All links that do not fit with the default color goes here */ /* All links that do not fit with the default color goes here */
.light-theme a:not([data-id]) > .icon, .light-theme a:not([data-id]) > .icon,
.light-theme summary > .icon,
.light-theme .pure-u-lg-1-5 > .h-box > a[href^="/watch?"], .light-theme .pure-u-lg-1-5 > .h-box > a[href^="/watch?"],
.light-theme .playlist-restricted > ol > li > a { .light-theme .playlist-restricted > ol > li > a {
color: #303030; color: #303030;
@ -573,13 +577,15 @@ span > select {
background-color: #fff2; background-color: #fff2;
} }
.no-theme a { .no-theme a,
.no-theme summary {
color: #335d7a; color: #335d7a;
text-decoration: none; text-decoration: none;
} }
/* All links that do not fit with the default color goes here */ /* All links that do not fit with the default color goes here */
.no-theme a:not([data-id]) > .icon, .no-theme a:not([data-id]) > .icon,
.no-theme summary > .icon,
.no-theme .pure-u-lg-1-5 > .h-box > a[href^="/watch?"], .no-theme .pure-u-lg-1-5 > .h-box > a[href^="/watch?"],
.no-theme .playlist-restricted > ol > li > a { .no-theme .playlist-restricted > ol > li > a {
color: #303030; color: #303030;
@ -625,7 +631,8 @@ span > select {
color: #ddd; color: #ddd;
} }
.dark-theme a { .dark-theme a,
.dark-theme summary {
color: #adadad; color: #adadad;
text-decoration: none; text-decoration: none;
} }
@ -661,7 +668,9 @@ body.dark-theme {
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
.no-theme a:hover, .no-theme a:hover,
.no-theme a:active, .no-theme a:active,
.no-theme a:focus { .no-theme summary:hover,
.no-theme a:focus,
.no-theme summary:focus {
color: rgb(0, 182, 240); color: rgb(0, 182, 240);
} }
@ -679,7 +688,7 @@ body.dark-theme {
color: #ddd; color: #ddd;
} }
.no-theme a { .no-theme a, .no-theme summary {
color: #adadad; color: #adadad;
text-decoration: none; text-decoration: none;
} }
@ -816,3 +825,77 @@ h1, h2, h3, h4, h5, p,
#download_widget { #download_widget {
width: 100%; width: 100%;
} }
#share-widget > summary {
display: block;
font-weight: bold;
text-align: center;
border-radius: 5px;
border:0;
padding: 10px;
}
#share-widget > div {
display: flex;
flex-direction: column;
padding: 20px;
gap: 20px;
}
#share-to-sites {
display: flex;
flex-wrap: wrap;
list-style: none;
padding: 0;
margin: 0;
justify-content: space-between;
}
#add-time-to-share-link-container {
display: flex;
gap: 10px;
align-items: center;
padding-left: 5px;
font-size: 16px;
}
#add-time-to-share-link-container input {
width: 20px;
height: 20px;
}
#add-time-to-share-link-container input:checked + label {
color: unset;
}
#add-time-to-share-link-container input + label {
color: #adadad;
}
#share-to-sites > li {
padding: 5px;
}
#share-to-sites > li:has(>details[open]) {
flex-basis: 100%;
width: 100%;
}
.share-site > a, .share-site > details > summary {
display: flex;
flex-direction: column;
align-items: center;
}
#share-to-sites i {
font-size: 32px;
}
#share-widget-embed-section > div {
font-family: monospace;
padding: 5px;
border: 1px solid #adadad;
border-radius: 10px;
margin: 20px 0px;
width: 100%;
}

View File

@ -115,12 +115,8 @@ ul.vjs-menu-content::-webkit-scrollbar {
order: 5; order: 5;
} }
.vjs-share-control {
order: 6;
}
.vjs-fullscreen-control { .vjs-fullscreen-control {
order: 7; order: 6;
} }
.vjs-playback-rate > .vjs-menu { .vjs-playback-rate > .vjs-menu {
@ -252,12 +248,6 @@ video.video-js {
top: 1.5em; top: 1.5em;
} }
@media screen and (max-width: 700px) {
.video-js .vjs-share {
justify-content: unset;
}
}
@media screen and (max-width: 650px) { @media screen and (max-width: 650px) {
.vjs-modal-dialog-content { .vjs-modal-dialog-content {
overflow-x: hidden; overflow-x: hidden;

View File

@ -95,6 +95,109 @@ if (video_data.params.quality === 'dash') {
}); });
} }
// Populated by DOMContentLoaded event
let shareWidgetDetailsBox
let shareToSiteContainer
let shareWidgetAddDurationButton
/**
* Modifies share widget links to remove or add the current time to the invidious video URL
*
* @param {bool} setTime
*/
function modifySocialWidgetURLs(setTime = false) {
for (let shareToSite of shareToSiteContainer ) {
let socialLink = shareToSite.getElementsByTagName("a")[0];
if (!socialLink) {
continue;
}
let shareUrl = URL.parse(socialLink.href);
let shareUrlParams = shareUrl.searchParams
let replaceAttr = socialLink.dataset.replaceAttr;
let videoUrl = shareUrlParams.get(replaceAttr)
if (videoUrl.startsWith("/")) {
videoUrl = window.location.origin + videoUrl;
}
let urlToReplace
if (setTime) {
urlToReplace = addCurrentTimeToURL(videoUrl)
} else {
urlToReplace = URL.parse(videoUrl)
urlToReplace.searchParams.delete('t');
urlToReplace = urlToReplace.toString()
}
shareUrlParams.set(replaceAttr, urlToReplace);
socialLink.href = shareUrl.toString();
}
// Edit url for iframe
const iframeCodeElement = document.getElementById("share-widget-embed-code")
const iframeParsedDom = new DOMParser().parseFromString(iframeCodeElement.textContent, "text/html")
const iframeElement = iframeParsedDom.getElementsByTagName("iframe")[0]
let iframeSrc = iframeElement.src
if (iframeSrc.startsWith("/")) {
iframeSrc = window.location.origin + iframeSrc;
}
if (setTime) {
iframeSrc = addCurrentTimeToURL(iframeSrc)
} else {
iframeSrc = URL.parse(iframeSrc)
iframeSrc.searchParams.delete('t');
iframeSrc = iframeSrc.toString()
}
iframeElement.src = iframeSrc
iframeCodeElement.textContent = iframeElement.outerHTML
}
/**
* Updates the time of the Start at ${time} text in the share widget
*
*/
function updateStartAtDurationStr() {
const label = shareWidgetAddDurationButton.labels[0];
const startAtDurationText = label.getElementsByTagName("span")[0];
if (label) {
const duration = Math.floor(player.currentTime());
if (duration == 0) {
startAtDurationText.innerHTML = "0:00"
return
}
const durationStrVals = [];
const paddedDurationString = [];
const days = Math.floor(duration / (60 * 60 * 24));
const hours = Math.floor((duration / (60 * 60)) % 24);
const minutes = Math.floor((duration / 60) % 60);
const seconds = Math.floor(duration % 60);
if (days !== 0) durationStrVals.push(days);
if (hours !== 0) durationStrVals.push(hours);
durationStrVals.push(minutes);
durationStrVals.push(seconds);
durationStrVals.forEach((val) => {
paddedDurationString.push(String(val).padStart(2, "0"))
})
startAtDurationText.innerHTML = paddedDurationString.join(":")
}
}
/** /**
* Function for add time argument to url * Function for add time argument to url
* *
@ -154,25 +257,14 @@ player.on('timeupdate', function () {
elem_iv_embed.href = addCurrentTimeToURL(base_url_iv_embed, domain); elem_iv_embed.href = addCurrentTimeToURL(base_url_iv_embed, domain);
elem_iv_other.href = addCurrentTimeToURL(base_url_iv_other, domain); elem_iv_other.href = addCurrentTimeToURL(base_url_iv_other, domain);
// Only modify share widget data if start at is selected
if (document.getElementById('share-add-duration').checked) {
modifySocialWidgetURLs(true);
}
}); });
var shareOptions = {
socials: ['fbFeed', 'tw', 'reddit', 'email'],
get url() {
return addCurrentTimeToURL(short_url);
},
title: player_data.title,
description: player_data.description,
image: player_data.thumbnail,
get embedCode() {
// Single quotes inside here required. HTML inserted as is into value attribute of input
return "<iframe id='ivplayer' width='640' height='360' src='" +
addCurrentTimeToURL(embed_url) + "' style='border:none;'></iframe>";
}
};
if (location.pathname.startsWith('/embed/')) { if (location.pathname.startsWith('/embed/')) {
var overlay_content = '<h1><a rel="noopener" target="_blank" href="' + location.origin + '/watch?v=' + video_data.id + '">' + player_data.title + '</a></h1>'; var overlay_content = '<h1><a rel="noopener" target="_blank" href="' + location.origin + '/watch?v=' + video_data.id + '">' + player_data.title + '</a></h1>';
player.overlay({ player.overlay({
@ -219,11 +311,8 @@ if (isMobile()) {
var playback_element = document.getElementsByClassName('vjs-playback-rate')[0]; var playback_element = document.getElementsByClassName('vjs-playback-rate')[0];
operations_bar_element.append(playback_element); operations_bar_element.append(playback_element);
// The share and http source selector element can't be fetched till the players ready. // The http source selector element can't be fetched till the players ready.
player.one('playing', function () { player.one('playing', function () {
var share_element = document.getElementsByClassName('vjs-share-control')[0];
operations_bar_element.append(share_element);
if (!video_data.params.listen && video_data.params.quality === 'dash') { if (!video_data.params.listen && video_data.params.quality === 'dash') {
var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0]; var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0];
operations_bar_element.append(http_source_selector); operations_bar_element.append(http_source_selector);
@ -725,9 +814,6 @@ addEventListener('keydown', function (e) {
player.on('DOMMouseScroll', mouseScroll); player.on('DOMMouseScroll', mouseScroll);
}()); }());
// Since videojs-share can sometimes be blocked, we defer it until last
if (player.share) player.share(shareOptions);
// show the preferred caption by default // show the preferred caption by default
if (player_data.preferred_caption_found) { if (player_data.preferred_caption_found) {
player.ready(function () { player.ready(function () {
@ -785,4 +871,31 @@ addEventListener('DOMContentLoaded', function () {
if (changeInstanceLink) changeInstanceLink.addEventListener('click', function () { if (changeInstanceLink) changeInstanceLink.addEventListener('click', function () {
changeInstanceLink.href = addCurrentTimeToURL(changeInstanceLink.href); changeInstanceLink.href = addCurrentTimeToURL(changeInstanceLink.href);
}); });
shareWidgetDetailsBox = document.getElementById("share-widget");
shareToSiteContainer = document.getElementsByClassName('share-site');
shareWidgetAddDurationButton = document.getElementById("share-add-duration");
shareWidgetAddDurationButton.addEventListener("change", () => {
if (shareWidgetAddDurationButton.checked) {
modifySocialWidgetURLs(true)
updateStartAtDurationStr()
} else {
modifySocialWidgetURLs(false)
updateStartAtDurationStr()
}
})
shareWidgetDetailsBox.addEventListener("toggle", () => {
// If share widget is opened and the share widget start at checkbox is checked
// then we will update the time to the current video time
if (shareWidgetDetailsBox.open && shareWidgetAddDurationButton.checked) {
modifySocialWidgetURLs(true)
updateStartAtDurationStr()
} else {
// Uncheck when closed
shareWidgetAddDurationButton.checked = false
modifySocialWidgetURLs(false)
}
})
}); });

View File

@ -498,5 +498,11 @@
"toggle_theme": "Toggle Theme", "toggle_theme": "Toggle Theme",
"carousel_slide": "Slide {{current}} of {{total}}", "carousel_slide": "Slide {{current}} of {{total}}",
"carousel_skip": "Skip the Carousel", "carousel_skip": "Skip the Carousel",
"carousel_go_to": "Go to slide `x`" "carousel_go_to": "Go to slide `x`",
"video_share_widget_label": "Share",
"video_share_widget_embed": "Embed",
"video_share_widget_twitter": "Twitter",
"video_share_widget_reddit": "Reddit",
"video_share_widget_email": "Email",
"video_share_add_duration_checkbox_label": "Start at `x`"
} }

View File

@ -1,7 +1,6 @@
<link rel="stylesheet" href="/videojs/video.js/video-js.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/videojs/video.js/video-js.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/videojs/videojs-http-source-selector/videojs-http-source-selector.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/videojs/videojs-http-source-selector/videojs-http-source-selector.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/videojs/videojs-markers/videojs.markers.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/videojs/videojs-markers/videojs.markers.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/videojs/videojs-share/videojs-share.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/videojs/videojs-vtt-thumbnails/videojs-vtt-thumbnails.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/videojs/videojs-vtt-thumbnails/videojs-vtt-thumbnails.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/videojs/videojs-mobile-ui/videojs-mobile-ui.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/videojs/videojs-mobile-ui/videojs-mobile-ui.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/player.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/css/player.css?v=<%= ASSET_COMMIT %>">
@ -11,7 +10,6 @@
<script src="/videojs/videojs-contrib-quality-levels/videojs-contrib-quality-levels.js?v=<%= ASSET_COMMIT %>"></script> <script src="/videojs/videojs-contrib-quality-levels/videojs-contrib-quality-levels.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/videojs/videojs-http-source-selector/videojs-http-source-selector.js?v=<%= ASSET_COMMIT %>"></script> <script src="/videojs/videojs-http-source-selector/videojs-http-source-selector.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/videojs/videojs-markers/videojs-markers.js?v=<%= ASSET_COMMIT %>"></script> <script src="/videojs/videojs-markers/videojs-markers.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/videojs/videojs-share/videojs-share.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/videojs/videojs-vtt-thumbnails/videojs-vtt-thumbnails.js?v=<%= ASSET_COMMIT %>"></script> <script src="/videojs/videojs-vtt-thumbnails/videojs-vtt-thumbnails.js?v=<%= ASSET_COMMIT %>"></script>

View File

@ -219,20 +219,6 @@
</td> </td>
</tr> </tr>
<tr>
<td>
<a href="/videojs/videojs-share/videojs-share.js?v=<%= ASSET_COMMIT %>">videojs-share.js</a>
</td>
<td>
<a href="http://www.jclark.com/xml/copying.txt">Expat</a>
</td>
<td>
<a href="https://github.com/mkhazov/videojs-share"><%= translate(locale, "source") %></a>
</td>
</tr>
<tr> <tr>
<td> <td>
<a href="/videojs/videojs-vtt-thumbnails/videojs-vtt-thumbnails.js?v=<%= ASSET_COMMIT %>">videojs-vtt-thumbnails.js</a> <a href="/videojs/videojs-vtt-thumbnails/videojs-vtt-thumbnails.js?v=<%= ASSET_COMMIT %>">videojs-vtt-thumbnails.js</a>

View File

@ -155,6 +155,35 @@ we're going to need to do it here in order to allow for translations.
<% end %> <% end %>
</p> </p>
<details id="share-widget">
<summary class="pure-button pure-button-primary"> <%=translate(locale, "video_share_widget_label")%> </summary>
<div>
<ol id="share-to-sites">
<% escaped_iv_watch_link = URI.encode_www_form(HOST_URL) + env.get?("current_page").as(String) %>
<% escaped_iv_embed_link = URI.encode_www_form(HOST_URL) + URI.encode_www_form(link_iv_embed.to_s.rstrip("?")) %>
<li class="share-site">
<details id="share-widget-embed-section">
<summary><i class="icon ion ion-md-code"></i><span><%=translate(locale, "video_share_widget_embed")%></span></summary>
<div id="share-widget-embed-code" contenteditable readonly><%=HTML.escape("<iframe id='ivplayer' width='640' height='360' src='#{escaped_iv_embed_link}' style='border:none;'></iframe>")%></div>
</details>
</li>
<li class="share-site">
<a href="https://twitter.com/intent/post?url=<%=escaped_iv_watch_link%>&text=<%=title%>" data-replace-attr="url"><i class="icon ion ion-logo-twitter"></i><span><%=translate(locale, "video_share_widget_twitter")%></span></a>
</li>
<li class="share-site">
<a href="https://www.reddit.com/submit?url=<%=escaped_iv_watch_link%>&title=<%=title%>" data-replace-attr="url"><i class="icon ion ion-logo-reddit"></i><span><%=translate(locale, "video_share_widget_reddit")%></span></a>
</li>
<li class="share-site">
<a href="mailto:?subject=<%=title%>&body=<%=escaped_iv_watch_link%>" data-replace-attr="body"><i class="icon ion ion-md-mail"></i><span><%=translate(locale, "video_share_widget_email")%></span></a>
</li>
</ol>
<div id="add-time-to-share-link-container">
<input type="checkbox" id="share-add-duration"/>
<label for="share-add-duration"><%=translate(locale, "video_share_add_duration_checkbox_label", "<span>0:00</span>")%></label>
</div>
</div>
</details>
<% if user %> <% if user %>
<% playlists = Invidious::Database::Playlists.select_user_created_playlists(user.email) %> <% playlists = Invidious::Database::Playlists.select_user_created_playlists(user.email) %>
<% if !playlists.empty? %> <% if !playlists.empty? %>

View File

@ -23,10 +23,6 @@ videojs-overlay:
version: 2.1.4 version: 2.1.4
shasum: 5a103b25374dbb753eb87960d8360c2e8f39cc05 shasum: 5a103b25374dbb753eb87960d8360c2e8f39cc05
videojs-share:
version: 3.2.1
shasum: 0a3024b981387b9d21c058c829760a72c14b8ceb
videojs-vr: videojs-vr:
version: 1.8.0 version: 1.8.0
shasum: 7f2f07f760d8a329c615acd316e49da6ee8edd34 shasum: 7f2f07f760d8a329c615acd316e49da6ee8edd34