mirror of
https://github.com/wbbaddons/Tims-Chat.git
synced 2025-01-22 02:00:40 +00:00
Merge branch 'master' into commands
Conflicts: file/lib/form/ChatForm.class.php template/chatMessage.tpl
This commit is contained in:
commit
81bdbccbe2
@ -1,8 +1,34 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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/maelstrom/aclOption.xsd">
|
<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/maelstrom/aclOption.xsd">
|
||||||
<import>
|
<import>
|
||||||
<option name="canEnter">
|
<categories>
|
||||||
|
<category name="user">
|
||||||
<objecttype>timwolla.wcf.chat.room</objecttype>
|
<objecttype>timwolla.wcf.chat.room</objecttype>
|
||||||
|
</category>
|
||||||
|
<category name="mod">
|
||||||
|
<objecttype>timwolla.wcf.chat.room</objecttype>
|
||||||
|
</category>
|
||||||
|
</categories>
|
||||||
|
|
||||||
|
<options>
|
||||||
|
<option name="user.canEnter">
|
||||||
|
<objecttype>timwolla.wcf.chat.room</objecttype>
|
||||||
|
<categoryname>user</categoryname>
|
||||||
</option>
|
</option>
|
||||||
|
<option name="user.canWrite">
|
||||||
|
<objecttype>timwolla.wcf.chat.room</objecttype>
|
||||||
|
<categoryname>user</categoryname>
|
||||||
|
</option>
|
||||||
|
|
||||||
|
|
||||||
|
<option name="mod.canAlwaysEnter">
|
||||||
|
<objecttype>timwolla.wcf.chat.room</objecttype>
|
||||||
|
<categoryname>mod</categoryname>
|
||||||
|
</option>
|
||||||
|
<option name="mod.canAlwaysWrite">
|
||||||
|
<objecttype>timwolla.wcf.chat.room</objecttype>
|
||||||
|
<categoryname>mod</categoryname>
|
||||||
|
</option>
|
||||||
|
</options>
|
||||||
</import>
|
</import>
|
||||||
</data>
|
</data>
|
22
acpMenu.xml
Normal file
22
acpMenu.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?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/maelstrom/acpMenu.xsd">
|
||||||
|
<import>
|
||||||
|
<acpmenuitem name="wcf.acp.menu.link.chat">
|
||||||
|
<parent>wcf.acp.menu.link.content</parent>
|
||||||
|
</acpmenuitem>
|
||||||
|
|
||||||
|
<acpmenuitem name="wcf.acp.menu.link.chat.room.list">
|
||||||
|
<link>index.php/ChatRoomList/</link>
|
||||||
|
<parent>wcf.acp.menu.link.chat</parent>
|
||||||
|
<permissions>admin.content.chat.canEditRoom,admin.content.chat.canDeleteRoom</permissions>
|
||||||
|
<showorder>1</showorder>
|
||||||
|
</acpmenuitem>
|
||||||
|
|
||||||
|
<acpmenuitem name="wcf.acp.menu.link.chat.room.add">
|
||||||
|
<link>index.php/ChatRoomAdd/</link>
|
||||||
|
<parent>wcf.acp.menu.link.chat</parent>
|
||||||
|
<permissions>admin.content.chat.canAddRoom</permissions>
|
||||||
|
<showorder>2</showorder>
|
||||||
|
</acpmenuitem>
|
||||||
|
</import>
|
||||||
|
</data>
|
101
acptemplate/chatRoomAdd.tpl
Normal file
101
acptemplate/chatRoomAdd.tpl
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{include file='header'}
|
||||||
|
|
||||||
|
<!-- ToDo: DEBUG ONLY -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="{@$__wcf->getPath('wcf')}style/acl.css" />
|
||||||
|
<!-- /DEBUG ONLY -->
|
||||||
|
|
||||||
|
<script type="text/javascript" src="{@$__wcf->getPath('wcf')}js/WCF.ACL.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
$(function() {
|
||||||
|
WCF.Icon.addObject({
|
||||||
|
'wcf.icon.delete': '{@$__wcf->getPath('wcf')}icon/delete1.svg',
|
||||||
|
'wcf.icon.user': '{@$__wcf->getPath('wcf')}icon/user1.svg',
|
||||||
|
'wcf.icon.users': '{@$__wcf->getPath('wcf')}icon/users1.svg'
|
||||||
|
});
|
||||||
|
|
||||||
|
new WCF.ACL.List($('#groupPermissions'), {@$objectTypeID}, ''{if $roomID|isset}, {@$roomID}{/if});
|
||||||
|
});
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header class="wcf-mainHeading wcf-container">
|
||||||
|
<img src="{@$__wcf->getPath('wcf')}icon/{$action}1.svg" alt="" class="wcf-containerIcon" />
|
||||||
|
<hgroup class="wcf-containerContent">
|
||||||
|
<h1>{lang}wcf.acp.chat.room.{$action}{/lang}</h1>
|
||||||
|
</hgroup>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{if $errorField}
|
||||||
|
<p class="wcf-error">{lang}wcf.global.form.error{/lang}</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if $success|isset}
|
||||||
|
<p class="wcf-success">{lang}wcf.global.form.{$action}.success{/lang}</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="wcf-contentHeader">
|
||||||
|
<nav>
|
||||||
|
<ul class="wcf-largeButtons">
|
||||||
|
<li><a href="{link controller='ChatRoomList'}{/link}" title="{lang}wcf.acp.menu.link.chat.room.list{/lang}" class="wcf-button"><img src="{@$__wcf->getPath('wcf')}icon/chat1.svg" alt="" /> <span>{lang}wcf.acp.menu.link.chat.room.list{/lang}</span></a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="post" action="{if $action == 'add'}{link controller='ChatRoomAdd'}{/link}{else}{link controller='ChatRoomEdit'}{/link}{/if}">
|
||||||
|
<div class="wcf-border wcf-content">
|
||||||
|
<fieldset>
|
||||||
|
<legend>{lang}wcf.acp.chat.room.data{/lang}</legend>
|
||||||
|
|
||||||
|
<dl{if $errorField == 'title'} class="wcf-formError"{/if}>
|
||||||
|
<dt><label for="title">{lang}wcf.acp.chat.room.title{/lang}</label></dt>
|
||||||
|
<dd>
|
||||||
|
<input type="text" id="title" name="title" value="{$title}" autofocus="autofocus" class="long" />
|
||||||
|
{if $errorField == 'title'}
|
||||||
|
<small class="wcf-innerError">
|
||||||
|
{if $errorType == 'empty'}
|
||||||
|
{lang}wcf.global.form.error.empty{/lang}
|
||||||
|
{else}
|
||||||
|
{lang}wcf.acp.chat.room.title.error.{@$errorType}{/lang}
|
||||||
|
{/if}
|
||||||
|
</small>
|
||||||
|
{/if}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
{include file='multipleLanguageInputJavascript' elementIdentifier='title'}
|
||||||
|
|
||||||
|
<dl{if $errorField == 'topic'} class="wcf-formError"{/if}>
|
||||||
|
<dt><label for="topic">{lang}wcf.acp.chat.room.topic{/lang}</label></dt>
|
||||||
|
<dd>
|
||||||
|
<input type="text" id="topic" name="topic" value="{$topic}" class="long" />
|
||||||
|
{if $errorField == 'topic'}
|
||||||
|
<small class="wcf-innerError">
|
||||||
|
{if $errorType == 'empty'}
|
||||||
|
{lang}wcf.global.form.error.empty{/lang}
|
||||||
|
{else}
|
||||||
|
{lang}wcf.acp.chat.room.topic.error.{@$errorType}{/lang}
|
||||||
|
{/if}
|
||||||
|
</small>
|
||||||
|
{/if}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
{include file='multipleLanguageInputJavascript' elementIdentifier='topic'}
|
||||||
|
|
||||||
|
<dl id="groupPermissions">
|
||||||
|
<dt>{lang}wcf.acp.acl.permissions{/lang}</dt>
|
||||||
|
<dd></dd>
|
||||||
|
</dl>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wcf-formSubmit">
|
||||||
|
<input type="reset" value="{lang}wcf.global.button.reset{/lang}" accesskey="r" />
|
||||||
|
<input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" />
|
||||||
|
{@SID_INPUT_TAG}
|
||||||
|
{if $roomID|isset}<input type="hidden" name="id" value="{@$roomID}" />{/if}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{include file='footer'}
|
58
acptemplate/chatRoomList.tpl
Normal file
58
acptemplate/chatRoomList.tpl
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{include file='header'}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
$(function() {
|
||||||
|
new WCF.Action.Delete('\\wcf\\data\\chat\\room\\ChatRoomAction', $('.chatRoomRow'));
|
||||||
|
new WCF.Sortable.List('chatRoomList', '\\wcf\\data\\chat\\room\\ChatRoomAction');
|
||||||
|
});
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header class="wcf-mainHeading wcf-container">
|
||||||
|
<img src="{@$__wcf->getPath('wcf')}icon/chat1.svg" alt="" class="wcf-containerIcon" />
|
||||||
|
<hgroup class="wcf-containerContent">
|
||||||
|
<h1>{lang}wcf.acp.chat.room.list{/lang}</h1>
|
||||||
|
</hgroup>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="wcf-contentHeader">
|
||||||
|
{pages print=true assign=pagesLinks controller="ChatRoomList" link="pageNo=%d"}
|
||||||
|
|
||||||
|
{if $__wcf->session->getPermission('admin.content.chat.canAddRoom')}
|
||||||
|
<nav>
|
||||||
|
<ul class="wcf-largeButtons">
|
||||||
|
<li><a href="{link controller='ChatRoomAdd'}{/link}" title="{lang}wcf.acp.chat.room.add{/lang}" class="wcf-button"><img src="{@$__wcf->getPath('wcf')}icon/add1.svg" alt="" /> <span>{lang}wcf.acp.chat.room.add{/lang}</span></a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section id="chatRoomList" class="wcf-border wcf-sortableListContainer">
|
||||||
|
{hascontent}
|
||||||
|
<ol class="wcf-sortableList" data-object-id="0">
|
||||||
|
{content}
|
||||||
|
{foreach from=$objects item=chatRoom}
|
||||||
|
<li class="wcf-sortableNode chatRoomRow" data-object-id="{@$chatRoom->roomID}">
|
||||||
|
<span class="wcf-sortableNodeLabel">
|
||||||
|
<a href="{link controller='ChatRoomEdit' id=$chatRoom->roomID}{/link}">{$chatRoom->title|language}</a>
|
||||||
|
|
||||||
|
<span class="wcf-sortableButtonContainer">
|
||||||
|
{if $__wcf->session->getPermission('admin.content.chat.canEditRoom')}
|
||||||
|
<a href="{link controller='ChatRoomEdit' id=$chatRoom->roomID}{/link}"><img src="{@$__wcf->getPath('wcf')}icon/edit1.svg" alt="" title="{lang}wcf.global.button.edit{/lang}" class="balloonTooltip" /></a>
|
||||||
|
{/if}
|
||||||
|
{if $__wcf->session->getPermission('admin.content.chat.canDeleteRoom')}
|
||||||
|
<img src="{@$__wcf->getPath('wcf')}icon/delete1.svg" alt="" title="{lang}wcf.global.button.delete{/lang}" class="jsDeleteButton jsTooltip" data-object-id="{@$chatRoom->roomID}" data-confirm-message="{lang}wcf.acp.bbcode.delete.sure{/lang}" />
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{/foreach}
|
||||||
|
{/content}
|
||||||
|
</ol>
|
||||||
|
{hascontentelse}
|
||||||
|
<p class="wcf-warning">{lang}wcf.acp.chat.room.noneAvailable{/lang}</p>
|
||||||
|
{/hascontent}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{include file='footer'}
|
13
build.php
13
build.php
@ -15,6 +15,7 @@ Cleaning up
|
|||||||
EOT;
|
EOT;
|
||||||
if (file_exists('file.tar')) unlink('file.tar');
|
if (file_exists('file.tar')) unlink('file.tar');
|
||||||
if (file_exists('template.tar')) unlink('template.tar');
|
if (file_exists('template.tar')) unlink('template.tar');
|
||||||
|
if (file_exists('acptemplate.tar')) unlink('acptemplate.tar');
|
||||||
foreach (glob('file/js/*.js') as $jsFile) unlink($jsFile);
|
foreach (glob('file/js/*.js') as $jsFile) unlink($jsFile);
|
||||||
foreach (glob('file/style/*.css') as $cssFile) unlink($cssFile);
|
foreach (glob('file/style/*.css') as $cssFile) unlink($cssFile);
|
||||||
if (file_exists('timwolla.wcf.chat.tar')) unlink('timwolla.wcf.chat.tar');
|
if (file_exists('timwolla.wcf.chat.tar')) unlink('timwolla.wcf.chat.tar');
|
||||||
@ -60,15 +61,25 @@ EOT;
|
|||||||
if ($code != 0) exit($code);
|
if ($code != 0) exit($code);
|
||||||
echo <<<EOT
|
echo <<<EOT
|
||||||
|
|
||||||
|
Building acptemplate.tar
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
EOT;
|
||||||
|
chdir('../acptemplate');
|
||||||
|
passthru('tar cvf ../acptemplate.tar *', $code);
|
||||||
|
if ($code != 0) exit($code);
|
||||||
|
echo <<<EOT
|
||||||
|
|
||||||
Building timwolla.wcf.chat.tar
|
Building timwolla.wcf.chat.tar
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
EOT;
|
EOT;
|
||||||
chdir('..');
|
chdir('..');
|
||||||
passthru('tar cvf timwolla.wcf.chat.tar * --exclude=file --exclude=template --exclude=build.php', $code);
|
passthru('tar cvf timwolla.wcf.chat.tar * --exclude=file --exclude=template --exclude=acptemplate --exclude=build.php', $code);
|
||||||
if ($code != 0) exit($code);
|
if ($code != 0) exit($code);
|
||||||
|
|
||||||
if (file_exists('file.tar')) unlink('file.tar');
|
if (file_exists('file.tar')) unlink('file.tar');
|
||||||
if (file_exists('template.tar')) unlink('template.tar');
|
if (file_exists('template.tar')) unlink('template.tar');
|
||||||
|
if (file_exists('acptemplate.tar')) unlink('acptemplate.tar');
|
||||||
foreach (glob('file/js/*.js') as $jsFile) unlink($jsFile);
|
foreach (glob('file/js/*.js') as $jsFile) unlink($jsFile);
|
||||||
foreach (glob('file/style/*.css') as $cssFile) unlink($cssFile);
|
foreach (glob('file/style/*.css') as $cssFile) unlink($cssFile);
|
||||||
|
34
file/acp/timwolla.wcf.chat.update.php
Normal file
34
file/acp/timwolla.wcf.chat.update.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
namespace timwolla\wcf\chat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles updates.
|
||||||
|
*
|
||||||
|
* @author Tim Düsterhus
|
||||||
|
* @copyright 2010-2012 Tim Düsterhus
|
||||||
|
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
||||||
|
* @package timwolla.wcf.chat
|
||||||
|
*/
|
||||||
|
final class Update {
|
||||||
|
private $rooms = null;
|
||||||
|
public function __construct() {
|
||||||
|
$this->rooms = \wcf\data\chat\room\ChatRoom::getCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute() {
|
||||||
|
foreach ($this->rooms as $room) {
|
||||||
|
$messageAction = new \wcf\data\chat\message\ChatMessageAction(array(), 'create', array(
|
||||||
|
'data' => array(
|
||||||
|
'roomID' => $room->roomID,
|
||||||
|
'time' => TIME_NOW,
|
||||||
|
'type' => \wcf\data\chat\message\ChatMessage::TYPE_INFORMATION,
|
||||||
|
// TODO: Language item
|
||||||
|
'message' => 'Tims Chat was updated. Please refresh the page.'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
$messageAction->executeAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$update = new Update();
|
||||||
|
$update->execute();
|
58
file/icon/chat.svg
Normal file
58
file/icon/chat.svg
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!--
|
||||||
|
@author Maximilian Mader
|
||||||
|
@copyright 2011 Tim Düsterhus
|
||||||
|
@license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
||||||
|
-->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" xml:space="preserve">
|
||||||
|
<title>Chat</title>
|
||||||
|
<desc>Chat Icon (outlined)</desc>
|
||||||
|
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
<![CDATA[
|
||||||
|
.Lower .bubble {
|
||||||
|
fill:none;
|
||||||
|
stroke:#ffffff;
|
||||||
|
stroke-opacity:1;
|
||||||
|
}
|
||||||
|
.Lower .leaderLine {
|
||||||
|
fill:#ffffff;
|
||||||
|
fill-opacity:1;
|
||||||
|
stroke:none;
|
||||||
|
}
|
||||||
|
.Upper .bubble {
|
||||||
|
fill:none;
|
||||||
|
stroke:#336699;
|
||||||
|
stroke-opacity:1;
|
||||||
|
}
|
||||||
|
.Upper .leaderLine {
|
||||||
|
fill:#336699;
|
||||||
|
fill-opacity:1;
|
||||||
|
stroke:none;
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<g id="IconChat">
|
||||||
|
<g class="Lower" style="display:inline">
|
||||||
|
<path class="bubble"
|
||||||
|
d="M 15,8 A 6,5 0 1 1 3,8 6,5 0 1 1 15,8 z"
|
||||||
|
transform="matrix(1.0345788,0,0,0.95089627,-1.510083,0.10801843)" />
|
||||||
|
<path class="leaderLine"
|
||||||
|
d="m 3.9001344,11.947742 c 0.075049,1.120603 -0.7948094,1.693805 -1.4915533,2.143417 1.0104403,
|
||||||
|
0.104041 3.4597063,-0.953975 3.9167086,-1.276108 0.00808,-0.0057 -2.4251553,-0.867309 -2.4251553,-0.867309 z" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g class="Upper" style="display:inline">
|
||||||
|
<path class="bubble"
|
||||||
|
d="M 15,8 A 6,5 0 1 1 3,8 6,5 0 1 1 15,8 z"
|
||||||
|
transform="matrix(1.0345788,0,0,0.95089627,-1.5100816,-0.50773368)" />
|
||||||
|
<path class="leaderLine"
|
||||||
|
d="m 3.9001358,11.331991 c 0.075049,1.120603 -0.7948094,1.693805 -1.4915533,2.143417 1.0104403,
|
||||||
|
0.104041 3.4597063,-0.953975 3.9167086,-1.276108 0.00808,-0.0057 -2.4251553,-0.867309 -2.4251553,-0.867309 z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -9,12 +9,18 @@
|
|||||||
|
|
||||||
TimWolla ?= {}
|
TimWolla ?= {}
|
||||||
TimWolla.WCF ?= {}
|
TimWolla.WCF ?= {}
|
||||||
|
consoleMock = console
|
||||||
consoleMock ?=
|
consoleMock ?=
|
||||||
log: () ->,
|
log: () ->,
|
||||||
warn: () ->
|
warn: () ->,
|
||||||
|
error: () ->
|
||||||
|
|
||||||
(($, window, console) ->
|
(($, window, console) ->
|
||||||
TimWolla.WCF.Chat =
|
TimWolla.WCF.Chat =
|
||||||
|
# Tims Chat stops loading when this reaches zero
|
||||||
|
# TODO: We need an explosion animation
|
||||||
|
shields: 3
|
||||||
|
|
||||||
# Templates
|
# Templates
|
||||||
titleTemplate: null
|
titleTemplate: null
|
||||||
messageTemplate: null
|
messageTemplate: null
|
||||||
@ -34,17 +40,21 @@ consoleMock ?=
|
|||||||
events:
|
events:
|
||||||
newMessage: $.Callbacks()
|
newMessage: $.Callbacks()
|
||||||
userMenu: $.Callbacks()
|
userMenu: $.Callbacks()
|
||||||
|
pe:
|
||||||
|
getMessages: null
|
||||||
|
refreshRoomList: null
|
||||||
|
fish: null
|
||||||
init: () ->
|
init: () ->
|
||||||
console.log '[TimWolla.WCF.Chat] Initializing'
|
console.log '[TimWolla.WCF.Chat] Initializing'
|
||||||
@bindEvents()
|
@bindEvents()
|
||||||
@events.newMessage.add $.proxy @notify, @
|
@events.newMessage.add $.proxy @notify, @
|
||||||
|
|
||||||
new WCF.PeriodicalExecuter $.proxy(@refreshRoomList, @), 60e3
|
@pe.refreshRoomList = new WCF.PeriodicalExecuter $.proxy(@refreshRoomList, @), 60e3
|
||||||
new WCF.PeriodicalExecuter $.proxy(@getMessages, @), @config.reloadTime * 1e3
|
@pe.getMessages = new WCF.PeriodicalExecuter $.proxy(@getMessages, @), @config.reloadTime * 1e3
|
||||||
@refreshRoomList()
|
@refreshRoomList()
|
||||||
@getMessages()
|
@getMessages()
|
||||||
|
|
||||||
console.log '[TimWolla.WCF.Chat] Finished initializing'
|
console.log '[TimWolla.WCF.Chat] Finished initializing - Shields at 104 percent'
|
||||||
###
|
###
|
||||||
# Autocompletes a username
|
# Autocompletes a username
|
||||||
###
|
###
|
||||||
@ -64,6 +74,7 @@ consoleMock ?=
|
|||||||
# Binds all the events needed for Tims Chat.
|
# Binds all the events needed for Tims Chat.
|
||||||
###
|
###
|
||||||
bindEvents: () ->
|
bindEvents: () ->
|
||||||
|
# Mark window as focused
|
||||||
$(window).focus $.proxy () ->
|
$(window).focus $.proxy () ->
|
||||||
document.title = @titleTemplate.fetch
|
document.title = @titleTemplate.fetch
|
||||||
title: $('#timsChatRoomList .activeMenuItem a').text()
|
title: $('#timsChatRoomList .activeMenuItem a').text()
|
||||||
@ -71,12 +82,19 @@ consoleMock ?=
|
|||||||
@isActive = true
|
@isActive = true
|
||||||
, @
|
, @
|
||||||
|
|
||||||
|
# Mark window as blurred
|
||||||
$(window).blur $.proxy () ->
|
$(window).blur $.proxy () ->
|
||||||
@isActive = false
|
@isActive = false
|
||||||
, @
|
, @
|
||||||
|
|
||||||
|
# Unload the chat
|
||||||
|
window.onbeforeunload = $.proxy () ->
|
||||||
|
@unload()
|
||||||
|
return undefined
|
||||||
|
, @
|
||||||
|
|
||||||
# Insert a smiley
|
# Insert a smiley
|
||||||
$('.smiley').click $.proxy (event) ->
|
$('.jsSmiley').click $.proxy (event) ->
|
||||||
@insertText ' ' + $(event.target).attr('alt') + ' '
|
@insertText ' ' + $(event.target).attr('alt') + ' '
|
||||||
, @
|
, @
|
||||||
|
|
||||||
@ -120,7 +138,7 @@ consoleMock ?=
|
|||||||
$('#timsChatClear').click (event) ->
|
$('#timsChatClear').click (event) ->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
$('.timsChatMessage').remove()
|
$('.timsChatMessage').remove()
|
||||||
@oldScrollTop = $('.timsChatMessageContainer').scrollTop()
|
@oldScrollTop = null
|
||||||
$('.timsChatMessageContainer').scrollTop $('.timsChatMessageContainer ul').height()
|
$('.timsChatMessageContainer').scrollTop $('.timsChatMessageContainer ul').height()
|
||||||
$('#timsChatInput').focus()
|
$('#timsChatInput').focus()
|
||||||
|
|
||||||
@ -139,7 +157,7 @@ consoleMock ?=
|
|||||||
|
|
||||||
# Immediatly scroll down when activating autoscroll
|
# Immediatly scroll down when activating autoscroll
|
||||||
$('#timsChatAutoscroll').click (event) ->
|
$('#timsChatAutoscroll').click (event) ->
|
||||||
$(this).removeClass('hot')
|
$(this).parent().removeClass('default')
|
||||||
if $(this).data 'status'
|
if $(this).data 'status'
|
||||||
$('.timsChatMessageContainer').scrollTop $('.timsChatMessageContainer ul').height()
|
$('.timsChatMessageContainer').scrollTop $('.timsChatMessageContainer ul').height()
|
||||||
@oldScrollTop = $('.timsChatMessageContainer').scrollTop()
|
@oldScrollTop = $('.timsChatMessageContainer').scrollTop()
|
||||||
@ -172,15 +190,15 @@ consoleMock ?=
|
|||||||
|
|
||||||
# Set new topic
|
# Set new topic
|
||||||
if data.topic is ''
|
if data.topic is ''
|
||||||
return if $('#topic').text().trim() is ''
|
return if $('#timsChatTopic').text().trim() is ''
|
||||||
|
|
||||||
$('#topic').wcfBlindOut 'vertical', () ->
|
$('#timsChatTopic').wcfBlindOut 'vertical', () ->
|
||||||
$(@).text ''
|
$(@).text ''
|
||||||
else
|
else
|
||||||
$('#topic').text data.topic
|
$('#timsChatTopic').text data.topic
|
||||||
$('#topic').wcfBlindIn() if $('#topic').text().trim() isnt '' and $('#topic').is(':hidden')
|
$('#timsChatTopic').wcfBlindIn() if $('#timsChatTopic').text().trim() isnt '' and $('#timsChatTopic').is(':hidden')
|
||||||
|
|
||||||
$('.timsChatMessage').animate('opacity', .8);
|
$('.timsChatMessage').addClass('unloaded', 800);
|
||||||
@handleMessages data.messages
|
@handleMessages data.messages
|
||||||
document.title = @titleTemplate.fetch data
|
document.title = @titleTemplate.fetch data
|
||||||
, @)
|
, @)
|
||||||
@ -198,7 +216,7 @@ consoleMock ?=
|
|||||||
# Frees the fish
|
# Frees the fish
|
||||||
###
|
###
|
||||||
freeTheFish: () ->
|
freeTheFish: () ->
|
||||||
return if $.wcfIsset('fish')
|
return if $.wcfIsset 'fish'
|
||||||
console.warn '[TimWolla.WCF.Chat] Freeing the fish'
|
console.warn '[TimWolla.WCF.Chat] Freeing the fish'
|
||||||
fish = $ '<div id="fish">' + WCF.String.escapeHTML('><((((\u00B0>') + '</div>'
|
fish = $ '<div id="fish">' + WCF.String.escapeHTML('><((((\u00B0>') + '</div>'
|
||||||
fish.css
|
fish.css
|
||||||
@ -210,16 +228,16 @@ consoleMock ?=
|
|||||||
zIndex: 9999
|
zIndex: 9999
|
||||||
|
|
||||||
fish.appendTo $ 'body'
|
fish.appendTo $ 'body'
|
||||||
new WCF.PeriodicalExecuter(() ->
|
@pe.fish = new WCF.PeriodicalExecuter(() ->
|
||||||
left = Math.random() * 100 - 50
|
left = Math.random() * 100 - 50
|
||||||
top = Math.random() * 100 - 50
|
top = Math.random() * 100 - 50
|
||||||
fish = $('#fish')
|
fish = $ '#fish'
|
||||||
|
|
||||||
left *= -1 unless fish.width() < (fish.position().left + left) < ($(document).width() - fish.width())
|
left *= -1 unless fish.width() < (fish.position().left + left) < ($(document).width() - fish.width())
|
||||||
top *= -1 unless fish.height() < (fish.position().top + top) < ($(document).height() - fish.height())
|
top *= -1 unless fish.height() < (fish.position().top + top) < ($(document).height() - fish.height())
|
||||||
|
|
||||||
fish.text('><((((\u00B0>') if left > 0
|
fish.text '><((((\u00B0>' if left > 0
|
||||||
fish.text('<\u00B0))))><') if left < 0
|
fish.text '<\u00B0))))><' if left < 0
|
||||||
|
|
||||||
fish.animate
|
fish.animate
|
||||||
top: '+=' + top
|
top: '+=' + top
|
||||||
@ -237,6 +255,15 @@ consoleMock ?=
|
|||||||
@handleMessages(data.messages)
|
@handleMessages(data.messages)
|
||||||
@handleUsers(data.users)
|
@handleUsers(data.users)
|
||||||
, @)
|
, @)
|
||||||
|
error: $.proxy((jqXHR, textStatus, errorThrown) ->
|
||||||
|
console.error '[TimWolla.WCF.Chat] Battle Station hit - shields at ' + (--@shields / 3 * 104) + ' percent'
|
||||||
|
if @shields is 0
|
||||||
|
@pe.refreshRoomList.stop()
|
||||||
|
@pe.getMessages.stop()
|
||||||
|
@freeTheFish()
|
||||||
|
console.error '[TimWolla.WCF.Chat] We got destroyed, but could free our friend the fish before he was killed as well. Have a nice life in freedom!'
|
||||||
|
alert 'herp i cannot load messages'
|
||||||
|
, @)
|
||||||
###
|
###
|
||||||
# Inserts the new messages.
|
# Inserts the new messages.
|
||||||
#
|
#
|
||||||
@ -248,14 +275,16 @@ consoleMock ?=
|
|||||||
if $('.timsChatMessageContainer').scrollTop() < @oldScrollTop
|
if $('.timsChatMessageContainer').scrollTop() < @oldScrollTop
|
||||||
if $('#timsChatAutoscroll').data('status') is 1
|
if $('#timsChatAutoscroll').data('status') is 1
|
||||||
$('#timsChatAutoscroll').click()
|
$('#timsChatAutoscroll').click()
|
||||||
$('#timsChatAutoscroll').addClass('hot').fadeOut('slow').fadeIn('slow')
|
$('#timsChatAutoscroll').parent().addClass('default').fadeOut('slow').fadeIn('slow')
|
||||||
|
|
||||||
# Insert the messages
|
# Insert the messages
|
||||||
for message in messages
|
for message in messages
|
||||||
|
continue if $.wcfIsset 'timsChatMessage'+message.messageID # Prevent problems with race condition
|
||||||
@events.newMessage.fire message
|
@events.newMessage.fire message
|
||||||
|
|
||||||
output = @messageTemplate.fetch message
|
output = @messageTemplate.fetch message
|
||||||
li = $ '<li></li>'
|
li = $ '<li></li>'
|
||||||
|
li.attr 'id', 'timsChatMessage'+message.messageID
|
||||||
li.addClass 'timsChatMessage timsChatMessage'+message.type
|
li.addClass 'timsChatMessage timsChatMessage'+message.type
|
||||||
li.addClass 'ownMessage' if message.sender is WCF.User.userID
|
li.addClass 'ownMessage' if message.sender is WCF.User.userID
|
||||||
li.append output
|
li.append output
|
||||||
@ -314,7 +343,7 @@ consoleMock ?=
|
|||||||
$(@).remove();
|
$(@).remove();
|
||||||
|
|
||||||
|
|
||||||
$('#toggleUsers .badge').text(users.length);
|
$('#toggleUsers .wcf-badge').text(users.length);
|
||||||
###
|
###
|
||||||
# Inserts text into our input.
|
# Inserts text into our input.
|
||||||
#
|
#
|
||||||
@ -371,7 +400,7 @@ consoleMock ?=
|
|||||||
success: $.proxy((data, textStatus, jqXHR) ->
|
success: $.proxy((data, textStatus, jqXHR) ->
|
||||||
$('#timsChatRoomList li').remove()
|
$('#timsChatRoomList li').remove()
|
||||||
$('#toggleRooms a').removeClass 'ajaxLoad'
|
$('#toggleRooms a').removeClass 'ajaxLoad'
|
||||||
$('#toggleRooms .badge').text(data.length);
|
$('#toggleRooms .wcf-badge').text(data.length);
|
||||||
|
|
||||||
for room in data
|
for room in data
|
||||||
li = $ '<li></li>'
|
li = $ '<li></li>'
|
||||||
@ -447,4 +476,11 @@ consoleMock ?=
|
|||||||
else
|
else
|
||||||
li.addClass 'activeMenuItem'
|
li.addClass 'activeMenuItem'
|
||||||
li.find('.timsChatUserMenu').wcfBlindIn 'vertical'
|
li.find('.timsChatUserMenu').wcfBlindIn 'vertical'
|
||||||
|
###
|
||||||
|
# Unloads the chat.
|
||||||
|
###
|
||||||
|
unload: () ->
|
||||||
|
$.ajax @config.unloadURL,
|
||||||
|
type: 'POST'
|
||||||
|
async: false
|
||||||
)(jQuery, @, consoleMock)
|
)(jQuery, @, consoleMock)
|
||||||
|
149
file/lib/acp/form/ChatRoomAddForm.class.php
Normal file
149
file/lib/acp/form/ChatRoomAddForm.class.php
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<?php
|
||||||
|
namespace wcf\acp\form;
|
||||||
|
use \wcf\system\exception\UserInputException;
|
||||||
|
use \wcf\system\language\I18nHandler;
|
||||||
|
use \wcf\system\package\PackageDependencyHandler;
|
||||||
|
use \wcf\system\WCF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the chatroom add form.
|
||||||
|
*
|
||||||
|
* @author Tim Düsterhus
|
||||||
|
* @copyright 2010-2012 Tim Düsterhus
|
||||||
|
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
||||||
|
* @package timwolla.wcf.chat
|
||||||
|
* @subpackage acp.form
|
||||||
|
*/
|
||||||
|
class ChatRoomAddForm extends ACPForm {
|
||||||
|
/**
|
||||||
|
* @see \wcf\acp\form\ACPForm::$activeMenuItem
|
||||||
|
*/
|
||||||
|
public $activeMenuItem = 'wcf.acp.menu.link.chat.room.add';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\AbstractPage::$neededPermissions
|
||||||
|
*/
|
||||||
|
public $neededPermissions = array('admin.content.chat.canAddRoom');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Title of the room
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $title = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Topic of the room
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $topic = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\AbstractPage::__construct()
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
$this->objectTypeID = \wcf\system\acl\ACLHandler::getInstance()->getObjectTypeID('timwolla.wcf.chat.room');
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\IPage::readParameters()
|
||||||
|
*/
|
||||||
|
public function readParameters() {
|
||||||
|
parent::readParameters();
|
||||||
|
|
||||||
|
I18nHandler::getInstance()->register('title');
|
||||||
|
I18nHandler::getInstance()->register('topic');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\form\IForm::readFormParameters()
|
||||||
|
*/
|
||||||
|
public function readFormParameters() {
|
||||||
|
parent::readFormParameters();
|
||||||
|
|
||||||
|
I18nHandler::getInstance()->readValues();
|
||||||
|
|
||||||
|
if (I18nHandler::getInstance()->isPlainValue('title')) $this->title = I18nHandler::getInstance()->getValue('title');
|
||||||
|
if (I18nHandler::getInstance()->isPlainValue('topic')) $this->topic = I18nHandler::getInstance()->getValue('topic');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\form\IForm::validate()
|
||||||
|
*/
|
||||||
|
public function validate() {
|
||||||
|
parent::validate();
|
||||||
|
|
||||||
|
// validate title
|
||||||
|
if (!I18nHandler::getInstance()->validateValue('title')) {
|
||||||
|
throw new UserInputException('title');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\form\IForm::save()
|
||||||
|
*/
|
||||||
|
public function save() {
|
||||||
|
parent::save();
|
||||||
|
|
||||||
|
// save room
|
||||||
|
$this->objectAction = new \wcf\data\chat\room\ChatRoomAction(array(), 'create', array('data' => array(
|
||||||
|
'title' => $this->title,
|
||||||
|
'topic' => $this->topic
|
||||||
|
)));
|
||||||
|
$this->objectAction->executeAction();
|
||||||
|
$returnValues = $this->objectAction->getReturnValues();
|
||||||
|
$chatRoomEditor = new \wcf\data\chat\room\ChatRoomEditor($returnValues['returnValues']);
|
||||||
|
$roomID = $returnValues['returnValues']->roomID;
|
||||||
|
|
||||||
|
if (!I18nHandler::getInstance()->isPlainValue('title')) {
|
||||||
|
I18nHandler::getInstance()->save('title', 'wcf.chat.room.title'.$roomID, 'wcf.chat.room', PackageDependencyHandler::getPackageID('timwolla.wcf.chat'));
|
||||||
|
|
||||||
|
// update title
|
||||||
|
$chatRoomEditor->update(array(
|
||||||
|
'title' => 'wcf.chat.room.title'.$roomID
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!I18nHandler::getInstance()->isPlainValue('topic')) {
|
||||||
|
I18nHandler::getInstance()->save('topic', 'wcf.chat.room.topic'.$roomID, 'wcf.chat.room', PackageDependencyHandler::getPackageID('timwolla.wcf.chat'));
|
||||||
|
|
||||||
|
// update topic
|
||||||
|
$chatRoomEditor->update(array(
|
||||||
|
'topic' => 'wcf.chat.room.topic'.$roomID
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
\wcf\system\acl\ACLHandler::getInstance()->save($roomID, $this->objectTypeID);
|
||||||
|
\wcf\system\chat\permission\ChatPermissionHandler::clearCache();
|
||||||
|
|
||||||
|
$this->saved();
|
||||||
|
|
||||||
|
// reset values
|
||||||
|
$this->topic = $this->title = '';
|
||||||
|
I18nHandler::getInstance()->disableAssignValueVariables();
|
||||||
|
|
||||||
|
// show success
|
||||||
|
WCF::getTPL()->assign(array(
|
||||||
|
'success' => true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\IPage::assignVariables()
|
||||||
|
*/
|
||||||
|
public function assignVariables() {
|
||||||
|
parent::assignVariables();
|
||||||
|
|
||||||
|
I18nHandler::getInstance()->assignVariables();
|
||||||
|
|
||||||
|
WCF::getTPL()->assign(array(
|
||||||
|
'action' => 'add',
|
||||||
|
'title' => $this->title,
|
||||||
|
'topic' => $this->topic,
|
||||||
|
'objectTypeID' => $this->objectTypeID
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
129
file/lib/acp/form/ChatRoomEditForm.class.php
Normal file
129
file/lib/acp/form/ChatRoomEditForm.class.php
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
namespace wcf\acp\form;
|
||||||
|
use wcf\system\language\I18nHandler;
|
||||||
|
use wcf\system\package\PackageDependencyHandler;
|
||||||
|
use wcf\system\WCF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the chatroom edit form.
|
||||||
|
*
|
||||||
|
* @author Tim Düsterhus
|
||||||
|
* @copyright 2010-2012 Tim Düsterhus
|
||||||
|
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
||||||
|
* @package timwolla.wcf.chat
|
||||||
|
* @subpackage acp.form
|
||||||
|
*/
|
||||||
|
class ChatRoomEditForm extends ChatRoomAddForm {
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\AbstractPage::$templateName
|
||||||
|
*/
|
||||||
|
public $templateName = 'chatRoomAdd';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\acp\form\ACPForm::$activeMenuItem
|
||||||
|
*/
|
||||||
|
public $activeMenuItem = 'wcf.acp.menu.link.chat.room.list';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\AbstractPage::$neededPermissions
|
||||||
|
*/
|
||||||
|
public $neededPermissions = array('admin.content.chat.canEditRoom');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* room id
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
public $roomID = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* room object
|
||||||
|
*
|
||||||
|
* @var \wcf\data\chat\room\ChatRoom
|
||||||
|
*/
|
||||||
|
public $roomObj = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\IPage::readParameters()
|
||||||
|
*/
|
||||||
|
public function readParameters() {
|
||||||
|
parent::readParameters();
|
||||||
|
|
||||||
|
if (isset($_REQUEST['id'])) $this->roomID = intval($_REQUEST['id']);
|
||||||
|
$this->roomObj = new \wcf\data\chat\room\ChatRoom($this->roomID);
|
||||||
|
if (!$this->roomObj->roomID) {
|
||||||
|
throw new \wcf\system\exception\IllegalLinkException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\form\IForm::save()
|
||||||
|
*/
|
||||||
|
public function save() {
|
||||||
|
ACPForm::save();
|
||||||
|
|
||||||
|
$this->title = 'wcf.chat.room.title'.$this->roomObj->roomID;
|
||||||
|
if (I18nHandler::getInstance()->isPlainValue('title')) {
|
||||||
|
I18nHandler::getInstance()->remove($this->title, PackageDependencyHandler::getPackageID('timwolla.wcf.chat'));
|
||||||
|
$this->title = I18nHandler::getInstance()->getValue('title');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
I18nHandler::getInstance()->save('title', $this->title, 'wcf.chat.room', PackageDependencyHandler::getPackageID('timwolla.wcf.chat'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->topic = 'wcf.chat.room.topic'.$this->roomObj->roomID;
|
||||||
|
if (I18nHandler::getInstance()->isPlainValue('topic')) {
|
||||||
|
I18nHandler::getInstance()->remove($this->topic, PackageDependencyHandler::getPackageID('timwolla.wcf.chat'));
|
||||||
|
$this->topic = I18nHandler::getInstance()->getValue('topic');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
I18nHandler::getInstance()->save('topic', $this->topic, 'wcf.chat.room', PackageDependencyHandler::getPackageID('timwolla.wcf.chat'));
|
||||||
|
}
|
||||||
|
|
||||||
|
\wcf\system\acl\ACLHandler::getInstance()->save($this->roomID, $this->objectTypeID);
|
||||||
|
\wcf\system\chat\permission\ChatPermissionHandler::clearCache();
|
||||||
|
|
||||||
|
// update room
|
||||||
|
$this->objectAction = new \wcf\data\chat\room\ChatRoomAction(array($this->roomID), 'update', array('data' => array(
|
||||||
|
'title' => $this->title,
|
||||||
|
'topic' => $this->topic
|
||||||
|
)));
|
||||||
|
$this->objectAction->executeAction();
|
||||||
|
|
||||||
|
$this->saved();
|
||||||
|
|
||||||
|
// show success
|
||||||
|
WCF::getTPL()->assign(array(
|
||||||
|
'success' => true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\IPage::readData()
|
||||||
|
*/
|
||||||
|
public function readData() {
|
||||||
|
parent::readData();
|
||||||
|
|
||||||
|
if (!count($_POST)) {
|
||||||
|
I18nHandler::getInstance()->setOptions('title', PackageDependencyHandler::getPackageID('timwolla.wcf.chat'), $this->roomObj->title, 'wcf.chat.room.title\d+');
|
||||||
|
I18nHandler::getInstance()->setOptions('topic', PackageDependencyHandler::getPackageID('timwolla.wcf.chat'), $this->roomObj->topic, 'wcf.chat.room.topic\d+');
|
||||||
|
|
||||||
|
$this->title = $this->roomObj->title;
|
||||||
|
$this->topic = $this->roomObj->topic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\IPage::assignVariables()
|
||||||
|
*/
|
||||||
|
public function assignVariables() {
|
||||||
|
parent::assignVariables();
|
||||||
|
|
||||||
|
I18nHandler::getInstance()->assignVariables((bool) count($_POST));
|
||||||
|
|
||||||
|
WCF::getTPL()->assign(array(
|
||||||
|
'roomID' => $this->roomID,
|
||||||
|
'action' => 'edit'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
46
file/lib/acp/page/ChatRoomListPage.class.php
Normal file
46
file/lib/acp/page/ChatRoomListPage.class.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
namespace wcf\acp\page;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists available chatrooms.
|
||||||
|
*
|
||||||
|
* @author Tim Düsterhus
|
||||||
|
* @copyright 2010-2012 Tim Düsterhus
|
||||||
|
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
||||||
|
* @package timwolla.wcf.chat
|
||||||
|
* @subpackage acp.page
|
||||||
|
*/
|
||||||
|
class ChatRoomListPage extends \wcf\page\MultipleLinkPage {
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\AbstractPage::$neededPermissions
|
||||||
|
*/
|
||||||
|
public $neededPermissions = array(
|
||||||
|
'admin.content.chat.canEditRoom',
|
||||||
|
'admin.content.chat.canDeleteRoom'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\MultipleLinkPage::$objectListClassName
|
||||||
|
*/
|
||||||
|
public $objectListClassName = '\wcf\data\chat\room\ChatRoomList';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\MultipleLinkPage::$sortField
|
||||||
|
*/
|
||||||
|
public $sortField = 'position';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\MultipleLinkPage::$sortOrder
|
||||||
|
*/
|
||||||
|
public $sortOrder = 'ASC';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\IPage::show()
|
||||||
|
*/
|
||||||
|
public function show() {
|
||||||
|
// set active menu item.
|
||||||
|
\wcf\system\menu\acp\ACPMenu::getInstance()->setActiveMenuItem('wcf.acp.menu.link.chat.room.list');
|
||||||
|
|
||||||
|
parent::show();
|
||||||
|
}
|
||||||
|
}
|
65
file/lib/action/ChatLeaveAction.class.php
Normal file
65
file/lib/action/ChatLeaveAction.class.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
namespace wcf\action;
|
||||||
|
use \wcf\data\chat;
|
||||||
|
use \wcf\system\WCF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the user leave Tims Chat.
|
||||||
|
*
|
||||||
|
* @author Tim Düsterhus
|
||||||
|
* @copyright 2010-2012 Tim Düsterhus
|
||||||
|
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
||||||
|
* @package timwolla.wcf.chat
|
||||||
|
* @subpackage action
|
||||||
|
*/
|
||||||
|
class ChatLeaveAction extends AbstractAction {
|
||||||
|
/**
|
||||||
|
* @see \wcf\action\AbstractAction::$neededModules
|
||||||
|
*/
|
||||||
|
public $neededModules = array('CHAT_ACTIVE');
|
||||||
|
//public $neededPermissions = array('user.chat.canEnter');
|
||||||
|
public $room = null;
|
||||||
|
public $userData = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\action\IAction::execute()
|
||||||
|
*/
|
||||||
|
public function execute() {
|
||||||
|
parent::execute();
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if (!WCF::getUser()->userID) {
|
||||||
|
throw new IllegalLinkException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->userData['roomID'] = \wcf\util\ChatUtil::readUserData('roomID');
|
||||||
|
|
||||||
|
$this->room = chat\room\ChatRoom::getCache()->search($this->userData['roomID']);
|
||||||
|
if (!$this->room) throw new \wcf\system\exception\IllegalLinkException();
|
||||||
|
if (!$this->room->canEnter()) throw new \wcf\system\exception\PermissionDeniedException();
|
||||||
|
|
||||||
|
if (CHAT_DISPLAY_JOIN_LEAVE) {
|
||||||
|
$this->userData['color'] = \wcf\util\ChatUtil::readUserData('color');
|
||||||
|
|
||||||
|
$messageAction = new chat\message\ChatMessageAction(array(), 'create', array(
|
||||||
|
'data' => array(
|
||||||
|
'roomID' => $this->room->roomID,
|
||||||
|
'sender' => WCF::getUser()->userID,
|
||||||
|
'username' => WCF::getUser()->username,
|
||||||
|
'time' => TIME_NOW,
|
||||||
|
'type' => chat\message\ChatMessage::TYPE_LEAVE,
|
||||||
|
'message' => '',
|
||||||
|
'color1' => $this->userData['color'][1],
|
||||||
|
'color2' => $this->userData['color'][2]
|
||||||
|
)
|
||||||
|
));
|
||||||
|
$messageAction->executeAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
\wcf\util\ChatUtil::writeUserData(array('roomID' => null));
|
||||||
|
|
||||||
|
$this->executed();
|
||||||
|
header("HTTP/1.0 204 No Content");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
@ -13,12 +13,12 @@ use \wcf\system\WCF;
|
|||||||
*/
|
*/
|
||||||
class ChatMessage extends \wcf\data\DatabaseObject {
|
class ChatMessage extends \wcf\data\DatabaseObject {
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\DatabaseObject::$databaseTableName
|
* @see \wcf\data\DatabaseObject::$databaseTableName
|
||||||
*/
|
*/
|
||||||
protected static $databaseTableName = 'chat_message';
|
protected static $databaseTableName = 'chat_message';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\DatabaseObject::$databaseTableIndexName
|
* @see \wcf\data\DatabaseObject::$databaseTableIndexName
|
||||||
*/
|
*/
|
||||||
protected static $databaseTableIndexName = 'messageID';
|
protected static $databaseTableIndexName = 'messageID';
|
||||||
|
|
||||||
@ -110,7 +110,8 @@ class ChatMessage extends \wcf\data\DatabaseObject {
|
|||||||
'time' => $this->time,
|
'time' => $this->time,
|
||||||
'receiver' => $this->receiver,
|
'receiver' => $this->receiver,
|
||||||
'type' => $this->type,
|
'type' => $this->type,
|
||||||
'roomID' => $this->roomID
|
'roomID' => $this->roomID,
|
||||||
|
'messageID' => $this->messageID
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($raw) return $array;
|
if ($raw) return $array;
|
||||||
|
@ -12,7 +12,7 @@ namespace wcf\data\chat\message;
|
|||||||
*/
|
*/
|
||||||
class ChatMessageAction extends \wcf\data\AbstractDatabaseObjectAction {
|
class ChatMessageAction extends \wcf\data\AbstractDatabaseObjectAction {
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\AbstractDatabaseObjectAction::$className
|
* @see \wcf\data\AbstractDatabaseObjectAction::$className
|
||||||
*/
|
*/
|
||||||
protected $className = '\wcf\data\chat\message\ChatMessageEditor';
|
protected $className = '\wcf\data\chat\message\ChatMessageEditor';
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace wcf\data\chat\message;
|
|||||||
*/
|
*/
|
||||||
class ChatMessageEditor extends \wcf\data\DatabaseObjectEditor {
|
class ChatMessageEditor extends \wcf\data\DatabaseObjectEditor {
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\DatabaseObjectDecorator::$baseClass
|
* @see \wcf\data\DatabaseObjectDecorator::$baseClass
|
||||||
*/
|
*/
|
||||||
protected static $baseClass = '\wcf\data\chat\message\ChatMessage';
|
protected static $baseClass = '\wcf\data\chat\message\ChatMessage';
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ namespace wcf\data\chat\message;
|
|||||||
*/
|
*/
|
||||||
class ChatMessageList extends \wcf\data\DatabaseObjectList {
|
class ChatMessageList extends \wcf\data\DatabaseObjectList {
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\DatabaseObjectList::$className
|
* @see \wcf\data\DatabaseObjectList::$className
|
||||||
*/
|
*/
|
||||||
public $className = 'wcf\data\chat\message\ChatMessage';
|
public $className = 'wcf\data\chat\message\ChatMessage';
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace wcf\data\chat\room;
|
namespace wcf\data\chat\room;
|
||||||
use \wcf\system\cache\CacheHandler;
|
use \wcf\system\cache\CacheHandler;
|
||||||
|
use \wcf\system\WCF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a chat room.
|
* Represents a chat room.
|
||||||
@ -13,12 +14,12 @@ use \wcf\system\cache\CacheHandler;
|
|||||||
*/
|
*/
|
||||||
class ChatRoom extends \wcf\data\DatabaseObject implements \wcf\system\request\IRouteController {
|
class ChatRoom extends \wcf\data\DatabaseObject implements \wcf\system\request\IRouteController {
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\DatabaseObject::$databaseTableName
|
* @see \wcf\data\DatabaseObject::$databaseTableName
|
||||||
*/
|
*/
|
||||||
protected static $databaseTableName = 'chat_room';
|
protected static $databaseTableName = 'chat_room';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\DatabaseObject::$databaseTableIndexName
|
* @see \wcf\data\DatabaseObject::$databaseTableIndexName
|
||||||
*/
|
*/
|
||||||
protected static $databaseTableIndexName = 'roomID';
|
protected static $databaseTableIndexName = 'roomID';
|
||||||
|
|
||||||
@ -29,6 +30,36 @@ class ChatRoom extends \wcf\data\DatabaseObject implements \wcf\system\request\I
|
|||||||
*/
|
*/
|
||||||
protected static $cache = null;
|
protected static $cache = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\data\chat\room\ChatRoom::getTitle();
|
||||||
|
*/
|
||||||
|
public function __toString() {
|
||||||
|
return $this->getTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of users currently active in this room.
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function countUsers() {
|
||||||
|
$packageID = \wcf\system\package\PackageDependencyHandler::getPackageID('timwolla.wcf.chat');
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
count(*) as count
|
||||||
|
FROM
|
||||||
|
wcf".WCF_N."_user_storage
|
||||||
|
WHERE
|
||||||
|
field = 'roomID'
|
||||||
|
AND packageID = ".intval($packageID)."
|
||||||
|
AND fieldValue = ".intval($this->roomID);
|
||||||
|
$stmt = WCF::getDB()->prepareStatement($sql);
|
||||||
|
$stmt->execute();
|
||||||
|
$row = $stmt->fetchArray();
|
||||||
|
|
||||||
|
return $row['count'];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the room cache.
|
* Loads the room cache.
|
||||||
*/
|
*/
|
||||||
@ -37,7 +68,7 @@ class ChatRoom extends \wcf\data\DatabaseObject implements \wcf\system\request\I
|
|||||||
CacheHandler::getInstance()->addResource(
|
CacheHandler::getInstance()->addResource(
|
||||||
'chatrooms',
|
'chatrooms',
|
||||||
WCF_DIR.'cache/cache.chatrooms.php',
|
WCF_DIR.'cache/cache.chatrooms.php',
|
||||||
'wcf\system\cache\builder\ChatRoomCacheBuilder'
|
'\wcf\system\cache\builder\ChatRoomCacheBuilder'
|
||||||
);
|
);
|
||||||
self::$cache = CacheHandler::getInstance()->get('chatrooms');
|
self::$cache = CacheHandler::getInstance()->get('chatrooms');
|
||||||
}
|
}
|
||||||
@ -46,10 +77,12 @@ class ChatRoom extends \wcf\data\DatabaseObject implements \wcf\system\request\I
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see \wcf\data\chat\room\ChatRoom::getTitle();
|
* Returns the ID of this chat-room.
|
||||||
|
*
|
||||||
|
* @see \wcf\system\request\IRouteController
|
||||||
*/
|
*/
|
||||||
public function __toString() {
|
public function getID() {
|
||||||
return $this->getTitle();
|
return $this->roomID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,12 +95,39 @@ class ChatRoom extends \wcf\data\DatabaseObject implements \wcf\system\request\I
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of this chat-room.
|
* Returns the users that are currently active in this room.
|
||||||
*
|
*
|
||||||
* @see \wcf\system\request\RRouteHandler
|
* @return array<\wcf\data\user\User>
|
||||||
*/
|
*/
|
||||||
public function getID() {
|
public function getUsers() {
|
||||||
return $this->roomID;
|
$packageID = \wcf\system\package\PackageDependencyHandler::getPackageID('timwolla.wcf.chat');
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
userID
|
||||||
|
FROM
|
||||||
|
wcf".WCF_N."_user_storage
|
||||||
|
WHERE
|
||||||
|
field = 'roomID'
|
||||||
|
AND packageID = ".intval($packageID)."
|
||||||
|
AND fieldValue = ".intval($this->roomID);
|
||||||
|
$stmt = WCF::getDB()->prepareStatement($sql);
|
||||||
|
$stmt->execute();
|
||||||
|
$userIDs = array();
|
||||||
|
while ($row = $stmt->fetchArray()) $userIDs[] = $row['userID'];
|
||||||
|
|
||||||
|
if (!count($userIDs)) return;
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
wcf".WCF_N."_user
|
||||||
|
WHERE
|
||||||
|
userID IN (".rtrim(str_repeat('?,', count($userIDs)), ',').")
|
||||||
|
ORDER BY
|
||||||
|
username ASC";
|
||||||
|
$stmt = WCF::getDB()->prepareStatement($sql);
|
||||||
|
$stmt->execute($userIDs);
|
||||||
|
return $stmt->fetchObjects('\wcf\data\user\User');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,6 +136,8 @@ class ChatRoom extends \wcf\data\DatabaseObject implements \wcf\system\request\I
|
|||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canEnter() {
|
public function canEnter() {
|
||||||
return \wcf\system\chat\permissions\ChatPermissionHandler::getInstance()->getPermission($this, 'canEnter');
|
$ph = \wcf\system\chat\permission\ChatPermissionHandler::getInstance();
|
||||||
|
|
||||||
|
return $ph->getPermission($this, 'user.canEnter') || $ph->getPermission($this, 'mod.canAlwaysEnter');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
95
file/lib/data/chat/room/ChatRoomAction.class.php
Normal file
95
file/lib/data/chat/room/ChatRoomAction.class.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
namespace wcf\data\chat\room;
|
||||||
|
use \wcf\system\WCF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes chatroom-related actions.
|
||||||
|
*
|
||||||
|
* @author Tim Düsterhus
|
||||||
|
* @copyright 2010-2012 Tim Düsterhus
|
||||||
|
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
||||||
|
* @package timwolla.wcf.chat
|
||||||
|
* @subpackage data.chat.room
|
||||||
|
*/
|
||||||
|
class ChatRoomAction extends \wcf\data\AbstractDatabaseObjectAction {
|
||||||
|
/**
|
||||||
|
* @see \wcf\data\AbstractDatabaseObjectAction::$className
|
||||||
|
*/
|
||||||
|
protected $className = '\wcf\data\chat\room\ChatRoomEditor';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\data\AbstractDatabaseObjectAction::$permissionsDelete
|
||||||
|
*/
|
||||||
|
protected $permissionsDelete = array('admin.content.chat.canDeleteRoom');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\data\AbstractDatabaseObjectAction::$permissionsUpdate
|
||||||
|
*/
|
||||||
|
protected $permissionsUpdate = array('admin.content.chat.canEditRoom');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fixes create to append new boards.
|
||||||
|
*/
|
||||||
|
public function create() {
|
||||||
|
$room = parent::create();
|
||||||
|
|
||||||
|
WCF::getDB()->beginTransaction();
|
||||||
|
$sql = "SELECT max(position) as max
|
||||||
|
FROM wcf".WCF_N."_chat_room
|
||||||
|
FOR UPDATE";
|
||||||
|
$stmt = WCF::getDB()->prepareStatement($sql);
|
||||||
|
$stmt->execute();
|
||||||
|
$row = $stmt->fetchArray();
|
||||||
|
|
||||||
|
$sql = "UPDATE wcf".WCF_N."_chat_room
|
||||||
|
SET position = ".($row['max'] + 1)."
|
||||||
|
WHERE roomID = ?";
|
||||||
|
$stmt = WCF::getDB()->prepareStatement($sql);
|
||||||
|
$stmt->execute(array($room->roomID));
|
||||||
|
WCF::getDB()->commitTransaction();
|
||||||
|
|
||||||
|
return $room;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates parameters to update sorting.
|
||||||
|
*/
|
||||||
|
public function validateUpdatePosition() {
|
||||||
|
// validate permissions
|
||||||
|
if (is_array($this->permissionsUpdate) && count($this->permissionsUpdate)) {
|
||||||
|
try {
|
||||||
|
WCF::getSession()->checkPermissions($this->permissionsUpdate);
|
||||||
|
}
|
||||||
|
catch (\wcf\system\exception\PermissionDeniedException $e) {
|
||||||
|
throw new ValidateActionException('Insufficient permissions');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new ValidateActionException('Insufficient permissions');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($this->parameters['data']['structure'])) {
|
||||||
|
throw new ValidateActionException('Missing parameter structure');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates sorting.
|
||||||
|
*/
|
||||||
|
public function updatePosition() {
|
||||||
|
$roomList = new \wcf\data\chat\room\ChatRoomList();
|
||||||
|
$roomList->sqlOrderBy = "chat_room.position";
|
||||||
|
$roomList->sqlLimit = 0;
|
||||||
|
$roomList->readObjects();
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
WCF::getDB()->beginTransaction();
|
||||||
|
foreach ($this->parameters['data']['structure'][0] as $roomID) {
|
||||||
|
$room = $roomList->search($roomID);
|
||||||
|
if ($room === null) continue;
|
||||||
|
$editor = new ChatRoomEditor($room);
|
||||||
|
$editor->update(array('position' => $i++));
|
||||||
|
}
|
||||||
|
WCF::getDB()->commitTransaction();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace wcf\data\chat\room;
|
namespace wcf\data\chat\room;
|
||||||
|
use \wcf\system\WCF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides functions to edit chat rooms.
|
* Provides functions to edit chat rooms.
|
||||||
@ -12,7 +13,7 @@ namespace wcf\data\chat\room;
|
|||||||
*/
|
*/
|
||||||
class ChatRoomEditor extends \wcf\data\DatabaseObjectEditor implements \wcf\data\IEditableCachedObject {
|
class ChatRoomEditor extends \wcf\data\DatabaseObjectEditor implements \wcf\data\IEditableCachedObject {
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\DatabaseObjectDecorator::$baseClass
|
* @see \wcf\data\DatabaseObjectDecorator::$baseClass
|
||||||
*/
|
*/
|
||||||
protected static $baseClass = '\wcf\data\chat\room\ChatRoom';
|
protected static $baseClass = '\wcf\data\chat\room\ChatRoom';
|
||||||
|
|
||||||
@ -20,7 +21,23 @@ class ChatRoomEditor extends \wcf\data\DatabaseObjectEditor implements \wcf\data
|
|||||||
* Clears the room cache.
|
* Clears the room cache.
|
||||||
*/
|
*/
|
||||||
public static function resetCache() {
|
public static function resetCache() {
|
||||||
self::getCache();
|
\wcf\system\cache\CacheHandler::getInstance()->clear(WCF_DIR.'cache', 'cache.chatrooms.php');
|
||||||
CacheHandler::getInstance()->clearResource('chatrooms');
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\data\DatabaseObjectEditor::deleteAll()
|
||||||
|
*/
|
||||||
|
public static function deleteAll(array $objectIDs = array()) {
|
||||||
|
parent::deleteAll($objectIDs);
|
||||||
|
$packageID = \wcf\system\package\PackageDependencyHandler::getPackageID('timwolla.wcf.chat');
|
||||||
|
|
||||||
|
WCF::getDB()->beginTransaction();
|
||||||
|
foreach ($objectIDs as $objectID) {
|
||||||
|
\wcf\system\language\I18nHandler::getInstance()->remove('wcf.chat.room.title'.$objectID, $packageID);
|
||||||
|
\wcf\system\language\I18nHandler::getInstance()->remove('wcf.chat.room.topic'.$objectID, $packageID);
|
||||||
|
}
|
||||||
|
WCF::getDB()->commitTransaction();
|
||||||
|
|
||||||
|
return count($objectIDs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace wcf\data\chat\room;
|
|||||||
*/
|
*/
|
||||||
class ChatRoomList extends \wcf\data\DatabaseObjectList {
|
class ChatRoomList extends \wcf\data\DatabaseObjectList {
|
||||||
/**
|
/**
|
||||||
* @see wcf\data\DatabaseObjectList::$className
|
* @see \wcf\data\DatabaseObjectList::$className
|
||||||
*/
|
*/
|
||||||
public $className = 'wcf\data\chat\room\ChatRoom';
|
public $className = 'wcf\data\chat\room\ChatRoom';
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace wcf\form;
|
namespace wcf\form;
|
||||||
use \wcf\data\chat;
|
use \wcf\data\chat;
|
||||||
use \wcf\system\exception\PermissionDeniedException;
|
|
||||||
use \wcf\system\exception\UserInputException;
|
use \wcf\system\exception\UserInputException;
|
||||||
use \wcf\system\WCF;
|
use \wcf\system\WCF;
|
||||||
use \wcf\util\StringUtil;
|
use \wcf\util\StringUtil;
|
||||||
@ -20,10 +19,14 @@ class ChatForm extends AbstractForm {
|
|||||||
public $message = '';
|
public $message = '';
|
||||||
public $room = null;
|
public $room = null;
|
||||||
public $userData = array();
|
public $userData = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\AbstractForm::$useTemplate
|
||||||
|
*/
|
||||||
public $useTemplate = false;
|
public $useTemplate = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see \wcf\page\AbstractPage::readData()
|
* @see \wcf\page\IPage::readData()
|
||||||
*/
|
*/
|
||||||
public function readData() {
|
public function readData() {
|
||||||
$this->userData['color'] = \wcf\util\ChatUtil::readUserData('color');
|
$this->userData['color'] = \wcf\util\ChatUtil::readUserData('color');
|
||||||
@ -37,17 +40,17 @@ class ChatForm extends AbstractForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see \wcf\form\AbstractForm::readFormParameters()
|
* @see \wcf\form\IForm::readFormParameters()
|
||||||
*/
|
*/
|
||||||
public function readFormParameters() {
|
public function readFormParameters() {
|
||||||
parent::readFormParameters();
|
parent::readFormParameters();
|
||||||
|
|
||||||
if (isset($_REQUEST['text'])) $this->message = StringUtil::trim($_REQUEST['text']);
|
if (isset($_REQUEST['text'])) $this->message = \wcf\util\MessageUtil::stripCrap(StringUtil::trim($_REQUEST['text']));
|
||||||
if (isset($_REQUEST['smilies'])) $this->enableSmilies = intval($_REQUEST['smilies']);
|
if (isset($_REQUEST['smilies'])) $this->enableSmilies = intval($_REQUEST['smilies']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see \wcf\form\AbstractForm::validate()
|
* @see \wcf\form\IForm::validate()
|
||||||
*/
|
*/
|
||||||
public function validate() {
|
public function validate() {
|
||||||
parent::validate();
|
parent::validate();
|
||||||
@ -55,10 +58,14 @@ class ChatForm extends AbstractForm {
|
|||||||
if ($this->message === '') {
|
if ($this->message === '') {
|
||||||
throw new UserInputException('text');
|
throw new UserInputException('text');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($this->message) > CHAT_MAX_LENGTH) {
|
||||||
|
throw new UserInputException('text', 'tooLong');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see \wcf\form\AbstractForm::save()
|
* @see \wcf\form\IForm::save()
|
||||||
*/
|
*/
|
||||||
public function save() {
|
public function save() {
|
||||||
parent::save();
|
parent::save();
|
||||||
@ -107,4 +114,12 @@ class ChatForm extends AbstractForm {
|
|||||||
|
|
||||||
$this->saved();
|
$this->saved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \wcf\page\IPage::show()
|
||||||
|
*/
|
||||||
|
public function show() {
|
||||||
|
header("HTTP/1.0 204 No Content");
|
||||||
|
parent::show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ class ChatMessagePage extends AbstractPage {
|
|||||||
|
|
||||||
$this->readRoom();
|
$this->readRoom();
|
||||||
$this->readMessages();
|
$this->readMessages();
|
||||||
$this->readUsers();
|
$this->users = $this->room->getUsers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function readMessages() {
|
public function readMessages() {
|
||||||
@ -54,34 +54,6 @@ class ChatMessagePage extends AbstractPage {
|
|||||||
if (!$this->room->canEnter()) throw new \wcf\system\exception\PermissionDeniedException();
|
if (!$this->room->canEnter()) throw new \wcf\system\exception\PermissionDeniedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function readUsers() {
|
|
||||||
$packageID = \wcf\system\package\PackageDependencyHandler::getPackageID('timwolla.wcf.chat');
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
userID
|
|
||||||
FROM
|
|
||||||
wcf".WCF_N."_user_storage
|
|
||||||
WHERE
|
|
||||||
field = 'roomID'
|
|
||||||
AND packageID = ".intval($packageID)."
|
|
||||||
AND fieldValue = ".intval($this->roomID);
|
|
||||||
$stmt = WCF::getDB()->prepareStatement($sql);
|
|
||||||
$stmt->execute();
|
|
||||||
while ($row = $stmt->fetchArray()) $userIDs[] = $row['userID'];
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
*
|
|
||||||
FROM
|
|
||||||
wcf".WCF_N."_user
|
|
||||||
WHERE
|
|
||||||
userID IN (".rtrim(str_repeat('?,', count($userIDs)), ',').")
|
|
||||||
ORDER BY
|
|
||||||
username ASC";
|
|
||||||
$stmt = WCF::getDB()->prepareStatement($sql);
|
|
||||||
$stmt->execute($userIDs);
|
|
||||||
$this->users = $stmt->fetchObjects('\wcf\data\user\User');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see \wcf\page\IPage::show()
|
* @see \wcf\page\IPage::show()
|
||||||
*/
|
*/
|
||||||
@ -94,6 +66,11 @@ class ChatMessagePage extends AbstractPage {
|
|||||||
parent::show();
|
parent::show();
|
||||||
|
|
||||||
@header('Content-type: application/json');
|
@header('Content-type: application/json');
|
||||||
|
// enable gzip compression
|
||||||
|
if (HTTP_ENABLE_GZIP && HTTP_GZIP_LEVEL > 0 && HTTP_GZIP_LEVEL < 10 && !defined('HTTP_DISABLE_GZIP')) {
|
||||||
|
\wcf\util\HeaderUtil::compressOutput();
|
||||||
|
}
|
||||||
|
|
||||||
$json = array('users' => array(), 'messages' => array());
|
$json = array('users' => array(), 'messages' => array());
|
||||||
|
|
||||||
foreach ($this->messages as $message) {
|
foreach ($this->messages as $message) {
|
||||||
|
@ -105,23 +105,22 @@ class ChatPage extends AbstractPage {
|
|||||||
public function readParameters() {
|
public function readParameters() {
|
||||||
parent::readParameters();
|
parent::readParameters();
|
||||||
|
|
||||||
if ($this->action == 'Message') {
|
switch ($this->action) {
|
||||||
|
case 'Message':
|
||||||
new ChatMessagePage();
|
new ChatMessagePage();
|
||||||
exit;
|
exit;
|
||||||
}
|
case 'Log':
|
||||||
else if ($this->action == 'Log') {
|
|
||||||
//TODO: Initialise LogPage
|
|
||||||
exit;
|
exit;
|
||||||
}
|
case 'RefreshRoomList':
|
||||||
else if ($this->action == 'RefreshRoomList') {
|
|
||||||
new ChatRefreshRoomListPage();
|
new ChatRefreshRoomListPage();
|
||||||
exit;
|
exit;
|
||||||
}
|
case 'Send':
|
||||||
else if ($this->action == 'Send') {
|
|
||||||
new \wcf\form\ChatForm();
|
new \wcf\form\ChatForm();
|
||||||
exit;
|
exit;
|
||||||
}
|
case 'Leave':
|
||||||
else if ($this->action == 'Copyright') {
|
new \wcf\action\ChatLeaveAction();
|
||||||
|
exit;
|
||||||
|
case 'Copyright':
|
||||||
new ChatCopyrightPage();
|
new ChatCopyrightPage();
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
44
file/lib/system/cache/builder/ChatPermissionCacheBuilder.class.php
vendored
Normal file
44
file/lib/system/cache/builder/ChatPermissionCacheBuilder.class.php
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
namespace wcf\system\cache\builder;
|
||||||
|
use wcf\system\WCF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches the chat permissions for a combination of user groups.
|
||||||
|
*
|
||||||
|
* @author Tim Düsterhus, Marcel Werk
|
||||||
|
* @copyright 2010-2012 WoltLab GmbH
|
||||||
|
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
|
||||||
|
* @package timwolla.wcf.chat
|
||||||
|
* @subpackage system.cache.builder
|
||||||
|
*/
|
||||||
|
class ChatPermissionCacheBuilder implements ICacheBuilder {
|
||||||
|
/**
|
||||||
|
* @see wcf\system\cache\ICacheBuilder::getData()
|
||||||
|
*/
|
||||||
|
public function getData(array $cacheResource) {
|
||||||
|
$data = array();
|
||||||
|
list(, $groupIDsStr) = explode('-', $cacheResource['cache']);
|
||||||
|
$groupIDs = explode(',', $groupIDsStr);
|
||||||
|
|
||||||
|
if (count($groupIDs)) {
|
||||||
|
$conditionBuilder = new \wcf\system\database\util\PreparedStatementConditionBuilder();
|
||||||
|
$conditionBuilder->add('acl_option.packageID IN (?)', array(\wcf\system\package\PackageDependencyHandler::getDependencies()));
|
||||||
|
$conditionBuilder->add('acl_option.objectTypeID = ?', array(\wcf\system\acl\ACLHandler::getInstance()->getObjectTypeID('timwolla.wcf.chat.room')));
|
||||||
|
$conditionBuilder->add('option_to_group.optionID = acl_option.optionID');
|
||||||
|
$conditionBuilder->add('option_to_group.groupID IN (?)', array($groupIDs));
|
||||||
|
$sql = "SELECT option_to_group.groupID, option_to_group.objectID AS roomID, option_to_group.optionValue,
|
||||||
|
acl_option.optionName AS permission
|
||||||
|
FROM wcf".WCF_N."_acl_option acl_option,
|
||||||
|
wcf".WCF_N."_acl_option_to_group option_to_group
|
||||||
|
".$conditionBuilder;
|
||||||
|
$statement = WCF::getDB()->prepareStatement($sql);
|
||||||
|
$statement->execute($conditionBuilder->getParameters());
|
||||||
|
while ($row = $statement->fetchArray()) {
|
||||||
|
if (!isset($data[$row['roomID']][$row['permission']])) $data[$row['roomID']][$row['permission']] = $row['optionValue'];
|
||||||
|
else $data[$row['roomID']][$row['permission']] = $row['optionValue'] || $data[$row['roomID']][$row['permission']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ namespace wcf\system\cache\builder;
|
|||||||
*/
|
*/
|
||||||
class ChatRoomCacheBuilder implements ICacheBuilder {
|
class ChatRoomCacheBuilder implements ICacheBuilder {
|
||||||
/**
|
/**
|
||||||
* @see wcf\system\cache\ICacheBuilder::getData()
|
* @see \wcf\system\cache\ICacheBuilder::getData()
|
||||||
*/
|
*/
|
||||||
public function getData(array $cacheResource) {
|
public function getData(array $cacheResource) {
|
||||||
// get all chat rooms
|
// get all chat rooms
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace wcf\system\chat\permissions;
|
namespace wcf\system\chat\permission;
|
||||||
use \wcf\system\acl\ACLHandler;
|
use \wcf\system\acl\ACLHandler;
|
||||||
|
use \wcf\system\cache\CacheHandler;
|
||||||
use \wcf\system\package\PackageDependencyHandler;
|
use \wcf\system\package\PackageDependencyHandler;
|
||||||
use \wcf\system\WCF;
|
use \wcf\system\WCF;
|
||||||
|
|
||||||
@ -15,14 +16,25 @@ use \wcf\system\WCF;
|
|||||||
*/
|
*/
|
||||||
class ChatPermissionHandler extends \wcf\system\SingletonFactory {
|
class ChatPermissionHandler extends \wcf\system\SingletonFactory {
|
||||||
protected $chatPermissions = array();
|
protected $chatPermissions = array();
|
||||||
|
protected static $defaults = array(
|
||||||
|
'user.canEnter' => true,
|
||||||
|
'user.canWrite' => true,
|
||||||
|
'mod.canAlwaysEnter' => false,
|
||||||
|
'mod.canAlwaysWrite' => false
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see wcf\system\SingletonFactory::init()
|
* @see \wcf\system\SingletonFactory::init()
|
||||||
*/
|
*/
|
||||||
protected function init() {
|
protected function init() {
|
||||||
$packageID = PackageDependencyHandler::getPackageID('timwolla.wcf.chat');
|
$packageID = PackageDependencyHandler::getPackageID('timwolla.wcf.chat');
|
||||||
$ush = \wcf\system\user\storage\UserStorageHandler::getInstance();
|
$ush = \wcf\system\user\storage\UserStorageHandler::getInstance();
|
||||||
// TODO: get groups permissions
|
|
||||||
|
// get groups permissions
|
||||||
|
$groups = implode(',', WCF::getUser()->getGroupIDs());
|
||||||
|
$groupsFileName = \wcf\util\StringUtil::getHash(implode('-', WCF::getUser()->getGroupIDs()));
|
||||||
|
CacheHandler::getInstance()->addResource('chatPermission-'.$groups, WCF_DIR.'cache/cache.chatPermission-'.$groupsFileName.'.php', 'wcf\system\cache\builder\ChatPermissionCacheBuilder');
|
||||||
|
$this->chatPermissions = CacheHandler::getInstance()->get('chatPermission-'.$groups);
|
||||||
|
|
||||||
// get user permissions
|
// get user permissions
|
||||||
if (WCF::getUser()->userID) {
|
if (WCF::getUser()->userID) {
|
||||||
@ -75,7 +87,20 @@ class ChatPermissionHandler extends \wcf\system\SingletonFactory {
|
|||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function getPermission(\wcf\data\chat\room\ChatRoom $room, $permission) {
|
public function getPermission(\wcf\data\chat\room\ChatRoom $room, $permission) {
|
||||||
if (!isset($this->chatPermissions[$room->roomID][$permission])) return true;
|
if (!isset($this->chatPermissions[$room->roomID][$permission])) {
|
||||||
|
return isset(self::$defaults[$permission]) ? self::$defaults[$permission] : false;
|
||||||
|
}
|
||||||
return (boolean) $this->chatPermissions[$room->roomID][$permission];
|
return (boolean) $this->chatPermissions[$room->roomID][$permission];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the cache.
|
||||||
|
*/
|
||||||
|
public static function clearCache() {
|
||||||
|
$packageID = PackageDependencyHandler::getPackageID('timwolla.wcf.chat');
|
||||||
|
$ush = \wcf\system\user\storage\UserStorageHandler::getInstance();
|
||||||
|
|
||||||
|
$ush->resetAll('chatUserPermissions', $packageID);
|
||||||
|
\wcf\system\cache\CacheHandler::getInstance()->clear(WCF_DIR.'cache', 'cache.chatPermission-[a-f0-9]{40}.php');
|
||||||
|
}
|
||||||
}
|
}
|
@ -12,13 +12,13 @@ namespace wcf\system\event\listener;
|
|||||||
*/
|
*/
|
||||||
class ChatRouteListener implements \wcf\system\event\IEventListener {
|
class ChatRouteListener implements \wcf\system\event\IEventListener {
|
||||||
/**
|
/**
|
||||||
* @see wcf\system\event\IEventListener::execute()
|
* @see \wcf\system\event\IEventListener::execute()
|
||||||
*/
|
*/
|
||||||
public function execute($eventObj, $className, $eventName) {
|
public function execute($eventObj, $className, $eventName) {
|
||||||
$route = new \wcf\system\request\Route('chatAction');
|
$route = new \wcf\system\request\Route('chatAction');
|
||||||
$route->setSchema('/{controller}/{action}');
|
$route->setSchema('/{controller}/{action}');
|
||||||
$route->setParameterOption('controller', null, 'Chat');
|
$route->setParameterOption('controller', null, 'Chat');
|
||||||
$route->setParameterOption('action', null, '(Message|Log|Send|RefreshRoomList|Copyright)');
|
$route->setParameterOption('action', null, '(Message|Log|Send|RefreshRoomList|Copyright|Leave)');
|
||||||
$eventObj->addRoute($route);
|
$eventObj->addRoute($route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,14 @@ namespace wcf\system\option;
|
|||||||
*/
|
*/
|
||||||
class TimeIntervalOptionType extends TextOptionType {
|
class TimeIntervalOptionType extends TextOptionType {
|
||||||
/**
|
/**
|
||||||
* @see wcf\system\option\IOptionType::getData()
|
* @see \wcf\system\option\IOptionType::getData()
|
||||||
*/
|
*/
|
||||||
public function getData(\wcf\data\option\Option $option, $newValue) {
|
public function getData(\wcf\data\option\Option $option, $newValue) {
|
||||||
return \wcf\util\ChatUtil::timeModifier($newValue);
|
return \wcf\util\ChatUtil::timeModifier($newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see wcf\system\option\TextOptionType::getFormElement()
|
* @see \wcf\system\option\TextOptionType::getFormElement()
|
||||||
*/
|
*/
|
||||||
public function getFormElement(\wcf\data\option\Option $option, $value) {
|
public function getFormElement(\wcf\data\option\Option $option, $value) {
|
||||||
$tmp = (int) ($value / 60);
|
$tmp = (int) ($value / 60);
|
||||||
|
@ -67,7 +67,7 @@ class ChatUtil {
|
|||||||
if ($data[WCF::getUser()->userID] === null) {
|
if ($data[WCF::getUser()->userID] === null) {
|
||||||
switch ($field) {
|
switch ($field) {
|
||||||
case 'color':
|
case 'color':
|
||||||
$data[WCF::getUser()->userID] = array(1 => 0xFF0000, 2 => 0x00FF00);
|
$data[WCF::getUser()->userID] = array(1 => self::getRandomNumber(), 2 => self::getRandomNumber() * 0xFFFF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
static::writeUserData(array($field => $data[WCF::getUser()->userID]));
|
static::writeUserData(array($field => $data[WCF::getUser()->userID]));
|
||||||
@ -79,6 +79,16 @@ class ChatUtil {
|
|||||||
else return $data[WCF::getUser()->userID];
|
else return $data[WCF::getUser()->userID];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a random number.
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public static function /* int */ getRandomNumber() {
|
||||||
|
return 4; // chosen by a fair dice roll
|
||||||
|
// guaranteed to be random
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes user data
|
* Writes user data
|
||||||
*
|
*
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.wcf-sidebar {
|
||||||
margin-bottom: -20px !important;
|
margin-bottom: -20px !important;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -32,7 +32,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#timsChatTopic, #smileyList, #timsChatOptions {
|
#timsChatTopic, #smileyList {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@
|
|||||||
padding-left: 7px !important;
|
padding-left: 7px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#smileyList .smilies, .smallButtons {
|
#smileyList .smilies {
|
||||||
li {
|
li {
|
||||||
display: inline;
|
display: inline;
|
||||||
margin: 5px 5px 0 0;
|
margin: 5px 5px 0 0;
|
||||||
@ -63,7 +63,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#timsChatOptions {
|
#timsChatOptions {
|
||||||
display: inline-block;
|
> ul {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#timsChatUserList {
|
#timsChatUserList {
|
||||||
@ -100,7 +102,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.unloaded {
|
&.unloaded {
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +180,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active .badge {
|
&.active .wcf-badge {
|
||||||
font-size: 65% !important;
|
font-size: 65% !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #369;
|
background-color: #369;
|
||||||
|
55
install.sql
55
install.sql
@ -1,18 +1,18 @@
|
|||||||
DROP TABLE IF EXISTS wcf1_chat_message;
|
DROP TABLE IF EXISTS wcf1_chat_message;
|
||||||
CREATE TABLE wcf1_chat_message (
|
CREATE TABLE wcf1_chat_message (
|
||||||
messageID int(10) NOT NULL AUTO_INCREMENT,
|
messageID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
roomID int(10) NOT NULL,
|
roomID INT(10) NOT NULL,
|
||||||
sender int(10) DEFAULT NULL,
|
sender INT(10) DEFAULT NULL,
|
||||||
username varchar(255) DEFAULT NULL,
|
username VARCHAR(255) DEFAULT NULL,
|
||||||
receiver int(10) DEFAULT NULL,
|
receiver INT(10) DEFAULT NULL,
|
||||||
time int(10) NOT NULL,
|
time INT(10) NOT NULL,
|
||||||
type tinyint(3) NOT NULL DEFAULT 1,
|
type TINYINT(3) NOT NULL DEFAULT 1,
|
||||||
message mediumtext NOT NULL,
|
message MEDIUMTEXT NOT NULL,
|
||||||
enableSmilies tinyint(1) NOT NULL DEFAULT 1,
|
enableSmilies TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
enableHTML tinyint(1) NOT NULL DEFAULT 0,
|
enableHTML TINYINT(1) NOT NULL DEFAULT 0,
|
||||||
color1 int(10) NOT NULL DEFAULT 0,
|
color1 INT(10) NOT NULL DEFAULT 0,
|
||||||
color2 int(10) NOT NULL DEFAULT 0,
|
color2 INT(10) NOT NULL DEFAULT 0,
|
||||||
PRIMARY KEY (messageID),
|
|
||||||
KEY roomID (roomID),
|
KEY roomID (roomID),
|
||||||
KEY sender (sender),
|
KEY sender (sender),
|
||||||
KEY receiver (receiver)
|
KEY receiver (receiver)
|
||||||
@ -20,25 +20,26 @@ CREATE TABLE wcf1_chat_message (
|
|||||||
|
|
||||||
DROP TABLE IF EXISTS wcf1_chat_room;
|
DROP TABLE IF EXISTS wcf1_chat_room;
|
||||||
CREATE TABLE wcf1_chat_room (
|
CREATE TABLE wcf1_chat_room (
|
||||||
roomID int(10) NOT NULL AUTO_INCREMENT,
|
roomID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
title varchar(25) NOT NULL,
|
title VARCHAR(255) NOT NULL,
|
||||||
topic varchar(255) NOT NULL,
|
topic VARCHAR(255) NOT NULL,
|
||||||
position int(10) NOT NULL DEFAULT 0,
|
position INT(10) NOT NULL DEFAULT 0,
|
||||||
permanent tinyint(1) NOT NULL DEFAULT 1,
|
permanent TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
owner int(10) DEFAULT NULL,
|
owner INT(10) DEFAULT NULL,
|
||||||
PRIMARY KEY (roomID),
|
|
||||||
KEY positionKey (position),
|
KEY positionKey (position),
|
||||||
KEY owner (owner)
|
KEY owner (owner)
|
||||||
);
|
);
|
||||||
|
|
||||||
DROP TABLE IF EXISTS wcf1_chat_room_suspension;
|
DROP TABLE IF EXISTS wcf1_chat_room_suspension;
|
||||||
CREATE TABLE wcf1_chat_room_suspension (
|
CREATE TABLE wcf1_chat_room_suspension (
|
||||||
roomID int(10) NOT NULL,
|
userID INT(10) NOT NULL,
|
||||||
userID int(10) NOT NULL,
|
roomID INT(10) DEFAULT NULL,
|
||||||
type tinyint(3) NOT NULL,
|
type TINYINT(3) NOT NULL,
|
||||||
time int(10) NOT NULL,
|
time INT(10) NOT NULL,
|
||||||
PRIMARY KEY (roomID, userID),
|
|
||||||
KEY userID (userID),
|
UNIQUE KEY main (userID, roomID),
|
||||||
|
KEY roomID (roomID),
|
||||||
KEY type (type, time),
|
KEY type (type, time),
|
||||||
KEY time (time)
|
KEY time (time)
|
||||||
);
|
);
|
||||||
@ -52,7 +53,7 @@ ALTER TABLE wcf1_chat_room ADD FOREIGN KEY (owner) REFERENCES wcf1_user (userID)
|
|||||||
ALTER TABLE wcf1_chat_room_suspension ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE CASCADE;
|
ALTER TABLE wcf1_chat_room_suspension ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE CASCADE;
|
||||||
ALTER TABLE wcf1_chat_room_suspension ADD FOREIGN KEY (roomID) REFERENCES wcf1_chat_room (roomID) ON DELETE CASCADE;
|
ALTER TABLE wcf1_chat_room_suspension ADD FOREIGN KEY (roomID) REFERENCES wcf1_chat_room (roomID) ON DELETE CASCADE;
|
||||||
|
|
||||||
INSERT INTO wcf1_chat_room (title, topic, position) VALUES ('Testroom 1', 'Topic of Testroom 1', 1);
|
INSERT INTO wcf1_chat_room (title, topic, position) VALUES ('wcf.chat.room.title1', 'wcf.chat.room.topic1', 1);
|
||||||
INSERT INTO wcf1_chat_room (title, topic, position) VALUES ('Testroom 2', 'Topic of Testroom 2', 2);
|
INSERT INTO wcf1_chat_room (title, topic, position) VALUES ('Testroom 2', 'Topic of Testroom 2', 2);
|
||||||
INSERT INTO wcf1_chat_room (title, topic, position) VALUES ('Testroom with a very long', 'The topic of this room is rather loing as well!', 3);
|
INSERT INTO wcf1_chat_room (title, topic, position) VALUES ('Testroom with a very long', 'The topic of this room is rather loing as well!', 3);
|
||||||
INSERT INTO wcf1_chat_room (title, topic, position) VALUES ('Room w/o topic', '', 4);
|
INSERT INTO wcf1_chat_room (title, topic, position) VALUES ('Room w/o topic', '', 4);
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<language 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/maelstrom/language.xsd" languagecode="de">
|
<language 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/maelstrom/language.xsd" languagecode="de">
|
||||||
|
<category name="wcf.acp.chat">
|
||||||
|
<item name="wcf.acp.chat.room.list"><![CDATA[Chaträume]]></item>
|
||||||
|
<item name="wcf.acp.chat.room.add"><![CDATA[Chatraum hinzufügen]]></item>
|
||||||
|
<item name="wcf.acp.chat.room.edit"><![CDATA[Chatraum bearbeiten]]></item>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="wcf.acp.menu">
|
||||||
|
<item name="wcf.acp.menu.link.chat"><![CDATA[Chat]]></item>
|
||||||
|
<item name="wcf.acp.menu.link.chat.room.list"><![CDATA[Chaträume auflisten]]></item>
|
||||||
|
<item name="wcf.acp.menu.link.chat.room.add"><![CDATA[Chatraum hinzufügen]]></item>
|
||||||
|
</category>
|
||||||
|
|
||||||
<category name="wcf.acp.option">
|
<category name="wcf.acp.option">
|
||||||
<item name="wcf.acp.option.category.chat"><![CDATA[Chat]]></item>
|
<item name="wcf.acp.option.category.chat"><![CDATA[Chat]]></item>
|
||||||
<item name="wcf.acp.option.category.chat.general"><![CDATA[Allgemein]]></item>
|
<item name="wcf.acp.option.category.chat.general"><![CDATA[Allgemein]]></item>
|
||||||
@ -14,8 +26,8 @@
|
|||||||
<item name="wcf.acp.option.chat_display_clock.description"><![CDATA[Aktiviert die Anzeige der Uhrzeit von Nachrichten]]></item>
|
<item name="wcf.acp.option.chat_display_clock.description"><![CDATA[Aktiviert die Anzeige der Uhrzeit von Nachrichten]]></item>
|
||||||
<item name="wcf.acp.option.chat_animations"><![CDATA[Animationen aktivieren]]></item>
|
<item name="wcf.acp.option.chat_animations"><![CDATA[Animationen aktivieren]]></item>
|
||||||
<item name="wcf.acp.option.chat_animations.description"><![CDATA[Aktiviert die Animation neuer Nachrichten.]]></item>
|
<item name="wcf.acp.option.chat_animations.description"><![CDATA[Aktiviert die Animation neuer Nachrichten.]]></item>
|
||||||
<item name="wcf.acp.option.chat_length"><![CDATA[Maximale Textlänge]]></item>
|
<item name="wcf.acp.option.chat_max_length"><![CDATA[Maximale Textlänge]]></item>
|
||||||
<item name="wcf.acp.option.chat_length.description"><![CDATA[Gibt die maximale Länge einer Chatnachricht an.]]></item>
|
<item name="wcf.acp.option.chat_max_length.description"><![CDATA[Gibt die maximale Länge einer Chatnachricht an.]]></item>
|
||||||
<item name="wcf.acp.option.chat_show_version"><![CDATA[Versionsnummer anzeigen]]></item>
|
<item name="wcf.acp.option.chat_show_version"><![CDATA[Versionsnummer anzeigen]]></item>
|
||||||
<item name="wcf.acp.option.chat_show_version.description"><![CDATA[Zeigt die Versionsnummer im Copyrighthinweis an.]]></item>
|
<item name="wcf.acp.option.chat_show_version.description"><![CDATA[Zeigt die Versionsnummer im Copyrighthinweis an.]]></item>
|
||||||
|
|
||||||
@ -25,10 +37,6 @@
|
|||||||
<item name="wcf.acp.option.chat_log_archivetime.description"><![CDATA[Gibt die Zeit in Minuten an, die eine Nachricht im Protokoll gespeichert bleibt.]]></item>
|
<item name="wcf.acp.option.chat_log_archivetime.description"><![CDATA[Gibt die Zeit in Minuten an, die eine Nachricht im Protokoll gespeichert bleibt.]]></item>
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
<category name="wcf.header">
|
|
||||||
<item name="wcf.header.menu.chat"><![CDATA[Chat]]></item>
|
|
||||||
</category>
|
|
||||||
|
|
||||||
<category name="wcf.chat">
|
<category name="wcf.chat">
|
||||||
<item name="wcf.chat.title"><![CDATA[Chat]]></item>
|
<item name="wcf.chat.title"><![CDATA[Chat]]></item>
|
||||||
<item name="wcf.chat.protocol"><![CDATA[Protokoll]]></item>
|
<item name="wcf.chat.protocol"><![CDATA[Protokoll]]></item>
|
||||||
@ -55,4 +63,14 @@
|
|||||||
<!-- 2 = TYPE_LEAVE -->
|
<!-- 2 = TYPE_LEAVE -->
|
||||||
<item name="wcf.chat.message.2"><![CDATA[hat den Chat verlassen.]]></item>
|
<item name="wcf.chat.message.2"><![CDATA[hat den Chat verlassen.]]></item>
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
|
<!-- I18N Values -->
|
||||||
|
<category name="wcf.chat.room">
|
||||||
|
<item name="wcf.chat.room.title1"><![CDATA[Hauptchat]]></item>
|
||||||
|
<item name="wcf.chat.room.topic1"><![CDATA[Vielen Dank, dass Sie sich für Tims Chat entschieden haben. Bitte besuchen Sie das ACP um diesen Text anzupassen.]]></item>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="wcf.header">
|
||||||
|
<item name="wcf.header.menu.chat"><![CDATA[Chat]]></item>
|
||||||
|
</category>
|
||||||
</language>
|
</language>
|
@ -49,7 +49,7 @@
|
|||||||
<defaultvalue>1</defaultvalue>
|
<defaultvalue>1</defaultvalue>
|
||||||
<showorder>7</showorder>
|
<showorder>7</showorder>
|
||||||
</option>
|
</option>
|
||||||
<option name="chat_length">
|
<option name="chat_max_length">
|
||||||
<categoryname>chat.general</categoryname>
|
<categoryname>chat.general</categoryname>
|
||||||
<optiontype>integer</optiontype>
|
<optiontype>integer</optiontype>
|
||||||
<defaultvalue>500</defaultvalue>
|
<defaultvalue>500</defaultvalue>
|
||||||
|
12
package.xml
12
package.xml
@ -5,7 +5,7 @@
|
|||||||
<packagedescription><![CDATA[Chat for WoltLab Community Framework™]]></packagedescription>
|
<packagedescription><![CDATA[Chat for WoltLab Community Framework™]]></packagedescription>
|
||||||
<standalone>0</standalone>
|
<standalone>0</standalone>
|
||||||
<isunique>1</isunique>
|
<isunique>1</isunique>
|
||||||
<version>3.0.0 Alpha 3</version>
|
<version>3.0.0 Alpha 8</version>
|
||||||
<date>2011-11-26</date>
|
<date>2011-11-26</date>
|
||||||
<plugin>com.woltlab.wcf.bbcode</plugin> <!-- TODO: Correct me -->
|
<plugin>com.woltlab.wcf.bbcode</plugin> <!-- TODO: Correct me -->
|
||||||
</packageinformation>
|
</packageinformation>
|
||||||
@ -19,30 +19,36 @@
|
|||||||
<requiredpackage minversion="2.0.0 Alpha 1">com.woltlab.wcf</requiredpackage>
|
<requiredpackage minversion="2.0.0 Alpha 1">com.woltlab.wcf</requiredpackage>
|
||||||
<requiredpackage minversion="1.0.0 Alpha 1">com.woltlab.wcf.bbcode</requiredpackage>
|
<requiredpackage minversion="1.0.0 Alpha 1">com.woltlab.wcf.bbcode</requiredpackage>
|
||||||
<requiredpackage minversion="1.0.0 Alpha 1">com.woltlab.wcf.acl</requiredpackage>
|
<requiredpackage minversion="1.0.0 Alpha 1">com.woltlab.wcf.acl</requiredpackage>
|
||||||
|
<requiredpackage minversion="1.0.0 Alpha 1">com.woltlab.wcf.message</requiredpackage>
|
||||||
</requiredpackages>
|
</requiredpackages>
|
||||||
|
|
||||||
<instructions type="install">
|
<instructions type="install">
|
||||||
<instruction type="language">language/*.xml</instruction>
|
<instruction type="language">language/*.xml</instruction>
|
||||||
<instruction type="file">file.tar</instruction>
|
<instruction type="file">file.tar</instruction>
|
||||||
<instruction type="template">template.tar</instruction>
|
<instruction type="template">template.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="option">option.xml</instruction>
|
<instruction type="option">option.xml</instruction>
|
||||||
<instruction type="pageMenu">pagemenu.xml</instruction>
|
<instruction type="pageMenu">pagemenu.xml</instruction>
|
||||||
<instruction type="eventListener">eventListener.xml</instruction>
|
<instruction type="eventListener">eventListener.xml</instruction>
|
||||||
<instruction type="templateListener">templatelistener.xml</instruction>
|
|
||||||
<instruction type="aclOption">acloptions.xml</instruction>
|
<instruction type="aclOption">acloptions.xml</instruction>
|
||||||
|
<instruction type="acpMenu">acpMenu.xml</instruction>
|
||||||
|
<instruction type="userGroupOption">userGroupOption.xml</instruction>
|
||||||
</instructions>
|
</instructions>
|
||||||
|
|
||||||
<instructions type="update" fromversion="3.0.0 Alpha *">
|
<instructions type="update" fromversion="3.0.0 Alpha *">
|
||||||
<instruction type="language">language/*.xml</instruction>
|
<instruction type="language">language/*.xml</instruction>
|
||||||
<instruction type="file">file.tar</instruction>
|
<instruction type="file">file.tar</instruction>
|
||||||
<instruction type="template">template.tar</instruction>
|
<instruction type="template">template.tar</instruction>
|
||||||
|
<instruction type="acpTemplate">acptemplate.tar</instruction>
|
||||||
<instruction type="objectType">objectType.xml</instruction>
|
<instruction type="objectType">objectType.xml</instruction>
|
||||||
<instruction type="option">option.xml</instruction>
|
<instruction type="option">option.xml</instruction>
|
||||||
<instruction type="pageMenu">pagemenu.xml</instruction>
|
<instruction type="pageMenu">pagemenu.xml</instruction>
|
||||||
<instruction type="eventListener">eventListener.xml</instruction>
|
<instruction type="eventListener">eventListener.xml</instruction>
|
||||||
<instruction type="templateListener">templatelistener.xml</instruction>
|
|
||||||
<instruction type="aclOption">acloptions.xml</instruction>
|
<instruction type="aclOption">acloptions.xml</instruction>
|
||||||
|
<instruction type="acpMenu">acpMenu.xml</instruction>
|
||||||
|
<instruction type="userGroupOption">userGroupOption.xml</instruction>
|
||||||
|
<instruction type="script">acp/timwolla.wcf.chat.update.php</instruction>
|
||||||
</instructions>
|
</instructions>
|
||||||
</package>
|
</package>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{include file='headInclude' sandbox=false}
|
{include file='headInclude' sandbox=false}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
@import url("{@RELATIVE_WCF_DIR}style/timwolla.wcf.chat.css");
|
@import url("{@$__wcf->getPath('wcf')}style/timwolla.wcf.chat.css");
|
||||||
#timsChatCopyrightDialog {
|
#timsChatCopyrightDialog {
|
||||||
background-image: url("{link controller='Chat' action='Copyright' sheep=1}{/link}");
|
background-image: url("{link controller='Chat' action='Copyright' sheep=1}{/link}");
|
||||||
background-position: right 45px;
|
background-position: right 45px;
|
||||||
@ -56,6 +56,7 @@
|
|||||||
|
|
||||||
.jsCounterInput {
|
.jsCounterInput {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
box-sizing: content-box !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsCounterInput, .jsCounter {
|
.jsCounterInput, .jsCounter {
|
||||||
@ -89,103 +90,63 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body id="tpl{$templateName|ucfirst}">
|
<body id="tpl{$templateName|ucfirst}">
|
||||||
{capture assign='sidebar'}
|
{capture assign='sidebar'}{include file='chatSidebar'}{/capture}
|
||||||
<div id="sidebarContent" class="sidebarContent">
|
{capture assign='headerNavigation'}{include file='chatNavigationInclude'}{/capture}
|
||||||
<nav class="timsChatSidebarTabs">
|
|
||||||
<ul>
|
|
||||||
<li id="toggleUsers" class="active"><a href="javascript:;" title="{lang}wcf.chat.users{/lang}">{lang}wcf.chat.users{/lang} <span class="badge">0</span></a></li>
|
|
||||||
<li id="toggleRooms"><a href="javascript:;" title="{lang}wcf.chat.rooms{/lang}" data-refresh-url="{link controller="Chat" action="RefreshRoomList"}{/link}">{lang}wcf.chat.rooms{/lang} <span class="badge">{#$rooms|count}</span></a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div id="sidebarContainer">
|
|
||||||
<ul id="timsChatUserList">
|
|
||||||
{*section name=user start=1 loop=26}
|
|
||||||
<li class="timsChatUser">
|
|
||||||
<a href="javascript:;">User {$user}</a>
|
|
||||||
<ul class="timsChatUserMenu">
|
|
||||||
<li>
|
|
||||||
<a href="javascript:;">{lang}wcf.chat.query{/lang}</a>
|
|
||||||
<a href="javascript:;">{lang}wcf.chat.kick{/lang}</a>
|
|
||||||
<a href="javascript:;">{lang}wcf.chat.ban{/lang}</a>
|
|
||||||
<a href="{link controller="User" id=$user}{/link}">{lang}wcf.chat.profile{/lang}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{/section*}
|
|
||||||
</ul>
|
|
||||||
<nav id="timsChatRoomList" class="sidebarMenu" style="display: none;">
|
|
||||||
<div>
|
|
||||||
<ul>
|
|
||||||
{foreach from=$rooms item='roomListRoom'}
|
|
||||||
{if $roomListRoom->canEnter()}
|
|
||||||
<li{if $roomListRoom->roomID == $room->roomID} class="activeMenuItem"{/if}>
|
|
||||||
<a href="{link controller='Chat' object=$roomListRoom}{/link}" class="timsChatRoom">{$roomListRoom}</a>
|
|
||||||
</li>
|
|
||||||
{/if}
|
|
||||||
{/foreach}
|
|
||||||
</ul>
|
|
||||||
<div style="text-align: center;"><button type="button">Force Refresh</button></div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/capture}
|
|
||||||
{include file='header' sandbox=false sidebarOrientation='right'}
|
{include file='header' sandbox=false sidebarOrientation='right'}
|
||||||
|
|
||||||
<div id="timsChatRoomContent">
|
<div id="timsChatRoomContent">
|
||||||
<div id="timsChatTopic" class="border"{if $room->topic|language === ''} style="display: none;"{/if}>{$room->topic|language}</div>
|
<div id="timsChatTopic" class="wcf-border"{if $room->topic|language === ''} style="display: none;"{/if}>{$room->topic|language}</div>
|
||||||
<div class="timsChatMessageContainer border content">
|
<div class="timsChatMessageContainer wcf-border wcf-content">
|
||||||
<ul>
|
<ul>
|
||||||
<noscript><li class="error">{lang}wcf.chat.noJs{/lang}</li></noscript>
|
<noscript><li class="wcf-error">{lang}wcf.chat.noJs{/lang}</li></noscript>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="timsChatForm" action="{link controller="Chat" action="Send"}{/link}" method="post">
|
<form id="timsChatForm" action="{link controller="Chat" action="Send"}{/link}" method="post">
|
||||||
<input type="text" id="timsChatInput" class="inputText long jsCounterInput" name="text" autocomplete="off" maxlength="{CHAT_LENGTH}" disabled="disabled" required="required" placeholder="{lang}wcf.chat.submit.default{/lang}" />
|
<input type="text" id="timsChatInput" class="inputText long jsCounterInput" name="text" autocomplete="off" maxlength="{@CHAT_MAX_LENGTH}" disabled="disabled" required="required" placeholder="{lang}wcf.chat.submit.default{/lang}" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div id="timsChatControls">
|
<div id="timsChatControls" class="wcf-border">
|
||||||
<div id="smileyList" class="border">
|
{if MODULE_SMILEY}
|
||||||
|
<div id="smileyList">
|
||||||
<ul class="smilies">
|
<ul class="smilies">
|
||||||
{foreach from=$smilies item='smiley'}
|
{foreach from=$smilies item='smiley'}
|
||||||
<li>
|
<li>
|
||||||
<img src="{$smiley->getURL()}" alt="{$smiley->smileyCode}" title="{$smiley->smileyCode}" class="smiley" />
|
<img src="{$smiley->getURL()}" alt="{$smiley->smileyCode}" title="{$smiley->smileyTitle}" class="jsSmiley jsTooltip" />
|
||||||
</li>
|
</li>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="timsChatOptions" class="border">
|
{/if}
|
||||||
<div class="smallButtons">
|
<nav id="timsChatOptions">
|
||||||
<ul>
|
<ul class="wcf-smallButtons">
|
||||||
<li>
|
<li>
|
||||||
<a id="timsChatAutoscroll" href="javascript:;" class="timsChatToggle balloonTooltip" title="{lang}wcf.global.button.disable{/lang}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" data-status="1">
|
<a id="timsChatAutoscroll" href="javascript:;" class="timsChatToggle jsTooltip wcf-button" title="{lang}wcf.global.button.disable{/lang}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" data-status="1">
|
||||||
<img alt="" src="{icon size='S'}enabled1{/icon}" /> <span>{lang}wcf.chat.scroll{/lang}</span>
|
<img alt="" src="{icon size='S'}enabled1{/icon}" /> <span>{lang}wcf.chat.scroll{/lang}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a id="timsChatNotify" href="javascript:;" class="timsChatToggle balloonTooltip" title="{lang}wcf.global.button.enable{/lang}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" data-status="0">
|
<a id="timsChatNotify" href="javascript:;" class="timsChatToggle jsTooltip wcf-button" title="{lang}wcf.global.button.enable{/lang}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" data-status="0">
|
||||||
<img alt="" src="{icon size='S'}disabled1{/icon}" /> <span>{lang}wcf.chat.notify{/lang}</span>
|
<img alt="" src="{icon size='S'}disabled1{/icon}" /> <span>{lang}wcf.chat.notify{/lang}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li{if !MODULE_SMILEY} style="display: none;"{/if}>
|
||||||
<a id="timsChatSmilies" href="javascript:;" class="timsChatToggle balloonTooltip" title="{lang}wcf.global.button.disable{/lang}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" data-status="1">
|
<a id="timsChatSmilies" href="javascript:;" class="timsChatToggle jsTooltip wcf-button" title="{lang}wcf.global.button.disable{/lang}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" data-status="1">
|
||||||
<img alt="" src="{icon size='S'}enabled1{/icon}" /> <span>{lang}wcf.chat.smilies{/lang}</span>
|
<img alt="" src="{icon size='S'}enabled1{/icon}" /> <span>{lang}wcf.chat.smilies{/lang}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a id="timsChatClear" href="javascript:;" class="balloonTooltip" title="{lang}wcf.chat.clear.description{/lang}">
|
<a id="timsChatClear" href="javascript:;" class="jsTooltip wcf-button" title="{lang}wcf.chat.clear.description{/lang}">
|
||||||
<img alt="" src="{icon size='S'}delete1{/icon}" /> <span>{lang}wcf.chat.clear{/lang}</span>
|
<img alt="" src="{icon size='S'}delete1{/icon}" /> <span>{lang}wcf.chat.clear{/lang}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a id="timsChatMark" href="javascript:;" class="balloonTooltip" title="{lang}wcf.chat.mark.description{/lang}">
|
<a id="timsChatMark" href="javascript:;" class="jsTooltip wcf-button" title="{lang}wcf.chat.mark.description{/lang}">
|
||||||
<img alt="" src="{icon size='S'}check1{/icon}" /> <span>{lang}wcf.chat.mark{/lang}</span>
|
<img alt="" src="{icon size='S'}check1{/icon}" /> <span>{lang}wcf.chat.mark{/lang}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</nav>
|
||||||
</div>
|
|
||||||
{include file='chatCopyright'}
|
{include file='chatCopyright'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -201,8 +162,7 @@
|
|||||||
// populate config
|
// populate config
|
||||||
TimWolla.WCF.Chat.config = {
|
TimWolla.WCF.Chat.config = {
|
||||||
reloadTime: {@CHAT_RELOADTIME},
|
reloadTime: {@CHAT_RELOADTIME},
|
||||||
animations: {@CHAT_ANIMATIONS},
|
unloadURL: '{link controller='Chat' action='Leave'}{/link}'
|
||||||
maxTextLength: {@CHAT_LENGTH}
|
|
||||||
}
|
}
|
||||||
WCF.Language.addObject({
|
WCF.Language.addObject({
|
||||||
'wcf.chat.query': '{lang}wcf.chat.query{/lang}',
|
'wcf.chat.query': '{lang}wcf.chat.query{/lang}',
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
<script type="text/javascript" src="{@RELATIVE_WCF_DIR}js/TimWolla.WCF.Chat.js{if $chatVersion|isset}?version={$chatVersion|urlencode}{/if}"></script>
|
<script type="text/javascript" src="{@$__wcf->getPath('wcf')}js/TimWolla.WCF.Chat.js{if $chatVersion|isset}?version={$chatVersion|urlencode}{/if}"></script>
|
||||||
<script type="text/javascript" src="{@RELATIVE_WCF_DIR}js/jCounter.jQuery.js"></script>
|
<script type="text/javascript" src="{@$__wcf->getPath('wcf')}js/jCounter.jQuery.js"></script>
|
@ -1 +1 @@
|
|||||||
{literal}<dl style="margin: 0;"><dt style="width: 145px; margin: 0;"><time style="float: left;">{@$formattedTime}</time> {@$formattedUsername}{$separator}</dt> <dd style="padding: 0; margin-left: 150px;">{@$formattedMessage}</dd></dl>{/literal}
|
<dl style="margin: 0;"><dt style="width: 145px; margin: 0;">{if CHAT_DISPLAY_CLOCK}<time style="float: left;">{ldelim}@$formattedTime}</time> {/if}{literal}{@$formattedUsername}{$separator}</dt> <dd style="padding: 0; margin-left: 150px;">{@$formattedMessage}</dd></dl>{/literal}
|
@ -1,4 +1,5 @@
|
|||||||
{if $templateName == 'chat'}
|
<li>
|
||||||
<li><a href="{link controller="Chat" action="Log"}{/link}" title="{lang}wcf.chat.protocol{/lang}" class="balloonTooltip"><img src="{icon size='S'}session1{/icon}" alt="" /> <span>{lang}wcf.chat.protocol{/lang}</span></a></li>
|
<a href="{link controller="Chat" action="Log"}{/link}" title="{lang}wcf.chat.protocol{/lang}" class="jsTooltip">
|
||||||
<li><a href="{link controller="Chat"}{/link}" title="{lang}wcf.chat.title{/lang}" class="balloonTooltip"><img src="{icon size='S'}chat1{/icon}" alt="" /> <span>{lang}wcf.chat.title{/lang}</span></a></li>
|
<img src="{icon size='S'}session1{/icon}" alt="" /> <span>{lang}wcf.chat.protocol{/lang}</span>
|
||||||
{/if}
|
</a>
|
||||||
|
</li>
|
27
template/chatSidebar.tpl
Normal file
27
template/chatSidebar.tpl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<div id="sidebarContent" class="wcf-sidebarContent">
|
||||||
|
<nav class="timsChatSidebarTabs">
|
||||||
|
<ul>
|
||||||
|
<li id="toggleUsers" class="active"><a href="javascript:;" title="{lang}wcf.chat.users{/lang}">{lang}wcf.chat.users{/lang} <span class="wcf-badge">0</span></a></li>
|
||||||
|
<li id="toggleRooms"><a href="javascript:;" title="{lang}wcf.chat.rooms{/lang}" data-refresh-url="{link controller="Chat" action="RefreshRoomList"}{/link}">{lang}wcf.chat.rooms{/lang} <span class="wcf-badge">{#$rooms|count}</span></a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div id="sidebarContainer">
|
||||||
|
<ul id="timsChatUserList">
|
||||||
|
</ul>
|
||||||
|
<nav id="timsChatRoomList" class="wcf-sidebarMenu" style="display: none;">
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
{foreach from=$rooms item='roomListRoom'}
|
||||||
|
{if $roomListRoom->canEnter()}
|
||||||
|
<li{if $roomListRoom->roomID == $room->roomID} class="activeMenuItem"{/if}>
|
||||||
|
<a href="{link controller='Chat' object=$roomListRoom}{/link}" class="timsChatRoom">{$roomListRoom}</a>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
{/foreach}
|
||||||
|
</ul>
|
||||||
|
<div style="text-align: center;"><button type="button">{lang}wcf.chat.forceRefresh{/lang}</button></div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,11 +0,0 @@
|
|||||||
<?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/templatelistener.xsd">
|
|
||||||
<import>
|
|
||||||
<templatelistener name="chatHeaderNavigation">
|
|
||||||
<environment>user</environment>
|
|
||||||
<templatename>header</templatename>
|
|
||||||
<eventname>headerNavigation</eventname>
|
|
||||||
<templatecode><![CDATA[{include file='chatNavigationInclude'}]]></templatecode>
|
|
||||||
</templatelistener>
|
|
||||||
</import>
|
|
||||||
</data>
|
|
31
userGroupOption.xml
Normal file
31
userGroupOption.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?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/maelstrom/userGroupOption.xsd">
|
||||||
|
<import>
|
||||||
|
<categories>
|
||||||
|
<category name="admin.content.chat">
|
||||||
|
<parent>admin.content</parent>
|
||||||
|
</category>
|
||||||
|
</categories>
|
||||||
|
|
||||||
|
<options>
|
||||||
|
<option name="admin.content.chat.canAddRoom">
|
||||||
|
<categoryname>admin.content.chat</categoryname>
|
||||||
|
<optiontype>boolean</optiontype>
|
||||||
|
<defaultvalue>0</defaultvalue>
|
||||||
|
<admindefaultvalue>1</admindefaultvalue>
|
||||||
|
</option>
|
||||||
|
<option name="admin.content.chat.canEditRoom">
|
||||||
|
<categoryname>admin.content.chat</categoryname>
|
||||||
|
<optiontype>boolean</optiontype>
|
||||||
|
<defaultvalue>0</defaultvalue>
|
||||||
|
<admindefaultvalue>1</admindefaultvalue>
|
||||||
|
</option>
|
||||||
|
<option name="admin.content.chat.canDeleteRoom">
|
||||||
|
<categoryname>admin.content.chat</categoryname>
|
||||||
|
<optiontype>boolean</optiontype>
|
||||||
|
<defaultvalue>0</defaultvalue>
|
||||||
|
<admindefaultvalue>1</admindefaultvalue>
|
||||||
|
</option>
|
||||||
|
</options>
|
||||||
|
</import>
|
||||||
|
</data>
|
Loading…
x
Reference in New Issue
Block a user