1
0
Эх сурвалжийг харах

Ticket #3618 - Comments: Use preview from Albums module in images attached to a comment.

AntonLV 4 жил өмнө
parent
commit
4b5f4ce428

+ 51 - 0
inc/classes/BxDolCmts.php

@@ -1341,6 +1341,57 @@ class BxDolCmts extends BxDolFactory implements iBxDolReplaceable, iBxDolContent
     	BxDolSession::getInstance()->setValue($sKey, 1);
     }
 
+    public function actionGetSiblingFiles()
+    {
+        $iFileId = 0;
+        if(bx_get('file_id') !== false)
+            $iFileId = bx_process_input(bx_get('file_id'), BX_DATA_INT);
+
+        if(!($aFileInfo = $this->_oQuery->getFileInfoById((int)$iFileId))) 
+            return echoJson(['error' => _t('_sys_txt_error_occured')]);
+
+        $aSiblings = [];
+        $aFiles = $this->_oQuery->getFiles($aFileInfo['system_id'], $aFileInfo['cmt_id']);
+        foreach($aFiles as $iIndex => $aFile) {
+            if($aFile['id'] != $iFileId)
+                continue;
+
+            $aSiblings['prev'] = isset($aFiles[$iIndex - 1]) ? $aFiles[$iIndex - 1] : false;
+            $aSiblings['next'] = isset($aFiles[$iIndex + 1]) ? $aFiles[$iIndex + 1] : false;
+        }
+
+        $oStorage = BxDolStorage::getObjectInstance($this->getStorageObjectName());
+        $oTranscoder = BxDolTranscoderImage::getObjectInstance($this->getTranscoderPreviewName());
+
+        foreach($aSiblings as $sSibling => $aSibling) {
+            if(!$aSibling)
+                continue;
+
+            $sFile = '';
+            if($oTranscoder && $oTranscoder->isMimeTypeSupported($aSibling['mime_type']))
+                $sFile = $oStorage->getFileUrlById($aSibling['image_id']);
+            else
+                $sFile = $oStorage->getFontIconNameByFileName($aFile['file_name']);
+
+            $aImageInfo = BxDolImageResize::getInstance()->getImageSize($sFile);
+
+            $iWidth = $iHeight = 0;
+            if(isset($aImageInfo['w']))
+                $iWidth = (int)$aImageInfo['w'];
+            if(isset($aImageInfo['h']))
+                $iHeight = (int)$aImageInfo['h'];
+
+            $aSiblings[$sSibling] = array_merge($aSibling, [
+                'file' => $sFile,
+                'file_id' => $aSibling['id'],
+                'w' => $iWidth, 
+                'h' => $iHeight
+            ]);
+        }
+
+        return echoJson($aSiblings);
+    }
+
     public function onPostAfter($iCmtId)
     {
         $iObjId = (int)$this->getId();

+ 16 - 0
inc/classes/BxDolCmtsQuery.php

@@ -579,6 +579,22 @@ class BxDolCmtsQuery extends BxDolDb
         return $this->getAll($sQuery, $aBindings);
     }
 
+    public function getFileInfoById($iFileId)
+    {
+        $sQuery = "SELECT 
+                `tf2e`.*,
+                `tf`.`file_name` AS `file_name`,
+                `tf`.`mime_type` AS `mime_type`,
+                `tf`.`size` AS `size` 
+            FROM `{$this->_sTableFiles2Entries}` AS `tf2e` 
+            LEFT JOIN `{$this->_sTableFiles}` AS `tf` ON (`tf2e`.`image_id` = `tf`.`id`) 
+            WHERE `tf2e`.`id`=:id ";
+
+        return $this->getRow($sQuery, array(
+            'id' => $iFileId
+    	));
+    }
+
     function deleteImages($iSystemId, $iCmtId, $iImageId = false)
     {
         $sWhereAddon = "";

+ 168 - 2
inc/js/classes/BxDolCmts.js

@@ -410,8 +410,174 @@ BxDolCmts.prototype.showMore = function(oLink)
 	$(oLink).parent('span').next('span').show().prev('span').remove();
 };
 
