Просмотр исходного кода

Ticket #4942 - Timeline: Filters panel.

AntonLV 1 год назад
Родитель
Сommit
7e6795bf71

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

@@ -157,6 +157,19 @@
     <string name="_bx_timeline_form_repost_input_sys_do_cancel"><![CDATA[Отмена]]></string>
     <string name="_bx_timeline_form_repost_input_do_cancel"><![CDATA[Отмена]]></string>
 
+    <string name="_bx_timeline_form_filters_input_by_hashtags"><![CDATA[Хэштеги:]]></string>
+    <string name="_bx_timeline_form_filters_input_by_hashtags_any"><![CDATA[Любой]]></string>
+    <string name="_bx_timeline_form_filters_input_by_modules"><![CDATA[Содержимое:]]></string>
+    <string name="_bx_timeline_form_filters_input_by_modules_all"><![CDATA[Всё]]></string>
+    <string name="_bx_timeline_form_filters_input_by_modules_selected"><![CDATA[Выборочно]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media"><![CDATA[Прикрепленные медиа:]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_all"><![CDATA[Все]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_selected"><![CDATA[Выборочно]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_images"><![CDATA[изображения]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_videos"><![CDATA[видео]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_files"><![CDATA[файлы]]></string>
+    <string name="_bx_timeline_form_filters_input_do_apply"><![CDATA[Применить]]></string>
+
     <string name="_bx_timeline_privacy_view"><![CDATA[Просматривать события]]></string>
 
     <string name="_bx_timeline_acl_action_post"><![CDATA[Писать сообщения]]></string>

+ 9 - 1
modules/boonex/timeline/classes/BxTimelineConfig.php

@@ -329,12 +329,14 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
         $this->_aJsClasses = array(
             'main' => 'BxTimelineMain',
             'view' => 'BxTimelineView',
+            'view_filters' => 'BxTimelineViewFilters',
             'post' => 'BxTimelinePost',
             'repost' => 'BxTimelineRepost',
             'manage_tools' => 'BxTimelineManageTools'
         );
         $this->_aJsObjects = array(
             'view' => 'oTimelineView',
+            'view_filters' => 'oTimelineViewFilters',
             'post' => 'oTimelinePost',
             'repost' => 'oTimelineRepost',
             'manage_tools' => 'oBxTimelineManageTools'
@@ -1103,7 +1105,13 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
 
     public function processParam($sValue, $sPattern = "/^[\d\w_]+$/")
     {
-        return bx_process_url_param($sValue, $sPattern);
+        if(!is_array($sValue))
+            return bx_process_url_param($sValue, $sPattern);
+
+        foreach($sValue as $_iKey => $_sValue)
+            $sValue[$_iKey] = bx_process_url_param($_sValue, $sPattern);
+
+        return $sValue;
     }
 
     public function processParamWithDefault($sValue, $sDefault, $sPattern = "/^[\d\w_]+$/")

+ 1 - 1
modules/boonex/timeline/classes/BxTimelineMenuFeeds.php

@@ -30,7 +30,7 @@ class BxTimelineMenuFeeds extends BxTemplMenu
 
     public function setBrowseParams($aParams = [])
     {
-        $this->_sJsObject = $this->_oModule->_oConfig->getJsObjectView($aParams);
+        $this->_sJsObject = $this->_oModule->_oConfig->getJsObject('view_filters');
         $this->_sStylePrefix = $this->_oModule->_oConfig->getPrefix('style');
 
         $aMarkers = array();

+ 23 - 16
modules/boonex/timeline/classes/BxTimelineModule.php

@@ -46,6 +46,8 @@ define('BX_TIMELINE_FILTER_ALL', 'all');
 define('BX_TIMELINE_FILTER_OWNER', 'owner');
 define('BX_TIMELINE_FILTER_OTHER', 'other');
 define('BX_TIMELINE_FILTER_OTHER_VIEWER', 'other_viewer');
+define('BX_TIMELINE_FILTER_PANEL', 'panel');
+define('BX_TIMELINE_FILTER_DEFAULT', BX_TIMELINE_FILTER_ALL);
 
 define('BX_TIMELINE_PARSE_TYPE_POST', 'post');
 define('BX_TIMELINE_PARSE_TYPE_REPOST', 'repost');
@@ -549,8 +551,8 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
             return echoJson(['code' => 1, 'msg' => $mixedResult]);
 
-        $sContent = $this->_oTemplate->getViewBlock($aParams);
-        if(empty($sContent))
+        $aContent = $this->_oTemplate->getViewBlock($aParams);
+        if(empty($aContent['content']))
             return echoJson([]);
 
         if(!empty($aParams['type']))
@@ -558,7 +560,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
         echoJson([
             'code' => 0, 
-            'content' => $sContent,
+            'content' => $aContent['content'],
         ]);
     }
 
@@ -1762,7 +1764,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
             'per_page' => -1, 
             'per_page_default' => $this->_oConfig->getPerPage(BX_BASE_MOD_NTFS_TYPE_OWNER), 
             'timeline' => -1, 
-            'filter' => '', 
+            'filter' => BX_TIMELINE_FILTER_PANEL, 
             'modules' => array()
         ));
     }
@@ -5364,7 +5366,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
             ]));
     }
 
