1
0
mirror of https://github.com/wbbaddons/Tims-Chat.git synced 2025-01-02 23:20:08 +00:00

Merge branch 'invite'

This commit is contained in:
Tim Düsterhus 2015-03-21 01:03:15 +01:00
commit ab32c52bad
13 changed files with 417 additions and 8 deletions

View File

@ -85,7 +85,7 @@ exposed by a function if necessary.
Initialize **Tims Chat**. Bind needed DOM events and initialize data structures. Initialize **Tims Chat**. Bind needed DOM events and initialize data structures.
initialized = false initialized = false
init = (roomID, config, titleTemplate, messageTemplate, userTemplate, userMenuTemplate) -> init = (roomID, config, titleTemplate, messageTemplate, userTemplate, userMenuTemplate, userInviteDialogTemplate) ->
return false if initialized return false if initialized
initialized = true initialized = true
@ -96,13 +96,24 @@ Initialize **Tims Chat**. Bind needed DOM events and initialize data structures.
v.messageTemplate = messageTemplate v.messageTemplate = messageTemplate
v.userTemplate = userTemplate v.userTemplate = userTemplate
v.userMenuTemplate = userMenuTemplate v.userMenuTemplate = userMenuTemplate
v.userInviteDialogTemplate = userInviteDialogTemplate
v.userInviteDialogUserListEntryTemplate = new WCF.Template """
<dl>
<dt></dt>
<dd>
<label>
<input type="checkbox" id="userInviteDialogUserID-{$user.objectID}" value="{$user.objectID}" checked="checked" /> {$user.label}
</label>
</dd>
</dl>
"""
console.log 'Initializing' console.log 'Initializing'
When **Tims Chat** becomes focused mark the chat as active and remove the number of new messages from the title. When **Tims Chat** becomes focused mark the chat as active and remove the number of new messages from the title.
$(window).focus -> $(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 newMessageCount = 0
isActive = true isActive = true
@ -178,7 +189,7 @@ Open the smiley wcfDialog
overlaySmileyList.css overlaySmileyList.css
'max-height': $(window).height() - overlaySmileyList.parent().siblings('.dialogTitlebar').outerHeight() 'max-height': $(window).height() - overlaySmileyList.parent().siblings('.dialogTitlebar').outerHeight()
'overflow': 'auto' 'overflow': 'auto'
Handle private channel menu Handle private channel menu
$('#timsChatMessageTabMenu > .tabMenu').on 'click', '.timsChatMessageTabMenuAnchor', -> $('#timsChatMessageTabMenu > .tabMenu').on 'click', '.timsChatMessageTabMenuAnchor', ->
@ -239,7 +250,7 @@ The the word the caret is in will be passed to `autocomplete` and replaced if a
toComplete = autocomplete.value.substring lastSpace + 1 toComplete = autocomplete.value.substring lastSpace + 1
nextSpace = toComplete.indexOf ' ' nextSpace = toComplete.indexOf ' '
if nextSpace is -1 if nextSpace is -1
afterComplete = ''; afterComplete = ''
else else
afterComplete = toComplete.substring nextSpace + 1 afterComplete = toComplete.substring nextSpace + 1
toComplete = toComplete.substring 0, nextSpace toComplete = toComplete.substring 0, nextSpace
@ -384,6 +395,68 @@ Toggle checkboxes.
else else
$('.timsChatMessageContainer').removeClass 'markEnabled' $('.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'
success: (data) ->
$('<div id="timsChatInviteDialog"></div>').appendTo 'body' unless $.wcfIsset 'timsChatInviteDialog'
timsChatInviteDialog = $ '#timsChatInviteDialog'
# Remove old event listeners
do timsChatInviteDialog.find('#userInviteDialogUsernameInput').off().remove
timsChatInviteDialog.html v.userInviteDialogTemplate.fetch
users: data.returnValues.users
new WCF.Search.User '#userInviteDialogUsernameInput', (user) ->
if $.wcfIsset "userInviteDialogUserID-#{user.objectID}"
$("#userInviteDialogUserID-#{user.objectID}").prop 'checked', true
else
$('#userInviteDialogUserList').append v.userInviteDialogUserListEntryTemplate.fetch
user: user
$('#userInviteDialogUsernameInput').val ""
, false, [ WCF.User.username ], false
$('#userInviteDialogFormSubmit').on 'click', (event) ->
checked = $ '#userInviteDialogUserList input[type=checkbox]:checked, #userInviteDialogFollowingList input[type=checkbox]:checked'
inviteUserList = [ ]
checked.each (k, v) -> inviteUserList.push do $(v).val
if inviteUserList.length
new WCF.Action.Proxy
autoSend: true
data:
actionName: 'invite'
className: 'chat\\data\\user\\UserAction'
parameters:
recipients: inviteUserList
success: (data) ->
do new WCF.System.Notification(WCF.Language.get 'wcf.global.success').show
failure: (data) ->
return true unless (data?.returnValues?.errorType?) or (data?.message?)
$("""<div class="ajaxDebugMessage">#{(data?.returnValues?.errorType) ? data.message}</div>""").wcfDialog title: WCF.Language.get 'wcf.global.error.title'
return false
$('#timsChatInviteDialog').wcfDialog 'close'
timsChatInviteDialog.wcfDialog
title: WCF.Language.get 'chat.global.invite'
onShow: -> do $('#userInviteDialogUsernameInput').focus
Hide topic container. Hide topic container.
$('#timsChatTopicCloser').on 'click', -> $('#timsChatTopicCloser').on 'click', ->
@ -1056,7 +1129,7 @@ Joins a room.
$('.timsChatMessage').addClass 'unloaded' $('.timsChatMessage').addClass 'unloaded'
document.title = v.titleTemplate.fetch roomList.active document.title = v.titleTemplate.fetch getRoomList().active
handleMessages roomList.active.messages handleMessages roomList.active.messages
do getMessages do getMessages
do refreshRoomList do refreshRoomList
@ -1191,6 +1264,8 @@ Remove the given callback from the given event.
true true
getRoomList = -> JSON.parse JSON.stringify roomList
The following code handles attachment uploads The following code handles attachment uploads
Enable attachment code if `WCF.Attachment.Upload` is defined Enable attachment code if `WCF.Attachment.Upload` is defined
@ -1416,8 +1491,8 @@ Return a copy of the object containing the IDs of the marked messages
getMarkedMessages: -> JSON.parse JSON.stringify markedMessages getMarkedMessages: -> JSON.parse JSON.stringify markedMessages
getUserList: -> JSON.parse JSON.stringify userList getUserList: -> JSON.parse JSON.stringify userList
getRoomList: -> JSON.parse JSON.stringify roomList getRoomList: getRoomList
refreshRoomList: refreshRoomList refreshRoomList: refreshRoomList
insertText: insertText insertText: insertText
freeTheFish: freeTheFish freeTheFish: freeTheFish

View File

@ -42,4 +42,86 @@ public function updateOption() {
)); ));
$userAction->executeAction(); $userAction->executeAction();
} }
/**
* Validates invite preparation.
*/
public function validatePrepareInvite() {
WCF::getSession()->checkPermissions(array('user.chat.canInvite'));
if (!WCF::getUser()->chatRoomID) throw new \wcf\system\exception\PermissionDeniedException();
$room = \chat\data\room\RoomCache::getInstance()->getRoom(WCF::getUser()->chatRoomID);
if ($room === null) throw new \wcf\system\exception\IllegalLinkException();
if (!$room->canEnter()) throw new \wcf\system\exception\PermissionDeniedException();
}
/**
* Prepares invites.
*/
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();
$json = array();
foreach ($users as $user) {
$json[] = array(
'userID' => $user->userID,
'username' => $user->username
);
}
return array(
'users' => $json
);
}
/**
* Validates invites.
*/
public function validateInvite() {
WCF::getSession()->checkPermissions(array('user.chat.canInvite'));
if (!WCF::getUser()->chatRoomID) throw new \wcf\system\exception\PermissionDeniedException();
$this->room = \chat\data\room\RoomCache::getInstance()->getRoom(WCF::getUser()->chatRoomID);
if ($this->room === null) throw new \wcf\system\exception\IllegalLinkException();
if (!$this->room->canEnter()) throw new \wcf\system\exception\PermissionDeniedException();
if (!isset($this->parameters['recipients'])) throw new \wcf\system\exception\UserInputException("recipients");
$this->parameters['recipients'] = \wcf\util\ArrayUtil::toIntegerArray($this->parameters['recipients']);
$ignoredByList = new \wcf\data\user\ignore\UserIgnoreList();
$ignoredByList->getConditionBuilder()->add('user_ignore.ignoreUserID = ?', array(WCF::getUser()->userID));
$ignoredByList->getConditionBuilder()->add('user_ignore.userID IN (?)', array($this->parameters['recipients']));
if (!empty($ignoredByList->sqlSelects)) $ignoredByList->sqlSelects .= ',';
$ignoredByList->sqlSelects .= "user_ignore.ignoreID";
$ignoredByList->sqlSelects .= ", user_table.username";
$ignoredByList->sqlJoins .= " LEFT JOIN wcf".WCF_N."_user user_table ON (user_table.userID = user_ignore.userID)";
$ignoredByList->readObjects();
$ignoredByUsers = $ignoredByList->getObjects();
if (!empty($ignoredByUsers)) {
$usernames = array();
foreach ($ignoredByUsers as $user) {
$usernames[] = $user->username;
}
throw new \wcf\system\exception\UserInputException("recipients", WCF::getLanguage()->getDynamicVariable('chat.error.invite.ignored', array('users' => $ignoredByUsers, 'usernames' => $usernames)));
}
}
/**
* Invites users.
*/
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->parameters['recipients'], array('userID' => WCF::getUser()->userID));
}
} }

