From 3e90377125fb668b2b903e681daeefb3ab4ec2f3 Mon Sep 17 00:00:00 2001 From: Hannes Mannerheim Date: Sat, 12 Mar 2016 21:36:00 +0100 Subject: [PATCH] vimeo embedding support, fixes #43 --- css/qvitter.css | 9 +++-- js/dom-functions.js | 30 +++++++++------ js/misc-functions.js | 87 +++++++++++++++++++++++++++++++++++++++++--- js/qvitter.js | 68 ++++++++++++++++++++++++---------- 4 files changed, 153 insertions(+), 41 deletions(-) diff --git a/css/qvitter.css b/css/qvitter.css index 0604a57..82ac56e 100644 --- a/css/qvitter.css +++ b/css/qvitter.css @@ -2403,7 +2403,8 @@ body.rtl .queet.rtl .expanded-content { background-size:100% auto; } -.queet .queet-thumbs.thumb-num-1 .thumb-container.youtube { +.queet .queet-thumbs.thumb-num-1 .thumb-container.host-youtube-com, +.queet .queet-thumbs.thumb-num-1 .thumb-container.host-vimeo-com { height:250px; } @@ -5013,11 +5014,13 @@ body.rtl .modal-footer button { margin: 0 auto; min-height: 0; } -#queet-thumb-popup .modal-body .thumb-container.youtube iframe { +#queet-thumb-popup .modal-body .thumb-container.host-youtube-com iframe, +#queet-thumb-popup .modal-body .thumb-container.host-vimeo-com iframe { position:absolute; z-index:2; } -#queet-thumb-popup .modal-body .thumb-container.youtube { +#queet-thumb-popup .modal-body .thumb-container.host-youtube-com, +#queet-thumb-popup .modal-body .thumb-container.host-vimeo-com { background-image:none !important; z-index:1; } diff --git a/js/dom-functions.js b/js/dom-functions.js index 8e57c47..8fdfa5d 100644 --- a/js/dom-functions.js +++ b/js/dom-functions.js @@ -1298,14 +1298,24 @@ function expand_queet(q,doScrolling) { } // if there's only one thumb and it's a youtube video, show it inline - if(q.children('.queet').find('.queet-thumbs.thumb-num-1').children('.thumb-container.play-button.youtube').length == 1) { - var youtubeURL = q.children('.queet').find('.queet-thumbs.thumb-num-1').children('.thumb-container.play-button.youtube').children('.attachment-thumb').attr('data-full-image-url'); + if(q.children('.queet').find('.queet-thumbs.thumb-num-1').children('.thumb-container.play-button.host-youtube-com').length == 1) { + var youtubeURL = q.children('.queet').find('.queet-thumbs.thumb-num-1').children('.thumb-container.play-button.host-youtube-com').children('.attachment-thumb').attr('data-full-image-url'); if(q.children('.queet').find('.expanded-content').children('.media').children('iframe[src="' + youTubeEmbedLinkFromURL(youtubeURL) + '"]').length < 1) { // not if already showed q.children('.queet').find('.queet-thumbs').addClass('hide-thumbs'); // show video q.children('.queet').find('.expanded-content').prepend('
'); } } + // if there's only one thumb and it's a vimeo video, show it inline + else if(q.children('.queet').find('.queet-thumbs.thumb-num-1').children('.thumb-container.play-button.host-vimeo-com').length == 1) { + var vimeoURL = q.children('.queet').find('.queet-thumbs.thumb-num-1').children('.thumb-container.play-button.host-vimeo-com').children('.attachment-thumb').attr('data-full-image-url'); + var embedURL = vimeoEmbedLinkFromURL(vimeoURL); + if(q.children('.queet').find('.expanded-content').children('.media').children('iframe[src="' + embedURL + '"]').length < 1) { // not if already showed + q.children('.queet').find('.queet-thumbs').addClass('hide-thumbs'); + // show video + q.children('.queet').find('.expanded-content').prepend(''); + } + } // show certain attachments in expanded content if(q.children('.queet').children('script.attachment-json').length > 0 @@ -2478,6 +2488,7 @@ function buildAttachmentHTML(attachments){ && this.oembed !== false && this.oembed.title !== null && this.oembed.provider != 'YouTube' + && this.oembed.provider != 'Vimeo' && this.oembed.type != 'photo') { var oembedImage = ''; @@ -2560,15 +2571,10 @@ function buildAttachmentHTML(attachments){ // play button for videos and animated gifs var playButtonClass = ''; - if((this.url.indexOf('://www.youtube.com') > -1 || this.url.indexOf('://youtu.be') > -1) - || (typeof this.animated != 'undefined' && this.animated === true)) { - var playButtonClass = ' play-button'; - } - - // youtube class - var youTubeClass = ''; - if(this.url.indexOf('://www.youtube.com') > -1 || this.url.indexOf('://youtu.be') > -1) { - youTubeClass = ' youtube'; + if(typeof this.animated != 'undefined' && this.animated === true + || (this.url.indexOf('://www.youtube.com') > -1 || this.url.indexOf('://youtu.be') > -1) + || this.url.indexOf('://vimeo.com') > -1) { + playButtonClass = ' play-button'; } // gif-class @@ -2600,7 +2606,7 @@ function buildAttachmentHTML(attachments){ var urlToHide = window.siteInstanceURL + 'attachment/' + this.id; - attachmentHTML += ''; + attachmentHTML += ''; urlsToHide.push(urlToHide); // hide this attachment url from the queet text attachmentNum++; } diff --git a/js/misc-functions.js b/js/misc-functions.js index da6e6e7..b4dc6cb 100644 --- a/js/misc-functions.js +++ b/js/misc-functions.js @@ -2634,24 +2634,99 @@ function shortenUrlsInBox(shortenButton) { } + +/* · + · + · Youtube ID from Youtube URL + · + · · · · · · · · · · · · · */ + +function youTubeIDFromYouTubeURL(url) { + return url.replace('https://youtube.com/watch?v=','').replace('http://youtube.com/watch?v=','').replace('http://www.youtube.com/watch?v=','').replace('https://www.youtube.com/watch?v=','').replace('http://youtu.be/','').replace('https://youtu.be/','').substr(0,11); + } + /* · · · Youtube embed link from youtube url · · · · · · · · · · · · · · */ -function youTubeEmbedLinkFromURL(url) { - var youtubeId = url.replace('http://www.youtube.com/watch?v=','').replace('https://www.youtube.com/watch?v=','').replace('http://youtu.be/','').replace('https://youtu.be/','').substr(0,11); - +function youTubeEmbedLinkFromURL(url, autoplay) { // get start time hash var l = document.createElement("a"); l.href = url; + + var addStart = ''; if(l.hash.substring(0,3) == '#t=') { - return '//www.youtube.com/embed/' + youtubeId + '?start=' + l.hash.substring(3); + addStart = '&start=' + l.hash.substring(3); } - else { - return '//www.youtube.com/embed/' + youtubeId; + + var addAutoplay = ''; + if(typeof autoplay != 'undefined' && autoplay === true) { + addAutoplay = '&autoplay=1'; } + + return '//www.youtube.com/embed/' + youTubeIDFromYouTubeURL(url) + '?enablejsapi=1&version=3&playerapiid=ytplayer' + addStart + addAutoplay; + } + +/* · + · + · Vimeo ID from Vimeo URL + · + · · · · · · · · · · · · · */ + +function vimeoIDFromVimeoURL(url) { + id = url.replace('http://vimeo.com/','').replace('https://vimeo.com/',''); + if(id.indexOf('#') > -1) { + id = id.substring(0,id.indexOf('#')); + } + return id; + } + +/* · + · + · Vimeo embed link from vimeo url + · + · · · · · · · · · · · · · */ + +function vimeoEmbedLinkFromURL(url, autoplay) { + // get start time hash + var l = document.createElement("a"); + l.href = url; + + var addStart = ''; + if(l.hash.substring(0,3) == '#t=') { + addStart = l.hash; + } + + var addAutoplay = '&autoplay=0'; + if(typeof autoplay != 'undefined' && autoplay === true) { + addAutoplay = '&autoplay=1'; + } + + return 'https://player.vimeo.com/video/' + vimeoIDFromVimeoURL(url) + '?api=1' + addAutoplay + addStart; + } + + +/* · + · + · CSS class name from URL + · + · · · · · · · · · · · · · */ + +function CSSclassNameByHostFromURL(url) { + var host = getHost(url); + if(host.indexOf('www.') === 0) { + host = host.substring(4); + } + host = host.toLowerCase().replace(/\./g, "-"); + host = host.replace(/[^a-zA-Z0-9-]+/g, "_"); + + if(host == 'youtu-be') { + host = 'youtube-com'; + } + + return 'host-' + host; } diff --git a/js/qvitter.js b/js/qvitter.js index 1d95115..7866b83 100644 --- a/js/qvitter.js +++ b/js/qvitter.js @@ -2179,23 +2179,18 @@ $('body').on('click','.stream-item .queet img.attachment-thumb',function (event) $thumbToDisplay = $queetThumbsClone.find('img.attachment-thumb[src="' + thisAttachmentThumbSrc + '"]'); $thumbToDisplay.parent().addClass('display-this-thumb'); - // "play" all animated gifs and add youtube iframes to all youtube videos + // "play" all animated gifs and add youtube iframes to all youtube and vimeo videos $.each($queetThumbsClone.find('img.attachment-thumb'),function(){ if($(this).attr('data-mime-type') == 'image/gif' && $(this).parent().hasClass('play-button')) { $(this).attr('src',$(this).attr('data-full-image-url')); $(this).parent('.thumb-container').css('background-image','url(\'' + $(this).attr('data-full-image-url') + '\')'); } - else if($(this).parent().hasClass('youtube')){ - - // autoplay a clicked video - var autoplayFlag = ''; - if($(this).parent().hasClass('display-this-thumb')) { - autoplayFlag = '&autoplay=1'; - } - - var youtubeId = $(this).attr('data-full-image-url').replace('http://www.youtube.com/watch?v=','').replace('https://www.youtube.com/watch?v=','').replace('http://youtu.be/','').replace('https://youtu.be/','').substr(0,11); - $(this).parent().prepend(''); + else if($(this).parent().hasClass('host-youtube-com')){ + $(this).parent().prepend(''); + } + else if($(this).parent().hasClass('host-vimeo-com')){ + $(this).parent().prepend(''); } }); @@ -2208,7 +2203,7 @@ $('body').on('click','.stream-item .queet img.attachment-thumb',function (event) if(parentStreamItem.hasClass('expanded')) { - var calculatedDimensions = calculatePopUpAndImageDimensions($thumbToDisplay.attr('src')); + var calculatedDimensions = calculatePopUpAndImageDimensions($thumbToDisplay); var $thisImgInQueetThumbsClone = $queetThumbsClone.find('img[src="' + $thumbToDisplay.attr('src') + '"]'); // set dimensions @@ -2220,12 +2215,22 @@ $('body').on('click','.stream-item .queet img.attachment-thumb',function (event) // open popup popUpAction('queet-thumb-popup', '', '' + $queetThumbsClone.outerHTML() + '', parentStreamItemHTMLWithoutFooter, calculatedDimensions.popUpWidth); disableOrEnableNavigationButtonsInImagePopup($('#queet-thumb-popup')); + + // for some reason vimeo autoplays when we have a #t=x start time, so stop any vimeo videos running in the background (delay so it has time to load) + setTimeout(function(){ + $.each($('#queet-thumb-popup').find('.thumb-container.host-vimeo-com:not(.display-this-thumb)').children('iframe'),function(){ + console.log($(this).attr('src')); + this.contentWindow.postMessage('{"method": "pause"}', '*'); + }); + },1000); } } }); // popups can be max 900px wide, and should not be higher than the window, so we need to do some calculating -function calculatePopUpAndImageDimensions(img_src) { +function calculatePopUpAndImageDimensions(img) { + + var img_src = img.attr('src'); // trick to get width and height, we can't go with what gnusocial tells us, because // gnusocial doesn't (always?) report width and height after proper orientation @@ -2285,7 +2290,14 @@ function calculatePopUpAndImageDimensions(img_src) { var popUpWidth = 900; } } - return {popUpWidth: popUpWidth, displayImgWidth: displayImgWidth}; + + // vimeo can't be too small, or the design freaks out + if(img.parent('.thumb-container').hasClass('host-vimeo-com') && displayImgWidth < 540) { + displayImgWidth = 540; + displayImgHeight = 305; + } + + return {popUpWidth: popUpWidth, displayImgWidth: displayImgWidth, displayImgHeight: displayImgHeight }; } // switch to next image when clicking the image in the popup @@ -2296,15 +2308,23 @@ $('body').on('click','#queet-thumb-popup .attachment-thumb',function (event) { if(nextImage.length>0) { // start and stop youtube videos, if any - $.each($(this).parent('.youtube').children('iframe'),function(){ + $.each($(this).parent('.host-youtube-com').children('iframe'),function(){ this.contentWindow.postMessage('{"event":"command","func":"' + 'stopVideo' + '","args":""}', '*'); }); - $.each(nextImage.parent('.youtube').children('iframe'),function(){ + $.each(nextImage.parent('.host-youtube-com').children('iframe'),function(){ this.contentWindow.postMessage('{"event":"command","func":"' + 'playVideo' + '","args":""}', '*'); }); + // start stop vimeo + $.each($(this).parent('.host-vimeo-com').children('iframe'),function(){ + this.contentWindow.postMessage('{"method": "pause"}', '*'); + }); + $.each(nextImage.parent('.host-vimeo-com').children('iframe'),function(){ + this.contentWindow.postMessage('{"method": "play"}', '*'); + }); + // set dimensions of next image and the popup - var calculatedDimensions = calculatePopUpAndImageDimensions(nextImage.attr('src')); + var calculatedDimensions = calculatePopUpAndImageDimensions(nextImage); nextImage.width(calculatedDimensions.displayImgWidth); nextImage.parent('.thumb-container').width(calculatedDimensions.displayImgWidth); nextImage.parent('.thumb-container').children('iframe').attr('width',calculatedDimensions.displayImgWidth); @@ -2329,15 +2349,23 @@ $('body').on('click','#queet-thumb-popup .prev-thumb',function (event) { if(prevImage.length>0) { // start and stop youtube videos, if any - $.each($(this).parent().find('.display-this-thumb.youtube').children('iframe'),function(){ + $.each($(this).parent().find('.display-this-thumb.host-youtube-com').children('iframe'),function(){ this.contentWindow.postMessage('{"event":"command","func":"' + 'stopVideo' + '","args":""}', '*'); }); - $.each(prevImage.parent('.youtube').children('iframe'),function(){ + $.each(prevImage.parent('.host-youtube-com').children('iframe'),function(){ this.contentWindow.postMessage('{"event":"command","func":"' + 'playVideo' + '","args":""}', '*'); }); + // start stop vimeo + $.each($(this).parent().find('.display-this-thumb.host-vimeo-com').children('iframe'),function(){ + this.contentWindow.postMessage('{"method": "pause"}', '*'); + }); + $.each(prevImage.parent('.host-vimeo-com').children('iframe'),function(){ + this.contentWindow.postMessage('{"method": "play"}', '*'); + }); + // set dimensions of next image and the popup - var calculatedDimensions = calculatePopUpAndImageDimensions(prevImage.attr('src')); + var calculatedDimensions = calculatePopUpAndImageDimensions(prevImage); prevImage.width(calculatedDimensions.displayImgWidth); prevImage.parent('.thumb-container').width(calculatedDimensions.displayImgWidth); prevImage.parent('.thumb-container').children('iframe').attr('width',calculatedDimensions.displayImgWidth);