Merge branch 'feat/video-audio-player' into 'master'

Feat/video audio player

See merge request idotj/mastodon-embed-feed-timeline!24
This commit is contained in:
i.j 2024-01-13 15:45:49 +00:00
commit 7be552b956
8 changed files with 216 additions and 70 deletions

View File

@ -1,3 +1,8 @@
v3.13.1 - 12/01/2024
- Add support for audio player
- Add support for video player
- Load video player when user clicks on video preview
v3.12.0 - 11/12/2023 v3.12.0 - 11/12/2023
- Fix link preview event on click - Fix link preview event on click

View File

@ -77,6 +77,9 @@ hide_reblog: false,
// Hide replies toots. Default: don't hide // Hide replies toots. Default: don't hide
hide_replies: false, hide_replies: false,
// Hide video image preview and load video player instead. Default: don't hide
hide_video_preview: false,
// Hide preview for links. Default: don't hide // Hide preview for links. Default: don't hide
hide_preview_link: false, hide_preview_link: false,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 KiB

After

Width:  |  Height:  |  Size: 260 KiB

View File

@ -7,24 +7,25 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="keywords" content="mastodon, embed timeline" /> <meta name="keywords" content="mastodon, embed timeline" />
<meta name="description" content="Mastodon embed timeline" /> <meta name="description" content="Mastodon embed timeline" />
<link rel="stylesheet" href="mastodon-timeline.css" /> <link rel="stylesheet" href="mastodon-timeline.min.css" />
<style> <style>
html { html {
height: 100%; height: 100%;
} }
body { body {
display: flex;
height: 100%; height: 100%;
justify-content: center;
align-items: center;
background: lightslategray; background: lightslategray;
font-size: 16px;
font-family: Arial, Helvetica, sans-serif; font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
margin: 0;
} }
.dummy-wrapper { .dummy-wrapper {
width: 100%; width: calc(100% - 1rem);
max-width: 26rem; max-width: 26rem;
height: calc(100% - 4rem); height: calc(100% - 3rem);
margin: 2rem auto;
} }
</style> </style>
</head> </head>
@ -38,6 +39,6 @@
</div> </div>
</div> </div>
<script src="mastodon-timeline.js"></script> <script src="mastodon-timeline.min.js"></script>
</body> </body>
</html> </html>

View File

