AntonLV 8 gadi atpakaļ
vecāks
revīzija
dbb02fec2b

+ 4 - 0
modules/boonex/russian/data/langs/bx_timeline/ru.xml

@@ -15,6 +15,10 @@
 	<string name="_bx_timeline_option_events_hide"><![CDATA[Показывать события в ленте]]></string>
 	<string name="_bx_timeline_option_chars_display_max"><![CDATA[Макс. число отображаемых символов в текстовом сообщении]]></string>
 	<string name="_bx_timeline_option_err_chars_display_max"><![CDATA[Введите число, желательно, большее 150.]]></string>
+    <string name="_bx_timeline_option_videos_autoplay"><![CDATA[Автоматически проигрывать видео ролики на Ленте]]></string>
+    <string name="_bx_timeline_option_videos_autoplay_off"><![CDATA[Отключено]]></string>
+    <string name="_bx_timeline_option_videos_autoplay_on_mute"><![CDATA[Включено (без звука)]]></string>
+    <string name="_bx_timeline_option_videos_autoplay_on"><![CDATA[Включено (cо звуком)]]></string>
 
 	<string name="_bx_timeline_form_post"><![CDATA[Сообщение]]></string>
 	<string name="_bx_timeline_form_post_display_add"><![CDATA[Написать сообщение]]></string>

+ 10 - 0
modules/boonex/timeline/classes/BxTimelineConfig.php

@@ -20,6 +20,7 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
     protected $_iRssLength;
     protected $_iCharsDisplayMax;
     protected $_iCharsDisplayMaxTitle;
+    protected $_sVideosAutoplay;
 
     protected $_sStorageObject;
     protected $_sTranscoderObjectPreview;
@@ -164,6 +165,9 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
 
         		'main_item' => $sHp . '-item',
 				'menu_popup' => $sHp . '-menu-popup-',
+
+        		'video_iframe' => $sHp . '-video-iframe-',
+                'video' => $sHp . '-video-',
             ),
             'post' => array(
                 'attach_link_popup' =>  $sHp . '-attach-link-popup',
@@ -217,6 +221,7 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
         $this->_iRssLength = (int)getParam($sOptionPrefix . 'rss_length');
         $this->_iCharsDisplayMax = (int)getParam($sOptionPrefix . 'chars_display_max');
         $this->_iCharsDisplayMaxTitle = 20;
+        $this->_sVideosAutoplay = getParam($sOptionPrefix . 'videos_autoplay');
     }
 
     public function isAllowEdit()
@@ -265,6 +270,11 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
         return $this->_iCharsDisplayMaxTitle;
     }
 
+    public function getVideosAutoplay()
+    {
+        return $this->_sVideosAutoplay;
+    }
+
     public function getRepostDefaults()
     {
         return $this->_aRepostDefaults;

+ 52 - 0
modules/boonex/timeline/classes/BxTimelineModule.php

@@ -33,6 +33,11 @@ define('BX_TIMELINE_PARSE_TYPE_DEFAULT', BX_TIMELINE_PARSE_TYPE_POST);
 define('BX_TIMELINE_MEDIA_PHOTO', 'photo');
 define('BX_TIMELINE_MEDIA_VIDEO', 'video');
 
+//--- Video Auto Play 
+define('BX_TIMELINE_VAP_OFF', 'off');
+define('BX_TIMELINE_VAP_ON_MUTE', 'on_mute');
+define('BX_TIMELINE_VAP_ON', 'on');
+
 class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolContentInfoService
 {
     protected $_sJsPostObject;
@@ -57,6 +62,22 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
     /**
      * ACTION METHODS
      */
+    public function actionVideo($iEventId, $iVideoId)
+    {
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iEventId));
+        if(empty($aEvent) || !is_array($aEvent) || !$this->_oConfig->isCommon($aEvent['type'], $aEvent['action']))
+            return;
+
+        $aData = $this->_oTemplate->getData($aEvent);
+        if($aData === false || !isset($aData['content']['videos'][$iVideoId]))
+            return;
+
+        $oTemplate = $this->_oTemplate;
+        $oTemplate->setPageNameIndex (BX_PAGE_CLEAR);
+        $oTemplate->setPageContent ('page_main_code', $this->_oTemplate->getVideo($aEvent, $aData['content']['videos'][$iVideoId]));
+        $oTemplate->getPageCode();
+    }
+
     public function actionPost()
     {
         $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
@@ -1306,6 +1327,37 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         return 'BxTimelineFormCheckerHelper';
     }
 
