mirror of
https://github.com/iv-org/invidious.git
synced 2025-07-19 20:08:29 +00:00
Merge 2e5ef09915
into 164d764d55
This commit is contained in:
commit
e01422dd21
@ -158,6 +158,8 @@ body a.pure-button {
|
||||
}
|
||||
|
||||
button.pure-button-primary,
|
||||
summary.pure-button-primary,
|
||||
#share-widget > summary,
|
||||
body a.pure-button-primary,
|
||||
.channel-owner:hover,
|
||||
.channel-owner:focus {
|
||||
@ -534,13 +536,15 @@ span > select {
|
||||
background-color: #fff2;
|
||||
}
|
||||
|
||||
.light-theme a {
|
||||
.light-theme a,
|
||||
.light-theme summary {
|
||||
color: #335d7a;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* All links that do not fit with the default color goes here */
|
||||
.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 .playlist-restricted > ol > li > a {
|
||||
color: #303030;
|
||||
@ -573,13 +577,15 @@ span > select {
|
||||
background-color: #fff2;
|
||||
}
|
||||
|
||||
.no-theme a {
|
||||
.no-theme a,
|
||||
.no-theme summary {
|
||||
color: #335d7a;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* All links that do not fit with the default color goes here */
|
||||
.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 .playlist-restricted > ol > li > a {
|
||||
color: #303030;
|
||||
@ -625,7 +631,8 @@ span > select {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.dark-theme a {
|
||||
.dark-theme a,
|
||||
.dark-theme summary {
|
||||
color: #adadad;
|
||||
text-decoration: none;
|
||||
}
|
||||
@ -661,8 +668,10 @@ body.dark-theme {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.no-theme a:hover,
|
||||
.no-theme a:active,
|
||||
.no-theme a:focus {
|
||||
color: rgb(0, 182, 240);
|
||||
.no-theme summary:hover,
|
||||
.no-theme a:focus,
|
||||
.no-theme summary:focus {
|
||||
color: rgb(0, 182, 240);
|
||||
}
|
||||
|
||||
.no-theme .pure-button-primary:hover,
|
||||
@ -679,7 +688,7 @@ body.dark-theme {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.no-theme a {
|
||||
.no-theme a, .no-theme summary {
|
||||
color: #adadad;
|
||||
text-decoration: none;
|
||||
}
|
||||
@ -816,3 +825,77 @@ h1, h2, h3, h4, h5, p,
|
||||
#download_widget {
|
||||
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%;
|
||||
}
|
@ -115,12 +115,8 @@ ul.vjs-menu-content::-webkit-scrollbar {
|
||||
order: 5;
|
||||
}
|
||||
|
||||
.vjs-share-control {
|
||||
order: 6;
|
||||
}
|
||||
|
||||
.vjs-fullscreen-control {
|
||||
order: 7;
|
||||
order: 6;
|
||||
}
|
||||
|
||||
.vjs-playback-rate > .vjs-menu {
|
||||
@ -252,12 +248,6 @@ video.video-js {
|
||||
top: 1.5em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.video-js .vjs-share {
|
||||
justify-content: unset;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
.vjs-modal-dialog-content {
|
||||
overflow-x: hidden;
|
||||
|
@ -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
|
||||
*
|
||||
@ -154,25 +257,14 @@ player.on('timeupdate', function () {
|
||||
|
||||
elem_iv_embed.href = addCurrentTimeToURL(base_url_iv_embed, 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/')) {
|
||||
var overlay_content = '<h1><a rel="noopener" target="_blank" href="' + location.origin + '/watch?v=' + video_data.id + '">' + player_data.title + '</a></h1>';
|
||||
player.overlay({
|
||||
@ -219,11 +311,8 @@ if (isMobile()) {
|
||||
var playback_element = document.getElementsByClassName('vjs-playback-rate')[0];
|
||||
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 () {
|
||||
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') {
|
||||
var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0];
|
||||
operations_bar_element.append(http_source_selector);
|
||||
@ -725,9 +814,6 @@ addEventListener('keydown', function (e) {
|
||||
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
|
||||
if (player_data.preferred_caption_found) {
|
||||
player.ready(function () {
|
||||
@ -785,4 +871,31 @@ addEventListener('DOMContentLoaded', function () {
|
||||
if (changeInstanceLink) changeInstanceLink.addEventListener('click', function () {
|
||||
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)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -498,5 +498,11 @@
|
||||
"toggle_theme": "Toggle Theme",
|
||||
"carousel_slide": "Slide {{current}} of {{total}}",
|
||||
"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`"
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
<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-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-mobile-ui/videojs-mobile-ui.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-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-share/videojs-share.js?v=<%= ASSET_COMMIT %>"></script>
|
||||
<script src="/videojs/videojs-vtt-thumbnails/videojs-vtt-thumbnails.js?v=<%= ASSET_COMMIT %>"></script>
|
||||
|
||||
|
||||
|
@ -219,20 +219,6 @@
|
||||
</td>
|
||||
</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>
|
||||
<td>
|
||||
<a href="/videojs/videojs-vtt-thumbnails/videojs-vtt-thumbnails.js?v=<%= ASSET_COMMIT %>">videojs-vtt-thumbnails.js</a>
|
||||
|
@ -155,6 +155,35 @@ we're going to need to do it here in order to allow for translations.
|
||||
<% end %>
|
||||
</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 %>
|
||||
<% playlists = Invidious::Database::Playlists.select_user_created_playlists(user.email) %>
|
||||
<% if !playlists.empty? %>
|
||||
|
@ -23,10 +23,6 @@ videojs-overlay:
|
||||
version: 2.1.4
|
||||
shasum: 5a103b25374dbb753eb87960d8360c2e8f39cc05
|
||||
|
||||
videojs-share:
|
||||
version: 3.2.1
|
||||
shasum: 0a3024b981387b9d21c058c829760a72c14b8ceb
|
||||
|
||||
videojs-vr:
|
||||
version: 1.8.0
|
||||
shasum: 7f2f07f760d8a329c615acd316e49da6ee8edd34
|
||||
|
Loading…
Reference in New Issue
Block a user