@ -1,4 +1,4 @@
/* Mastodon embed feed timeline v3.12.0 */ /* Mastodon embed feed timeline v3.13.1 */
/* More info at: */ /* More info at: */
/* https://gitlab.com/idotj/mastodon-embed-feed-timeline */ /* https://gitlab.com/idotj/mastodon-embed-feed-timeline */
@ -223,6 +223,7 @@ html[data-theme="dark"] {
/* Medias */ /* Medias */
.mt-toot-media { .mt-toot-media {
position: relative;
overflow: hidden; overflow: hidden;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
@ -233,15 +234,26 @@ html[data-theme="dark"] {
z-index: 1; z-index: 1;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
} }
.mt-toot-media-spoiler > img { .mt-toot-media-spoiler > img,
.mt-toot-media-spoiler > audio,
.mt-toot-media-spoiler > video,
.mt-toot-media-spoiler > .mt-toot-media-play-icon {
filter: blur(2rem); filter: blur(2rem);
pointer-events: none;
} }
.img-ratio14_7 { .mt-toot-media.img-ratio14_7,
position: relative; .mt-toot-media.video-ratio14_7 {
padding-top: 56.95%; padding-top: 56.95%;
width: 100%; width: 100%;
} }
.img-ratio14_7 > img { .mt-toot-media > audio {
width: 100%;
position: relative;
z-index: 1;
}
.img-ratio14_7 > img,
.video-ratio14_7 > img,
.video-ratio14_7 > video {
width: 100%; width: 100%;
height: auto; height: auto;
position: absolute; position: absolute;
@ -251,6 +263,29 @@ html[data-theme="dark"] {
text-align: center; text-align: center;
color: var(--content-text); color: var(--content-text);
} }
.mt-toot-media.loading-spinner .mt-toot-media-play-icon {
display: none;
}
.mt-toot-media-play-icon {
display: flex;
position: absolute;
width: 3rem;
height: 3rem;
top: calc(50% - 1.5rem);
left: calc(50% - 1.5rem);
justify-content: center;
align-items: center;
background-color: transparent;
border: none;
cursor: pointer;
}
.mt-toot-media-play-icon > svg {
width: 2.5rem;
height: 2.5rem;
fill: var(--bg-color);
stroke:var(--content-text);
stroke-width: 1px;
}
/* Preview link */ /* Preview link */
.mt-toot-preview { .mt-toot-preview {

View File

@ -1,5 +1,5 @@
/** /**
* Mastodon embed feed timeline v3.12.0 * Mastodon embed feed timeline v3.13.1
* More info at: * More info at:
* https://gitlab.com/idotj/mastodon-embed-feed-timeline * https://gitlab.com/idotj/mastodon-embed-feed-timeline
*/ */
@ -46,6 +46,9 @@ window.addEventListener("load", () => {
// Hide replies toots. Default: don't hide // Hide replies toots. Default: don't hide
hide_replies: false, hide_replies: false,
// Hide video image preview and load video player instead. Default: don't hide
hide_video_preview: false,
// Hide preview card if toot contains a link, photo or video from a URL. Default: don't hide // Hide preview card if toot contains a link, photo or video from a URL. Default: don't hide
hide_preview_link: false, hide_preview_link: false,
@ -89,6 +92,10 @@ const MastodonApi = function (params_) {
typeof params_.hide_reblog !== "undefined" ? params_.hide_reblog : false; typeof params_.hide_reblog !== "undefined" ? params_.hide_reblog : false;
this.HIDE_REPLIES = this.HIDE_REPLIES =
typeof params_.hide_replies !== "undefined" ? params_.hide_replies : false; typeof params_.hide_replies !== "undefined" ? params_.hide_replies : false;
this.HIDE_VIDEO_PREVIEW =
typeof params_.hide_video_preview !== "undefined"
? params_.hide_video_preview
: false;
this.HIDE_PREVIEW_LINK = this.HIDE_PREVIEW_LINK =
typeof params_.hide_preview_link !== "undefined" typeof params_.hide_preview_link !== "undefined"
? params_.hide_preview_link ? params_.hide_preview_link
@ -185,7 +192,8 @@ MastodonApi.prototype.buildTimeline = async function () {
if ( if (
e.target.localName == "article" || e.target.localName == "article" ||
e.target.offsetParent?.localName == "article" || e.target.offsetParent?.localName == "article" ||
e.target.localName == "img" (e.target.localName == "img" &&
!e.target.parentNode.classList.contains("video-ratio14_7"))
) { ) {
openTootURL(e); openTootURL(e);
} }
@ -193,6 +201,19 @@ MastodonApi.prototype.buildTimeline = async function () {
if (e.target.localName == "button" && e.target.className == "spoiler-btn") { if (e.target.localName == "button" && e.target.className == "spoiler-btn") {
toogleSpoiler(e); toogleSpoiler(e);
} }
// Check if video preview image or play icon/button was clicked
if (
e.target.className == "mt-toot-media-play-icon" ||
(e.target.localName == "svg" &&
e.target.parentNode.className == "mt-toot-media-play-icon") ||
(e.target.localName == "path" &&
e.target.parentNode.parentNode.className ==
"mt-toot-media-play-icon") ||
(e.target.localName == "img" &&
e.target.parentNode.classList.contains("video-ratio14_7"))
) {
loadTootVideo(e);
}
}); });
this.mtBodyContainer.addEventListener("keydown", function (e) { this.mtBodyContainer.addEventListener("keydown", function (e) {
// Check if Enter key was pressed with focus in an article // Check if Enter key was pressed with focus in an article
@ -229,7 +250,11 @@ MastodonApi.prototype.buildTimeline = async function () {
*/ */
const toogleSpoiler = function (e) { const toogleSpoiler = function (e) {
const nextSibling = e.target.nextSibling; const nextSibling = e.target.nextSibling;
if (nextSibling.localName === "img") { if (
nextSibling.localName === "img" ||
nextSibling.localName === "audio" ||
nextSibling.localName === "video"
) {
e.target.parentNode.classList.remove("mt-toot-media-spoiler"); e.target.parentNode.classList.remove("mt-toot-media-spoiler");
e.target.style.display = "none"; e.target.style.display = "none";
} else if ( } else if (
@ -249,6 +274,18 @@ MastodonApi.prototype.buildTimeline = async function () {
} }
} }
}; };
/**
* Replace the video preview image by the video player
* @param {event} e User interaction trigger
*/
const loadTootVideo = function (e) {
const parentNode = e.target.closest("[data-video-url]");
const videoURL = parentNode.dataset.videoUrl;
parentNode.replaceChildren();
parentNode.innerHTML =
'<video controls src="' + videoURL + '" autoplay></video>';
};
}; };
/** /**
@ -541,14 +578,14 @@ MastodonApi.prototype.assambleToot = function (c, i) {
// Media attachments // Media attachments
let media = []; let media = [];
if (c.media_attachments.length > 0) { if (c.media_attachments.length > 0) {
for (let picid in c.media_attachments) { for (let i in c.media_attachments) {
media.push(this.placeMedias(c.media_attachments[picid], c.sensitive)); media.push(this.placeMedias(c.media_attachments[i], c.sensitive));
} }
} }
if (c.reblog && c.reblog.media_attachments.length > 0) { if (c.reblog && c.reblog.media_attachments.length > 0) {
for (let picid in c.reblog.media_attachments) { for (let i in c.reblog.media_attachments) {
media.push( media.push(
this.placeMedias(c.reblog.media_attachments[picid], c.reblog.sensitive) this.placeMedias(c.reblog.media_attachments[i], c.reblog.sensitive)
); );
} }
} }
@ -729,7 +766,11 @@ MastodonApi.prototype.replaceHTMLtag = function (
*/ */
MastodonApi.prototype.placeMedias = function (m, s) { MastodonApi.prototype.placeMedias = function (m, s) {
const spoiler = s || false; const spoiler = s || false;
const pic = const type = m.type;
let media = "";
if (type === "image") {
media =
'<div class="mt-toot-media img-ratio14_7 ' + '<div class="mt-toot-media img-ratio14_7 ' +
(spoiler ? "mt-toot-media-spoiler " : "") + (spoiler ? "mt-toot-media-spoiler " : "") +
this.SPINNER_CLASS + this.SPINNER_CLASS +
@ -741,8 +782,69 @@ MastodonApi.prototype.placeMedias = function (m, s) {
(m.description ? this.escapeHtml(m.description) : "") + (m.description ? this.escapeHtml(m.description) : "") +
'" loading="lazy" />' + '" loading="lazy" />' +
"</div>"; "</div>";
}
return pic; if (type === "audio") {
if (m.preview_url) {
media =
'<div class="mt-toot-media img-ratio14_7 ' +
(spoiler ? "mt-toot-media-spoiler " : "") +
this.SPINNER_CLASS +
'">' +
(spoiler ? '<button class="spoiler-btn">Show content</button>' : "") +
'<audio controls src="' +
m.url +
'"></audio>' +
'<img src="' +
m.preview_url +
'" alt="' +
(m.description ? this.escapeHtml(m.description) : "") +
'" loading="lazy" />' +
"</div>";
} else {
media =
'<div class="mt-toot-media ' +
(spoiler ? "mt-toot-media-spoiler " : "") +
'">' +
(spoiler ? '<button class="spoiler-btn">Show content</button>' : "") +
'<audio controls src="' +
m.url +
'"></audio>' +
"</div>";
}
}
if (type === "video") {
if (!this.HIDE_VIDEO_PREVIEW) {
media =
'<div class="mt-toot-media video-ratio14_7 ' +
(spoiler ? "mt-toot-media-spoiler " : "") +
this.SPINNER_CLASS +
'" data-video-url="' +
m.url +
'">' +
(spoiler ? '<button class="spoiler-btn">Show content</button>' : "") +
'<img src="' +
m.preview_url +
'" alt="' +
(m.description ? this.escapeHtml(m.description) : "") +
'" loading="lazy" />' +
'<button class="mt-toot-media-play-icon" title="Load video"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 14"><path d="M9.5 7l-9 6.3V.7z"/></svg></button>' +
"</div>";
} else {
media =
'<div class="mt-toot-media video-ratio14_7 ' +
(spoiler ? "mt-toot-media-spoiler " : "") +
'">' +
(spoiler ? '<button class="spoiler-btn">Show content</button>' : "") +
'<video controls src="' +
m.url +
'"></video>' +
"</div>";
}
}
return media;
}; };
/** /**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long