+	/**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_options_videos_autoplay get_options_videos_autoplay
+     * 
+     * @code bx_srv('bx_timeline', 'get_options_videos_autoplay', [...]); @endcode
+     * 
+     * Get an array with available options for 'Videos autoplay in Timeline' setting.
+     *
+     * @return an array with available options represented as key => value pairs.
+     * 
+     * @see BxTimelineModule::serviceGetOptionsVideosAutoplay
+     */
+    /** 
+     * @ref bx_timeline-get_options_videos_autoplay "get_options_videos_autoplay"
+     */
+    public function serviceGetOptionsVideosAutoplay()
+    {
+        $aOptions = array(BX_TIMELINE_VAP_OFF, BX_TIMELINE_VAP_ON_MUTE, BX_TIMELINE_VAP_ON);
+
+        $aResult = array();
+        foreach($aOptions as $sOption)
+            $aResult[] = array(
+                'key' => $sOption,
+                'value' => _t('_bx_timeline_option_videos_autoplay_' . $sOption)
+            );
+
+        return $aResult;
+    }
+
     /*
      * COMMON METHODS
      */

+ 33 - 7
modules/boonex/timeline/classes/BxTimelineTemplate.php

@@ -52,6 +52,7 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
             'modernizr.js',
         	'flickity/flickity.pkgd.min.js',
 			'emoji/js/jquery.emojiarea.js',
+            'player.min.js',
             'BxDolCmts.js',            
             'post.js',
             'repost.js',
@@ -66,6 +67,7 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
             'style_prefix' => $this->_oConfig->getPrefix('style'),
             'js_object' => $this->_oConfig->getJsObject('post'),
             'js_content' => $this->getJsCode('post', array(
+        		'sVideosAutoplay' => $this->_oConfig->getVideosAutoplay(),
             	'oRequestParams' => array('owner_id' => $iOwnerId)
         	)),
             'form' => $aForm['form']
