diff --git a/file/js/be.bastelstu.Chat.litcoffee b/file/js/be.bastelstu.Chat.litcoffee
index 8ad112a..1440f4c 100644
--- a/file/js/be.bastelstu.Chat.litcoffee
+++ b/file/js/be.bastelstu.Chat.litcoffee
@@ -37,6 +37,7 @@ exposed by a function if necessary.
current: {}
allTime: {}
currentRoom = {}
+ fileUploaded = no
errorVisible = false
inputErrorHidingTimer = null
@@ -809,35 +810,218 @@ Remove the given callback from the given event.
events[event].remove callback
true
-
- if WCF?.Attachment?.Upload?
+
+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'), $('
').appendTo('#content'), 'be.bastelstu.chat.message', 0, 0, 0, 1, null
+ @_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 = $ """"""
- @_fileUpload.change =>
- do @_upload
- button = $ """#{WCF.Language.get("wcf.global.button.upload")}"""
- button.prepend @_fileUpload
- else
- button = $ """#{WCF.Language.get("wcf.global.button.upload")}"""
- button.click =>
- do @_showOverlay
+ @_fileUpload = $ """"""
+ @_fileUpload.change => do @_upload
+ @_fileUpload.appendTo 'body'
- @_insertButton button
+ _removeButton: ->
+ do @_fileUpload.remove
- _insertButton: (button) ->
- @_super(button)
- @_buttonSelector.removeClass 'invisible'
+See WCF.Attachment.Upload._getParameters()
- _upload: ->
+ _getParameters: ->
@_tmpHash = do Math.random
- @_objectID = be.bastelstu.Chat.currentRoomID
+ @_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 = $("""-
+
+
+
+
"""
+ ).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
+ $('#timsChatUploadContainer').append """#{WCF.Language.get('wcf.attachment.upload.error.tooLarge')}"""
+
+ do @_error
+ li.addClass 'uploadFailed'
+ li
+
+ _validateLimit: ->
+ innerError = @_buttonSelector.next 'small.innerError'
+
+ if fileUploaded
+ # reached limit
+ unless innerError.length
+ 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 """
+
+
+
+ """
+
+ li.click (event) => @_insert(event)
+
+ filename = li.data 'filename'
+
+ if data.returnValues and data.returnValues.attachments[filename]
+ if data.returnValues.attachments[filename].tinyURL
+ li.find('.box32 > div.attachmentImageContainer > .icon-paper-clip').replaceWith $("""""")
+
+ link = $ ''
+ link.attr {'href': data.returnValues.attachments[filename].url, 'title': filename}
+
+ unless parseInt(data.returnValues.attachments[filename].isImage) is 0
+ link.addClass('jsImageViewer')
+
+ if !data.returnValues.attachments[filename].tinyURL
+ li.find('.box32 > div.attachmentImageContainer > .icon-paper-clip').replaceWith $("""""")
+
+ li.find('.attachmentTinyThumbnail').wrap link
+ li.find('small').append data.returnValues.attachments[filename].formattedFilesize
+
+ li.data 'objectID', data.returnValues.attachments[filename].attachmentID
+
+ deleteButton = $ """
+ -
+
+
+ #{WCF.Language.get('wcf.global.button.delete')}
+
+
"""
+ li.parent().append deleteButton
+ else
+ $('#timsChatUpload .icon-spinner').removeClass('icon-spinner').addClass 'icon-ban-circle'
+
+ if data.returnValues and data.returnValues.errors[filename]
+ errorMessage = data.returnValues.errors[filename].errorType
+ else
+ errorMessage = 'uploadFailed'
+
+ $('#timsChatUpload').addClass('uploadFailed').after """#{WCF.Language.get('wcf.attachment.upload.error.' + errorMessage)}"""
+ do $('#timsChatUploadDropdownMenu .sendAttachmentButton').remove
+ do $('#timsChatUploadDropdownMenu .uploadButton').show
+
+ do WCF.DOMNodeInsertedHandler.execute
+
+ fileUploaded = yes
+ $('#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'
+ $('#timsChatUpload').addClass('uploadFailed').after """#{WCF.Language.get('wcf.attachment.upload.error.uploadFailed')}"""
+
+ do $('#timsChatUploadDropdownMenu .uploadProgress').remove
+ do $('#timsChatUploadDropdownMenu .uploadButton').show
+
+ 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 =
@@ -847,11 +1031,11 @@ And finally export the public methods and variables.
insertText: insertText
freeTheFish: freeTheFish
join: join
- currentRoomID: currentRoom.roomID
listener:
add: addListener
remove: removeListener
Chat.Attachment = Attachment if Attachment?
+ Chat.Action = Action if Attachment?
window.be ?= {}
be.bastelstu ?= {}
diff --git a/file/lib/data/message/Message.class.php b/file/lib/data/message/Message.class.php
index 9464f31..5845cb1 100644
--- a/file/lib/data/message/Message.class.php
+++ b/file/lib/data/message/Message.class.php
@@ -3,6 +3,7 @@
use \chat\util\ChatUtil;
use \wcf\system\Regex;
use \wcf\system\WCF;
+use \wcf\system\bbcode\AttachmentBBCode;
/**
* Represents a chat message.
@@ -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('[attach]'. $message .'[/attach]', 0, 0, true, false);
+ break;
case self::TYPE_WHISPER:
case self::TYPE_NORMAL:
case self::TYPE_ME:
diff --git a/file/lib/data/message/MessageAction.class.php b/file/lib/data/message/MessageAction.class.php
index c85288a..223b6af 100644
--- a/file/lib/data/message/MessageAction.class.php
+++ b/file/lib/data/message/MessageAction.class.php
@@ -197,4 +197,76 @@ 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,
+ 'receiver' => null,
+ 'time' => TIME_NOW,
+ 'type' => Message::TYPE_ATTACHMENT,
+ 'message' => $this->parameters['objectID'],
+ 'enableSmilies' => 0,
+ 'enableHTML' => 0,
+ 'color1' => $this->parameters['userData']['color1'],
+ 'color2' => $this->parameters['userData']['color2'],
+ 'additionalData' => null
+ )
+ ));
+
+ $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);
+ }
}
diff --git a/file/lib/system/attachment/MessageAttachmentObjectType.class.php b/file/lib/system/attachment/MessageAttachmentObjectType.class.php
index 85c4e7d..c90fc5b 100644
--- a/file/lib/system/attachment/MessageAttachmentObjectType.class.php
+++ b/file/lib/system/attachment/MessageAttachmentObjectType.class.php
@@ -37,12 +37,19 @@ public function getMaxCount() {
* @see wcf\system\attachment\IAttachmentObjectType::canDownload()
*/
public function canDownload($objectID) {
- if ($objectID) {
+ // TODO get the room ID
+ /*if ($objectID) {
$room = \chat\data\room\RoomCache::getInstance()->getRoom($objectID);
if ($room && $room->canEnter()) return true;
}
- return false;
+ return false;*/
+
+ return true;
+ }
+
+ public function canPreview($objectID) {
+ return $this->canDownload($objectID);
}
/**
@@ -61,6 +68,7 @@ public function canUpload($objectID, $parentObjectID = 0) {
* @see wcf\system\attachment\IAttachmentObjectType::canDelete()
*/
public function canDelete($objectID) {
+ // TODO Allow attachments to be deleted in ACP
return false;
}
}
diff --git a/template/chat.tpl b/template/chat.tpl
index 0b24bde..c3383a8 100644
--- a/template/chat.tpl
+++ b/template/chat.tpl
@@ -34,7 +34,10 @@
// Boot the chat
{if MODULE_SMILEY}WCF.TabMenu.init();{/if}
- {if MODULE_ATTACHMENT}new be.bastelstu.Chat.Attachment();{/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}
@@ -127,7 +130,18 @@
*}- {lang}chat.general.smilies{/lang}
{*
- *}{*
+ *}{if MODULE_ATTACHMENT && $__wcf->session->getPermission('user.chat.canUploadAttachment')}{*
+ *}-
+
+
+ {lang}wcf.global.button.upload{/lang}
+
+
+
{/if}{*
*}- {lang}chat.general.clear{/lang}
{*
diff --git a/template/javascriptInclude.tpl b/template/javascriptInclude.tpl
index 95c7e9d..1fdc331 100644
--- a/template/javascriptInclude.tpl
+++ b/template/javascriptInclude.tpl
@@ -1,3 +1,3 @@
-{if MODULE_ATTACHMENT}{/if}
+{if MODULE_ATTACHMENT && $__wcf->session->getPermission('user.chat.canUploadAttachment')}{/if}
{event name='javascript'}