-BxDolCmts.prototype.showImage = function(oLink, sUrl) {
-	$(this._sRootId + '-view-image-popup').dolPopupImage(sUrl, $(oLink).parents('.cmt-attached:first'));
+BxDolCmts.prototype.showImage = function(eve, oLink)
+{
+    var $this = this;
+    var ePswp = document.querySelectorAll('.pswp.cmts')[0];
+
+    var aItems = []; // more items are added dynamically
+    var oItem = {};
+    var iCount = 0;
+    var options = {
+        shareEl: false,
+        counterEl: false,
+        history: false,
+        loop: false,
+        showHideOpacity: true,
+        index: 0,
+        getThumbBoundsFn: function(index) {
+            var e = $('a[data-file-id] img');
+            if (!e.length)
+                return false;
+
+            return {x:e.offset().left, y:e.offset().top, w:e.width()};
+        }
+    };
+
+    var fnProcessRetina = function (o) {
+        var dpr = ((window.glBxDisableRetina !== undefined && window.glBxDisableRetina) || window.devicePixelRatio === undefined ? 1 : window.devicePixelRatio);
+        if (dpr < 2)
+            return o;
+        o.w *= 2;
+        o.h *= 2;
+        return o;
+    };
+
+    eve.preventDefault ? eve.preventDefault() : eve.returnValue = false;
+
+    // get data for initial item from the attributes of the item which was clicked
+    $.each(oLink.attributes, function(i, attr) {
+        var sName = attr.name;
+        if (sName.indexOf('data-') !== 0)
+            return;
+
+        sName = sName.replace('data-', '');
+        oItem[sName] = attr.value;        
+
+        ++iCount;
+    });
+
+    oItem.msrc = oItem.src;
+    oItem = fnProcessRetina(oItem);
+
+    if(!iCount)
+        return false;
+
+    aItems.push(oItem);
+
+    var fnConverMedia = function (oMedia) {
+        var oMap = {
+            'id': 'file-id',
+            'file' : 'src',
+            'w': 'w',
+            'h': 'h'
+        };
+
+        var o = {};
+        for (var i in oMap)
+            o[oMap[i]] = oMedia[i];
+
+        return fnProcessRetina(o);
+    };
+
+    var fnIndexOfMediaObject = function (oArray, oItem) {
+        var iLength = oArray.length;
+        for (var i=0 ; i < iLength ; ++i)
+            if (oItem['file-id'] == oArray[i]['file-id'])
+                return i;
+
+        return -1;
+    };
+
+    var fnDisableArrows = function (oItem) {
+
+        // disable prev item and action if we are on the first item
+        if (0 == fnIndexOfMediaObject(aItems, oItem)) {
+            $('.pswp.cmts .pswp__button--arrow--left').hide();
+            glSysCmtsPrevFn = glSysCmtsGallery.prev;
+            glSysCmtsGallery.prev = function () { };
+        } 
+        else {
+            $('.pswp.cmts .pswp__button--arrow--left').show();
+            if ('undefined' !== typeof(glSysCmtsPrevFn))
+                glSysCmtsGallery.prev = glSysCmtsPrevFn;
+        }
+
+        // disable next item and action when we are in the last item
+        if ((aItems.length-1) == fnIndexOfMediaObject(aItems, oItem)) {
+            $('.pswp.cmts .pswp__button--arrow--right').hide();
+            glSysCmtsNextFn = glSysCmtsGallery.next;
+            glSysCmtsGallery.next = function () { };
+        } 
+        else {
+            $('.pswp.cmts .pswp__button--arrow--right').show();
+            if ('undefined' !== typeof(glSysCmtsNextFn))
+                glSysCmtsGallery.next = glSysCmtsNextFn;
+        }
+    };
+
+    var fnLoadMoreItem = function (oItemCurrent, bFirstLoad) {
+
+        // load addutional items only for items on the border
+        if (0 != fnIndexOfMediaObject(aItems, oItemCurrent) && (aItems.length-1) != fnIndexOfMediaObject(aItems, oItemCurrent))
+            return;
+
+        var sUrl = bx_append_url_params($this._sActionsUrl, {sys: $this._sSystem, id: $this._iObjId, action: 'GetSiblingFiles', file_id: oItemCurrent['file-id']});
+        $.getJSON(sUrl, function(oData) {
+
+            if ('undefined' !== typeof(oData.error)) {
+                if ('undefined' !== typeof(console))
+                    console.log(oData.error);
+
+                return;
+            }
+
+            var iGoTo = -1;
+            var iLength = aItems.length;
+
+            if (0 == fnIndexOfMediaObject(aItems, oItemCurrent) && 'undefined' !== typeof(oData.prev.file)) {
+                aItems.unshift(fnConverMedia(oData.prev));
+                if (bFirstLoad)
+                    options.index = 1;
+                else
+                    iGoTo = glSysCmtsGallery.getCurrentIndex() + 1;
+            }
+    
+            if ((aItems.length - 1) == fnIndexOfMediaObject(aItems, oItemCurrent) && 'undefined' !== typeof(oData.next.file))
+                aItems.push(fnConverMedia(oData.next));
+
+            if (!bFirstLoad && iLength != aItems.length) {
+                glSysCmtsGallery.invalidateCurrItems();
+                glSysCmtsGallery.updateSize(true);
+
+                if(iGoTo >= 0)
+                    glSysCmtsGallery.goTo(iGoTo);
+            }
+
+            if (bFirstLoad) {
+                glSysCmtsGallery = new PhotoSwipe(ePswp, PhotoSwipeUI_Default, aItems, options);
+                glSysCmtsGallery.init();
+
+                glSysCmtsGallery.listen('beforeChange', function() { 
+                    // load more items if we are on first or on the last item
+                    fnLoadMoreItem(glSysCmtsGallery.currItem, false);
+                });
+
+                glSysCmtsGallery.listen('afterChange', function() {
+                    fnDisableArrows(glSysCmtsGallery.currItem);
+                });
+
+                glSysCmtsGallery.listen('close', function() {
+                });
+
+                fnDisableArrows(glSysCmtsGallery.currItem);
+            }
+        });
+    };
+
+    fnLoadMoreItem(oItem, true);
+
+    return false;
 };
 
 BxDolCmts.prototype.toggleReply = function(e, iCmtParentId, iQuote)

+ 12 - 12
template/comment_attachments.html

@@ -1,14 +1,14 @@
 <bx_repeat:attached>
-	<div class="__style_prefix__-attached-preview bx-def-round-corners bx-def-margin-thd">
-		<bx_if:show_image>
-			<a href="javascript:void(0)" onclick="__js_object__.showImage(this, '__file__'); return false;" title="<bx_text_attribute:_cmt_view_attached_image />">
-				<img src="<bx_image_url:spacer.gif />" style="background-image:url(__preview__)" />
-			</a>
-		</bx_if:show_image>
-		<bx_if:show_file>
-			<a href="__file__" title="<bx_text_attribute:_cmt_download_attached_file />">
-				<img src="<bx_image_url:spacer.gif />" style="background-image:url(__preview__)" />
-			</a>
-		</bx_if:show_file>
-	</div>
+    <div class="__style_prefix__-attached-preview bx-def-round-corners bx-def-margin-thd">
+        <bx_if:show_image>
+            <a href="javascript:void(0)" onclick="__js_object__.showImage(event || window.event, this)" data-file-id="__file_id__" data-src="__file__" data-w="__w__" data-h="__h__" title="<bx_text_attribute:_cmt_view_attached_image />">
+                <img src="<bx_image_url:spacer.gif />" style="background-image:url(__preview__)" />
+            </a>
+        </bx_if:show_image>
+        <bx_if:show_file>
+            <a href="__file__" title="<bx_text_attribute:_cmt_download_attached_file />">
+                <img src="<bx_image_url:spacer.gif />" style="background-image:url(__preview__)" />
+            </a>
+        </bx_if:show_file>
+    </div>
 </bx_repeat:attached>

+ 0 - 1
template/comment_block.html

@@ -5,5 +5,4 @@
 		</ul>
 	</div>
 </div>
-__view_image_popup__
 __script__

+ 1 - 2
template/comment_search.html

@@ -1,2 +1 @@
-__comment__
-__view_image_popup__
+__comment__

+ 0 - 1
template/comments_block.html

@@ -10,5 +10,4 @@
     </div>
     __post_form_bottom__
 </div>
-__view_image_popup__
 __script__

+ 64 - 0
template/comments_photoswipe.html

@@ -0,0 +1,64 @@
+<!-- Root element of PhotoSwipe. Must have class pswp. -->
+<div class="pswp cmts" tabindex="-1" role="dialog" aria-hidden="true">
+
+    <!-- Background of PhotoSwipe. 
+         It's a separate element as animating opacity is faster than rgba(). -->
+    <div class="pswp__bg"></div>
+
+    <!-- Slides wrapper with overflow:hidden. -->
+    <div class="pswp__scroll-wrap">
+
+        <!-- Container that holds slides. 
+            PhotoSwipe keeps only 3 of them in the DOM to save memory.
+            Don't modify these 3 pswp__item elements, data is added later on. -->
+        <div class="pswp__container">
+            <div class="pswp__item"></div>
+            <div class="pswp__item"></div>
+            <div class="pswp__item"></div>
+        </div>
+
+        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
+        <div class="pswp__ui pswp__ui--hidden">
+
+            <div class="pswp__top-bar">
+
+                <!--  Controls are self-explanatory. Order can be changed. -->
+
+                <div class="pswp__counter"></div>
+
+                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
+
+                <button class="pswp__button pswp__button--share" title="Share"></button>
+
+                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
+
+                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
+
+                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
+                <!-- element will get class pswp__preloader - active when preloader is running -->
+                <div class="pswp__preloader">
+                    <div class="pswp__preloader__icn">
+                      <div class="pswp__preloader__cut">
+                        <div class="pswp__preloader__donut"></div>
+                      </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
+                <div class="pswp__share-tooltip"></div> 
+            </div>
+
+            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"></button>
+
+            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"></button>
+
+            <div class="pswp__caption">
+                <div class="pswp__caption__center"></div>
+            </div>
+
+        </div>
+
+    </div>
+
+</div>

+ 33 - 16
template/scripts/BxBaseCmts.php

@@ -87,6 +87,16 @@ class BxBaseCmts extends BxDolCmts
     {
         $oForm = BxDolForm::getObjectInstance($this->_sFormObject, $this->_sFormDisplayPost);
         $oForm->addCssJs();
+
+        $this->_oTemplate->addCss(array(
+            BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'photo-swipe/|photoswipe.css',
+            BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'photo-swipe/default-skin/|default-skin.css',
+        ));
+
+        $this->_oTemplate->addJs(array(
+            'photo-swipe/photoswipe.min.js',
+            'photo-swipe/photoswipe-ui-default.min.js',
+        ));
     }
 
     public function getJsObjectName()
@@ -182,10 +192,11 @@ class BxBaseCmts extends BxDolCmts
             'content_after' => $sContentAfter,
             'post_form_top' => $sPostFormTop,
             'post_form_bottom'  => $sPostFormBottom,
-            'view_image_popup' => $this->_getViewImagePopup(),
             'script' => $sJsContent
         ));
 