-    public function getParams($sView = '', $sType = '', $iOwnerId = 0, $iStart = 0, $iPerPage = 0, $sFilter = BX_TIMELINE_FILTER_ALL, $aModules = array(), $iTimeline = 0)
+    public function getParams($sView = '', $sType = '', $iOwnerId = 0, $iStart = 0, $iPerPage = 0, $sFilter = BX_TIMELINE_FILTER_DEFAULT, $aModules = array(), $iTimeline = 0)
     {
         return $this->_prepareParams(array(
             'view' => $sView,
@@ -5813,7 +5815,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
             'request_url' => '/api.php?r=bx_timeline/get_posts/&params[]=',
             'params' => $aParams,
             'data' => $aResult
-        ])] : ['content' => $aResult];
+        ])] : $aResult;
     }
 
     protected function _getBlockPost($iProfileId, $aParams = array())
@@ -5870,7 +5872,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
             array('id' => $sView . '-get-rss', 'name' => $sView . '-get-rss', 'class' => '', 'link' => $sRssUrl, 'onclick' => '', 'target' => '_blank', 'title' => _t('_bx_timeline_menu_item_get_rss')),
         );
 
-        $sContent = '';
+        $mixedContent = '';
 
         /**
          * @hooks
@@ -5888,26 +5890,31 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_view', $this->_iOwnerId, $this->getUserId(), [
             'params' => &$aParams,
             'menu' => &$aMenu,
-            'override_content' => &$sContent,
+            'override_content' => &$mixedContent,
         ]);
 
         $oMenu = new BxTemplMenuInteractive(['template' => 'menu_interactive_vertical.html', 'menu_id'=> $sView . '-view-all', 'menu_items' => $aMenu]);
         $oMenu->setSelected('', $sView . '-view-all');
 
-        if (!$sContent)
-            $sContent = $this->_oTemplate->getViewBlock($aParams);
-        
+        if(!$mixedContent)
+            $mixedContent = $this->_oTemplate->getViewBlock($aParams);
+
         if($this->_bIsApi)
             return [bx_api_get_block('browse', [
                 'unit' => 'feed',  
                 'request_url' => '/api.php?r=bx_timeline/get_posts/&params[]=',
                 'params' => $aParams,
-                'data' => $sContent
+                'data' => $mixedContent
             ])];
 
         BxDolTemplate::getInstance()->addPageRssLink(_t('_bx_timeline_page_title_view'), $sRssUrl);
 
-        return array('content' => $sContent, 'menu' => $oMenu);
+        if(is_string($mixedContent))
+            $mixedContent = ['content' => $mixedContent];
+
+        return array_merge($mixedContent, [
+            'menu' => $oMenu
+        ]);
     }
     
     protected function _getContentForTimelinePost($aEvent, $aContentInfo, $aBrowseParams = array())
@@ -6237,7 +6244,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
             $aParams['timeline'] = 0;
 
         if(empty($aParams['filter']))
-            $aParams['filter'] = BX_TIMELINE_FILTER_ALL;
+            $aParams['filter'] = BX_TIMELINE_FILTER_DEFAULT;
 
         if(empty($aParams['modules']) || !is_array($aParams['modules']))
             $aParams['modules'] = array();
@@ -6290,7 +6297,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         $aParams['per_page'] = $aParams['per_page'] !== false ? bx_process_input($aParams['per_page'], BX_DATA_INT) : $this->_oConfig->getPerPage($aParams['type']);
         $aParams['per_page_default'] = $aParams['per_page_default'] !== false ? bx_process_input($aParams['per_page_default'], BX_DATA_INT) : $this->_oConfig->getPerPage($aParams['type']);
         $aParams['timeline'] = $aParams['timeline'] !== false ? bx_process_input($aParams['timeline']) : '';
-        $aParams['filter'] = $aParams['filter'] !== false ? bx_process_input($aParams['filter'], BX_DATA_TEXT) : BX_TIMELINE_FILTER_ALL;
+        $aParams['filter'] = $aParams['filter'] !== false ? bx_process_input($aParams['filter'], BX_DATA_TEXT) : BX_TIMELINE_FILTER_DEFAULT;
         $aParams['modules'] = $aParams['modules'] !== false ? bx_process_input($aParams['modules'], BX_DATA_TEXT) : [];
         $aParams['media'] = $aParams['media'] !== false ? $this->_oConfig->processParam($aParams['media']) : '';
         $aParams['context'] = $aParams['context'] !== false ? $this->_oConfig->processParam($aParams['context']) : '';
@@ -6402,7 +6409,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
         $sType = BX_TIMELINE_TYPE_OWNER_AND_CONNECTIONS;
         $sView = BX_TIMELINE_VIEW_DEFAULT;
-        $sFilter = BX_TIMELINE_FILTER_ALL;
+        $sFilter = BX_TIMELINE_FILTER_DEFAULT;
 
         $aModules = array();
 

+ 152 - 43
modules/boonex/timeline/classes/BxTimelineTemplate.php

@@ -101,6 +101,12 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
                 }
                 break;
 
+            case 'view_filters':
+                $aJs = array_merge($aJs, array(
+                    'view_filters.js',
+                ));
+                break;
+
             case 'post':
                 $aJs = array_merge($aJs, array(
                     'jquery.form.min.js',
@@ -131,7 +137,16 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
 
         return parent::getJsCode('view', $aParams, $bWrap, $bDynamic);
     }
+    
+    public function getJsCodeViewFilters($aParams = [], $bWrap = true, $bDynamic = false)
+    {
+        $aParams = array_merge([
+            'sObjNameMenuFeeds' => $this->_oConfig->getObject('menu_feeds')
+        ], $aParams);
 
+        return parent::getJsCode('view_filters', $aParams, $bWrap, $bDynamic);
+    }
+    
     public function getJsCodePost($iOwnerId, $aParams = array(), $bWrap = true, $bDynamic = false)
     {
         $aGeneralParams = [];
@@ -238,12 +253,14 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
 
         $sTitle = _t('_bx_timeline_page_block_title_views_' . $aParams['view']);
 
-        if (bx_is_api())
+        if ($this->_bIsApi)
             return [
                 'content' => [bx_api_get_block('browse', ['unit' => 'feed', 'data' => $this->getViewBlock($aParams)])],
                 'menu' => $oMenu->getCodeAPI()
             ];
 
+        $aResult = $this->getViewBlock($aParams);
+
         return [
             'content' => $this->parseHtmlByName('block_views.html', [
                 'style_prefix' => $sStylePrefix,
@@ -251,7 +268,7 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
                 'html_id_content' => $this->_oConfig->getHtmlIdView('views_content', $aParams, ['with_type' => false]),
                 'html_id_view_placeholder' => $this->_oConfig->getHtmlIdView('main', array_merge($aParams, ['type' => 'placeholder'])),
                 'title' => $sTitle,
-                'content' => $this->getViewBlock($aParams)
+                'content' => $aResult['content']
             ]),
             'menu' => $oMenu
         ];
@@ -261,25 +278,26 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
     {
         $sStylePrefix = $this->_oConfig->getPrefix('style');
 
-        $sJsObject = $this->_oConfig->getJsObjectView($aParams);
-        $sJsContent = $this->getJsCodeView([
+        $sJsObject = $this->_oConfig->getJsObject('view_filters');
+        $sJsContent = $this->getJsCodeViewFilters([
             'sObjName' => $sJsObject,
             'sName' => $aParams['name'],
             'sView' => $aParams['view'],
             'sType' => $aParams['type'],
-            'sVideosAutoplay' => $this->_oConfig->getVideosAutoplay(),
             'oRequestParams' => $aParams
         ], [
             'wrap' => true,
             'mask_markers' => ['object' => $sJsObject]
         ]);
 
+        $aViewBlock = $this->getViewBlock(array_merge($aParams, ['name' => '']));
+
         return array(
             'content' => $this->parseHtmlByName('block_views_db.html', array(
                 'style_prefix' => $sStylePrefix,
                 'html_id' => $this->_oConfig->getHtmlIdView('views', $aParams, array('with_type' => false)),
                 'html_id_content' => $this->_oConfig->getHtmlIdView('views_content', $aParams, array('with_type' => false)),
-                'content' => $this->getViewBlock(array_merge($aParams, ['name' => ''])),
+                'content' => $aViewBlock['content'],
                 'js_content' => $sJsContent
             )),
             'buttons' => [
@@ -291,8 +309,40 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
     public function getViewFilters($aParams)
     {
         $sStylePrefix = $this->_oConfig->getPrefix('style');
-        $sJsObject = $this->_oConfig->getJsObjectView($aParams);
+        $sJsObject = $this->_oConfig->getJsObject('view_filters');
 
+        $iProfile = bx_get_logged_profile_id();
+
+        $aInputs = [];
+
+        //--- by Hashtag
+        if($aParams['name'] != BX_TIMELINE_NAME_VIEWS_DB) {
+            $oModuleQuery = BxDolModuleQuery::getInstance();
+
+            if(($sChannels = 'bx_channels') && $oModuleQuery->isEnabledByName($sChannels)) {
+                $aChannelsIds = BxDolConnection::getObjectInstance('sys_profiles_subscriptions')->getConnectedContentByType($iProfile, [$sChannels]);
+                if(!empty($aChannelsIds) && is_array($aChannelsIds)) {
+                    $aInputs['by_hashtag'] = [
+                        'name' => 'by_hashtag',
+                        'type' => 'select',
+                        'caption' => _t('_bx_timeline_form_filters_input_by_hashtags'),
+                        'values' => [
+                            ['key' => 0, 'value' => _t('_bx_timeline_form_filters_input_by_hashtags_any')],
+                        ]
+                    ];
+
+                    foreach($aChannelsIds as $iChannelId) {
+                        $oContext = BxDolProfile::getInstance($iChannelId);
+                        if(!$oContext)
+                            continue;
+
+                        $aInputs['by_hashtag']['values'][] = ['key' => $iChannelId, 'value' => $oContext->getDisplayName()];
+                    }
+                }
+            }
+        }
+
+        //--- by Module
         $aHandlers = $this->_oDb->getHandlers(['type' => 'by_type', 'value' => 'insert']);       
 
         $aModules = [];
@@ -320,38 +370,66 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
             return strcmp($aV1['value'], $aV2['value']);
         });
 
-        $aForm = [
-            'inputs' => [
-                'by_module' => [
-                    'name' => 'by_module',
-                    'type' => 'radio_set',
-                    'caption' => _t('_bx_timeline_form_filters_input_by_modules'),
-                    'values' => [
-                        ['key' => 'all', 'value' => _t('_bx_timeline_form_filters_input_by_modules_all')],
-                        ['key' => 'selected', 'value' => _t('_bx_timeline_form_filters_input_by_modules_selected')]
-                    ],
-                    'value' => 'all',
-                    'attrs' => ['onchange' => $sJsObject . '.onFilterByModuleChange(this)'],
-                    'dv_thd' => 1
+        $aInputs = array_merge($aInputs, [
+            'by_module' => [
+                'name' => 'by_module',
+                'type' => 'radio_set',
+                'caption' => _t('_bx_timeline_form_filters_input_by_modules'),
+                'values' => [
+                    ['key' => 'all', 'value' => _t('_bx_timeline_form_filters_input_by_modules_all')],
+                    ['key' => 'selected', 'value' => _t('_bx_timeline_form_filters_input_by_modules_selected')]
                 ],
-                'modules' => [
-                    'name' => 'modules',
-                    'type' => 'checkbox_set',
-                    'values' => array_values($aModules),
-                    'tr_attrs' => ['class' => 'modules', 'style' => 'display:none']
+                'value' => 'all',
+                'attrs' => ['onchange' => $sJsObject . '.onFilterByModuleChange(this)'],
+                'dv_thd' => 1
+            ],
+            'modules' => [
+                'name' => 'modules',
+                'type' => 'checkbox_set',
+                'values' => array_values($aModules),
+                'tr_attrs' => ['class' => 'modules', 'style' => 'display:none']
+            ]
+        ]);
+
+        //--- by Media
+        $aInputs = array_merge($aInputs, [
+            'by_media' => [
+                'name' => 'by_media',
+                'type' => 'radio_set',
+                'caption' => _t('_bx_timeline_form_filters_input_by_media'),
+                'values' => [
+                    ['key' => 'all', 'value' => _t('_bx_timeline_form_filters_input_by_media_all')],
+                    ['key' => 'selected', 'value' => _t('_bx_timeline_form_filters_input_by_media_selected')]
                 ],
+                'value' => 'all',
+                'attrs' => ['onchange' => $sJsObject . '.onFilterByMediaChange(this)'],
+                'dv_thd' => 1
+            ],
+            'media' => [
+                'name' => 'media',
+                'type' => 'checkbox_set',
+                'values' => [
+                    ['key' => 'images', 'value' => _t('_bx_timeline_form_filters_input_by_media_images')],
+                    ['key' => 'videos', 'value' => _t('_bx_timeline_form_filters_input_by_media_videos')],
+                    ['key' => 'files', 'value' => _t('_bx_timeline_form_filters_input_by_media_files')]
+                ],
+                'tr_attrs' => ['class' => 'media', 'style' => 'display:none']
+            ]
+        ]);
+
+        $aForm = [
+            'inputs' => array_merge($aInputs, [                
                 'apply' => [
                     'name' => 'apply',
                     'type' => 'button',
                     'value' => _t('_bx_timeline_form_filters_input_do_apply'),
                     'attrs' => ['onclick' => $sJsObject . '.onFilterApply(this)']
                 ]
-            ]
+            ])
         ];
         $oForm = new BxTemplFormView($aForm);
-        
 
-        $sViewFiltersPopupId = $this->_oConfig->getHtmlIdView('filters_popup', $aParams);
+        $sViewFiltersPopupId = $this->_oConfig->getHtmlIdView('filters_popup', array_merge($aParams, ['name' => '']));
         $sViewFiltersPopupContent = $this->parseHtmlByName('block_view_filters.html', array(
             'style_prefix' => $sStylePrefix,
             'js_object' => $sJsObject,
@@ -389,6 +467,7 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
         }
 
         list($sContent, $sLoadMore, $sBack, $sEmpty, $iEvent, $bEventsToLoad) = $this->getPosts($aParams);
+
         //--- Add live update
         $oModule->actionResumeLiveUpdate($aParams['type'], $aParams['owner_id']);
 
@@ -428,6 +507,12 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
         $sContentBefore = '';
         $sContentAfter = '';
 
+        $bUseFilters = false;
+        if($aParams['filter'] == BX_TIMELINE_FILTER_PANEL) {
+            $bUseFilters = true;
+            $aParams['filter'] = BX_TIMELINE_FILTER_DEFAULT;
+        }
+
         $sJsObject = $this->_oConfig->getJsObjectView($aParams);
         $sJsContent = $this->getJsCodeView(array(
             'sObjName' => $sJsObject,
@@ -474,21 +559,45 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
             'js_content' => &$sJsContent
         ]);
 
-        return $this->parseHtmlByName('block_view.html', array(
-            'style_prefix' => $this->_oConfig->getPrefix('style'),
-            'html_id' => $this->_oConfig->getHtmlIdView('main', $aParams),
-            'view' => $aParams['view'],
-            'back' => $sBack,
-            'empty' => $sEmpty,
-            'content_before' => $sContentBefore,
-            'content' => $sContent,
-            'content_after' => $sContentAfter,
-            'load_more' =>  $sLoadMore,
-            'show_more' => $this->_getShowMore($aParams),
-            'view_image_popup' => $this->_getImagePopup($aParams),
-            'live_update_code' => $sLiveUpdateCode,
-            'js_content' => $sJsContent
-        ));
+        $sJsObjectFilters = '';
+        if($bUseFilters) {
+            $sJsObjectFilters = $this->_oConfig->getJsObject('view_filters');
+            $sJsContent .= $this->getJsCodeViewFilters([
+                'sObjName' => $sJsObject,
+                'sName' => $aParams['name'],
+                'sView' => $aParams['view'],
+                'sType' => $aParams['type'],
+                'oRequestParams' => $aParams
+            ], [
+                'wrap' => true,
+                'mask_markers' => ['object' => $sJsObjectFilters]
+            ]);
+        }
+
+        $aResult = [
+            'content' => $this->parseHtmlByName('block_view.html', [
+                'style_prefix' => $this->_oConfig->getPrefix('style'),
+                'html_id' => $this->_oConfig->getHtmlIdView('main', $aParams),
+                'view' => $aParams['view'],
+                'back' => $sBack,
+                'empty' => $sEmpty,
+                'content_before' => $sContentBefore,
+                'content' => $sContent,
+                'content_after' => $sContentAfter,
+                'load_more' =>  $sLoadMore,
+                'show_more' => $this->_getShowMore($aParams),
+                'view_image_popup' => $this->_getImagePopup($aParams),
+                'live_update_code' => $sLiveUpdateCode,
+                'js_content' => $sJsContent
+            ])
+        ];
+
+        if($bUseFilters)
+            $aResult['buttons'] = [
+                ['title' => _t('_bx_timeline_txt_filters'), 'href' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObjectFilters . '.changeFeedFilters(this)']
+            ];
+
+        return $aResult;
     }
 
     public function getSearchBlock($sContent)

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

@@ -157,9 +157,17 @@
     <string name="_bx_timeline_form_repost_input_sys_do_cancel"><![CDATA[Cancel]]></string>
     <string name="_bx_timeline_form_repost_input_do_cancel"><![CDATA[Cancel]]></string>
 
+    <string name="_bx_timeline_form_filters_input_by_hashtags"><![CDATA[Hashtags:]]></string>
+    <string name="_bx_timeline_form_filters_input_by_hashtags_any"><![CDATA[Any]]></string>
     <string name="_bx_timeline_form_filters_input_by_modules"><![CDATA[Content:]]></string>
     <string name="_bx_timeline_form_filters_input_by_modules_all"><![CDATA[All]]></string>
     <string name="_bx_timeline_form_filters_input_by_modules_selected"><![CDATA[Selected]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media"><![CDATA[Attached media:]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_all"><![CDATA[All]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_selected"><![CDATA[Selected]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_images"><![CDATA[images]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_videos"><![CDATA[videos]]></string>
+    <string name="_bx_timeline_form_filters_input_by_media_files"><![CDATA[files]]></string>
     <string name="_bx_timeline_form_filters_input_do_apply"><![CDATA[Apply]]></string>
 
     <string name="_bx_timeline_privacy_view"><![CDATA[View event]]></string>

+ 0 - 143
modules/boonex/timeline/js/view.js

@@ -393,149 +393,6 @@ BxTimelineView.prototype.reload = function(oSource, onLoad)
     });
 };
 
-BxTimelineView.prototype.changeFeed = function(oLink, sType, oRequestParams)
-{
-    var $this = this;
-    var oViews = $(this._getHtmlId('views_content', this._oRequestParams, {with_type: false})); 
-    var oViewActive = oViews.children(':visible');
-
-    if(this._sVideosAutoplay != 'off')
-        this.pauseVideos(oViewActive);
-
-    var sFilters = this._getHtmlId('filters_popup', jQuery.extend({}, this._oRequestParams, {name: ''}));
-    if($(sFilters).length)
-        $(sFilters).remove();
-
-    this._oRequestParams.type = sType;
-    oRequestParams = jQuery.extend({}, this._oRequestParams, {
-        name: '',
-        start: 0
-    }, oRequestParams);
-
-    var oData = this._getDefaultData(oLink);
-    oData = jQuery.extend({}, oData, oRequestParams);
-
-    var sView = $this._getHtmlId('main', oRequestParams);
-
-    var oTab = $(oLink);
-    var sTabActive = 'bx-menu-tab-active';
-    var sTabActiveBg = 'bx-def-color-bg-active';
-    oTab.parents('ul.' + this.sSP + '-menu-feeds').find('li.' + sTabActive).removeClass(sTabActive + ' ' + sTabActiveBg);
-    oTab.parents('li:first').addClass(sTabActive + ' ' + sTabActiveBg);
-
-    this.loadingIn(oLink, true);
-
-    jQuery.get (
-        this._sActionsUrl + 'get_view',
-        oData,
-        function(oResponse) {
-            if(oLink)
-                $this.loadingIn(oLink, false);
-
-            if(!oResponse.content)
-                return;
-
-            oViewActive.hide('fast', function() {
-                oViews.html('').append(oResponse.content).find(sView).bxProcessHtml();
-            });
-        },
-        'json'
-    );
-
-    return false;
-};
-
-BxTimelineView.prototype.changeFeedFilters = function(oLink, oRequestParams)
-{
-    var $this = this;
-
-    oRequestParams = jQuery.extend({}, this._oRequestParams, {
-        name: '',
-        start: 0
-    }, oRequestParams);
-
-    var sFilters = this._getHtmlId('filters_popup', oRequestParams);
-    if($(sFilters).length)
-        return $(sFilters).dolPopup(this._oFiltersPopupOptions);
-
-    var oData = this._getDefaultData(oLink);
-    if(oRequestParams != undefined)
-        oData = jQuery.extend({}, oData, oRequestParams);
-
-    this.loadingIn(oLink, true);
-
-    jQuery.get (
-        this._sActionsUrl + 'get_view_filters',
-        oData,
-        function(oResponse) {
-            if(oLink)
-                $this.loadingIn(oLink, false);
-
-            if(oResponse && oResponse.popup != undefined) {
-                $this._oFiltersPopupOptions = jQuery.extend({}, oResponse.popup.options, {
-                    pointer: { 
-                        el: $(oLink),
-                        align: 'right'
-                    }
-                });
-
-                oResponse.popup.options = $this._oFiltersPopupOptions;
-            }
-
-            processJsonData(oResponse);
-        },
-        'json'
-    );
-};
-
-BxTimelineView.prototype.toggleMenuItemFeeds = function(oSource)
-{
-    bx_menu_toggle(oSource, this._sObjNameMenuFeeds);
-};
-
-BxTimelineView.prototype.onFilterByModuleChange = function(oSource)
-{
-    var oModules = $(oSource).parents('.bx-form-element-wrapper:first').siblings('.modules');
-    oModules.find("input[name='modules[]']:checked").removeAttr('checked');
-    oModules.bx_anim($(oSource).val() == 'selected' ? 'show' : 'hide');
-};
-
-BxTimelineView.prototype.onFilterApply = function(oSource)
-{
-    var $this = this;
-    var sView = this._getHtmlId('main', this._oRequestParams); 
-    var oFilters = $(oSource).parents('.bx-tl-view-filters:first');
-
-    this._oRequestParams.start = 0;
-    this._oRequestParams.modules = [];
-    if(oFilters.find("input[name='by_module']:checked").val() == 'selected')
-        oFilters.find("input[name='modules[]']:checked").each(function() {
-            $this._oRequestParams.modules.push($(this).val());
-        });
-
-    var oData = this._getDefaultData(oSource);
-
-    this.loadingIn(oSource, true);
-
-    jQuery.get (
-        this._sActionsUrl + 'get_view',
-        oData,
-        function(oResponse) {
-            if(oSource)
-                $this.loadingIn(oSource, false);
-
-            if(!oResponse.content)
-                return;
-
-            $('.bx-popup-applied:visible').dolPopupHide();
-
-            $(sView).replaceWith(oResponse.content);
-            $(sView).bxProcessHtml();
-        },
-        'json'
-    );
-};
-
 BxTimelineView.prototype.changeView = function(oLink, sType, oRequestParams)
 {
     var $this = this;

+ 203 - 0
modules/boonex/timeline/js/view_filters.js

@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Timeline Timeline
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxTimelineViewFilters(oOptions) {
+    BxTimelineMain.call(this, oOptions);
+
+    this._sActionsUri = oOptions.sActionUri;
+    this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oTimelineViewFilters' : oOptions.sObjName;
+    this._sObjNameMenuFeeds = oOptions.sObjNameMenuFeeds == undefined ? 'bx_timeline_menu_feeds' : oOptions.sObjNameMenuFeeds;
+    this._sName = oOptions.sName == undefined ? '' : oOptions.sName;
+    this._sView = oOptions.sView == undefined ? 'timeline' : oOptions.sView;
+    this._sType = oOptions.sType == undefined ? 'public' : oOptions.sType;
+    this._iOwnerId = oOptions.iOwnerId == undefined ? 0 : oOptions.iOwnerId;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
+    this._oFiltersPopupOptions = {};
+}
+
+BxTimelineViewFilters.prototype = Object.create(BxTimelineMain.prototype);
+BxTimelineViewFilters.prototype.constructor = BxTimelineViewFilters;
+
+BxTimelineViewFilters.prototype.changeFeed = function(oLink, sType, oRequestParams)
+{
+    var $this = this;
+    var oViews = $(this._getHtmlId('views_content', this._oRequestParams, {with_type: false})); 
+    var oViewActive = oViews.children(':visible');
+
+    var sFilters = this._getHtmlId('filters_popup', jQuery.extend({}, this._oRequestParams, {name: ''}));
+    if($(sFilters).length)
+        $(sFilters).remove();
+
+    this._oRequestParams.type = sType;
+    oRequestParams = jQuery.extend({}, this._oRequestParams, {
+        name: '',
+        start: 0
+    }, oRequestParams);
+
+    var oData = this._getDefaultData(oLink);
+    oData = jQuery.extend({}, oData, oRequestParams);
+
+    var sView = $this._getHtmlId('main', oRequestParams);
+
+    var oTab = $(oLink);
+    var sTabActive = 'bx-menu-tab-active';
+    var sTabActiveBg = 'bx-def-color-bg-active';
+    oTab.parents('ul.' + this.sSP + '-menu-feeds').find('li.' + sTabActive).removeClass(sTabActive + ' ' + sTabActiveBg);
+    oTab.parents('li:first').addClass(sTabActive + ' ' + sTabActiveBg);
+
+    this.loadingIn(oLink, true);
+
+    jQuery.get (
+        this._sActionsUrl + 'get_view',
+        oData,
+        function(oResponse) {
+            if(oLink)
+                $this.loadingIn(oLink, false);
+
+            if(!oResponse.content)
+                return;
+
+            oViewActive.hide('fast', function() {
+                oViews.html('').append(oResponse.content).find(sView).bxProcessHtml();
+            });
+        },
+        'json'
+    );
+
+    return false;
+};
+
+BxTimelineViewFilters.prototype.changeFeedFilters = function(oLink, oRequestParams)
+{
+    var $this = this;
+
+    oRequestParams = jQuery.extend({}, this._oRequestParams, {
+        start: 0
+    }, oRequestParams);
+
+    var sFilters = this._getHtmlId('filters_popup', jQuery.extend({}, oRequestParams, {name: '', type: (this._sName != '' ? this._oRequestParams.type : this._sType)}));
+    if($(sFilters).length)
+        return $(sFilters).dolPopup(this._oFiltersPopupOptions);
+
+    var oData = this._getDefaultData(oLink);
+    if(oRequestParams != undefined)
+        oData = jQuery.extend({}, oData, oRequestParams);
+
+    this.loadingIn(oLink, true);
+
+    jQuery.get (
+        this._sActionsUrl + 'get_view_filters',
+        oData,
+        function(oResponse) {
+            if(oLink)
+                $this.loadingIn(oLink, false);
+
+            if(oResponse && oResponse.popup != undefined) {
+                $this._oFiltersPopupOptions = jQuery.extend({}, oResponse.popup.options, {
+                    pointer: { 
+                        el: $(oLink),
+                        align: 'right'
+                    }
+                });
+
+                oResponse.popup.options = $this._oFiltersPopupOptions;
+            }
+
+            processJsonData(oResponse);
+        },
+        'json'
+    );
+};
+
+BxTimelineViewFilters.prototype.toggleMenuItemFeeds = function(oSource)
+{
+    bx_menu_toggle(oSource, this._sObjNameMenuFeeds);
+};
+
+BxTimelineViewFilters.prototype.onFilterByModuleChange = function(oSource)
+{
+    var oModules = $(oSource).parents('.bx-form-element-wrapper:first').siblings('.modules');
+    oModules.find("input[name='modules[]']:checked").removeAttr('checked');
+    oModules.bx_anim($(oSource).val() == 'selected' ? 'show' : 'hide');
+};
+
+BxTimelineViewFilters.prototype.onFilterByMediaChange = function(oSource)
+{
+    var oModules = $(oSource).parents('.bx-form-element-wrapper:first').siblings('.media');
+    oModules.find("input[name='media[]']:checked").removeAttr('checked');
+    oModules.bx_anim($(oSource).val() == 'selected' ? 'show' : 'hide');
+};
+
+BxTimelineViewFilters.prototype.onFilterApply = function(oSource)
+{
+    var $this = this;
+
+    oRequestParams = jQuery.extend({}, this._oRequestParams, {
+        name: '',
+        start: 0
+    });
+
+    var sView = this._getHtmlId('main', oRequestParams); 
+    var oFilters = $(oSource).parents('.bx-tl-view-filters:first');
+
+    //--- Apply feed Types
+    var oContext = oFilters.find("select[name='by_hashtag']");
+    if(oContext.length) {
+        var iContext = parseInt(oContext.val());
+        var sType = iContext ? 'bx_channels' : this._sType;
+
+        this._oRequestParams.type = sType;
+
+        oRequestParams.type = sType;
+        oRequestParams.context = iContext;
+    }
+
+    //--- Apply feed Filters
+    oRequestParams.modules = [];
+    if(oFilters.find("input[name='by_module']:checked").val() == 'selected')
+        oFilters.find("input[name='modules[]']:checked").each(function() {
+            oRequestParams.modules.push($(this).val());
+        });
+
+    oRequestParams.media = [];
+    if(oFilters.find("input[name='by_media']:checked").val() == 'selected')
+        oFilters.find("input[name='media[]']:checked").each(function() {
+            oRequestParams.media.push($(this).val());
+        });
+
+    var oData = this._getDefaultData(oSource);
+    if(oRequestParams != undefined)
+        oData = jQuery.extend({}, oData, oRequestParams);
+
+    this.loadingIn(oSource, true);
+
+    jQuery.get (
+        this._sActionsUrl + 'get_view',
+        oData,
+        function(oResponse) {
+            if(oSource)
+                $this.loadingIn(oSource, false);
+
+            if(!oResponse.content)
+                return;
+
+            $('.bx-popup-applied:visible').dolPopupHide();
+
+            $(sView).replaceWith(oResponse.content);
+            $(sView).bxProcessHtml();
+        },
+        'json'
+    );
+};