From 83976453546cef767d0e62e3e8a39b098ec1144d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 29 Sep 2014 01:38:13 +0200 Subject: [PATCH 1/8] Add first pieces of invitation system --- .../InvitedUserNotificationEvent.class.php | 75 +++++++++++++++++++ .../RoomUserNotificationObject.class.php | 50 +++++++++++++ .../RoomUserNotificationObjectType.class.php | 28 +++++++ language/de.xml | 5 ++ language/en.xml | 5 ++ objectType.xml | 6 ++ package.xml | 1 + userNotificationEvent.xml | 12 +++ 8 files changed, 182 insertions(+) create mode 100644 file/lib/system/user/notification/event/InvitedUserNotificationEvent.class.php create mode 100644 file/lib/system/user/notification/object/RoomUserNotificationObject.class.php create mode 100644 file/lib/system/user/notification/object/type/RoomUserNotificationObjectType.class.php create mode 100644 userNotificationEvent.xml diff --git a/file/lib/system/user/notification/event/InvitedUserNotificationEvent.class.php b/file/lib/system/user/notification/event/InvitedUserNotificationEvent.class.php new file mode 100644 index 0000000..c76d2ff --- /dev/null +++ b/file/lib/system/user/notification/event/InvitedUserNotificationEvent.class.php @@ -0,0 +1,75 @@ + + * @package be.bastelstu.chat + * @subpackage system.user.notification.event + */ +class InvitedUserNotificationEvent extends \wcf\system\user\notification\event\AbstractUserNotificationEvent { + /** + * @see \wcf\system\user\notification\event\AbstractUserNotificationEvent::$stackable + */ + protected $stackable = false; + + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::getAuthorID() + */ + public function getAuthorID() { + return $this->getAuthor()->userID; + } + + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::getAuthor() + */ + public function getAuthor() { + // TODO: caching + return new \wcf\data\user\UserProfile(new \wcf\data\user\User($this->additionalData['userID'])); + } + + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::getTitle() + */ + public function getTitle() { + return $this->getLanguage()->get('chat.notification.invited.title'); + } + + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::getMessage() + */ + public function getMessage() { + return $this->getLanguage()->getDynamicVariable('chat.notification.invited.message', array( + 'userNotificationObject' => $this->userNotificationObject, + 'author' => $this->author + )); + } + + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::getLink() + */ + public function getLink() { + return \wcf\system\request\LinkHandler::getInstance()->getLink('Chat', array( + 'application' => 'chat', + 'object' => $this->userNotificationObject->getDecoratedObject() + )); + } + + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::supportsEmailNotification() + */ + public function supportsEmailNotification() { + return false; + } + + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::checkAccess() + */ + public function checkAccess() { + // TODO + return true; + } +} diff --git a/file/lib/system/user/notification/object/RoomUserNotificationObject.class.php b/file/lib/system/user/notification/object/RoomUserNotificationObject.class.php new file mode 100644 index 0000000..18d95ec --- /dev/null +++ b/file/lib/system/user/notification/object/RoomUserNotificationObject.class.php @@ -0,0 +1,50 @@ + + * @package be.bastelstu.chat + * @subpackage system.user.notification.object + */ +class RoomUserNotificationObject extends \wcf\data\DatabaseObjectDecorator implements \wcf\system\user\notification\object\IUserNotificationObject { + /** + * @see \wcf\data\DatabaseObjectDecorator::$baseClass + */ + protected static $baseClass = 'chat\data\room\Room'; + + /** + * @see \wcf\system\user\notification\object\IUserNotificationObject::getObjectID() + */ + public function getObjectID() { + return $this->roomID; + } + + /** + * @see \wcf\system\user\notification\object\IUserNotificationObject::getTitle() + */ + public function getTitle() { + return $this->getDecoratedObject()->getTitle(); + } + + /** + * @see \wcf\system\user\notification\object\IUserNotificationObject::getURL() + */ + public function getURL() { + return \wcf\system\request\LinkHandler::getInstance()->getLink('Chat', array( + 'application' => 'chat', + 'object' => $this->userNotificationObject->getRoom(), + )); + } + + /** + * @see \wcf\system\user\notification\object\IUserNotificationObject::getAuthorID() + */ + public function getAuthorID() { + // this value is ignored + return PHP_INT_MAX; + } +} diff --git a/file/lib/system/user/notification/object/type/RoomUserNotificationObjectType.class.php b/file/lib/system/user/notification/object/type/RoomUserNotificationObjectType.class.php new file mode 100644 index 0000000..5a0eed1 --- /dev/null +++ b/file/lib/system/user/notification/object/type/RoomUserNotificationObjectType.class.php @@ -0,0 +1,28 @@ + + * @package be.bastelstu.chat + * @subpackage system.user.notification.object.type + */ +class RoomUserNotificationObjectType extends \wcf\system\user\notification\object\type\AbstractUserNotificationObjectType { + /** + * @see \wcf\system\user\notification\object\type\AbstractUserNotificationObjectType::$decoratorClassName + */ + protected static $decoratorClassName = 'chat\system\user\notification\object\RoomUserNotificationObject'; + + /** + * @see \wcf\system\user\notification\object\type\AbstractUserNotificationObjectType::$objectClassName + */ + protected static $objectClassName = 'chat\data\room\Room'; + + /** + * @see \wcf\system\user\notification\object\type\AbstractUserNotificationObjectType::$objectListClassName + */ + protected static $objectListClassName = 'chat\data\room\RoomList'; +} diff --git a/language/de.xml b/language/de.xml index 7a23b6e..de5b1b0 100644 --- a/language/de.xml +++ b/language/de.xml @@ -39,6 +39,11 @@ + + + username}“ möchte mit Ihnen im Chatraum „{$userNotificationObject->getTitle()}“ chatten!]]> + + diff --git a/language/en.xml b/language/en.xml index ac38cc9..6dde73c 100644 --- a/language/en.xml +++ b/language/en.xml @@ -39,6 +39,11 @@ + + + username}“ möchte mit Ihnen im Chatraum „{$userNotificationObject->getTitle()}“ chatten!]]> + + diff --git a/objectType.xml b/objectType.xml index e920f9c..4d5ffca 100644 --- a/objectType.xml +++ b/objectType.xml @@ -27,5 +27,11 @@ com.woltlab.wcf.attachment.objectType chat\system\attachment\MessageAttachmentObjectType + + be.bastelstu.chat.room + com.woltlab.wcf.notification.objectType + chat\system\user\notification\object\type\RoomUserNotificationObjectType + be.bastelstu.chat + diff --git a/package.xml b/package.xml index 065c127..3300421 100644 --- a/package.xml +++ b/package.xml @@ -29,6 +29,7 @@ acptemplate.tar install.sql objectType.xml + userNotificationEvent.xml option.xml templateListener.xml pageMenu.xml diff --git a/userNotificationEvent.xml b/userNotificationEvent.xml new file mode 100644 index 0000000..2427056 --- /dev/null +++ b/userNotificationEvent.xml @@ -0,0 +1,12 @@ + + + + + invited + be.bastelstu.chat.room + chat\system\user\notification\event\InvitedUserNotificationEvent + 1 + module_chat + + + From 47a84a9d7f7ec30556284962d4f7ced533f49be7 Mon Sep 17 00:00:00 2001 From: Maximilian Mader Date: Tue, 9 Dec 2014 23:57:25 +0100 Subject: [PATCH 2/8] Implement invitations in frontend --- file/js/be.bastelstu.Chat.litcoffee | 37 ++++++++--- file/lib/data/user/UserAction.class.php | 54 ++++++++++++++++ language/de.xml | 4 ++ language/en.xml | 4 ++ template/chat.tpl | 8 +++ template/userInviteDialog.tpl | 84 +++++++++++++++++++++++++ 6 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 file/lib/data/user/UserAction.class.php create mode 100644 template/userInviteDialog.tpl diff --git a/file/js/be.bastelstu.Chat.litcoffee b/file/js/be.bastelstu.Chat.litcoffee index 871d64e..27368ab 100644 --- a/file/js/be.bastelstu.Chat.litcoffee +++ b/file/js/be.bastelstu.Chat.litcoffee @@ -101,7 +101,7 @@ Initialize **Tims Chat**. Bind needed DOM events and initialize data structures. When **Tims Chat** becomes focused mark the chat as active and remove the number of new messages from the title. $(window).focus -> - document.title = v.titleTemplate.fetch(roomList.active) if roomList.active?.title? and roomList.active.title.trim() isnt '' + document.title = v.titleTemplate.fetch(getRoomList().active) if roomList.active?.title? and roomList.active.title.trim() isnt '' newMessageCount = 0 isActive = true @@ -177,7 +177,7 @@ Open the smiley wcfDialog overlaySmileyList.css 'max-height': $(window).height() - overlaySmileyList.parent().siblings('.dialogTitlebar').outerHeight() 'overflow': 'auto' - + Handle private channel menu $('#timsChatMessageTabMenu > .tabMenu').on 'click', '.timsChatMessageTabMenuAnchor', -> @@ -351,6 +351,25 @@ Toggle checkboxes. else $('.timsChatMessageContainer').removeClass 'markEnabled' +Show invite dialog. + + $('#timsChatInvite').click (event) -> + do event.preventDefault + + new WCF.Action.Proxy + autoSend: true + data: + actionName: 'prepareInvite' + className: 'chat\\data\\user\\UserAction' + showLoadingOverlay: true + suppressErrors: false + success: (data) -> + $('
').appendTo 'body' unless $.wcfIsset 'timsChatInviteDialog' + + $('#timsChatInviteDialog').html(data.returnValues.template).wcfDialog + title: WCF.Language.get 'chat.global.invite' + + Hide topic container. $('#timsChatTopicCloser').on 'click', -> @@ -858,7 +877,7 @@ Fetch the roomlist from the server and update it in the GUI. roomList = active: {} available: {} - + do $('.timsChatRoom').remove $('#toggleRooms .badge').text data.returnValues.length @@ -874,7 +893,7 @@ Fetch the roomlist from the server and update it in the GUI. a.appendTo li $("""#{WCF.String.formatNumeric room.userCount}""").appendTo li $('#timsChatRoomList ul').append li - + if window.history?.replaceState? $('.timsChatRoom a').click (event) -> do event.preventDefault @@ -887,7 +906,7 @@ Fetch the roomlist from the server and update it in the GUI. join target.data 'roomID' $('#timsChatRoomList .active').removeClass 'active' target.parent().addClass 'active' - + console.log "Found #{data.returnValues.length} rooms" Shows an unrecoverable error with the given text. @@ -945,7 +964,7 @@ Joins a room. $('.timsChatMessage').addClass 'unloaded' - document.title = v.titleTemplate.fetch roomList.active + document.title = v.titleTemplate.fetch getRoomList().active handleMessages roomList.active.messages do getMessages do refreshRoomList @@ -1068,6 +1087,8 @@ Remove the given callback from the given event. true + getRoomList = -> JSON.parse JSON.stringify roomList + The following code handles attachment uploads Enable attachment code if `WCF.Attachment.Upload` is defined @@ -1293,8 +1314,8 @@ Return a copy of the object containing the IDs of the marked messages getMarkedMessages: -> JSON.parse JSON.stringify markedMessages getUserList: -> JSON.parse JSON.stringify userList - getRoomList: -> JSON.parse JSON.stringify roomList - + getRoomList: getRoomList + refreshRoomList: refreshRoomList insertText: insertText freeTheFish: freeTheFish diff --git a/file/lib/data/user/UserAction.class.php b/file/lib/data/user/UserAction.class.php new file mode 100644 index 0000000..9d9b87c --- /dev/null +++ b/file/lib/data/user/UserAction.class.php @@ -0,0 +1,54 @@ + + * @package be.bastelstu.chat + * @subpackage data.user + */ +class UserAction extends \wcf\data\AbstractDatabaseObjectAction { + protected $className = 'wcf\data\user\UserEditor'; + + public function validatePrepareInvite() { + // Todo: Proper validation + } + + public function prepareInvite() { + $followingList = new \wcf\data\user\follow\UserFollowingList(); + $followingList->getConditionBuilder()->add('user_follow.userID = ?', array(WCF::getUser()->userID)); + $followingList->readObjects(); + $users = $followingList->getObjects(); + + WCF::getTPL()->assign(array( + 'users' => $users + )); + + return array( + 'template' => WCF::getTPL()->fetch('userInviteDialog', 'chat') + ); + } + + public function validateInvite() { + $this->recipients = (isset($_POST['recipients'])) ? $_POST['recipients'] : null; + + if (!$this->recipients) { + throw new \wcf\system\exception\UserInputException("recipients"); + } + + if (WCF::getUser()->chatRoomID) { + $this->room = \chat\data\room\RoomCache::getInstance()->getRoom(WCF::getUser()->chatRoomID); + } + else { + throw new \wcf\system\exception\UserInputException("roomID"); + } + } + + public function invite() { + \wcf\system\user\notification\UserNotificationHandler::getInstance()->fireEvent('invited', 'be.bastelstu.chat.room', new \chat\system\user\notification\object\RoomUserNotificationObject($this->room), $this->recipients, [ 'userID' => WCF::getUser()->userID ]); + } +} diff --git a/language/de.xml b/language/de.xml index a7d9439..af66711 100644 --- a/language/de.xml +++ b/language/de.xml @@ -161,6 +161,9 @@ Probieren Sie, den Chat neu zu laden