+        $this->_oTemplate->addInjection ('injection_footer', 'text', $this->_oTemplate->parseHtmlByName('comments_photoswipe.html', []));
+
         return $aDp['in_designbox'] ? DesignBoxContent($sBlockTitle, $sContent, BX_DB_DEF, $sBlockMenu) : array(
             'title' => $sBlockTitle,
             'content' => $sContent,
@@ -276,11 +287,12 @@ class BxBaseCmts extends BxDolCmts
         if (!$sComment)
             return '';
 
+        $this->_oTemplate->addInjection ('injection_footer', 'text', $this->_oModule->_oTemplate->parseHtmlByName('comments_photoswipe.html', []));
+
         return $this->_oTemplate->parseHtmlByName('comment_block.html', array(
             'system' => $this->_sSystem,
             'id' => $this->getId(),
             'comment' => $sComment,
-            'view_image_popup' => $this->_getViewImagePopup(), 
             'script' => $this->getJsScript($aBp, $aDp)
         ));
     }
@@ -442,9 +454,10 @@ class BxBaseCmts extends BxDolCmts
         if(empty($sAddon))
             $sAddon = $this->getJsScript($aBp, $aDp);
 
+        $this->_oTemplate->addInjection ('injection_footer', 'text', $this->_oTemplate->parseHtmlByName('comments_photoswipe.html', []));
+
         return $this->_oTemplate->parseHtmlByName('comment_search.html', array(
             'comment' => $this->getComment($iCmtId, $aBp, $aDp),
-            'view_image_popup' => $this->_getViewImagePopup(), 
         )); 
     }
 
