mirror of
https://github.com/wbbaddons/Tims-Chat.git
synced 2025-01-14 01:10:07 +00:00
Initial import
This commit is contained in:
commit
317ee29461
17
.babelrc
Normal file
17
.babelrc
Normal file
@ -0,0 +1,17 @@
|
||||
{ "presets": [ [ "env"
|
||||
, { "targets": { "browsers": [ "last 2 chrome versions"
|
||||
, "last 2 chromeandroid versions"
|
||||
, "firefox esr"
|
||||
, "not firefox 52"
|
||||
, "last 2 firefox versions"
|
||||
, "edge >= 15"
|
||||
, "safari >= 11"
|
||||
, "ios >= 11"
|
||||
]
|
||||
}
|
||||
, "debug": true
|
||||
, "include": [ ]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
node_modules
|
||||
|
||||
be.bastelstu.chat.tar.gz
|
||||
be.bastelstu.chat.tar
|
||||
files.tar
|
||||
files_wcf.tar
|
||||
acptemplates.tar
|
||||
templates.tar
|
||||
|
||||
Bastelstu.be.Chat.js
|
||||
Bastelstu.be.Chat.babel.js
|
||||
|
||||
files_wcf/js/Bastelstu.be.Chat.min.js
|
104
LICENSE
Normal file
104
LICENSE
Normal file
@ -0,0 +1,104 @@
|
||||
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
||||
“Business Source License” is a trademark of MariaDB Corporation Ab.
|
||||
|
||||
Parameters
|
||||
|
||||
Licensor: Tim Düsterhus
|
||||
Licensed Work: Tim’s Chat 4.0
|
||||
The Licensed Work is (c) 2010-2018 Tim Düsterhus
|
||||
Additional Use Grant: You may use the Licensed Work when your application
|
||||
uses the Licensed Work for a purpose that does neither
|
||||
directly or indirectly generate revenue.
|
||||
|
||||
Change Date: 2022-08-16
|
||||
|
||||
Change License: Version 2 or later of the GNU General Public License as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
For information about alternative licensing arrangements for the Software,
|
||||
please email: tim <at the domain> bastelstu.be
|
||||
|
||||
Notice
|
||||
|
||||
The Business Source License (this document, or the “License”) is not an Open
|
||||
Source license. However, the Licensed Work will eventually be made available
|
||||
under an Open Source License, as stated in this License.
|
||||
|
||||
For more information on the use of the Business Source License for MariaDB
|
||||
products, please visit the MariaDB Business Source License FAQ at
|
||||
https://mariadb.com/bsl-faq-mariadb.
|
||||
|
||||
For more information on the use of the Business Source License generally,
|
||||
please visit the Adopting and Developing Business Source License FAQ at
|
||||
https://mariadb.com/bsl-faq-adopting.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Business Source License 1.1
|
||||
|
||||
Terms
|
||||
|
||||
The Licensor hereby grants you the right to copy, modify, create derivative
|
||||
works, redistribute, and make non-production use of the Licensed Work. The
|
||||
Licensor may make an Additional Use Grant, above, permitting limited
|
||||
production use.
|
||||
|
||||
Effective on the Change Date, or the fourth anniversary of the first publicly
|
||||
available distribution of a specific version of the Licensed Work under this
|
||||
License, whichever comes first, the Licensor hereby grants you rights under
|
||||
the terms of the Change License, and the rights granted in the paragraph
|
||||
above terminate.
|
||||
|
||||
If your use of the Licensed Work does not comply with the requirements
|
||||
currently in effect as described in this License, you must purchase a
|
||||
commercial license from the Licensor, its affiliated entities, or authorized
|
||||
resellers, or you must refrain from using the Licensed Work.
|
||||
|
||||
All copies of the original and modified Licensed Work, and derivative works
|
||||
of the Licensed Work, are subject to this License. This License applies
|
||||
separately for each version of the Licensed Work and the Change Date may vary
|
||||
for each version of the Licensed Work released by Licensor.
|
||||
|
||||
You must conspicuously display this License on each original or modified copy
|
||||
of the Licensed Work. If you receive the Licensed Work in original or
|
||||
modified form from a third party, the terms and conditions set forth in this
|
||||
License apply to your use of that work.
|
||||
|
||||
Any use of the Licensed Work in violation of this License will automatically
|
||||
terminate your rights under this License for the current and all other
|
||||
versions of the Licensed Work.
|
||||
|
||||
This License does not grant you any right in any trademark or logo of
|
||||
Licensor or its affiliates (provided that you may use a trademark or logo of
|
||||
Licensor as expressly required by this License).
|
||||
|
||||
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
||||
AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
||||
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
||||
TITLE.
|
||||
|
||||
MariaDB hereby grants you permission to use this License’s text to license
|
||||
your works, and to refer to it using the trademark “Business Source License”,
|
||||
as long as you comply with the Covenants of Licensor below.
|
||||
|
||||
Covenants of Licensor
|
||||
|
||||
In consideration of the right to use this License’s text and the “Business
|
||||
Source License” name and trademark, Licensor covenants to MariaDB, and to all
|
||||
other recipients of the licensed work to be provided by Licensor:
|
||||
|
||||
1. To specify as the Change License the GPL Version 2.0 or any later version,
|
||||
or a license that is compatible with GPL Version 2.0 or a later version,
|
||||
where “compatible” means that software provided under the Change License can
|
||||
be included in a program with software provided under GPL Version 2.0 or a
|
||||
later version. Licensor may specify additional Change Licenses without
|
||||
limitation.
|
||||
|
||||
2. To either: (a) specify an additional grant of rights to use that does not
|
||||
impose any additional restriction on the right granted in this License, as
|
||||
the Additional Use Grant; or (b) insert the text “None”.
|
||||
|
||||
3. To specify a Change Date.
|
||||
|
||||
4. Not to modify this License in any other way.
|
43
Makefile
Normal file
43
Makefile
Normal file
@ -0,0 +1,43 @@
|
||||
FILES = $(shell find files -type f)
|
||||
WCF_FILES = $(shell find files_wcf -type f)
|
||||
JS_MODULE_FILES = $(shell find files_wcf/js/Bastelstu.be -type f)
|
||||
|
||||
all: be.bastelstu.chat.tar be.bastelstu.chat.tar.gz
|
||||
|
||||
be.bastelstu.chat.tar.gz: be.bastelstu.chat.tar
|
||||
gzip -9 < $< > $@
|
||||
|
||||
be.bastelstu.chat.tar: files.tar files_wcf.tar acptemplates.tar templates.tar *.xml LICENSE sql/*.sql language/*.xml
|
||||
tar cvf be.bastelstu.chat.tar --numeric-owner --exclude-vcs -- $^
|
||||
|
||||
files.tar: $(FILES)
|
||||
files_wcf.tar: $(WCF_FILES) files_wcf/js/Bastelstu.be.Chat.min.js
|
||||
acptemplates.tar: acptemplates/*.tpl
|
||||
templates.tar: templates/*.tpl
|
||||
|
||||
%.tar:
|
||||
tar cvf $@ --numeric-owner --exclude-vcs -C $* -- $(^:$*/%=%)
|
||||
|
||||
files_wcf/js/Bastelstu.be.Chat.min.js: Bastelstu.be.Chat.babel.js
|
||||
yarn run terser --comments '/Copyright|stackoverflow/' -m -c pure_funcs=[console.debug] --verbose --timings -o $@ $^
|
||||
|
||||
Bastelstu.be.Chat.babel.js: Bastelstu.be.Chat.js .babelrc
|
||||
yarn run babel $< --out-file $@
|
||||
|
||||
Bastelstu.be.Chat.js: $(JS_MODULE_FILES)
|
||||
yarn run r.js -o require.build.js
|
||||
|
||||
clean:
|
||||
-rm -f files.tar
|
||||
-rm -f files_wcf.tar
|
||||
-rm -f templates.tar
|
||||
-rm -f acptemplates.tar
|
||||
-rm -f Bastelstu.be.Chat.js
|
||||
-rm -f Bastelstu.be.Chat.babel.js
|
||||
-rm -f files_wcf/js/Bastelstu.be.Chat.min.js
|
||||
|
||||
distclean: clean
|
||||
-rm -f be.bastelstu.chat.tar
|
||||
-rm -f be.bastelstu.chat.tar.gz
|
||||
|
||||
.PHONY: distclean clean
|
48
aclOption.xml
Normal file
48
aclOption.xml
Normal file
@ -0,0 +1,48 @@
|
||||
<?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">
|
||||
<import>
|
||||
<categories>
|
||||
<category name="user">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
</category>
|
||||
<category name="mod">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
</category>
|
||||
</categories>
|
||||
|
||||
<options>
|
||||
<option name="user.canSee">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
<categoryname>user</categoryname>
|
||||
</option>
|
||||
<option name="user.canSeeLog">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
<categoryname>user</categoryname>
|
||||
</option>
|
||||
<option name="user.canWrite">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
<categoryname>user</categoryname>
|
||||
</option>
|
||||
<option name="mod.canIgnoreUserLimit">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
<categoryname>mod</categoryname>
|
||||
</option>
|
||||
<option name="mod.canMute">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
<categoryname>mod</categoryname>
|
||||
</option>
|
||||
<option name="mod.canIgnoreMute">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
<categoryname>mod</categoryname>
|
||||
</option>
|
||||
<option name="mod.canBan">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
<categoryname>mod</categoryname>
|
||||
</option>
|
||||
<option name="mod.canIgnoreBan">
|
||||
<objecttype>be.bastelstu.chat.room</objecttype>
|
||||
<categoryname>mod</categoryname>
|
||||
</option>
|
||||
</options>
|
||||
</import>
|
||||
</data>
|
42
acpMenu.xml
Normal file
42
acpMenu.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<?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="chat.acp.menu.link.chat">
|
||||
<parent>wcf.acp.menu.link.application</parent>
|
||||
</acpmenuitem>
|
||||
|
||||
<acpmenuitem name="chat.acp.menu.link.room.list">
|
||||
<controller>chat\acp\page\RoomListPage</controller>
|
||||
<parent>chat.acp.menu.link.chat</parent>
|
||||
<permissions>admin.chat.canManageRoom</permissions>
|
||||
<showorder>1</showorder>
|
||||
</acpmenuitem>
|
||||
|
||||
<acpmenuitem name="chat.acp.menu.link.room.add">
|
||||
<controller>chat\acp\form\RoomAddForm</controller>
|
||||
<parent>chat.acp.menu.link.room.list</parent>
|
||||
<permissions>admin.chat.canManageRoom</permissions>
|
||||
<icon>fa-plus</icon>
|
||||
</acpmenuitem>
|
||||
|
||||
<acpmenuitem name="chat.acp.menu.link.command.trigger.list">
|
||||
<controller>chat\acp\page\CommandTriggerListPage</controller>
|
||||
<parent>chat.acp.menu.link.chat</parent>
|
||||
<permissions>admin.chat.canManageTriggers</permissions>
|
||||
</acpmenuitem>
|
||||
|
||||
<acpmenuitem name="chat.acp.menu.link.command.trigger.add">
|
||||
<controller>chat\acp\form\CommandTriggerAddForm</controller>
|
||||
<parent>chat.acp.menu.link.command.trigger.list</parent>
|
||||
<permissions>admin.chat.canManageTriggers</permissions>
|
||||
<icon>fa-plus</icon>
|
||||
</acpmenuitem>
|
||||
|
||||
<acpmenuitem name="chat.acp.menu.link.suspension.list">
|
||||
<controller>chat\acp\page\SuspensionListPage</controller>
|
||||
<parent>chat.acp.menu.link.chat</parent>
|
||||
<permissions>admin.chat.canManageSuspensions</permissions>
|
||||
</acpmenuitem>
|
||||
</import>
|
||||
</data>
|
||||
|
5
acptemplates/__chatVersion.tpl
Normal file
5
acptemplates/__chatVersion.tpl
Normal file
@ -0,0 +1,5 @@
|
||||
<dl>
|
||||
<dt>{lang}chat.acp.index.system.software.chatVersion{/lang}</dt>
|
||||
<dd>{$__chat->getPackage()->packageVersion}</dd>
|
||||
</dl>
|
||||
|
72
acptemplates/commandTriggerAdd.tpl
Normal file
72
acptemplates/commandTriggerAdd.tpl
Normal file
@ -0,0 +1,72 @@
|
||||
{include file='header' pageTitle='chat.acp.command.trigger.'|concat:$action}
|
||||
|
||||
<header class="contentHeader">
|
||||
<div class="contentHeaderTitle">
|
||||
<h1 class="contentTitle">{lang}chat.acp.command.trigger.{$action}{/lang}</h1>
|
||||
</div>
|
||||
|
||||
<nav class="contentHeaderNavigation">
|
||||
<ul>
|
||||
<li><a href="{link application='chat' controller='CommandTriggerList'}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}chat.acp.command.trigger.list{/lang}</span></a></li>
|
||||
|
||||
{event name='contentHeaderNavigation'}
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{include file='formError'}
|
||||
|
||||
{if $success|isset}
|
||||
<p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
|
||||
{/if}
|
||||
|
||||
<form method="post" action="{if $action == 'add'}{link application='chat' controller='CommandTriggerAdd'}{/link}{else}{link application='chat' controller='CommandTriggerEdit' id=$triggerID}{/link}{/if}">
|
||||
<div class="section">
|
||||
<div class="section">
|
||||
<dl{if $errorField == 'commandTrigger'} class="formError"{/if}>
|
||||
<dt><label for="commandTrigger">{lang}chat.acp.command.trigger{/lang}</label></dt>
|
||||
<dd>
|
||||
<input type="text" id="commandTrigger" name="commandTrigger" value="{$commandTrigger}" autofocus class="medium">
|
||||
{if $errorField == 'commandTrigger'}
|
||||
<small class="innerError">
|
||||
{if $errorType == 'empty'}
|
||||
{lang}wcf.global.form.error.empty{/lang}
|
||||
{else}
|
||||
{lang}chat.acp.command.trigger.commandTrigger.error.{@$errorType}{/lang}
|
||||
{/if}
|
||||
</small>
|
||||
{/if}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl{if $errorField == 'className'} class="formError"{/if}>
|
||||
<dt><label for="className">{lang}chat.acp.command.className{/lang}</label></dt>
|
||||
<dd>
|
||||
<select id="className" name="className">
|
||||
{foreach from=$availableCommands item=$command}
|
||||
<option value="{$command->className}"{if $command->className === $className} selected{/if}>{$command->className}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
|
||||
{if $errorField == 'className'}
|
||||
<small class="innerError">
|
||||
{if $errorType == 'empty'}
|
||||
{lang}wcf.global.form.error.empty{/lang}
|
||||
{else}
|
||||
{lang}chat.acp.command.trigger.className.error.{@$errorType}{/lang}
|
||||
{/if}
|
||||
</small>
|
||||
{/if}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="formSubmit">
|
||||
<input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
|
||||
{@SECURITY_TOKEN_INPUT_TAG}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{include file='footer'}
|
||||
|
86
acptemplates/commandTriggerList.tpl
Normal file
86
acptemplates/commandTriggerList.tpl
Normal file
@ -0,0 +1,86 @@
|
||||
{include file='header' pageTitle='chat.acp.command.trigger.list'}
|
||||
|
||||
<script data-relocate="true">
|
||||
$(function() {
|
||||
new WCF.Action.Delete('chat\\data\\command\\CommandTriggerAction', '.jsTriggerRow');
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<header class="contentHeader">
|
||||
<div class="contentHeaderTitle">
|
||||
<h1 class="contentTitle">{lang}chat.acp.command.trigger.list{/lang}</h1>
|
||||
</div>
|
||||
|
||||
<nav class="contentHeaderNavigation">
|
||||
<ul>
|
||||
<li><a href="{link controller='CommandTriggerAdd' application='chat'}{/link}" class="button"><span class="icon icon16 fa-plus"></span> <span>{lang}chat.acp.command.trigger.add{/lang}</span></a></li>
|
||||
|
||||
{event name='contentHeaderNavigation'}
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{hascontent}
|
||||
<div class="paginationTop">
|
||||
{content}{pages print=true assign=pagesLinks controller="CommandTriggerList" application="chat" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
|
||||
</div>
|
||||
{/hascontent}
|
||||
|
||||
{hascontent}
|
||||
<div class="section tabularBox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="columnID columnTriggerID{if $sortField == 'triggerID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='CommandTriggerList' application='chat'}pageNo={@$pageNo}&sortField=triggerID&sortOrder={if $sortField == 'triggerID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
|
||||
<th class="columnTitle columnTrigger{if $sortField == 'commandTrigger'} active {@$sortOrder}{/if}"><a href="{link controller='CommandTriggerList' application='chat'}pageNo={@$pageNo}&sortField=commandTrigger&sortOrder={if $sortField == 'commandTrigger' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}chat.acp.command.trigger{/lang}</a></th>
|
||||
<th class="columnText columnClassName{if $sortField == 'className'} active {@$sortOrder}{/if}"><a href="{link controller='CommandTriggerList' application='chat'}pageNo={@$pageNo}&sortField=className&sortOrder={if $sortField == 'className' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}chat.acp.command.className{/lang}</a></th>
|
||||
|
||||
{event name='columnHeads'}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{content}
|
||||
{foreach from=$objects item=trigger}
|
||||
<tr class="jsTriggerRow">
|
||||
<td class="columnIcon">
|
||||
<a href="{link controller='CommandTriggerEdit' object=$trigger application='chat'}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
|
||||
<span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$trigger->triggerID}" data-confirm-message-html="{lang __encode=true}chat.acp.command.trigger.delete.sure{/lang}"></span>
|
||||
|
||||
{event name='rowButtons'}
|
||||
</td>
|
||||
|
||||
<td class="columnID">{@$trigger->triggerID}</td>
|
||||
<td class="columnTitle columnTrigger"><a href="{link controller='CommandTriggerEdit' object=$trigger application='chat'}{/link}">/{$trigger->commandTrigger}</a></td>
|
||||
<td class="columnText columnClassName">{$trigger->className}</td>
|
||||
|
||||
{event name='columns'}
|
||||
</tr>
|
||||
{/foreach}
|
||||
{/content}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{hascontentelse}
|
||||
<p class="info">{lang}wcf.global.noItems{/lang}</p>
|
||||
{/hascontent}
|
||||
|
||||
<footer class="contentFooter">
|
||||
{hascontent}
|
||||
<div class="paginationBottom">
|
||||
{content}{@$pagesLinks}{/content}
|
||||
</div>
|
||||
{/hascontent}
|
||||
|
||||
<nav class="contentFooterNavigation">
|
||||
<ul>
|
||||
<li><a href="{link controller='CommandTriggerAdd' application='chat'}{/link}" class="button"><span class="icon icon16 fa-plus"></span> <span>{lang}chat.acp.command.trigger.add{/lang}</span></a></li>
|
||||
|
||||
{event name='contentFooterNavigation'}
|
||||
</ul>
|
||||
</nav>
|
||||
</footer>
|
||||
|
||||
{include file='footer'}
|
||||
|
113
acptemplates/roomAdd.tpl
Normal file
113
acptemplates/roomAdd.tpl
Normal file
@ -0,0 +1,113 @@
|
||||
{include file='header' pageTitle='chat.acp.room.'|concat:$action}
|
||||
|
||||
{include file='aclPermissions'}
|
||||
|
||||
{include file='multipleLanguageInputJavascript' elementIdentifier='title' forceSelection=false}
|
||||
{include file='multipleLanguageInputJavascript' elementIdentifier='topic' forceSelection=false}
|
||||
|
||||
{if $roomID|isset}
|
||||
{include file='aclPermissionJavaScript' containerID='aclContainer' objectTypeID=$aclObjectTypeID objectID=$roomID}
|
||||
{else}
|
||||
{include file='aclPermissionJavaScript' containerID='aclContainer' objectTypeID=$aclObjectTypeID}
|
||||
{/if}
|
||||
|
||||
<header class="contentHeader">
|
||||
<div class="contentHeaderTitle">
|
||||
<h1 class="contentTitle">{lang}chat.acp.room.{$action}{/lang}</h1>
|
||||
{if $action == 'edit'}<p class="contentHeaderDescription">{$room->getTitle()}</p>{/if}
|
||||
</div>
|
||||
|
||||
<nav class="contentHeaderNavigation">
|
||||
<ul>
|
||||
<li><a href="{link application='chat' controller='RoomList'}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}chat.acp.room.list{/lang}</span></a></li>
|
||||
|
||||
{event name='contentHeaderNavigation'}
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{include file='formError'}
|
||||
|
||||
{if $success|isset}
|
||||
<p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
|
||||
{/if}
|
||||
|
||||
<form method="post" action="{if $action == 'add'}{link application='chat' controller='RoomAdd'}{/link}{else}{link application='chat' controller='RoomEdit' id=$roomID}{/link}{/if}">
|
||||
<div class="section">
|
||||
<div class="section">
|
||||
<dl{if $errorField == 'title'} class="formError"{/if}>
|
||||
<dt><label for="title">{lang}wcf.global.title{/lang}</label></dt>
|
||||
<dd>
|
||||
<input type="text" id="title" name="title" value="{$i18nPlainValues['title']}" autofocus class="medium">
|
||||
{if $errorField == 'title'}
|
||||
<small class="innerError">
|
||||
{if $errorType == 'empty'}
|
||||
{lang}wcf.global.form.error.empty{/lang}
|
||||
{elseif $errorType == 'multilingual'}
|
||||
{lang}wcf.global.form.error.multilingual{/lang}
|
||||
{else}
|
||||
{lang}chat.acp.room.title.error.{@$errorType}{/lang}
|
||||
{/if}
|
||||
</small>
|
||||
{/if}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl{if $errorField == 'topic'} class="formError"{/if}>
|
||||
<dt><label for="topic">{lang}chat.acp.room.topic{/lang}</label></dt>
|
||||
<dd>
|
||||
<input type="text" id="topic" name="topic" value="{$i18nPlainValues['topic']}" class="medium">
|
||||
|
||||
{if $errorField == 'topic'}
|
||||
<small class="innerError">
|
||||
{if $errorType == 'empty'}
|
||||
{lang}wcf.global.form.error.empty{/lang}
|
||||
{else}
|
||||
{lang}chat.acp.room.topic.error.{@$errorType}{/lang}
|
||||
{/if}
|
||||
</small>
|
||||
{/if}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl{if $errorField == 'topicUseHtml'} class="formError"{/if}>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<label><input type="checkbox" name="topicUseHtml" value="1"{if $topicUseHtml} checked{/if}> {lang}chat.acp.room.topicUseHtml{/lang}</label>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl{if $errorField == 'userLimit'} class="formError"{/if}>
|
||||
<dt><label for="userLimit">{lang}chat.acp.room.userLimit{/lang}</label></dt>
|
||||
<dd>
|
||||
<input type="number" id="userLimit" name="userLimit" value="{$userLimit}" min="0" class="medium">
|
||||
|
||||
{if $errorField == 'userLimit'}
|
||||
<small class="innerError">
|
||||
{if $errorType == 'empty'}
|
||||
{lang}wcf.global.form.error.empty{/lang}
|
||||
{else}
|
||||
{lang}chat.acp.room.userLimit.error.{@$errorType}{/lang}
|
||||
{/if}
|
||||
</small>
|
||||
{/if}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<dl id="aclContainer">
|
||||
<dt>{lang}wcf.acl.permissions{/lang}</dt>
|
||||
<dd></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="formSubmit">
|
||||
<input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
|
||||
{@SECURITY_TOKEN_INPUT_TAG}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{include file='footer'}
|
||||
|
81
acptemplates/roomList.tpl
Normal file
81
acptemplates/roomList.tpl
Normal file
@ -0,0 +1,81 @@
|
||||
{include file='header' pageTitle='chat.acp.room.list'}
|
||||
|
||||
<script data-relocate="true">
|
||||
$(function() {
|
||||
require([ 'WoltLabSuite/Core/Ui/Sortable/List' ], function (UiSortableList) {
|
||||
new UiSortableList({ containerId: 'roomNodeList'
|
||||
, className: 'chat\\data\\room\\RoomAction'
|
||||
})
|
||||
})
|
||||
|
||||
new WCF.Action.Delete('chat\\data\\room\\RoomAction', '#roomNodeList')
|
||||
})
|
||||
</script>
|
||||
|
||||
<header class="contentHeader">
|
||||
<div class="contentHeaderTitle">
|
||||
<h1 class="contentTitle">{lang}chat.acp.room.list{/lang}</h1>
|
||||
</div>
|
||||
|
||||
<nav class="contentHeaderNavigation">
|
||||
<ul>
|
||||
<li><a href="{link controller='RoomAdd' application='chat'}{/link}" class="button"><span class="icon icon16 fa-plus"></span> <span>{lang}chat.acp.room.add{/lang}</span></a></li>
|
||||
|
||||
{event name='contentHeaderNavigation'}
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{hascontent}
|
||||
<div class="paginationTop">
|
||||
{content}{pages print=true assign=pagesLinks controller="RoomList" application="chat" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
|
||||
</div>
|
||||
{/hascontent}
|
||||
|
||||
{hascontent}
|
||||
<div id="roomNodeList" class="section sortableListContainer">
|
||||
<ol id="roomContainer0" class="sortableList" data-object-id="0">
|
||||
{content}
|
||||
{foreach from=$objects item=room}
|
||||
<li class="sortableNode sortableNoNesting" data-object-id="{@$room->roomID}">
|
||||
<span class="sortableNodeLabel">
|
||||
<a href="{link controller='RoomEdit' application='chat' object=$room}{/link}">{$room}</a>
|
||||
|
||||
<span class="statusDisplay sortableButtonContainer">
|
||||
<span class="icon icon16 fa-arrows sortableNodeHandle"></span>
|
||||
<a href="{link controller='RoomEdit' application='chat' object=$room}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
|
||||
<span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$room->roomID}" data-confirm-message-html="{lang __encode=true}chat.acp.room.delete.sure{/lang}"></span>
|
||||
{event name='itemButtons'}
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
{/foreach}
|
||||
{/content}
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="formSubmit">
|
||||
<button class="button buttonPrimary" data-type="submit">{lang}wcf.global.button.saveSorting{/lang}</button>
|
||||
</div>
|
||||
{hascontentelse}
|
||||
<p class="info">{lang}wcf.global.noItems{/lang}</p>
|
||||
{/hascontent}
|
||||
|
||||
<footer class="contentFooter">
|
||||
{hascontent}
|
||||
<div class="paginationBottom">
|
||||
{content}{@$pagesLinks}{/content}
|
||||
</div>
|
||||
{/hascontent}
|
||||
|
||||
<nav class="contentFooterNavigation">
|
||||
<ul>
|
||||
<li><a href="{link controller='RoomAdd' application='chat'}{/link}" class="button"><span class="icon icon16 fa-plus"></span> <span>{lang}chat.acp.room.add{/lang}</span></a></li>
|
||||
|
||||
{event name='contentFooterNavigation'}
|
||||
</ul>
|
||||
</nav>
|
||||
</footer>
|
||||
|
||||
{include file='footer'}
|
||||
|
192
acptemplates/suspensionList.tpl
Normal file
192
acptemplates/suspensionList.tpl
Normal file
@ -0,0 +1,192 @@
|
||||
{include file='header' pageTitle='chat.acp.suspension.list'}
|
||||
|
||||
<script>
|
||||
require([ 'Bastelstu.be/PromiseWrap/Ajax', 'Bastelstu.be/PromiseWrap/Ui/Confirmation', 'WoltLabSuite/Core/Dom/Traverse' ], function (Ajax, Confirmation, Traverse) {
|
||||
elBySelAll('.jsRevokeButton:not(.disabled)', document, function (button) {
|
||||
const row = Traverse.parentByClass(button, 'jsSuspensionRow')
|
||||
if (row == null) {
|
||||
throw new Error('Unreachable')
|
||||
}
|
||||
const objectID = row.dataset.objectId
|
||||
const listener = function (event) {
|
||||
Confirmation.show({
|
||||
message: button.dataset.confirmMessageHtml,
|
||||
messageIsHtml: true
|
||||
}).then(function () {
|
||||
const payload = { data: { className: 'chat\\data\\suspension\\SuspensionAction'
|
||||
, actionName: 'revoke'
|
||||
, objectIDs: [ objectID ]
|
||||
}
|
||||
}
|
||||
return Ajax.apiOnce(payload)
|
||||
}).then(function () {
|
||||
button.classList.remove('pointer')
|
||||
button.classList.add('disabled')
|
||||
button.removeEventListener('click', listener)
|
||||
})
|
||||
}
|
||||
button.addEventListener('click', listener)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<header class="contentHeader">
|
||||
<div class="contentHeaderTitle">
|
||||
<h1 class="contentTitle">{lang}chat.acp.suspension.list{/lang}</h1>
|
||||
</div>
|
||||
|
||||
{hascontent}
|
||||
<nav class="contentHeaderNavigation">
|
||||
<ul>
|
||||
{content}{event name='contentHeaderNavigation'}{/content}
|
||||
</ul>
|
||||
</nav>
|
||||
{/hascontent}
|
||||
</header>
|
||||
|
||||
<form method="post" action="{link controller='SuspensionList' application='chat'}{/link}">
|
||||
<section class="section">
|
||||
<h2 class="sectionTitle">{lang}wcf.global.filter{/lang}</h2>
|
||||
|
||||
<div class="row rowColGap formGrid">
|
||||
<dl class="col-xs-12 col-md-4">
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<select name="roomID" id="roomID">
|
||||
<option value=""{if $roomID === null} selected{/if}>{lang}chat.acp.suspension.room.all{/lang}</option>
|
||||
<option value="0"{if $roomID === 0} selected{/if}>{lang}chat.acp.suspension.room.global{/lang}</option>
|
||||
{htmlOptions options=$availableRooms selected=$roomID}
|
||||
</select>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl class="col-xs-12 col-md-4">
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<select name="objectTypeID" id="objectTypeID">
|
||||
<option value="">{lang}chat.acp.suspension.objectType.allTypes{/lang}</option>
|
||||
{foreach from=$availableObjectTypes item=availableObjectType}
|
||||
<option value="{$availableObjectType->objectTypeID}"{if $availableObjectType->objectTypeID == $objectTypeID} selected{/if}>{lang}chat.acp.suspension.type.{$availableObjectType->objectType}{/lang}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl class="col-xs-12 col-md-4">
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<input type="text" id="searchUsername" name="searchUsername" value="{$searchUsername}" placeholder="{lang}chat.acp.suspension.username{/lang}" class="long">
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<dl class="col-xs-12 col-md-4">
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<input type="text" id="searchJudge" name="searchJudge" value="{$searchJudge}" placeholder="{lang}chat.acp.suspension.judge{/lang}" class="long">
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl class="col-xs-12 col-md-4">
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<label><input name="showExpired" value="1" type="checkbox"{if $showExpired !== false} checked{/if}>{lang}chat.acp.suspension.showExpired{/lang}</label>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
{event name='filterFields'}
|
||||
</div>
|
||||
|
||||
<div class="formSubmit">
|
||||
<input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
|
||||
{@SECURITY_TOKEN_INPUT_TAG}
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
||||
|
||||
{capture assign=additionalParameters}{*
|
||||
*}{if $userID !== null}&userID={$userID}{/if}{*
|
||||
*}{if $judgeID !== null}&judgeID={$judgeID}{/if}{*
|
||||
*}{if $roomID !== null}&roomID={$roomID}{/if}{*
|
||||
*}{if $objectTypeID !== null}&objectTypeID={$objectTypeID}{/if}{*
|
||||
*}{if $showExpired !== null}&showExpired={$showExpired}{/if}{*
|
||||
*}{/capture}
|
||||
|
||||
{hascontent}
|
||||
<div class="paginationTop">
|
||||
{content}{pages print=true assign=pagesLinks controller="SuspensionList" application="chat" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder$additionalParameters"}{/content}
|
||||
</div>
|
||||
{/hascontent}
|
||||
|
||||
{hascontent}
|
||||
<div class="section tabularBox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="columnID columnSuspensionID{if $sortField == 'suspensionID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='SuspensionList' application='chat'}pageNo={@$pageNo}&sortField=suspensionID&sortOrder={if $sortField == 'suspensionID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$additionalParameters}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
|
||||
<th class="columnTitle columnObjectType">{lang}chat.acp.suspension.type{/lang}</th>
|
||||
<th class="columnText columnUsername">{lang}chat.acp.suspension.username{/lang}</th>
|
||||
<th class="columnText columnJudge">{lang}chat.acp.suspension.judge{/lang}</th>
|
||||
<th class="columnText columnRoom">{lang}chat.acp.suspension.room{/lang}</th>
|
||||
<th class="columnText columnTime{if $sortField == 'time'} active {@$sortOrder}{/if}"><a href="{link controller='SuspensionList' application='chat'}pageNo={@$pageNo}&sortField=time&sortOrder={if $sortField == 'time' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$additionalParameters}{/link}">{lang}chat.acp.suspension.time{/lang}</a></th>
|
||||
<th class="columnText columnExpires{if $sortField == 'expiresSort'} active {@$sortOrder}{/if}"><a href="{link controller='SuspensionList' application='chat'}pageNo={@$pageNo}&sortField=expiresSort&sortOrder={if $sortField == 'expiresSort' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$additionalParameters}{/link}">{lang}chat.acp.suspension.expires{/lang}</a></th>
|
||||
|
||||
{event name='columnHeads'}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{content}
|
||||
{foreach from=$objects item=suspension}
|
||||
<tr class="jsSuspensionRow" data-object-id="{$suspension->suspensionID}">
|
||||
<td class="columnIcon">
|
||||
<span class="icon icon16 fa-undo{if !$suspension->isActive()} disabled{else} pointer{/if} jsRevokeButton" title="{lang}chat.acp.suspension.revoke{/lang}" data-confirm-message-html="{lang}chat.acp.suspension.revoke.sure{/lang}"></span>
|
||||
{event name='rowButtons'}
|
||||
</td>
|
||||
|
||||
<td class="columnID">{@$suspension->suspensionID}</td>
|
||||
<td class="columnTitle columnObjectType"><a href="{link controller="SuspensionList" application="chat"}objectTypeID={$suspension->objectTypeID}{/link}">{lang}chat.acp.suspension.type.{$suspension->getSuspensionType()->objectType}{/lang}</a></td>
|
||||
<td class="columnText columnUsername"><a href="{link controller="SuspensionList" application="chat"}userID={$suspension->userID}{/link}">{$suspension->getUser()->username}</a></td>
|
||||
<td class="columnText columnJudge"><a href="{link controller="SuspensionList" application="chat"}judgeID={$suspension->judgeID}{/link}">{$suspension->judge}</a></td>
|
||||
<td class="columnText columnRoom"><a href="{link controller="SuspensionList" application="chat"}roomID={$suspension->roomID}{/link}">{if $suspension->getRoom() !== null}{$suspension->getRoom()}{else}-{/if}</a></td>
|
||||
<td class="columnText columnTime">{@$suspension->time|time}</td>
|
||||
<td class="columnText columnExpires">
|
||||
{assign var='isActive' value=$suspension->isActive()}
|
||||
{if $isActive}<strong>{/if}
|
||||
{if $suspension->expires !== null}{@$suspension->expires|time}{else}{lang}chat.acp.suspension.expires.forever{/lang}{/if}
|
||||
{if $isActive}</strong>{/if}
|
||||
{if $suspension->revoked !== null}
|
||||
<br>{lang}chat.acp.suspension.revoked{/lang}
|
||||
{/if}
|
||||
</td>
|
||||
|
||||
{event name='columns'}
|
||||
</tr>
|
||||
{/foreach}
|
||||
{/content}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{hascontentelse}
|
||||
<p class="info">{lang}wcf.global.noItems{/lang}</p>
|
||||
{/hascontent}
|
||||
|
||||
<footer class="contentFooter">
|
||||
{hascontent}
|
||||
<div class="paginationBottom">
|
||||
{content}{@$pagesLinks}{/content}
|
||||
</div>
|
||||
{/hascontent}
|
||||
|
||||
{hascontent}
|
||||
<nav class="contentFooterNavigation">
|
||||
<ul>
|
||||
{content}{event name='contentFooterNavigation'}{/content}
|
||||
</ul>
|
||||
</nav>
|
||||
{/hascontent}
|
||||
</footer>
|
||||
|
||||
{include file='footer'}
|
||||
|
42
box.xml
Normal file
42
box.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<?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/vortex/box.xsd">
|
||||
<import>
|
||||
<box identifier="be.bastelstu.chat.roomListDashboard">
|
||||
<name language="de">Chaträume (Inhaltsbereich)</name>
|
||||
<name language="en">Chat Rooms (Content)</name>
|
||||
<boxType>system</boxType>
|
||||
<objectType>be.bastelstu.chat.roomList</objectType>
|
||||
<position>contentTop</position>
|
||||
<showHeader>1</showHeader>
|
||||
<visibleEverywhere>0</visibleEverywhere>
|
||||
<visibilityExceptions>
|
||||
<page>com.woltlab.wcf.Dashboard</page>
|
||||
</visibilityExceptions>
|
||||
<content language="de">
|
||||
<title>Chaträume</title>
|
||||
</content>
|
||||
<content language="en">
|
||||
<title>Chat Rooms</title>
|
||||
</content>
|
||||
</box>
|
||||
|
||||
<box identifier="be.bastelstu.chat.roomListSidebar">
|
||||
<name language="de">Chaträume (Seitenleiste)</name>
|
||||
<name language="en">Chat Rooms (Sidebar)</name>
|
||||
<boxType>system</boxType>
|
||||
<objectType>be.bastelstu.chat.roomList</objectType>
|
||||
<position>sidebarRight</position>
|
||||
<showHeader>1</showHeader>
|
||||
<visibleEverywhere>0</visibleEverywhere>
|
||||
<visibilityExceptions>
|
||||
<page>be.bastelstu.chat.Room</page>
|
||||
</visibilityExceptions>
|
||||
<content language="de">
|
||||
<title>Chaträume</title>
|
||||
</content>
|
||||
<content language="en">
|
||||
<title>Chat Rooms</title>
|
||||
</content>
|
||||
</box>
|
||||
</import>
|
||||
</data>
|
103
chatCommand.xml
Normal file
103
chatCommand.xml
Normal file
@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<import>
|
||||
<command name="away">
|
||||
<classname>chat\system\command\AwayCommand</classname>
|
||||
<triggers>
|
||||
<trigger>away</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="back">
|
||||
<classname>chat\system\command\BackCommand</classname>
|
||||
</command>
|
||||
|
||||
<command name="ban">
|
||||
<classname>chat\system\command\BanCommand</classname>
|
||||
<triggers>
|
||||
<trigger>ban</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="broadcast">
|
||||
<classname>chat\system\command\BroadcastCommand</classname>
|
||||
<triggers>
|
||||
<trigger>broadcast</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="color">
|
||||
<classname>chat\system\command\ColorCommand</classname>
|
||||
<triggers>
|
||||
<trigger>color</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="info">
|
||||
<classname>chat\system\command\InfoCommand</classname>
|
||||
<triggers>
|
||||
<trigger>info</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="me">
|
||||
<classname>chat\system\command\MeCommand</classname>
|
||||
<triggers>
|
||||
<trigger>me</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="mute">
|
||||
<classname>chat\system\command\MuteCommand</classname>
|
||||
<triggers>
|
||||
<trigger>mute</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="plain">
|
||||
<classname>chat\system\command\PlainCommand</classname>
|
||||
</command>
|
||||
|
||||
<command name="team">
|
||||
<classname>chat\system\command\TeamCommand</classname>
|
||||
<triggers>
|
||||
<trigger>team</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="temproom">
|
||||
<classname>chat\system\command\TemproomCommand</classname>
|
||||
<triggers>
|
||||
<trigger>temproom</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="unban">
|
||||
<classname>chat\system\command\UnbanCommand</classname>
|
||||
<triggers>
|
||||
<trigger>unban</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="unmute">
|
||||
<classname>chat\system\command\UnmuteCommand</classname>
|
||||
<triggers>
|
||||
<trigger>unmute</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="where">
|
||||
<classname>chat\system\command\WhereCommand</classname>
|
||||
<triggers>
|
||||
<trigger>where</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
|
||||
<command name="whisper">
|
||||
<classname>chat\system\command\WhisperCommand</classname>
|
||||
<triggers>
|
||||
<trigger>whisper</trigger>
|
||||
</triggers>
|
||||
</command>
|
||||
</import>
|
||||
</data>
|
166
eventListener.xml
Normal file
166
eventListener.xml
Normal file
@ -0,0 +1,166 @@
|
||||
<?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/eventListener.xsd">
|
||||
<import>
|
||||
<!-- Hourly Cleanup -->
|
||||
<eventlistener name="hourlyCleanUpUser">
|
||||
<eventclassname>wcf\system\cronjob\HourlyCleanUpCronjob</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\HourlyCleanUpCronjobExecuteChatCleanUpListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="hourlyCleanUpAdmin">
|
||||
<eventclassname>wcf\system\cronjob\HourlyCleanUpCronjob</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\HourlyCleanUpCronjobExecuteChatCleanUpListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
|
||||
<!-- Temprooms -->
|
||||
<eventlistener name="temproomHourlyCleanUpUser">
|
||||
<eventclassname>wcf\system\cronjob\HourlyCleanUpCronjob</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\HourlyCleanUpCronjobExecuteTemproomListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="temproomHourlyCleanUpAdmin">
|
||||
<eventclassname>wcf\system\cronjob\HourlyCleanUpCronjob</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\HourlyCleanUpCronjobExecuteTemproomListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="temproomCanSee">
|
||||
<eventclassname>chat\data\room\Room</eventclassname>
|
||||
<eventname>canSee</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomCanSeeTemproomListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="temproomRoomList">
|
||||
<eventclassname>chat\acp\page\RoomListPage</eventclassname>
|
||||
<eventname>calculateNumberOfPages</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomListPageTemproomListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="temproomRoomEdit">
|
||||
<eventclassname>chat\acp\form\RoomEditForm</eventclassname>
|
||||
<eventname>readParameters</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomEditFormTemproomListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="temproomSuspensionList">
|
||||
<eventclassname>chat\acp\page\SuspensionListPage</eventclassname>
|
||||
<eventname>readData</eventname>
|
||||
<listenerclassname>chat\system\event\listener\SuspensionListPageTemproomListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
|
||||
<!-- User Limit -->
|
||||
<eventlistener name="userLimitCanJoin">
|
||||
<eventclassname>chat\data\room\Room</eventclassname>
|
||||
<eventname>canJoin</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomCanJoinUserLimitListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
|
||||
<!-- Suspensions -->
|
||||
<eventlistener name="suspensionCanJoin">
|
||||
<eventclassname>chat\data\room\Room</eventclassname>
|
||||
<eventname>canJoin</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomCanJoinBanListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="suspensionCanWritePublicly">
|
||||
<eventclassname>chat\data\room\Room</eventclassname>
|
||||
<eventname>canWritePublicly</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomCanWritePubliclyMuteListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="suspensionInfoCommand">
|
||||
<eventclassname>chat\system\command\InfoCommand</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\InfoCommandSuspensionsListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener name="moderatorPermissions">
|
||||
<eventclassname>chat\data\room\RoomAction</eventclassname>
|
||||
<eventname>getUsers</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomActionGetUsersModeratorListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
</import>
|
||||
|
||||
<delete>
|
||||
<!-- Hourly Cleanup -->
|
||||
<eventlistener>
|
||||
<eventclassname>wcf\system\cronjob\HourlyCleanUpCronjob</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\HourlyCleanUpCronjobExecuteChatCleanUpListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener>
|
||||
<eventclassname>wcf\system\cronjob\HourlyCleanUpCronjob</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\HourlyCleanUpCronjobExecuteChatCleanUpListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
|
||||
<!-- Temprooms -->
|
||||
<eventlistener>
|
||||
<eventclassname>wcf\system\cronjob\HourlyCleanUpCronjob</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\HourlyCleanUpCronjobExecuteTemproomListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener>
|
||||
<eventclassname>wcf\system\cronjob\HourlyCleanUpCronjob</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\HourlyCleanUpCronjobExecuteTemproomListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
<eventlistener>
|
||||
<eventclassname>chat\data\room\Room</eventclassname>
|
||||
<eventname>canSee</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomCanSeeTemproomListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener>
|
||||
<eventclassname>chat\acp\page\RoomListPage</eventclassname>
|
||||
<eventname>calculateNumberOfPages</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomListPageTemproomListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
<eventlistener>
|
||||
<eventclassname>chat\acp\form\RoomEditForm</eventclassname>
|
||||
<eventname>readParameters</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomEditFormTemproomListener</listenerclassname>
|
||||
<environment>admin</environment>
|
||||
</eventlistener>
|
||||
|
||||
<!-- User Limit -->
|
||||
<eventlistener>
|
||||
<eventclassname>chat\data\room\Room</eventclassname>
|
||||
<eventname>canJoin</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomCanJoinUserLimitListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
|
||||
<!-- Suspensions -->
|
||||
<eventlistener>
|
||||
<eventclassname>chat\data\room\Room</eventclassname>
|
||||
<eventname>canJoin</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomCanJoinBanListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener>
|
||||
<eventclassname>chat\data\room\Room</eventclassname>
|
||||
<eventname>canWritePublicly</eventname>
|
||||
<listenerclassname>chat\system\event\listener\RoomCanWritePubliclyMuteListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
<eventlistener>
|
||||
<eventclassname>chat\system\command\InfoCommand</eventclassname>
|
||||
<eventname>execute</eventname>
|
||||
<listenerclassname>chat\system\event\listener\InfoCommandSuspensionsListener</listenerclassname>
|
||||
<environment>user</environment>
|
||||
</eventlistener>
|
||||
</delete>
|
||||
</data>
|
21
files/acp/be.bastelstu.chat_install.php
Normal file
21
files/acp/be.bastelstu.chat_install.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2010-2018 Tim Düsterhus.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the LICENSE file.
|
||||
*
|
||||
* Change Date: 2022-08-16
|
||||
*
|
||||
* On the date above, in accordance with the Business Source
|
||||
* License, use of this software will be governed by version 2
|
||||
* or later of the General Public License.
|
||||
*/
|
||||
|
||||
use \wcf\system\box\BoxHandler;
|
||||
|
||||
BoxHandler::getInstance()->createBoxCondition( 'be.bastelstu.chat.roomListDashboard'
|
||||
, 'be.bastelstu.chat.box.roomList.condition'
|
||||
, 'be.bastelstu.chat.roomFilled'
|
||||
, [ 'chatRoomIsFilled' => 1 ]
|
||||
);
|
35
files/acp/be.bastelstu.chat_update.php
Normal file
35
files/acp/be.bastelstu.chat_update.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2010-2018 Tim Düsterhus.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the LICENSE file.
|
||||
*
|
||||
* Change Date: 2022-08-16
|
||||
*
|
||||
* On the date above, in accordance with the Business Source
|
||||
* License, use of this software will be governed by version 2
|
||||
* or later of the General Public License.
|
||||
*/
|
||||
|
||||
use \chat\data\message\MessageAction;
|
||||
|
||||
$objectTypeID = \wcf\data\object\type\ObjectTypeCache::getInstance()->getObjectTypeIDByName('be.bastelstu.chat.messageType', 'be.bastelstu.chat.messageType.chatUpdate');
|
||||
|
||||
if ($objectTypeID) {
|
||||
(new MessageAction([ ], 'create', [ 'data' => [ 'roomID' => null
|
||||
, 'userID' => null
|
||||
, 'username' => ''
|
||||
, 'time' => TIME_NOW
|
||||
, 'objectTypeID' => $objectTypeID
|
||||
, 'payload' => serialize([ ])
|
||||
]
|
||||
]
|
||||
)
|
||||
)->executeAction();
|
||||
}
|
||||
|
||||
$CHATCore = file_get_contents(__DIR__.'/../lib/system/CHATCore.class.php');
|
||||
if (strpos($CHATCore, 'chat.phar.php') === false) {
|
||||
@unlink(__DIR__.'/../chat.phar.php');
|
||||
}
|
18
files/acp/global.php
Normal file
18
files/acp/global.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2010-2018 Tim Düsterhus.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the LICENSE file.
|
||||
*
|
||||
* Change Date: 2022-08-16
|
||||
*
|
||||
* On the date above, in accordance with the Business Source
|
||||
* License, use of this software will be governed by version 2
|
||||
* or later of the General Public License.
|
||||
*/
|
||||
|
||||
define('RELATIVE_CHAT_DIR', '../');
|
||||
|
||||
require_once(RELATIVE_CHAT_DIR.'/config.inc.php');
|
||||
require_once(RELATIVE_WCF_DIR.'acp/global.php');
|
16
files/acp/index.php
Normal file
16
files/acp/index.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2010-2018 Tim Düsterhus.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the LICENSE file.
|
||||
*
|
||||
* Change Date: 2022-08-16
|
||||
*
|
||||
* On the date above, in accordance with the Business Source
|
||||
* License, use of this software will be governed by version 2
|
||||
* or later of the General Public License.
|
||||
*/
|
||||
|
||||
require('./global.php');
|
||||
\wcf\system\request\RequestHandler::getInstance()->handle('chat', true);
|
16
files/global.php
Normal file
16
files/global.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2010-2018 Tim Düsterhus.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the LICENSE file.
|
||||
*
|
||||
* Change Date: 2022-08-16
|
||||
*
|
||||
* On the date above, in accordance with the Business Source
|
||||
* License, use of this software will be governed by version 2
|
||||
* or later of the General Public License.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__).'/config.inc.php');
|
||||
require_once(RELATIVE_WCF_DIR.'global.php');
|
16
files/index.php
Normal file
16
files/index.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2010-2018 Tim Düsterhus.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the LICENSE file.
|
||||
*
|
||||
* Change Date: 2022-08-16
|
||||
*
|
||||
* On the date above, in accordance with the Business Source
|
||||
* License, use of this software will be governed by version 2
|
||||
* or later of the General Public License.
|
||||
*/
|
||||
|
||||
require('./global.php');
|
||||
\wcf\system\request\RequestHandler::getInstance()->handle('chat');
|
159
files/lib/acp/form/CommandTriggerAddForm.class.php
Normal file
159
files/lib/acp/form/CommandTriggerAddForm.class.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2010-2018 Tim Düsterhus.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the LICENSE file.
|
||||
*
|
||||
* Change Date: 2022-08-16
|
||||
*
|
||||
* On the date above, in accordance with the Business Source
|
||||
* License, use of this software will be governed by version 2
|
||||
* or later of the General Public License.
|
||||
*/
|
||||
|
||||
namespace chat\acp\form;
|
||||
|
||||
use \chat\data\command\CommandCache;
|
||||
use \chat\data\command\CommandTrigger;
|
||||
use \chat\data\command\CommandTriggerAction;
|
||||
use \chat\data\command\CommandTriggerEditor;
|
||||
use \wcf\system\exception\UserInputException;
|
||||
use \wcf\system\WCF;
|
||||
|
||||
/**
|
||||
* Shows the command trigger add form.
|
||||
*/
|
||||
class CommandTriggerAddForm extends \wcf\form\AbstractForm {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $activeMenuItem = 'chat.acp.menu.link.command.trigger.add';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $neededPermissions = [ 'admin.chat.canManageTriggers' ];
|
||||
|
||||
/**
|
||||
* The new trigger for the specified command
|
||||
* @var string
|
||||
*/
|
||||
public $commandTrigger = '';
|
||||
|
||||
/**
|
||||
* List of currently known commands
|
||||
* @var array
|
||||
*/
|
||||
public $commands = [ ];
|
||||
|
||||
/**
|
||||
* The selected command.
|
||||
*
|
||||
* @param Command
|
||||
*/
|
||||
public $command = null;
|
||||
|
||||
/**
|
||||
* The fully qualified name of the command
|
||||
* @var string
|
||||
*/
|
||||
public $className = '';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function readData() {
|
||||
$commandList = new \chat\data\command\CommandList();
|
||||
$commandList->sqlOrderBy = 'command.className';
|
||||
$commandList->readObjects();
|
||||
|
||||
$this->commands = $commandList->getObjects();
|
||||
|
||||
parent::readData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function readFormParameters() {
|
||||
parent::readFormParameters();
|
||||
|
||||
if (isset($_POST['commandTrigger'])) $this->commandTrigger = \wcf\util\StringUtil::trim($_POST['commandTrigger']);
|
||||
if (isset($_POST['className'])) $this->className = \wcf\util\StringUtil::trim($_POST['className']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function validate() {
|
||||
parent::validate();
|
||||
|
||||
if (empty($this->commandTrigger)) {
|
||||
throw new UserInputException('commandTrigger', 'empty');
|
||||
}
|
||||
|
||||
// Triggers must not contain whitespace
|
||||
if (preg_match('~\s~', $this->commandTrigger)) {
|
||||
throw new UserInputException('commandTrigger', 'invalid');
|
||||
}
|
||||
|
||||
// Check for duplicates
|
||||
$trigger = CommandTrigger::getTriggerByName($this->commandTrigger);
|
||||
if ((!isset($this->trigger) && $trigger->triggerID) || (isset($this->trigger) && $trigger->triggerID != $this->trigger->triggerID)) {
|
||||
throw new UserInputException('commandTrigger', 'duplicate');
|
||||
}
|
||||
|
||||
if (empty($this->className)) {
|
||||
throw new UserInputException('className', 'empty');
|
||||
}
|
||||
|
||||
// Check if the command is registered
|
||||
foreach ($this->commands as $command) {
|
||||
if ($command->className === $this->className) {
|
||||
$this->command = $command;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->command) {
|
||||
throw new UserInputException('className', 'notFound');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function save() {
|
||||
parent::save();
|
||||
|
||||
$fields = [ 'commandTrigger' => $this->commandTrigger
|
||||
, 'commandID' => $this->command->commandID
|
||||
];
|
||||
|
||||
// create room
|
||||
$this->objectAction = new \chat\data\command\CommandTriggerAction([ ], 'create', [ 'data' => array_merge($this->additionalFields, $fields) ]);
|
||||
$this->objectAction->executeAction();
|
||||
|
||||
$this->saved();
|
||||
|
||||
// reset values
|
||||
$this->commandTrigger = $this->className = '';
|
||||
|
||||
// show success message
|
||||
WCF::getTPL()->assign('success', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function assignVariables() {
|
||||
parent::assignVariables();
|
||||
|
||||
WCF::getTPL()->assign([ 'action' => 'add'
|
||||
, 'commandTrigger' => $this->commandTrigger
|
||||
, 'className' => $this->className
|
||||
, 'availableCommands' => $this->commands
|
||||
]);
|
||||
}
|
||||
}
|
112
files/lib/acp/form/CommandTriggerEditForm.class.php
Normal file
112
files/lib/acp/form/CommandTriggerEditForm.class.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2010-2018 Tim Düsterhus.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License
|
||||
* included in the LICENSE file.
|
||||
*
|
||||
* Change Date: 2022-08-16
|
||||
*
|
||||
* On the date above, in accordance with the Business Source
|
||||
* License, use of this software will be governed by version 2
|
||||
* or later of the General Public License.
|
||||
*/
|
||||
|
||||
namespace chat\acp\form;
|
||||
|
||||
use \chat\data\command\CommandTrigger;
|
||||
use \chat\data\command\CommandTriggerAction;
|
||||
use \chat\data\command\CommandTriggerEditor;
|
||||
use \wcf\system\exception\IllegalLinkException;
|
||||
use \wcf\system\exception\UserInputException;
|
||||
use \wcf\system\WCF;
|
||||
|
||||
/**
|
||||
* Shows the command trigger edit form.
|
||||
*/
|
||||
class CommandTriggerEditForm extends CommandTriggerAddForm {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public $activeMenuItem = 'chat.acp.menu.link.command.trigger.list';
|
||||
|
||||
/**
|
||||
* The requested command trigger ID.
|
||||