View File

@ -0,0 +1,75 @@
<?php
namespace chat\system\user\notification\event;
/**
*
*
* @author Tim Düsterhus
* @copyright 2010-2014 Tim Düsterhus
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
* @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;
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace chat\system\user\notification\object;
/**
*
*
* @author Tim Düsterhus
* @copyright 2010-2014 Tim Düsterhus
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
* @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;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace chat\system\user\notification\object\type;
/**
*
*
* @author Tim Düsterhus
* @copyright 2010-2014 Tim Düsterhus
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
* @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';
}

View File

@ -39,6 +39,11 @@
<item name="chat.acp.menu.link.suspension.list"><![CDATA[Sanktionen auflisten]]></item> <item name="chat.acp.menu.link.suspension.list"><![CDATA[Sanktionen auflisten]]></item>
</category> </category>
<category name="chat.notification">
<item name="chat.notification.invited.title"><![CDATA[Jemand möchte mit Ihnen chatten!]]></item>
<item name="chat.notification.invited.message"><![CDATA[„{$author->username}“ möchte mit Ihnen im Chatraum „{$userNotificationObject->getTitle()}“ chatten!]]></item>
</category>
<category name="wcf.acl.option"> <category name="wcf.acl.option">
<item name="wcf.acl.option.category.be.bastelstu.chat.room.user"><![CDATA[Benutzerrechte]]></item> <item name="wcf.acl.option.category.be.bastelstu.chat.room.user"><![CDATA[Benutzerrechte]]></item>
<item name="wcf.acl.option.category.be.bastelstu.chat.room.mod"><![CDATA[Moderative Rechte]]></item> <item name="wcf.acl.option.category.be.bastelstu.chat.room.mod"><![CDATA[Moderative Rechte]]></item>
@ -55,6 +60,7 @@
<item name="wcf.acp.group.option.user.chat.canEnter"><![CDATA[Kann Chat betreten]]></item> <item name="wcf.acp.group.option.user.chat.canEnter"><![CDATA[Kann Chat betreten]]></item>
<item name="wcf.acp.group.option.user.chat.canWrite"><![CDATA[Kann im Chat schreiben]]></item> <item name="wcf.acp.group.option.user.chat.canWrite"><![CDATA[Kann im Chat schreiben]]></item>
<item name="wcf.acp.group.option.user.chat.canTempRoom"><![CDATA[Kann temporäre Räume erstellen]]></item> <item name="wcf.acp.group.option.user.chat.canTempRoom"><![CDATA[Kann temporäre Räume erstellen]]></item>
<item name="wcf.acp.group.option.user.chat.canInvite"><![CDATA[Kann Benutzer zum Chatten einladen]]></item>
<item name="wcf.acp.group.option.user.chat.allowedBBCodes"><![CDATA[Erlaubte BBCodes]]></item> <item name="wcf.acp.group.option.user.chat.allowedBBCodes"><![CDATA[Erlaubte BBCodes]]></item>
<item name="wcf.acp.group.option.user.chat.allowedBBCodes.description"><![CDATA[Die hier ausgewählten BBCodes dürfen von Mitgliedern dieser Benutzergruppe verwendet werden.]]></item> <item name="wcf.acp.group.option.user.chat.allowedBBCodes.description"><![CDATA[Die hier ausgewählten BBCodes dürfen von Mitgliedern dieser Benutzergruppe verwendet werden.]]></item>
<item name="wcf.acp.group.option.user.chat.canUploadAttachment"><![CDATA[Kann Dateien anhängen]]></item> <item name="wcf.acp.group.option.user.chat.canUploadAttachment"><![CDATA[Kann Dateien anhängen]]></item>
@ -148,6 +154,7 @@ Probieren Sie, den Chat neu zu laden<!-- , bei Risiken und Nebenwirkungen fragen
<item name="chat.error.reload"><![CDATA[Neu laden]]></item> <item name="chat.error.reload"><![CDATA[Neu laden]]></item>
<item name="chat.error.whisper.ignoresYou"><![CDATA[„{$user}“ hat Sie blockiert.]]></item> <item name="chat.error.whisper.ignoresYou"><![CDATA[„{$user}“ hat Sie blockiert.]]></item>
<item name="chat.error.invite.ignored"><![CDATA[Die folgenden Nutzer haben Sie blockiert: {implode from=$usernames item=username}{$username}{/implode}]]></item>
</category> </category>
<category name="chat.global"> <category name="chat.global">
@ -163,6 +170,9 @@ Probieren Sie, den Chat neu zu laden<!-- , bei Risiken und Nebenwirkungen fragen
<item name="chat.global.error.join.full"><![CDATA[Der Raum „{$room}“ hat die maximale Anzahl an Mitgliedern erreicht. Bitte versuchen Sie es später erneut.]]></item> <item name="chat.global.error.join.full"><![CDATA[Der Raum „{$room}“ hat die maximale Anzahl an Mitgliedern erreicht. Bitte versuchen Sie es später erneut.]]></item>
<item name="chat.global.invite"><![CDATA[Benutzer einladen]]></item>
<item name="chat.global.invite.noFollowing"><![CDATA[Sie folgen niemandem, verwenden Sie bitte die Suche.]]></item>
<item name="chat.global.copyright"><![CDATA[<a href="http://tims.bastelstu.be"{if EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}><strong>Tims Chat{if SHOW_VERSION_NUMBER} {PACKAGE_VERSION}{/if}</strong>, entwickelt in <strong>Tims Bastelstu.be</strong></a>]]></item> <item name="chat.global.copyright"><![CDATA[<a href="http://tims.bastelstu.be"{if EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}><strong>Tims Chat{if SHOW_VERSION_NUMBER} {PACKAGE_VERSION}{/if}</strong>, entwickelt in <strong>Tims Bastelstu.be</strong></a>]]></item>
<item name="chat.global.copyright.leader"><![CDATA[Projektleiter]]></item> <item name="chat.global.copyright.leader"><![CDATA[Projektleiter]]></item>
<item name="chat.global.copyright.developer"><![CDATA[Entwickler]]></item> <item name="chat.global.copyright.developer"><![CDATA[Entwickler]]></item>
@ -255,5 +265,6 @@ Probieren Sie, den Chat neu zu laden<!-- , bei Risiken und Nebenwirkungen fragen
<category name="chat.user"> <category name="chat.user">
<item name="chat.user.usersOnline.location.ChatPage"><![CDATA[<a href="{link controller='Chat' application='chat' object=$room}{/link}">Chatraum „{$room}“</a>]]></item> <item name="chat.user.usersOnline.location.ChatPage"><![CDATA[<a href="{link controller='Chat' application='chat' object=$room}{/link}">Chatraum „{$room}“</a>]]></item>
<item name="chat.user.search"><![CDATA[Benutzer suchen]]></item>
</category> </category>
</language> </language>

View File

@ -39,6 +39,11 @@
<item name="chat.acp.menu.link.suspension.list"><![CDATA[List Suspensions]]></item> <item name="chat.acp.menu.link.suspension.list"><![CDATA[List Suspensions]]></item>
</category> </category>
<category name="chat.notification">
<item name="chat.notification.invited.title"><![CDATA[Someone wants to chat with you!]]></item>
<item name="chat.notification.invited.message"><![CDATA[“{$author->username}” wants to chat with you in “{$userNotificationObject->getTitle()}”!]]></item>
</category>
<category name="wcf.acl.option"> <category name="wcf.acl.option">
<item name="wcf.acl.option.category.be.bastelstu.chat.room.user"><![CDATA[User Permissions]]></item> <item name="wcf.acl.option.category.be.bastelstu.chat.room.user"><![CDATA[User Permissions]]></item>
<item name="wcf.acl.option.category.be.bastelstu.chat.room.mod"><![CDATA[Moderator Permissions]]></item> <item name="wcf.acl.option.category.be.bastelstu.chat.room.mod"><![CDATA[Moderator Permissions]]></item>
@ -55,6 +60,7 @@
<item name="wcf.acp.group.option.user.chat.canEnter"><![CDATA[Can enter chat]]></item> <item name="wcf.acp.group.option.user.chat.canEnter"><![CDATA[Can enter chat]]></item>
<item name="wcf.acp.group.option.user.chat.canWrite"><![CDATA[Can write messages]]></item> <item name="wcf.acp.group.option.user.chat.canWrite"><![CDATA[Can write messages]]></item>
<item name="wcf.acp.group.option.user.chat.canTempRoom"><![CDATA[Can create temporary rooms]]></item> <item name="wcf.acp.group.option.user.chat.canTempRoom"><![CDATA[Can create temporary rooms]]></item>
<item name="wcf.acp.group.option.user.chat.canInvite"><![CDATA[Can invite users to chat]]></item>
<item name="wcf.acp.group.option.user.chat.allowedBBCodes"><![CDATA[Allowed BBCodes]]></item> <item name="wcf.acp.group.option.user.chat.allowedBBCodes"><![CDATA[Allowed BBCodes]]></item>
<item name="wcf.acp.group.option.user.chat.allowedBBCodes.description"><![CDATA[Selected BBCodes may be used by members of this group.]]></item> <item name="wcf.acp.group.option.user.chat.allowedBBCodes.description"><![CDATA[Selected BBCodes may be used by members of this group.]]></item>
<item name="wcf.acp.group.option.user.chat.canUploadAttachment"><![CDATA[Can upload attachments]]></item> <item name="wcf.acp.group.option.user.chat.canUploadAttachment"><![CDATA[Can upload attachments]]></item>
@ -148,6 +154,7 @@ Please try to reload the chat.]]></item>
<item name="chat.error.reload"><![CDATA[Reload]]></item> <item name="chat.error.reload"><![CDATA[Reload]]></item>
<item name="chat.error.whisper.ignoresYou"><![CDATA[“{$user}” has blocked you.]]></item> <item name="chat.error.whisper.ignoresYou"><![CDATA[“{$user}” has blocked you.]]></item>
<item name="chat.error.invite.ignored"><![CDATA[The following users have blocked you: {implode from=$usernames item=username}{$username}{/implode}]]></item>
</category> </category>
<category name="chat.global"> <category name="chat.global">
@ -162,6 +169,9 @@ Please try to reload the chat.]]></item>
<item name="chat.global.users"><![CDATA[Users]]></item> <item name="chat.global.users"><![CDATA[Users]]></item>
<item name="chat.global.error.join.full"><![CDATA[The room “{$room}” has reached the maximum amount of concurrent chatters. Please try again later.]]></item> <item name="chat.global.error.join.full"><![CDATA[The room “{$room}” has reached the maximum amount of concurrent chatters. Please try again later.]]></item>
<item name="chat.global.invite"><![CDATA[Invite users]]></item>
<item name="chat.global.invite.noFollowing"><![CDATA[You do not follow anybody, please use the search function instead.]]></item>
<item name="chat.global.copyright"><![CDATA[<a href="http://tims.bastelstu.be"{if EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}><strong>Tims Chat{if SHOW_VERSION_NUMBER} {PACKAGE_VERSION}{/if}</strong>, developed in <strong>Tims Bastelstu.be</strong></a>]]></item> <item name="chat.global.copyright"><![CDATA[<a href="http://tims.bastelstu.be"{if EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}><strong>Tims Chat{if SHOW_VERSION_NUMBER} {PACKAGE_VERSION}{/if}</strong>, developed in <strong>Tims Bastelstu.be</strong></a>]]></item>
<item name="chat.global.copyright.leader"><![CDATA[Project Lead]]></item> <item name="chat.global.copyright.leader"><![CDATA[Project Lead]]></item>
@ -255,5 +265,6 @@ Please try to reload the chat.]]></item>
<category name="chat.user"> <category name="chat.user">
<item name="chat.user.usersOnline.location.ChatPage"><![CDATA[<a href="{link controller='Chat' application='chat' object=$room}{/link}">Chatroom “{$room}”</a>]]></item> <item name="chat.user.usersOnline.location.ChatPage"><![CDATA[<a href="{link controller='Chat' application='chat' object=$room}{/link}">Chatroom “{$room}”</a>]]></item>
<item name="chat.user.search"><![CDATA[Search for users]]></item>
</category> </category>
</language> </language>

View File

@ -27,5 +27,11 @@
<definitionname>com.woltlab.wcf.attachment.objectType</definitionname> <definitionname>com.woltlab.wcf.attachment.objectType</definitionname>
<classname>chat\system\attachment\MessageAttachmentObjectType</classname> <classname>chat\system\attachment\MessageAttachmentObjectType</classname>
</type> </type>
<type>
<name>be.bastelstu.chat.room</name>
<definitionname>com.woltlab.wcf.notification.objectType</definitionname>
<classname>chat\system\user\notification\object\type\RoomUserNotificationObjectType</classname>
<category>be.bastelstu.chat</category>
</type>
</import> </import>
</data> </data>

View File

@ -29,6 +29,7 @@
<instruction type="acpTemplate">acptemplate.tar</instruction> <instruction type="acpTemplate">acptemplate.tar</instruction>
<instruction type="sql">install.sql</instruction> <instruction type="sql">install.sql</instruction>
<instruction type="objectType">objectType.xml</instruction> <instruction type="objectType">objectType.xml</instruction>
<instruction type="userNotificationEvent">userNotificationEvent.xml</instruction>
<instruction type="option">option.xml</instruction> <instruction type="option">option.xml</instruction>
<instruction type="templateListener">templateListener.xml</instruction> <instruction type="templateListener">templateListener.xml</instruction>
<instruction type="pageMenu">pageMenu.xml</instruction> <instruction type="pageMenu">pageMenu.xml</instruction>

View File

@ -22,6 +22,7 @@
'chat.global.query': '{lang}chat.global.query{/lang}', 'chat.global.query': '{lang}chat.global.query{/lang}',
'chat.global.smilies': '{lang}chat.global.smilies{/lang}', 'chat.global.smilies': '{lang}chat.global.smilies{/lang}',
'chat.global.whisper': '{lang}chat.global.whisper{/lang}', 'chat.global.whisper': '{lang}chat.global.whisper{/lang}',
'chat.global.invite': '{lang}chat.global.invite{/lang}',
'chat.error.duplicateTab': '{lang}chat.error.duplicateTab{/lang}', 'chat.error.duplicateTab': '{lang}chat.error.duplicateTab{/lang}',
'chat.error.join': '{lang}chat.error.join{/lang}', 'chat.error.join': '{lang}chat.error.join{/lang}',
'chat.error.onMessageLoad': '{@"chat.error.onMessageLoad"|language|encodeJS}', 'chat.error.onMessageLoad': '{@"chat.error.onMessageLoad"|language|encodeJS}',
@ -56,6 +57,7 @@
{capture assign='messageTemplate'}{include application='chat' file='message'}{/capture} {capture assign='messageTemplate'}{include application='chat' file='message'}{/capture}
{capture assign='userTemplate'}{include application='chat' file='userListUser'}{/capture} {capture assign='userTemplate'}{include application='chat' file='userListUser'}{/capture}
{capture assign='userMenuTemplate'}{include application='chat' file='userListUserMenu'}{/capture} {capture assign='userMenuTemplate'}{include application='chat' file='userListUserMenu'}{/capture}
{capture assign='userInviteDialogTemplate'}{include application='chat' file='userInviteDialog'}{/capture}
var config = { var config = {
reloadTime: {@CHAT_RELOADTIME}, reloadTime: {@CHAT_RELOADTIME},
@ -74,7 +76,8 @@
new WCF.Template('{literal}{if $newMessageCount}({#$newMessageCount}) {/if}{$title} - {/literal}{"chat.global.title"|language|encodeJS} - {PAGE_TITLE|language|encodeJS}'), new WCF.Template('{literal}{if $newMessageCount}({#$newMessageCount}) {/if}{$title} - {/literal}{"chat.global.title"|language|encodeJS} - {PAGE_TITLE|language|encodeJS}'),
new WCF.Template('{@$messageTemplate|encodeJS}'), new WCF.Template('{@$messageTemplate|encodeJS}'),
new WCF.Template('{@$userTemplate|encodeJS}'), new WCF.Template('{@$userTemplate|encodeJS}'),
new WCF.Template('{@$userMenuTemplate|encodeJS}') new WCF.Template('{@$userMenuTemplate|encodeJS}'),
new WCF.Template('{@$userInviteDialogTemplate|encodeJS}')
); );
{event name='afterInit'} {event name='afterInit'}
@ -198,6 +201,15 @@
</li> </li>
{/if} {/if}
{if $__wcf->session->getPermission('user.chat.canInvite')}
<li>
<a id="timsChatInvite" class="button jsTooltip" title="{lang}chat.global.invite{/lang}">
<span class="icon icon16 icon-user"></span>
<span class="invisible">{lang}chat.global.invite{/lang}</span>
</a>
</li>
{/if}
<li> <li>
<a id="timsChatClear" class="button jsTooltip" title="{lang}chat.global.clear{/lang}"> <a id="timsChatClear" class="button jsTooltip" title="{lang}chat.global.clear{/lang}">
<span class="icon icon16 icon-remove"></span> <span class="icon icon16 icon-remove"></span>

View File

@ -0,0 +1,39 @@
{literal}
<div id="userInviteDialogContainer">
<fieldset>
<legend>{lang}wcf.user.access.following{/lang}</legend>
{if $users.length === 0}
<p class="info">{lang}chat.global.invite.noFollowing{/lang}</p>
{else}
<div id="userInviteDialogFollowingList">
<dl>
{foreach from=$users item="user"}
<dt></dt>
<dd><label><input type="checkbox" id="userInviteDialogUserID-{$user.userID}" value="{$user.userID}" /> {$user.username}</label></dd>
{/foreach}
</dl>
</div>
{/if}
</fieldset>
<fieldset>
<legend>{lang}chat.user.search{/lang}</legend>
<div id="userInviteDialogUserList"></div>
<dl class="marginTop">
<dt><label for="username">{lang}wcf.user.username{/lang}</label></dt>
<dd>
<span>
<input autocomplete="off" id="userInviteDialogUsernameInput" name="username" class="medium" value="" type="text" />
</span>
</dd>
</dl>
<div class="formSubmit">
<input id="userInviteDialogFormSubmit" type="submit" value="{lang}wcf.global.button.submit{/lang}" />
</div>
</fieldset>
</div>
{/literal}

View File

@ -35,6 +35,13 @@
<admindefaultvalue>1</admindefaultvalue> <admindefaultvalue>1</admindefaultvalue>
<usersonly>1</usersonly> <usersonly>1</usersonly>
</option> </option>
<option name="user.chat.canInvite">
<categoryname>user.chat</categoryname>
<optiontype>boolean</optiontype>
<defaultvalue>0</defaultvalue>
<admindefaultvalue>1</admindefaultvalue>
<usersonly>1</usersonly>
</option>
<option name="user.chat.allowedBBCodes"> <option name="user.chat.allowedBBCodes">
<categoryname>user.chat</categoryname> <categoryname>user.chat</categoryname>
<optiontype>BBCodeSelect</optiontype> <optiontype>BBCodeSelect</optiontype>

12
userNotificationEvent.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/userNotificationEvent.xsd">
<import>
<event>
<name>invited</name>
<objecttype>be.bastelstu.chat.room</objecttype>
<classname>chat\system\user\notification\event\InvitedUserNotificationEvent</classname>
<preset>1</preset>
<options>module_chat</options>
</event>
</import>
</data>