@@ -87,6 +89,7 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
             'show_more' => $this->_getShowMore($aParams),
         	'view_image_popup' => $this->_getImagePopup($aParams),
             'js_content' => $this->getJsCode('view', array(
+                'sVideosAutoplay' => $this->_oConfig->getVideosAutoplay(),
             	'oRequestParams' => array(
 	                'type' => $aParams['type'],
 	                'owner_id' => $aParams['owner_id'],
@@ -758,6 +761,15 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
         return $aResult;
     }
 
+    public function getVideo(&$aEvent, &$aVideo)
+    {
+        $sVideoId = $this->_oConfig->getHtmlIds('view', 'video') . $aEvent['id'] . '-' . $aVideo['id'];
+        return $this->parseHtmlByName('video_player.html', array(
+            'player' => BxTemplFunctions::getInstance()->videoPlayer($aVideo['src_poster'], $aVideo['src_mp4'], $aVideo['src_webm'], array('id' => $sVideoId)),
+            'html_id' => $sVideoId
+        ));
+    }
+
     public function getItemIcon($bT, $bL, $bP, $bV)
     {
         $sResult = '';
@@ -1090,14 +1102,27 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
         }
 
     	//--- Process Videos ---//
+    	$sVap = $this->_oConfig->getVideosAutoplay();
+    	$sVapId = $this->_oConfig->getHtmlIds('view', 'video_iframe') . $aEvent['id'] . '-';
+    	$sVapSrc = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'video/' . $aEvent['id'] . '/';
+
         $aTmplVarsVideos = array();
         if(!empty($aContent['videos']))
-            foreach($aContent['videos'] as $aVideo) {
-                $aTmplVarsVideos[] = array(
-                    'style_prefix' => $sStylePrefix,
-                	'video' => BxTemplFunctions::getInstance()->videoPlayer($aVideo['src_poster'], $aVideo['src_mp4'], $aVideo['src_webm']) 
-                );
-            }
+            foreach($aContent['videos'] as $iVideo => $aVideo)
+                if($sVap == BX_TIMELINE_VAP_OFF)
+                    $aTmplVarsVideos[] = array(
+                        'style_prefix' => $sStylePrefix,
+                    	'video' => BxTemplFunctions::getInstance()->videoPlayer($aVideo['src_poster'], $aVideo['src_mp4'], $aVideo['src_webm']) 
+                    );
+                else 
+                    $aTmplVarsVideos[] = array(
+                        'style_prefix' => $sStylePrefix,
+                    	'video' => $this->parseHtmlByName('video_iframe.html', array(
+                    		'style_prefix' => $sStylePrefix,
+                            'html_id' => $sVapId . $iVideo,
+                            'src' => $sVapSrc . $iVideo . '/'
+                        )) 
+                    );
 
         return array(
             'style_prefix' => $sStylePrefix,
@@ -1323,7 +1348,8 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
                     $oTranscoderWebm = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_webm'));
 
                     foreach($aVideos as $iVideoId) {
-                        $aResult['content']['videos'][] = array(
+                        $aResult['content']['videos'][$iVideoId] = array(
+                            'id' => $iVideoId,
                             'src_poster' => $oTranscoderPoster->getFileUrl($iVideoId),
                         	'src_mp4' => $oTranscoderMp4->getFileUrl($iVideoId),
                         	'src_webm' => $oTranscoderWebm->getFileUrl($iVideoId),

+ 4 - 0
modules/boonex/timeline/install/langs/en.xml

@@ -15,6 +15,10 @@
 	<string name="_bx_timeline_option_events_hide"><![CDATA[Show events in Timeline]]></string>
 	<string name="_bx_timeline_option_chars_display_max"><![CDATA[Max number of displayed character in text post]]></string>
 	<string name="_bx_timeline_option_err_chars_display_max"><![CDATA[Enter the number which should be greater then 150.]]></string>
+	<string name="_bx_timeline_option_videos_autoplay"><![CDATA[Videos autoplay in Timeline]]></string>
+	<string name="_bx_timeline_option_videos_autoplay_off"><![CDATA[Disabled]]></string>
+	<string name="_bx_timeline_option_videos_autoplay_on_mute"><![CDATA[Enabled without sound]]></string>
+	<string name="_bx_timeline_option_videos_autoplay_on"><![CDATA[Enabled with sound]]></string>
 
 	<string name="_bx_timeline_form_post"><![CDATA[Post]]></string>
 	<string name="_bx_timeline_form_post_display_add"><![CDATA[Write Post]]></string>

+ 2 - 1
modules/boonex/timeline/install/sql/enable.sql

@@ -136,7 +136,8 @@ INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `c
 ('bx_timeline_events_per_page', '24', @iCategId, '_bx_timeline_option_events_per_page', 'digit', '', '', '', '', 13),
 ('bx_timeline_rss_length', '5', @iCategId, '_bx_timeline_option_rss_length', 'digit', '', '', '', '', 20),
 ('bx_timeline_events_hide', '', @iCategId, '_bx_timeline_option_events_hide', 'rlist', '', '', '', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:21:"get_actions_checklist";}', 30),
-('bx_timeline_chars_display_max', '300', @iCategId, '_bx_timeline_option_chars_display_max', 'digit', 'GreaterThan', 'a:1:{s:3:"min";i:150;}', '_bx_timeline_option_err_chars_display_max', '', 40);
+('bx_timeline_chars_display_max', '300', @iCategId, '_bx_timeline_option_chars_display_max', 'digit', 'GreaterThan', 'a:1:{s:3:"min";i:150;}', '_bx_timeline_option_err_chars_display_max', '', 40),
+('bx_timeline_videos_autoplay', 'off', @iCategId, '_bx_timeline_option_videos_autoplay', 'select', '', '', '', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:27:"get_options_videos_autoplay";}', 50);
 
 
 -- PRIVACY 

+ 6 - 0
modules/boonex/timeline/js/main.js

@@ -36,6 +36,12 @@ function BxTimelineMain() {
 	this.bViewOutline = false;
 }
 
+BxTimelineMain.prototype.initVideos = function(oParent) {
+	oParent.find('iframe').load(function() {
+		$(this).height(($(this).contents().find('video').height()) + 'px');
+	});
+};
+
 BxTimelineMain.prototype.isMasonry = function() {
 	return $(this.sIdViewOutline + ' .' + this.sClassItems).hasClass(this.sClassMasonry);
 };

+ 7 - 3
modules/boonex/timeline/js/post.js

@@ -16,6 +16,7 @@ function BxTimelinePost(oOptions) {
     this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
     this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
     this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._sVideosAutoplay = oOptions.sVideosAutoplay == undefined ? 'off' : oOptions.sVideosAutoplay;
     this._oRequestParams = {
     	timeline: null,
     	outline: null,
@@ -308,8 +309,8 @@ BxTimelinePost.prototype._onGetPost = function(oData) {
 	var oContent = $(oData.item).bxTime();
 	switch(oData.view) {
 		case 'timeline':
-			var oItem = null;
-			var oItems = $('#' + this._aHtmlIds['main_timeline'] + ' ' + '.' + this.sClassItems);
+			var oTimeline = $('#' + this._aHtmlIds['main_timeline']);
+			var oItems = oTimeline.find('.' + this.sClassItems);
 			var oDivider  = oItems.find('.' + this.sClassDividerToday);
 			var bDivider = oDivider.length > 0;
 
@@ -318,7 +319,7 @@ BxTimelinePost.prototype._onGetPost = function(oData) {
 
 			oContent.hide();
 
-			oItem = bDivider ? oDivider.after(oContent).next('.' + this.sClassItem + ':hidden') : oContent.prependTo(oItems);
+			var oItem = bDivider ? oDivider.after(oContent).next('.' + this.sClassItem + ':hidden') : oContent.prependTo(oItems);
 			oItem.bx_anim('show', this._sAnimationEffect, this._iAnimationSpeed, function() {
 				$(this).find('.bx-tl-item-text .bx-tl-content').checkOverflowHeight($this.sSP + '-overflow', function(oElement) {
 					$this.onFindOverflow(oElement);
@@ -326,6 +327,9 @@ BxTimelinePost.prototype._onGetPost = function(oData) {
 
 				$this.initFlickity();
 			});
+
+			if(this._sVideosAutoplay != 'off')
+				this.initVideos(oTimeline);
 			break;
 
 		case 'outline':

+ 54 - 1
modules/boonex/timeline/js/view.js

@@ -17,6 +17,7 @@ function BxTimelineView(oOptions) {
     this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
     this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
     this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._sVideosAutoplay = oOptions.sVideosAutoplay == undefined ? 'off' : oOptions.sVideosAutoplay;
     this._oRequestParams = {
     	timeline: null,
     	outline: null,
@@ -26,6 +27,10 @@ function BxTimelineView(oOptions) {
     this._fOutsideOffset = 0.8;
     this._oSaved = {};
 
+    this._oVapPlayers = {};
+    this._fVapOffsetStart = 0.8;
+    this._fVapOffsetStop = 0.2;
+
     var $this = this;
     $(document).ready(function() {
     	$this.init();
@@ -54,7 +59,7 @@ BxTimelineView.prototype.init = function() {
 		//--- Hide timeline Events which are outside the viewport
 		this.hideEvents(oItems, this._fOutsideOffset);
 
-		//on scolling, show/animate timeline Events when enter the viewport
+		//--- on scolling, show/animate timeline Events when enter the viewport
 		$(window).on('scroll', function() {
 			if(!window.requestAnimationFrame) 
 				setTimeout(function() {
@@ -65,6 +70,32 @@ BxTimelineView.prototype.init = function() {
 					$this.showEvents(oItems, $this._fOutsideOffset);
 				});
 		});
+		
+		//--- Init Video Autoplay
+		if(this._sVideosAutoplay != 'off') {
+			this.initVideos(this.oViewTimeline);
+
+			this.oViewTimeline.find('iframe').each(function() {
+				var oPlayer = new playerjs.Player(this);
+				if($this._sVideosAutoplay == 'on_mute')
+					oPlayer.mute();
+				
+				$this._oVapPlayers[$(this).attr('id')] = oPlayer;
+			});
+
+			$(window).on('scroll', function() {
+				var oItems = $this.oViewTimeline.find('.' + $this.sClassItem);
+
+				if(!window.requestAnimationFrame) 
+					setTimeout(function() {
+						$this.playVideos(oItems, $this._fVapOffsetStart, $this._fVapOffsetStop);
+					}, 100);
+				else
+					window.requestAnimationFrame(function() {
+						$this.playVideos(oItems, $this._fVapOffsetStart, $this._fVapOffsetStop);
+					});
+			});
+		}
 	}
 
 	if(this.bViewOutline) {
@@ -95,6 +126,28 @@ BxTimelineView.prototype.showEvents = function(oEvents, fOffset) {
 	});
 };
 
+BxTimelineView.prototype.playVideos = function(oEvents, fOffsetStart, fOffsetStop) {
+	var $this = this;
+
+	oEvents.each(function() {
+		$(this).find('iframe').each(function() {
+			var oFrame = $(this);
+			var oPlayer = $this._oVapPlayers[oFrame.attr('id')];
+			if(!oPlayer)
+				return;
+
+			var iFrameTop = oFrame.offset().top;
+			var iFrameBottom = iFrameTop + oFrame.height();
+			var iWindowTop = $(window).scrollTop();
+			var iWindowHeight = $(window).height();
+			if(iFrameTop <= iWindowTop + iWindowHeight * fOffsetStart && iFrameBottom >= iWindowTop + iWindowHeight * fOffsetStop)
+				oPlayer.play();
+			else
+				oPlayer.pause();
+		});
+	});
+};
+
 BxTimelineView.prototype.changePage = function(oLink, iStart, iPerPage) {
 	var $this = this;
 	var sView = this._getView(oLink);

+ 6 - 0
modules/boonex/timeline/template/css/view.css

@@ -284,6 +284,12 @@ div.bx-tl-view-outline div.bx-tl-item-image img {
 	object-position: center center;
 }
 
+/*+++ Item Video +++*/
+.bx-tl-video-iframe {
+	width: 100%;
+	border: none;
+}
+
 /*+++ Item Link +++*/
 div.bx-tl-view-outline div.bx-tl-item-link {
 	text-align: center;

+ 14 - 0
modules/boonex/timeline/template/page_2.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
+	<head>
+	    <meta http-equiv="Content-Type" content="text/html; charset=__page_charset__" />
+	    <title>__page_header__</title>
+	    <base href="<bx_url_root />" />
+
+        <link href="<bx_url_root />template/css/common.css" rel="stylesheet" type="text/css" />
+
+		<script language="javascript" type="text/javascript" src="<bx_url_root />plugins_public/jquery/jquery.min.js"></script>
+		<script language="javascript" type="text/javascript" src="<bx_url_root />plugins_public/player.min.js"></script>
+	</head>
+	<body class=>__page_main_code__</body>
+</html>

+ 1 - 0
modules/boonex/timeline/template/video_iframe.html

@@ -0,0 +1 @@
+<iframe id="__html_id__" class="__style_prefix__-video-iframe" src="__src__" scrolling="no"></iframe>

+ 8 - 0
modules/boonex/timeline/template/video_player.html

@@ -0,0 +1,8 @@
+__player__
+<script language="javascript" type="text/javascript">
+	var oVideo = $('#__html_id__').get(0);
+	oVideo.load();
+
+	var oAdapter = playerjs.HTML5Adapter(oVideo);
+	oAdapter.ready();
+</script>