From a16926dbed40fc69c631e5a7fc876fb58e65f884 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Tue, 6 Dec 2016 18:35:29 +0100 Subject: [PATCH] Fixed multiple instances of recent activities --- .../templates/boxRecentActivity.tpl | 16 ++-- .../Core/Ui/User/Activity/Recent.js | 86 +++++++++++++++++++ .../event/UserActivityEventAction.class.php | 60 ++++++++++--- .../RecentActivityListBoxController.class.php | 33 +++++++ 4 files changed, 177 insertions(+), 18 deletions(-) create mode 100644 wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Activity/Recent.js diff --git a/com.woltlab.wcf/templates/boxRecentActivity.tpl b/com.woltlab.wcf/templates/boxRecentActivity.tpl index 70ed0d93c9..db1bc08e38 100644 --- a/com.woltlab.wcf/templates/boxRecentActivity.tpl +++ b/com.woltlab.wcf/templates/boxRecentActivity.tpl @@ -1,11 +1,17 @@ -
+

{lang}wcf.user.recentActivity{/lang}

{assign var='__events' value=$eventList->getObjects()} {assign var='__lastEvent' value=$__events|end} -
    +
      {if $canFilterByFollowedUsers}
      • @@ -20,12 +26,12 @@
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Activity/Recent.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Activity/Recent.js new file mode 100644 index 0000000000..2bda92c98c --- /dev/null +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Activity/Recent.js @@ -0,0 +1,86 @@ +define(['Ajax', 'Language', 'Dom/Util'], function(Ajax, Language, DomUtil) { + "use strict"; + + function UiUserActivityRecent(containerId) { this.init(containerId); } + UiUserActivityRecent.prototype = { + init: function (containerId) { + this._containerId = containerId; + var container = elById(this._containerId); + this._list = elBySel('.recentActivityList', container); + + var showMoreItem = elCreate('li'); + showMoreItem.className = 'showMore'; + if (this._list.childElementCount) { + showMoreItem.innerHTML = ''; + showMoreItem.children[0].addEventListener(WCF_CLICK_EVENT, this._showMore.bind(this)); + } + else { + showMoreItem.innerHTML = '' + Language.get('wcf.user.recentActivity.noMoreEntries') + ''; + } + + this._list.appendChild(showMoreItem); + this._showMoreItem = showMoreItem; + + var button = elBySel('.jsRecentActivitySwitchContext button:not(.active)', container); + if (button !== null) { + button.addEventListener(WCF_CLICK_EVENT, this._switchContext.bind(this)); + } + }, + + _showMore: function (event) { + event.preventDefault(); + + this._showMoreItem.children[0].disabled = true; + + Ajax.api(this, { + actionName: 'load', + parameters: { + boxID: ~~elData(this._list, 'box-id'), + filteredByFollowedUsers: elDataBool(this._list, 'filtered-by-followed-users'), + lastEventId: elData(this._list, 'last-event-id'), + lastEventTime: elData(this._list, 'last-event-time'), + userID: ~~elData(this._list, 'user-id') + } + }); + }, + + _switchContext: function(event) { + event.preventDefault(); + + Ajax.api( + this, + { + actionName: 'switchContext' + }, + (function () { + window.location.hash = '#' + this._containerId; + window.location.reload(); + }).bind(this) + ); + }, + + _ajaxSuccess: function(data) { + if (data.returnValues.template) { + DomUtil.insertHtml(data.returnValues.template, this._showMoreItem, 'before'); + + elData(this._list, 'last-event-time', data.returnValues.lastEventTime); + elData(this._list, 'last-event-id', data.returnValues.lastEventID); + + this._showMoreItem.children[0].disabled = false; + } + else { + this._showMoreItem.innerHTML = '' + Language.get('wcf.user.recentActivity.noMoreEntries') + ''; + } + }, + + _ajaxSetup: function () { + return { + data: { + className: 'wcf\\data\\user\\activity\\event\\UserActivityEventAction' + } + }; + } + }; + + return UiUserActivityRecent; +}); diff --git a/wcfsetup/install/files/lib/data/user/activity/event/UserActivityEventAction.class.php b/wcfsetup/install/files/lib/data/user/activity/event/UserActivityEventAction.class.php index 501d46f5b7..4911f47302 100644 --- a/wcfsetup/install/files/lib/data/user/activity/event/UserActivityEventAction.class.php +++ b/wcfsetup/install/files/lib/data/user/activity/event/UserActivityEventAction.class.php @@ -1,8 +1,11 @@ readInteger('boxID', true); $this->readBoolean('filteredByFollowedUsers', true); $this->readInteger('lastEventTime'); $this->readInteger('lastEventID', true); $this->readInteger('userID', true); + + if ($this->parameters['boxID']) { + $box = new Box($this->parameters['boxID']); + if ($box->boxID) { + $this->boxController = $box->getController(); + if ($this->boxController instanceof RecentActivityListBoxController) { + // all checks passed, end validation; otherwise throw the exception below + return; + } + } + + throw new UserInputException('boxID'); + } } /** @@ -40,25 +62,33 @@ class UserActivityEventAction extends AbstractDatabaseObjectAction { * @return array */ public function load() { - $eventList = new ViewableUserActivityEventList(); - if ($this->parameters['lastEventID']) { - $eventList->getConditionBuilder()->add("user_activity_event.time <= ?", [$this->parameters['lastEventTime']]); - $eventList->getConditionBuilder()->add("user_activity_event.eventID < ?", [$this->parameters['lastEventID']]); + $box = null; + if ($this->boxController !== null) { + $eventList = $this->boxController->getFilteredList(); + } else { - $eventList->getConditionBuilder()->add("user_activity_event.time < ?", [$this->parameters['lastEventTime']]); + $eventList = new ViewableUserActivityEventList(); + + // profile view + if ($this->parameters['userID']) { + $eventList->getConditionBuilder()->add("user_activity_event.userID = ?", [$this->parameters['userID']]); + } + else { + /** @noinspection PhpUndefinedMethodInspection */ + if ($this->parameters['filteredByFollowedUsers'] && count(WCF::getUserProfileHandler()->getFollowingUsers())) { + /** @noinspection PhpUndefinedMethodInspection */ + $eventList->getConditionBuilder()->add('user_activity_event.userID IN (?)', [WCF::getUserProfileHandler()->getFollowingUsers()]); + } + } } - // profile view - if ($this->parameters['userID']) { - $eventList->getConditionBuilder()->add("user_activity_event.userID = ?", [$this->parameters['userID']]); + if ($this->parameters['lastEventID']) { + $eventList->getConditionBuilder()->add("user_activity_event.time <= ?", [$this->parameters['lastEventTime']]); + $eventList->getConditionBuilder()->add("user_activity_event.eventID < ?", [$this->parameters['lastEventID']]); } else { - /** @noinspection PhpUndefinedMethodInspection */ - if ($this->parameters['filteredByFollowedUsers'] && count(WCF::getUserProfileHandler()->getFollowingUsers())) { - /** @noinspection PhpUndefinedMethodInspection */ - $eventList->getConditionBuilder()->add('user_activity_event.userID IN (?)', [WCF::getUserProfileHandler()->getFollowingUsers()]); - } + $eventList->getConditionBuilder()->add("user_activity_event.time < ?", [$this->parameters['lastEventTime']]); } $eventList->readObjects(); @@ -71,6 +101,10 @@ class UserActivityEventAction extends AbstractDatabaseObjectAction { // removes orphaned and non-accessible events UserActivityEventHandler::validateEvents($eventList); + if ($this->boxController !== null) { + $eventList->truncate($this->boxController->getBox()->limit); + } + if (!count($eventList)) { return []; } diff --git a/wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php b/wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php index c0708a77cc..720adafb82 100644 --- a/wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php +++ b/wcfsetup/install/files/lib/system/box/RecentActivityListBoxController.class.php @@ -1,6 +1,8 @@ getBox()->position == 'contentTop' || $this->getBox()->position == 'contentBottom') { /** @noinspection PhpUndefinedMethodInspection */ return WCF::getTPL()->fetch('boxRecentActivity', 'wcf', [ + 'boxID' => $this->getBox()->boxID, 'canFilterByFollowedUsers' => $this->canFilterByFollowedUsers, 'eventList' => $this->objectList, 'lastEventTime' => $this->objectList->getLastEventTime(), @@ -101,6 +104,7 @@ class RecentActivityListBoxController extends AbstractDatabaseObjectListBoxContr } else { return WCF::getTPL()->fetch('boxRecentActivitySidebar', 'wcf', [ + 'boxID' => $this->getBox()->boxID, 'eventList' => $this->objectList ], true); } @@ -135,4 +139,33 @@ class RecentActivityListBoxController extends AbstractDatabaseObjectListBoxContr // remove unused items $this->objectList->truncate($this->box->limit); } + + public function getFilteredList() { + $this->objectList = $this->getObjectList(); + + if ($this->limit) { + $this->objectList->sqlLimit = $this->box->limit; + } + + if ($this->sortOrder && $this->sortField) { + $alias = $this->objectList->getDatabaseTableAlias(); + $this->objectList->sqlOrderBy = $this->sortField . ' ' . $this->sortOrder . ", " . ($alias ? $alias . "." : "") . $this->objectList->getDatabaseTableIndexName() . " " . $this->sortOrder; + } + + if ($this->conditionDefinition) { + foreach ($this->box->getConditions() as $condition) { + /** @var IObjectListCondition $processor */ + $processor = $condition->getObjectType()->getProcessor(); + $processor->addObjectListCondition($this->objectList, $condition->conditionData); + } + } + + // apply filter + if (($this->getBox()->position == 'contentTop' || $this->getBox()->position == 'contentBottom') && $this->filteredByFollowedUsers) { + /** @noinspection PhpUndefinedMethodInspection */ + $this->objectList->getConditionBuilder()->add('user_activity_event.userID IN (?)', [WCF::getUserProfileHandler()->getFollowingUsers()]); + } + + return $this->objectList; + } } -- 2.20.1