mirror of
https://github.com/wbbaddons/Tims-Chat.git
synced 2024-10-31 14:10:08 +00:00
Merge branch 'attachments'
This commit is contained in:
commit
71dabf35fa
@ -37,6 +37,7 @@ exposed by a function if necessary.
|
||||
current: {}
|
||||
allTime: {}
|
||||
currentRoom = {}
|
||||
fileUploaded = no
|
||||
|
||||
errorVisible = false
|
||||
inputErrorHidingTimer = null
|
||||
@ -643,7 +644,7 @@ Fetch the roomlist from the server and update it in the GUI.
|
||||
for room in data.returnValues
|
||||
li = $ '<li></li>'
|
||||
li.addClass 'active' if room.active
|
||||
$("""<a href="#{room.link}">#{room.title} <span class="badge">#{WCF.String.formatNumeric room.userCount}</span></a>""").addClass('timsChatRoom').data('roomID', room.roomID).appendTo li
|
||||
$("""<a href="#{room.link}">#{WCF.String.escapeHTML(room.title)} <span class="badge">#{WCF.String.formatNumeric room.userCount}</span></a>""").addClass('timsChatRoom').data('roomID', room.roomID).appendTo li
|
||||
$('#timsChatRoomList ul').append li
|
||||
|
||||
if window.history?.replaceState?
|
||||
@ -741,7 +742,7 @@ Open private channel
|
||||
|
||||
if userID isnt 0
|
||||
$('#timsChatTopic').removeClass 'hidden empty'
|
||||
$('#timsChatTopic > .topic').text WCF.Language.get 'chat.general.privateChannelTopic', {username: userList.allTime[userID].username}
|
||||
$('#timsChatTopic > .topic').html WCF.Language.get 'chat.general.privateChannelTopic', {username: userList.allTime[userID].username}
|
||||
$('#timsChatTopic > .jsTopicCloser').attr 'title', WCF.Language.get 'chat.general.closePrivateChannel'
|
||||
|
||||
unless $.wcfIsset "privateChannel#{userID}"
|
||||
@ -809,7 +810,222 @@ Remove the given callback from the given event.
|
||||
events[event].remove callback
|
||||
|
||||
true
|
||||
|
||||
The following code handles attachment uploads
|
||||
|
||||
Enable attachment code if `WCF.Attachment.Upload` is defined
|
||||
|
||||
if WCF?.Attachment?.Upload? and $('#timsChatUploadContainer').length
|
||||
Attachment = WCF.Attachment.Upload.extend
|
||||
fileUploaded: no
|
||||
|
||||
Initialize WCF.Attachment.Upload
|
||||
See WCF.Attachment.Upload.init()
|
||||
|
||||
init: ->
|
||||
@_super $('#timsChatUploadContainer'), $(false), 'be.bastelstu.chat.message', 0, 0, 0, 1, null
|
||||
unless @_supportsAJAXUpload
|
||||
$('#timsChatUploadDropdownMenu .uploadButton').click => do @_showOverlay
|
||||
|
||||
label = $ '#timsChatUploadDropdownMenu li > span > label'
|
||||
parent = do label.parent
|
||||
|
||||
css = parent.css ['padding-top', 'padding-right', 'padding-bottom', 'padding-left']
|
||||
|
||||
label.css css
|
||||
label.css 'margin', "-#{css['padding-top']} -#{css['padding-right']} -#{css['padding-bottom']} -#{css['padding-left']}"
|
||||
$('#timsChatUpload').click ->
|
||||
$('#timsChatUpload > span.icon-ban-circle').removeClass('icon-ban-circle').addClass 'icon-paper-clip'
|
||||
do $('#timsChatUploadContainer .innerError').remove
|
||||
|
||||
Overwrite WCF.Attachment.Upload._createButton() to create the upload button as small button into a button group
|
||||
|
||||
_createButton: ->
|
||||
if @_supportsAJAXUpload
|
||||
@_fileUpload = $ """<input id="timsChatUploadInput" type="file" name="#{@_name}" />"""
|
||||
@_fileUpload.change => do @_upload
|
||||
@_fileUpload.appendTo 'body'
|
||||
|
||||
_removeButton: ->
|
||||
do @_fileUpload.remove
|
||||
|
||||
See WCF.Attachment.Upload._getParameters()
|
||||
|
||||
_getParameters: ->
|
||||
@_tmpHash = do Math.random
|
||||
@_parentObjectID = currentRoom.roomID
|
||||
|
||||
do @_super
|
||||
|
||||
|
||||
_upload: ->
|
||||
files = @_fileUpload.prop 'files'
|
||||
if files.length
|
||||
$('#timsChatUpload > span.icon').removeClass('icon-paper-clip icon-ban-circle').addClass('icon-spinner')
|
||||
do @_super
|
||||
|
||||
Create a message containing the uploaded attachment
|
||||
|
||||
_insert: (event) ->
|
||||
objectID = $(event.currentTarget).data 'objectID'
|
||||
|
||||
new WCF.Action.Proxy
|
||||
autoSend: true
|
||||
data:
|
||||
actionName: 'sendAttachment'
|
||||
className: 'chat\\data\\message\\MessageAction'
|
||||
parameters:
|
||||
objectID: objectID
|
||||
tmpHash: @_tmpHash
|
||||
parentObjectID: 1#@_parentObjectID
|
||||
showLoadingOverlay: false
|
||||
|
||||
success: ->
|
||||
do $('#timsChatUploadDropdownMenu .jsDeleteButton').parent().remove
|
||||
do $('#timsChatUploadDropdownMenu .sendAttachmentButton').remove
|
||||
do $('#timsChatUploadDropdownMenu .uploadButton').show
|
||||
$('#timsChatUpload > span.icon').removeClass('icon-ok-sign').addClass 'icon-paper-clip'
|
||||
fileUploaded = no
|
||||
|
||||
failure: (data) ->
|
||||
false
|
||||
|
||||
_initFile: (file) ->
|
||||
li = $("""<li class="uploadProgress">
|
||||
<span>
|
||||
<progress max="100"></progress>
|
||||
</span>
|
||||
</li>"""
|
||||
).data('filename', file.name)
|
||||
|
||||
$('#timsChatUploadDropdownMenu').append li
|
||||
do $('#timsChatUploadDropdownMenu .uploadButton').hide
|
||||
# validate file size
|
||||
if @_buttonSelector.data('maxSize') < file.size
|
||||
# remove progress bar
|
||||
do li.find('progress').remove
|
||||
|
||||
# upload icon
|
||||
$('#timsChatUpload > span.icon-spinner').removeClass('icon-spinner').addClass 'icon-ban-circle'
|
||||
|
||||
# error message
|
||||
$('#timsChatUpload').addClass('uploadFailed').after """<small class="innerError">#{WCF.Language.get('wcf.attachment.upload.error.tooLarge')}</small>"""
|
||||
|
||||
do @_error
|
||||
li.addClass 'uploadFailed'
|
||||
li
|
||||
|
||||
_validateLimit: ->
|
||||
innerError = @_buttonSelector.next 'small.innerError'
|
||||
|
||||
if fileUploaded
|
||||
# reached limit
|
||||
unless innerError.length
|
||||
innerError = $('<small class="innerError" />').insertAfter '#timsChatUpload'
|
||||
|
||||
innerError.html WCF.Language.get('wcf.attachment.upload.error.reachedLimit')
|
||||
innerError.css 'position', 'absolute'
|
||||
|
||||
return false
|
||||
|
||||
# remove previous errors
|
||||
do innerError.remove
|
||||
|
||||
true
|
||||
|
||||
_success: (uploadID, data) ->
|
||||
for li in @_uploadMatrix[uploadID]
|
||||
do li.find('progress').remove
|
||||
li.removeClass('uploadProgress').addClass 'sendAttachmentButton'
|
||||
|
||||
li.find('span').addClass('box32').append """
|
||||
<div class="framed attachmentImageContainer">
|
||||
<span class="attachmentTinyThumbnail icon icon32 icon-paper-clip"></span>
|
||||
</div>
|
||||
<div class="containerHeaderline">
|
||||
<p></p>
|
||||
<small></small>
|
||||
<p>#{WCF.Language.get('wcf.global.button.submit')}</p>
|
||||
</div>"""
|
||||
|
||||
li.click (event) => @_insert(event)
|
||||
|
||||
filename = li.data 'filename'
|
||||
internalFileID = li.data 'internalFileID'
|
||||
|
||||
if data.returnValues and data.returnValues.attachments[internalFileID]
|
||||
if data.returnValues.attachments[internalFileID].tinyURL
|
||||
li.find('.box32 > div.attachmentImageContainer > .icon-paper-clip').replaceWith $("""<img src="#{data.returnValues.attachments[internalFileID].tinyURL}'" alt="" class="attachmentTinyThumbnail" style="width: 32px; height: 32px;" />""")
|
||||
|
||||
link = $ '<a href="" class="jsTooltip"></a>'
|
||||
link.attr {'href': data.returnValues.attachments[internalFileID].url, 'title': filename}
|
||||
|
||||
unless parseInt(data.returnValues.attachments[internalFileID].isImage) is 0
|
||||
link.addClass('jsImageViewer')
|
||||
|
||||
if !data.returnValues.attachments[internalFileID].tinyURL
|
||||
li.find('.box32 > div.attachmentImageContainer > .icon-paper-clip').replaceWith $("""<img src="#{data.returnValues.attachments[internalFileID].url}'" alt="" class="attachmentTinyThumbnail" style="width: 32px; height: 32px;" />""")
|
||||
|
||||
li.find('.attachmentTinyThumbnail').wrap link
|
||||
li.find('small').append data.returnValues.attachments[internalFileID].formattedFilesize
|
||||
|
||||
li.data 'objectID', data.returnValues.attachments[internalFileID].attachmentID
|
||||
|
||||
deleteButton = $ """
|
||||
<li>
|
||||
<span class="jsDeleteButton" data-object-id="#{data.returnValues.attachments[internalFileID].attachmentID}" data-confirm-message="#{WCF.Language.get('wcf.attachment.delete.sure')}">
|
||||
<span class="icon icon16 icon-remove pointer jsTooltip" />
|
||||
<span>#{WCF.Language.get('wcf.global.button.delete')}</span>
|
||||
</span>
|
||||
</li>"""
|
||||
li.parent().append deleteButton
|
||||
fileUploaded = yes
|
||||
else
|
||||
$('#timsChatUpload .icon-spinner').removeClass('icon-spinner').addClass 'icon-ban-circle'
|
||||
|
||||
if data.returnValues and data.returnValues.errors[internalFileID]
|
||||
errorMessage = data.returnValues.errors[internalFileID].errorType
|
||||
else
|
||||
errorMessage = 'uploadFailed'
|
||||
|
||||
$('#timsChatUpload').addClass('uploadFailed').after """<small class="innerError">#{WCF.Language.get('wcf.attachment.upload.error.' + errorMessage)}</small>"""
|
||||
do $('#timsChatUploadDropdownMenu .sendAttachmentButton').remove
|
||||
do $('#timsChatUploadDropdownMenu .uploadButton').show
|
||||
fileUploaded = no
|
||||
|
||||
do WCF.DOMNodeInsertedHandler.execute
|
||||
|
||||
$('#timsChatUpload > span.icon').removeClass('icon-spinner').addClass 'icon-ok-sign'
|
||||
do $('#timsChatUploadDropdownMenu .uploadProgress').remove
|
||||
do $('#timsChatUploadDropdownMenu .sendAttachmentButton').show
|
||||
|
||||
_error: (jqXHR, textStatus, errorThrown) ->
|
||||
$('#timsChatUpload > .icon-spinner').removeClass('icon-spinner').addClass 'icon-ban-circle'
|
||||
unless $('#timsChatUpload').hasClass('uploadFailed')
|
||||
$('#timsChatUpload').addClass('uploadFailed').after """<small class="innerError">#{WCF.Language.get('wcf.attachment.upload.error.uploadFailed')}</small>"""
|
||||
|
||||
do $('#timsChatUploadDropdownMenu .uploadProgress').remove
|
||||
do $('#timsChatUploadDropdownMenu .uploadButton').show
|
||||
fileUploaded = no
|
||||
|
||||
Action = {}
|
||||
Action.Delete = WCF.Action.Delete.extend
|
||||
triggerEffect: (objectIDs) ->
|
||||
for index in @_containers
|
||||
container = $ "##{index}"
|
||||
if WCF.inArray container.find(@_buttonSelector).data('objectID'), objectIDs
|
||||
self = @
|
||||
container.wcfBlindOut 'up', (event) ->
|
||||
parent = do $(@).parent
|
||||
do $(@).remove
|
||||
do parent.find('.sendAttachmentButton').remove
|
||||
do parent.find('.uploadButton').show
|
||||
$('#timsChatUpload > .icon-ok-sign').removeClass('icon-ok-sign').addClass 'icon-paper-clip'
|
||||
|
||||
self._containers.splice(self._containers.indexOf $(@).wcfIdentify(), 1)
|
||||
self._didTriggerEffect($ @)
|
||||
fileUploaded = no
|
||||
return
|
||||
And finally export the public methods and variables.
|
||||
|
||||
Chat =
|
||||
@ -822,7 +1038,9 @@ And finally export the public methods and variables.
|
||||
listener:
|
||||
add: addListener
|
||||
remove: removeListener
|
||||
|
||||
Chat.Attachment = Attachment if Attachment?
|
||||
Chat.Action = Action if Attachment?
|
||||
|
||||
window.be ?= {}
|
||||
be.bastelstu ?= {}
|
||||
window.be.bastelstu.Chat = Chat
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace chat\data\message;
|
||||
use \chat\util\ChatUtil;
|
||||
use \wcf\system\bbcode\AttachmentBBCode;
|
||||
use \wcf\system\Regex;
|
||||
use \wcf\system\WCF;
|
||||
|
||||
@ -36,6 +37,7 @@ class Message extends \chat\data\CHATDatabaseObject {
|
||||
const TYPE_CLEAR = 9;
|
||||
const TYPE_TEAM = 10;
|
||||
const TYPE_GLOBALMESSAGE = 11;
|
||||
const TYPE_ATTACHMENT = 12;
|
||||
|
||||
/**
|
||||
* cache for users
|
||||
@ -87,6 +89,16 @@ public function getFormattedMessage($type = 'text/html') {
|
||||
|
||||
$message = $messageParser->parse($message, false, false, true, false);
|
||||
break;
|
||||
case self::TYPE_ATTACHMENT:
|
||||
$attachmentList = new \wcf\data\attachment\GroupedAttachmentList('be.bastelstu.chat.message');
|
||||
$attachmentList->getConditionBuilder()->add('attachment.objectID IN (?)', array($this->messageID));
|
||||
$attachmentList->readObjects();
|
||||
|
||||
AttachmentBBCode::setAttachmentList($attachmentList);
|
||||
AttachmentBBCode::setObjectID($this->messageID);
|
||||
|
||||
$message = $messageParser->parse($message, false, false, true, false);
|
||||
break;
|
||||
case self::TYPE_WHISPER:
|
||||
case self::TYPE_NORMAL:
|
||||
case self::TYPE_ME:
|
||||
@ -137,7 +149,7 @@ public function jsonify($raw = false) {
|
||||
|
||||
$array = array(
|
||||
'formattedUsername' => $this->getUsername(true),
|
||||
'formattedMessage' => $this->getFormattedMessage(),
|
||||
'formattedMessage' => $this->getFormattedMessage('text/html'),
|
||||
'formattedTime' => \wcf\util\DateUtil::format(\wcf\util\DateUtil::getDateTimeByTimestamp($this->time), 'H:i:s'),
|
||||
'separator' => $separator,
|
||||
'message' => $this->getFormattedMessage('text/plain'),
|
||||
|
@ -197,4 +197,73 @@ public function validateGetMessages() {
|
||||
$this->parameters['room'] = room\RoomCache::getInstance()->getRoom($this->parameters['roomID']);
|
||||
if ($this->parameters['room'] === null) throw new \wcf\system\exception\IllegalLinkException();
|
||||
}
|
||||
|
||||
public function validateSendAttachment() {
|
||||
// read user data
|
||||
$this->parameters['userData']['color1'] = WCF::getUser()->chatColor1;
|
||||
$this->parameters['userData']['color2'] = WCF::getUser()->chatColor2;
|
||||
$this->parameters['userData']['roomID'] = WCF::getUser()->chatRoomID;
|
||||
$this->parameters['userData']['away'] = WCF::getUser()->chatAway;
|
||||
|
||||
// read and validate room
|
||||
$this->parameters['room'] = room\RoomCache::getInstance()->getRoom($this->parameters['userData']['roomID']);
|
||||
if ($this->parameters['room'] === null) throw new \wcf\system\exception\IllegalLinkException();
|
||||
if (!$this->parameters['room']->canEnter()) throw new \wcf\system\exception\PermissionDeniedException();
|
||||
if (!$this->parameters['room']->canWrite()) throw new \wcf\system\exception\PermissionDeniedException();
|
||||
|
||||
$this->readInteger('objectID');
|
||||
if (!$this->parameters['objectID']) throw new \wcf\system\exception\IllegalLinkException();
|
||||
|
||||
$this->readInteger('parentObjectID');
|
||||
if (!$this->parameters['parentObjectID']) throw new \wcf\system\exception\IllegalLinkException();
|
||||
|
||||
$editor = new \wcf\data\user\UserEditor(WCF::getUser());
|
||||
$editor->update(array(
|
||||
'chatAway' => null,
|
||||
'chatLastActivity' => TIME_NOW
|
||||
));
|
||||
|
||||
// mark user as back
|
||||
if ($this->parameters['userData']['away'] !== null) {
|
||||
$messageAction = new MessageAction(array(), 'create', array(
|
||||
'data' => array(
|
||||
'roomID' => $this->parameters['room']->roomID,
|
||||
'sender' => WCF::getUser()->userID,
|
||||
'username' => WCF::getUser()->username,
|
||||
'time' => TIME_NOW,
|
||||
'type' => Message::TYPE_BACK,
|
||||
'message' => '',
|
||||
'color1' => $this->parameters['userData']['color1'],
|
||||
'color2' => $this->parameters['userData']['color2']
|
||||
)
|
||||
));
|
||||
$messageAction->executeAction();
|
||||
}
|
||||
}
|
||||
|
||||
public function sendAttachment() {
|
||||
$this->objectAction = new MessageAction(array(), 'create', array(
|
||||
'data' => array(
|
||||
'roomID' => $this->parameters['room']->roomID,
|
||||
'sender' => WCF::getUser()->userID,
|
||||
'username' => WCF::getUser()->username,
|
||||
'time' => TIME_NOW,
|
||||
'type' => Message::TYPE_ATTACHMENT,
|
||||
'message' => '[attach]'. $this->parameters['objectID'] .'[/attach]',
|
||||
'color1' => $this->parameters['userData']['color1'],
|
||||
'color2' => $this->parameters['userData']['color2'],
|
||||
'attachmentID' => $this->parameters['objectID']
|
||||
)
|
||||
));
|
||||
|
||||
$this->objectAction->executeAction();
|
||||
$returnValues = $this->objectAction->getReturnValues();
|
||||
|
||||
$this->parameters['parentObjectID'] = 0;
|
||||
$attachmentHandler = new \wcf\system\attachment\AttachmentHandler('be.bastelstu.chat.message', $this->parameters['objectID'], $this->parameters['tmpHash'], $this->parameters['parentObjectID']);
|
||||
$attachmentHandler->updateObjectID($returnValues['returnValues']->messageID);
|
||||
|
||||
// add activity points
|
||||
\wcf\system\user\activity\point\UserActivityPointHandler::getInstance()->fireEvent('be.bastelstu.chat.activityPointEvent.message', $returnValues['returnValues']->messageID, WCF::getUser()->userID);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,17 @@ class MessageEditor extends \wcf\data\DatabaseObjectEditor {
|
||||
*/
|
||||
protected static $baseClass = '\chat\data\message\Message';
|
||||
|
||||
/**
|
||||
* @see wcf\data\DatabaseObjectEditor::deleteAll()
|
||||
*/
|
||||
public static function deleteAll(array $objectIDs = array()) {
|
||||
$count = parent::deleteAll($objectIDs);
|
||||
// delete attached files
|
||||
\wcf\system\attachment\AttachmentHandler::removeAttachments('be.bastelstu.chat.message', $objectIDs);
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the Push-Server.
|
||||
*/
|
||||
|
@ -203,7 +203,7 @@ public function join() {
|
||||
}
|
||||
|
||||
$ipAddress = '';
|
||||
if ($this->parameters['user']->userID == WCF::getUser()->userID) $ipAddress = \wcf\util\UserUtil::convertIPv6To4(\wcf\util\UserUtil::getIpAddress());
|
||||
if (LOG_IP_ADDRESS && $this->parameters['user']->userID == WCF::getUser()->userID) $ipAddress = \wcf\util\UserUtil::convertIPv6To4(\wcf\util\UserUtil::getIpAddress());
|
||||
|
||||
// join message
|
||||
$messageAction = new message\MessageAction(array(), 'create', array(
|
||||
|
@ -73,6 +73,12 @@ class ChatPage extends \wcf\page\AbstractPage {
|
||||
*/
|
||||
public $smileyCategories = array();
|
||||
|
||||
/**
|
||||
* attachment handler
|
||||
* @see \wcf\system\attachment\AttachmentHandler
|
||||
*/
|
||||
public $attachmentHandler = null;
|
||||
|
||||
/**
|
||||
* @see wcf\page\AbstractPage::$enableTracking
|
||||
*/
|
||||
@ -94,6 +100,7 @@ public function assignVariables() {
|
||||
'messageTypes' => $reflection->getConstants(),
|
||||
'defaultSmilies' => $this->defaultSmilies,
|
||||
'smileyCategories' => $this->smileyCategories,
|
||||
'attachmentHandler' => $this->attachmentHandler,
|
||||
'sidebarCollapsed' => \wcf\system\user\collapsible\content\UserCollapsibleContentHandler::getInstance()->isCollapsed('com.woltlab.wcf.collapsibleSidebar', 'be.bastelstu.chat.ChatPage'),
|
||||
'sidebarName' => 'be.bastelstu.chat.ChatPage'
|
||||
));
|
||||
@ -125,6 +132,10 @@ public function readData() {
|
||||
$this->defaultSmilies = \wcf\data\smiley\SmileyCache::getInstance()->getCategorySmilies($firstCategory->categoryID ?: null);
|
||||
}
|
||||
}
|
||||
|
||||
if (MODULE_ATTACHMENT) {
|
||||
$this->attachmentHandler = new \wcf\system\attachment\AttachmentHandler('be.bastelstu.chat.message', 0, '', 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
namespace chat\system\attachment;
|
||||
use \wcf\system\WCF;
|
||||
|
||||
/**
|
||||
* Attachment object type implementation for chat messages.
|
||||
*
|
||||
* @author Maximilian Mader
|
||||
* @copyright 2010-2013 Tim Düsterhus
|
||||
* @license Creative Commons Attribution-NonCommercial-ShareAlike <http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode>
|
||||
* @package be.bastelstu.chat
|
||||
* @subpackage system.attachment
|
||||
*/
|
||||
class MessageAttachmentObjectType extends \wcf\system\attachment\AbstractAttachmentObjectType {
|
||||
/**
|
||||
* @see wcf\system\attachment\IAttachmentObjectType::getMaxSize()
|
||||
*/
|
||||
public function getMaxSize() {
|
||||
return WCF::getSession()->getPermission('user.chat.maxAttachmentSize');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see wcf\system\attachment\IAttachmentObjectType::getAllowedExtensions()
|
||||
*/
|
||||
public function getAllowedExtensions() {
|
||||
return \wcf\util\ArrayUtil::trim(explode("\n", WCF::getSession()->getPermission('user.chat.allowedAttachmentExtensions')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see wcf\system\attachment\IAttachmentObjectType::getMaxCount()
|
||||
*/
|
||||
public function getMaxCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see wcf\system\attachment\IAttachmentObjectType::canDownload()
|
||||
*/
|
||||
public function canDownload($objectID) {
|
||||
if ($objectID) {
|
||||
$message = new \chat\data\message\Message($objectID);
|
||||
if (isset($message->roomID) && $message->roomID) {
|
||||
$room = \chat\data\room\RoomCache::getInstance()->getRoom($message->roomID);
|
||||
if ($room && $room->canEnter()) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canPreview($objectID) {
|
||||
return $this->canDownload($objectID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see wcf\system\attachment\IAttachmentObjectType::canUpload()
|
||||
*/
|
||||
public function canUpload($objectID, $parentObjectID = 0) {
|
||||
if ($objectID) {
|
||||
$room = \chat\data\room\RoomCache::getInstance()->getRoom($parentObjectID);
|
||||
if (!$room || !$room->canWrite()) return false;
|
||||
}
|
||||
|
||||
return WCF::getSession()->getPermission('user.chat.canUploadAttachment');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see wcf\system\attachment\IAttachmentObjectType::canDelete()
|
||||
*/
|
||||
public function canDelete($objectID) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@
|
||||
* @subpackage system.chat.command.commands
|
||||
*/
|
||||
class InfoCommand extends \chat\system\command\AbstractCommand {
|
||||
public $enableHTML = self::SETTING_ON;
|
||||
public $lines = array();
|
||||
public $user = null;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
from {
|
||||
border-color: @wcfContainerBorderColor;
|
||||
}
|
||||
|
||||
|
||||
to {
|
||||
border-color: @wcfInputHoverBorderColor;
|
||||
}
|
||||
@ -92,7 +92,7 @@
|
||||
> .userAvatar, .userAvatar > .icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
> .userAvatar {
|
||||
&.large {
|
||||
display: none;
|
||||
@ -102,7 +102,7 @@
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.active {
|
||||
> .userAvatar {
|
||||
&.large {
|
||||
@ -192,9 +192,24 @@
|
||||
padding: 5px 20px 5px 5px;
|
||||
position: relative;
|
||||
|
||||
.userAvatar {
|
||||
float: left;
|
||||
margin-left: 16px;
|
||||
> div.avatarContainer {
|
||||
position: absolute;
|
||||
width: 40px;
|
||||
height: 38px;
|
||||
|
||||
> .userAvatar {
|
||||
float: left;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
> .avatarExtra {
|
||||
box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.3);
|
||||
position: absolute;
|
||||
left: 24px;
|
||||
bottom: -2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.innerMessage {
|
||||
@ -219,11 +234,9 @@
|
||||
}
|
||||
|
||||
&.bubble {
|
||||
.userAvatar {
|
||||
margin-left: 0;
|
||||
|
||||
.icon {
|
||||
padding: 2px;
|
||||
> div.avatarContainer {
|
||||
.userAvatar {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,6 +401,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
#timsChatUploadInput {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#timsChatUploadContainer {
|
||||
.innerError {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
#timsChatRoomList {
|
||||
> div {
|
||||
> div {
|
||||
|
@ -22,10 +22,12 @@ CREATE TABLE chat1_message (
|
||||
color1 INT(10) NOT NULL DEFAULT 0,
|
||||
color2 INT(10) NOT NULL DEFAULT 0,
|
||||
additionalData TEXT DEFAULT NULL,
|
||||
attachmentID INT(10) DEFAULT NULL,
|
||||
|
||||
KEY (roomID),
|
||||
KEY (sender),
|
||||
KEY (receiver)
|
||||
KEY (receiver),
|
||||
KEY (attachmentID)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS chat1_room;
|
||||
@ -69,6 +71,7 @@ ALTER TABLE wcf1_user ADD COLUMN chatLastSeen INT(10) NOT NULL DEFAULT 0;
|
||||
ALTER TABLE chat1_message ADD FOREIGN KEY (receiver) REFERENCES wcf1_user (userID) ON DELETE CASCADE;
|
||||
ALTER TABLE chat1_message ADD FOREIGN KEY (roomID) REFERENCES chat1_room (roomID) ON DELETE CASCADE;
|
||||
ALTER TABLE chat1_message ADD FOREIGN KEY (sender) REFERENCES wcf1_user (userID) ON DELETE SET NULL;
|
||||
ALTER TABLE chat1_message ADD FOREIGN KEY (attachmentID) REFERENCES wcf1_attachment (attachmentID) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE chat1_room ADD FOREIGN KEY (owner) REFERENCES wcf1_user (userID) ON DELETE SET NULL;
|
||||
|
||||
|
@ -194,6 +194,8 @@ Probieren Sie, den Chat neu zu laden<!-- , bei Risiken und Nebenwirkungen fragen
|
||||
<item name="chat.message.5.unban"><![CDATA[hat {@$link} entbannt.]]></item>
|
||||
<item name="chat.message.5.ungmute"><![CDATA[hat {@$link} global entknebelt.]]></item>
|
||||
<item name="chat.message.5.ungban"><![CDATA[hat {@$link} global entbannt.]]></item>
|
||||
<!-- 12 = TYPE_ATTACHMENT -->
|
||||
<item name="chat.message.12"><![CDATA[hat eine Datei geteilt:]]></item>
|
||||
|
||||
<item name="chat.message.color.success"><![CDATA[Die Farbe wurde erfolgreich geändert.]]></item>
|
||||
<item name="chat.message.temproom.success"><![CDATA[Der temporäre Raum „{$roomName}“ wurde erfolgreich erstellt. Laden Sie die Raumliste neu, damit dieser sichtbar wird.]]></item>
|
||||
|
@ -24,5 +24,10 @@
|
||||
<classname>chat\system\user\online\location\ChatLocation</classname>
|
||||
<languagevariable>chat.user.usersOnline.location.ChatPage</languagevariable>
|
||||
</type>
|
||||
<type>
|
||||
<name>be.bastelstu.chat.message</name>
|
||||
<definitionname>com.woltlab.wcf.attachment.objectType</definitionname>
|
||||
<classname>chat\system\attachment\MessageAttachmentObjectType</classname>
|
||||
</type>
|
||||
</import>
|
||||
</data>
|
||||
|
@ -21,12 +21,26 @@
|
||||
'chat.error.onMessageLoad': '{@"chat.error.onMessageLoad"|language|encodeJS}',
|
||||
'chat.error.duplicateTab': '{lang}chat.error.duplicateTab{/lang}',
|
||||
'chat.error.join': '{lang}chat.error.join{/lang}',
|
||||
'chat.error.reload': '{lang}chat.error.reload{/lang}'
|
||||
'chat.error.reload': '{lang}chat.error.reload{/lang}',
|
||||
'wcf.attachment.upload.error.invalidExtension': '{lang}wcf.attachment.upload.error.invalidExtension{/lang}',
|
||||
'wcf.attachment.upload.error.tooLarge': '{lang}wcf.attachment.upload.error.tooLarge{/lang}',
|
||||
'wcf.attachment.upload.error.reachedLimit': '{lang}wcf.attachment.upload.error.reachedLimit{/lang}',
|
||||
'wcf.attachment.upload.error.reachedRemainingLimit': '{lang}wcf.attachment.upload.error.reachedRemainingLimit{/lang}',
|
||||
'wcf.attachment.upload.error.uploadFailed': '{lang}wcf.attachment.upload.error.uploadFailed{/lang}',
|
||||
'wcf.global.button.upload': '{lang}wcf.global.button.upload{/lang}',
|
||||
'wcf.attachment.insert': '{lang}wcf.attachment.insert{/lang}',
|
||||
'wcf.attachment.delete.sure': '{lang}wcf.attachment.delete.sure{/lang}',
|
||||
'chat.message.{$messageTypes[TYPE_ATTACHMENT]}': '{lang}chat.message.{$messageTypes[TYPE_ATTACHMENT]}{/lang}'
|
||||
});
|
||||
|
||||
// Boot the chat
|
||||
{if MODULE_SMILEY}WCF.TabMenu.init();{/if}
|
||||
{if MODULE_ATTACHMENT && $__wcf->session->getPermission('user.chat.canUploadAttachment')}
|
||||
new be.bastelstu.Chat.Attachment();
|
||||
new be.bastelstu.Chat.Action.Delete('wcf\\data\\attachment\\AttachmentAction', '#timsChatUploadDropdownMenu > li');
|
||||
{/if}
|
||||
new WCF.Message.Smilies();
|
||||
|
||||
{capture assign='messageTemplate'}{include application='chat' file='message'}{/capture}
|
||||
{capture assign='userTemplate'}{include application='chat' file='userListUser'}{/capture}
|
||||
|
||||
@ -113,10 +127,28 @@
|
||||
<span class="invisible">{lang}chat.general.controls{/lang}</span>
|
||||
<ul class="smallButtons buttonGroup">
|
||||
<li><a id="timsChatAutoscroll" accesskey="d" class="button active timsChatToggle jsTooltip" title="{lang}chat.general.scroll{/lang}" data-status="1"><span class="icon icon16 icon-arrow-down"></span><span class="invisible">{lang}chat.general.scroll{/lang}</span></a></li>{*
|
||||
|
||||
*}<li><a id="timsChatFullscreen" accesskey="f" class="button timsChatToggle jsTooltip" title="{lang}chat.general.fullscreen{/lang}" data-status="0"><span class="icon icon16 icon-fullscreen"></span><span class="invisible">{lang}chat.general.fullscreen{/lang}</span></a></li>{*
|
||||
|
||||
*}<li><a id="timsChatNotify" accesskey="n" class="button timsChatToggle jsTooltip" title="{lang}chat.general.notify{/lang}" data-status="0"><span class="icon icon16 icon-bell-alt"></span><span class="invisible">{lang}chat.general.notify{/lang}</span></a></li>{*
|
||||
|
||||
*}<li{if !MODULE_SMILEY || !$smileyCategories|count} style="display: none;"{/if}><a id="timsChatSmilies" accesskey="e" class="button{if ENABLE_SMILIES_DEFAULT_VALUE} active{/if} timsChatToggle jsTooltip" title="{lang}chat.general.smilies{/lang}" data-status="{@ENABLE_SMILIES_DEFAULT_VALUE}"><span class="icon icon16 icon-smile"></span><span class="invisible">{lang}chat.general.smilies{/lang}</span></a></li>{*
|
||||
|
||||
*}{if MODULE_ATTACHMENT && $__wcf->session->getPermission('user.chat.canUploadAttachment')}{*
|
||||
*}<li id="timsChatUploadContainer" class="dropdown" data-max-size="{$attachmentHandler->getMaxSize()}">
|
||||
<a id="timsChatUpload" class="dropdownToggle button jsTooltip" title="{lang}wcf.attachment.attachments{/lang}" data-toggle="timsChatUploadContainer">
|
||||
<span class="icon icon16 icon-paper-clip"></span>
|
||||
<span class="invisible">{lang}wcf.attachment.attachments{/lang}</span>
|
||||
</a>
|
||||
<ul id="timsChatUploadDropdownMenu" class="dropdownMenu">
|
||||
<li class="uploadButton" style="margin-top: 0;">
|
||||
<span><label for="timsChatUploadInput">{lang}wcf.global.button.upload{/lang}</label></span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>{/if}{*
|
||||
|
||||
*}<li><a id="timsChatClear" class="button jsTooltip" title="{lang}chat.general.clear{/lang}"><span class="icon icon16 icon-remove"></span><span class="invisible">{lang}chat.general.clear{/lang}</span></a></li>{*
|
||||
|
||||
*}<li><a id="timsChatMark" class="button timsChatToggle jsTooltip" title="{lang}chat.general.mark{/lang}" data-status="0"><span class="icon icon16 icon-check"></span><span class="invisible">{lang}chat.general.mark{/lang}</span></a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
@ -1,2 +1,3 @@
|
||||
{if MODULE_ATTACHMENT && $__wcf->session->getPermission('user.chat.canUploadAttachment')}<script data-relocate="true" src="{@$__wcf->getPath()}js/WCF.Attachment{if !ENABLE_DEBUG_MODE}.min{/if}.js?v={@$__wcfVersion}"></script>{/if}
|
||||
<script data-relocate="true" src="{$__wcf->getPath('chat')}js/be.bastelstu.Chat{if !ENABLE_DEBUG_MODE}.min{/if}.js?version={PACKAGE_VERSION|rawurlencode}"></script>
|
||||
{event name='javascript'}
|
||||
|
@ -1,19 +1,26 @@
|
||||
{literal}
|
||||
<div class="messageIcon">
|
||||
{if $message.type == $messageTypes.LEAVE || $message.type == $messageTypes.JOIN}
|
||||
<span class="icon icon16 icon-{if $message.type == $messageTypes.LEAVE}signout{else}signin{/if}"></span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="innerMessageContainer{if $message.type == $messageTypes.NORMAL || $message.type == $messageTypes.WHISPER || $message.type == $messageTypes.INFORMATION} bubble{/if}{if $message.type == $messageTypes.WHISPER && $message.sender != $__wcf.User.userID} right{/if}">
|
||||
<div class="userAvatar framed">
|
||||
{if $message.type != $messageTypes.INFORMATION}
|
||||
{if $message.type == $messageTypes.NORMAL || $message.type == $messageTypes.WHISPER}
|
||||
{@$message.avatar[32]}
|
||||
{if $message.type == $messageTypes.LEAVE || $message.type == $messageTypes.JOIN}
|
||||
<div class="messageIcon">
|
||||
<span class="icon icon16 icon-{if $message.type == $messageTypes.LEAVE}signout{elseif $message.type == $messageTypes.JOIN}signin{/if}"></span>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="innerMessageContainer{if $message.type == $messageTypes.NORMAL || $message.type == $messageTypes.WHISPER || $message.type == $messageTypes.INFORMATION || $message.type == $messageTypes.ATTACHMENT} bubble{/if}{if $message.type == $messageTypes.WHISPER && $message.sender != $__wcf.User.userID} right{/if}">
|
||||
<div class="avatarContainer">
|
||||
<div class="userAvatar framed">
|
||||
{if $message.type != $messageTypes.INFORMATION}
|
||||
{if $message.type == $messageTypes.NORMAL || $message.type == $messageTypes.WHISPER || $message.type == $messageTypes.ATTACHMENT}
|
||||
{@$message.avatar[32]}
|
||||
{else}
|
||||
{@$message.avatar[16]}
|
||||
{/if}
|
||||
{else}
|
||||
{@$message.avatar[16]}
|
||||
<span class="icon icon32 icon-info-sign"></span>
|
||||
{/if}
|
||||
{else}
|
||||
<span class="icon icon32 icon-info-sign"></span>
|
||||
</div>
|
||||
{if $message.type == $messageTypes.ATTACHMENT}
|
||||
<small class="framed avatarExtra">
|
||||
<span class="icon icon16 icon-paperclip"></span>
|
||||
</small>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="innerMessage">
|
||||
@ -36,7 +43,8 @@
|
||||
|
||||
<time>{@$message.formattedTime}</time>
|
||||
|
||||
{if $message.type == $messageTypes.NORMAL || $message.type == $messageTypes.WHISPER}
|
||||
{if $message.type == $messageTypes.NORMAL || $message.type == $messageTypes.WHISPER || $message.type == $messageTypes.ATTACHMENT}
|
||||
{if $message.type == $messageTypes.ATTACHMENT}<span>{lang}chat.message.{$messageTypes.ATTACHMENT}{/lang}</span>{/if}
|
||||
<ul class="text">
|
||||
<li>
|
||||
{if $message.isFollowUp} <time>{@$message.formattedTime}</time>{/if}
|
||||
|
@ -38,6 +38,34 @@
|
||||
<defaultvalue>none</defaultvalue>
|
||||
<admindefaultvalue>all</admindefaultvalue>
|
||||
</option>
|
||||
<option name="user.chat.canUploadAttachment">
|
||||
<categoryname>user.chat</categoryname>
|
||||
<optiontype>boolean</optiontype>
|
||||
<defaultvalue>1</defaultvalue>
|
||||
<enableoptions>user.chat.maxAttachmentSize,user.chat.allowedAttachmentExtensions</enableoptions>
|
||||
<options>module_attachment</options>
|
||||
</option>
|
||||
<option name="user.chat.maxAttachmentSize">
|
||||
<categoryname>user.chat</categoryname>
|
||||
<optiontype>fileSize</optiontype>
|
||||
<defaultvalue>1000000</defaultvalue>
|
||||
<options>module_attachment</options>
|
||||
<minvalue>10000</minvalue>
|
||||
</option>
|
||||
<option name="user.chat.allowedAttachmentExtensions">
|
||||
<categoryname>user.chat</categoryname>
|
||||
<optiontype>textarea</optiontype>
|
||||
<defaultvalue><![CDATA[gif
|
||||
jpg
|
||||
jpeg
|
||||
png
|
||||
bmp
|
||||
zip
|
||||
txt
|
||||
pdf]]></defaultvalue>
|
||||
<options>module_attachment</options>
|
||||
<wildcard><![CDATA[*]]></wildcard>
|
||||
</option>
|
||||
<option name="mod.chat.canAlwaysEnter">
|
||||
<categoryname>mod.chat</categoryname>
|
||||
<optiontype>boolean</optiontype>
|
||||
|
Loading…
Reference in New Issue
Block a user