@@ -1324,16 +1337,6 @@ class BxBaseCmts extends BxDolCmts
         ));
     }
 
-    protected function _getViewImagePopup()
-    {
-    	$sViewImagePopupId = 'cmts-box-' . $this->_sSystem . '-' . $this->getId() . '-view-image-popup' ;
-        $sViewImagePopupContent = $this->_oTemplate->parseHtmlByName('popup_image.html', array(
-            'image_url' => ''
-    	));
-
-    	return BxTemplFunctions::getInstance()->transBox($sViewImagePopupId, $sViewImagePopupContent, true);
-    }
-
     protected function _getAttachments($aCmt)
     {
         $aTmplImages = array();
@@ -1346,11 +1349,22 @@ class BxBaseCmts extends BxDolCmts
             $oTranscoder = BxDolTranscoderImage::getObjectInstance($this->getTranscoderPreviewName());
 
             foreach($aFiles as $aFile) {
+                $sFile = $oStorage->getFileUrlById($aFile['image_id']);
                 $bImage = $oTranscoder && $oTranscoder->isMimeTypeSupported($aFile['mime_type']);
 
                 $sPreview = '';
-                if($oTranscoder && $bImage)
-                    $sPreview = $oTranscoder->getFileUrl($aFile['image_id']);
+                $iWidth = $iHeight = 0;
+
+                if($bImage) {
+                    if($oTranscoder)
+                        $sPreview = $oTranscoder->getFileUrl($aFile['image_id']);
+
+                    $aImageInfo = BxDolImageResize::getInstance()->getImageSize($sFile);
+                    if(isset($aImageInfo['w']))
+                        $iWidth = (int)$aImageInfo['w'];
+                    if(isset($aImageInfo['h']))
+                        $iHeight = (int)$aImageInfo['h'];
+                }
 
                 if(!$sPreview)
                     $sPreview = $this->_oTemplate->getIconUrl($oStorage->getIconNameByFileName($aFile['file_name']));
@@ -1358,10 +1372,13 @@ class BxBaseCmts extends BxDolCmts
                 $aTmplVarsFile = array(
                     'js_object' => $this->_sJsObjName,
                     'preview' => $sPreview,
-                    'file' => $oStorage->getFileUrlById($aFile['image_id']),
+                    'file' => $sFile,
+                    'file_id' => $aFile['id'],
                     'file_name' => $aFile['file_name'],
                     'file_icon' => $oStorage->getFontIconNameByFileName($aFile['file_name']),
                     'file_size' => _t_format_size($aFile['size']),
+                    'w' => $iWidth, 
+                    'h' => $iHeight
                 );
 
                 $aTmplImages[] = array(