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:
		
						commit
						7be552b956
					
				| @ -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 | ||||
| - Fix link preview event on click | ||||
| 
 | ||||
|  | ||||
| @ -77,6 +77,9 @@ hide_reblog: false, | ||||
| // Hide replies toots. Default: don't hide | ||||
| 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_link: false, | ||||
| 
 | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 260 KiB | 
| @ -7,24 +7,25 @@ | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|     <meta name="keywords" 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> | ||||
|       html { | ||||
|         height: 100%; | ||||
|       } | ||||
| 
 | ||||
|       body { | ||||
|         display: flex; | ||||
|         height: 100%; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         background: lightslategray; | ||||
|         font-size: 16px; | ||||
|         font-family: Arial, Helvetica, sans-serif; | ||||
|         font-size: 16px; | ||||
|         margin: 0; | ||||
|       } | ||||
| 
 | ||||
|       .dummy-wrapper { | ||||
|         width: 100%; | ||||
|         width: calc(100% - 1rem); | ||||
|         max-width: 26rem; | ||||
|         height: calc(100% - 4rem); | ||||
|         margin: 2rem auto; | ||||
|         height: calc(100% - 3rem); | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
| @ -38,6 +39,6 @@ | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <script src="mastodon-timeline.js"></script> | ||||
|     <script src="mastodon-timeline.min.js"></script> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* Mastodon embed feed timeline v3.12.0 */ | ||||
| /* Mastodon embed feed timeline v3.13.1 */ | ||||
| /* More info at: */ | ||||
| /* https://gitlab.com/idotj/mastodon-embed-feed-timeline */ | ||||
| 
 | ||||
| @ -223,6 +223,7 @@ html[data-theme="dark"] { | ||||
| 
 | ||||
| /* Medias */ | ||||
| .mt-toot-media { | ||||
|   position: relative; | ||||
|   overflow: hidden; | ||||
|   margin-bottom: 1rem; | ||||
| } | ||||
| @ -233,15 +234,26 @@ html[data-theme="dark"] { | ||||
|   z-index: 1; | ||||
|   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); | ||||
|   pointer-events: none; | ||||
| } | ||||
| .img-ratio14_7 { | ||||
|   position: relative; | ||||
| .mt-toot-media.img-ratio14_7, | ||||
| .mt-toot-media.video-ratio14_7 { | ||||
|   padding-top: 56.95%; | ||||
|   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%; | ||||
|   height: auto; | ||||
|   position: absolute; | ||||
| @ -251,6 +263,29 @@ html[data-theme="dark"] { | ||||
|   text-align: center; | ||||
|   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 */ | ||||
| .mt-toot-preview { | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /** | ||||
|  * Mastodon embed feed timeline v3.12.0 | ||||
|  * Mastodon embed feed timeline v3.13.1 | ||||
|  * More info at: | ||||
|  * https://gitlab.com/idotj/mastodon-embed-feed-timeline
 | ||||
|  */ | ||||
| @ -46,6 +46,9 @@ window.addEventListener("load", () => { | ||||
|     // Hide replies toots. Default: don't hide
 | ||||
|     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_link: false, | ||||
| 
 | ||||
| @ -89,6 +92,10 @@ const MastodonApi = function (params_) { | ||||
|     typeof params_.hide_reblog !== "undefined" ? params_.hide_reblog : false; | ||||
|   this.HIDE_REPLIES = | ||||
|     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 = | ||||
|     typeof params_.hide_preview_link !== "undefined" | ||||
|       ? params_.hide_preview_link | ||||
| @ -185,7 +192,8 @@ MastodonApi.prototype.buildTimeline = async function () { | ||||
|     if ( | ||||
|       e.target.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); | ||||
|     } | ||||
| @ -193,6 +201,19 @@ MastodonApi.prototype.buildTimeline = async function () { | ||||
|     if (e.target.localName == "button" && e.target.className == "spoiler-btn") { | ||||
|       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) { | ||||
|     // 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 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.style.display = "none"; | ||||
|     } 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
 | ||||
|   let media = []; | ||||
|   if (c.media_attachments.length > 0) { | ||||
|     for (let picid in c.media_attachments) { | ||||
|       media.push(this.placeMedias(c.media_attachments[picid], c.sensitive)); | ||||
|     for (let i in c.media_attachments) { | ||||
|       media.push(this.placeMedias(c.media_attachments[i], c.sensitive)); | ||||
|     } | ||||
|   } | ||||
|   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( | ||||
|         this.placeMedias(c.reblog.media_attachments[picid], c.reblog.sensitive) | ||||
|         this.placeMedias(c.reblog.media_attachments[i], c.reblog.sensitive) | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| @ -729,20 +766,85 @@ MastodonApi.prototype.replaceHTMLtag = function ( | ||||
|  */ | ||||
| MastodonApi.prototype.placeMedias = function (m, s) { | ||||
|   const spoiler = s || false; | ||||
|   const pic = | ||||
|     '<div class="mt-toot-media img-ratio14_7 ' + | ||||
|     (spoiler ? "mt-toot-media-spoiler " : "") + | ||||
|     this.SPINNER_CLASS + | ||||
|     '">' + | ||||
|     (spoiler ? '<button class="spoiler-btn">Show content</button>' : "") + | ||||
|     '<img src="' + | ||||
|     m.preview_url + | ||||
|     '" alt="' + | ||||
|     (m.description ? this.escapeHtml(m.description) : "") + | ||||
|     '" loading="lazy" />' + | ||||
|     "</div>"; | ||||
|   const type = m.type; | ||||
|   let media = ""; | ||||
| 
 | ||||
|   return pic; | ||||
|   if (type === "image") { | ||||
|     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>' : "") + | ||||
|       '<img src="' + | ||||
|       m.preview_url + | ||||
|       '" alt="' + | ||||
|       (m.description ? this.escapeHtml(m.description) : "") + | ||||
|       '" loading="lazy" />' + | ||||
|       "</div>"; | ||||
|   } | ||||
| 
 | ||||
|   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; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  | ||||
							
								
								
									
										2
									
								
								src/mastodon-timeline.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								src/mastodon-timeline.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								src/mastodon-timeline.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								src/mastodon-timeline.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 i.j
						i.j