runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- - name: phpcs
- uses: chekalsky/phpcs-action@e269c2f264f400adcda7c6b24c8550302350d495
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:
- php-version: '8.0'
+ php-version: '8.1'
extensions: ctype, dom, exif, gd, gmp, hash, intl, json, libxml, mbstring, opcache, pcre, pdo, pdo_mysql, zlib
- tools: php-cs-fixer
+ tools: cs2pr, phpcs, php-cs-fixer
+ - name: phpcs
+ run: phpcs -n -q --report=checkstyle | cs2pr
- name: php-cs-fixer
run: php-cs-fixer fix --dry-run --diff
ts:
--- /dev/null
+name: d.ts Exporter
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: '37 15 * * 4'
+
+jobs:
+ export:
+ name: "Export (${{ matrix.branch }})"
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ branch:
+ - '6.0'
+ - 'master'
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ matrix.branch }}
+ - name: Determine commit
+ id: determine-commit
+ run: |
+ echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
+ - name: Set up node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: "18"
+ cache: "npm"
+ - run: npm install
+ - uses: actions/checkout@v4
+ with:
+ repository: WoltLab/d.ts
+ ssh-key: ${{ secrets.WOLTLAB_D_TS_DEPLOY_KEY }}
+ path: d.ts
+ ref: ${{ matrix.branch }}
+ - run: npx tsc --declaration --emitDeclarationOnly --outdir ./d.ts/
+ - name: Prepare git
+ run: |
+ git config --global user.name "WoltLab GmbH"
+ git config --global user.email "woltlab@woltlab.com"
+ - name: Push the update
+ run: |
+ set -x
+ cd d.ts/
+ git add .
+
+ if git diff --cached --quiet; then
+ exit 0
+ fi
+
+ git commit -m "Update ${{ github.repository }} definitions
+
+ Generated using:
+
+ npx tsc --declaration --emitDeclarationOnly --outdir ./d.ts/
+
+ from ${{ github.repository }}@${{ steps.determine-commit.outputs.sha }}"
+ git push
- "5.3"
- "5.4"
- "5.5"
+ - "6.0"
- master
pull_request:
- "5.3"
- "5.4"
- "5.5"
+ - "6.0"
- master
+ paths:
+ - '*.php'
pull_request:
+ paths:
+ - '*.php'
permissions:
contents: read
fail-fast: false
matrix:
php:
- - '7.2'
- - '7.3'
- - '7.4'
- - '8.0'
- '8.1'
+ - '8.2'
+ - '8.3'
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
branches:
- "5.4"
- "5.5"
+ - "6.0"
- master
pull_request:
return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
- '@PSR1' => true,
- '@PSR2' => true,
+ '@PER-CS2.0' => true,
+ 'single_line_empty_body' => false,
'array_push' => true,
'backtick_to_shell_exec' => true,
'non_printable_character' => ['use_escape_sequences_in_strings' => true],
- 'lowercase_static_reference' => true,
'magic_constant_casing' => true,
'magic_method_casing' => true,
'native_function_casing' => true,
'native_function_type_declaration_casing' => true,
'cast_spaces' => ['space' => 'none'],
- 'lowercase_cast' => true,
'no_unset_cast' => true,
- 'short_scalar_cast' => true,
'class_attributes_separation' => true,
- 'no_blank_lines_after_class_opening' => true,
'no_null_property_initialization' => true,
'self_accessor' => true,
'single_class_element_per_statement' => true,
- 'single_trait_insert_per_statement' => true,
'no_empty_comment' => true,
'single_line_comment_style' => ['comment_types' => ['hash']],
'native_function_invocation' => ['include' => ['@internal']],
'no_unreachable_default_argument_value' => true,
'nullable_type_declaration_for_default_null_value' => true,
- 'return_type_declaration' => true,
'static_lambda' => true,
'fully_qualified_strict_types' => true,
- 'no_leading_import_slash' => true,
'no_unused_imports' => true,
'ordered_imports' => true,
- 'declare_equal_normalize' => true,
'dir_constant' => true,
'explicit_indirect_variable' => true,
'function_to_constant' => true,
'clean_namespace' => true,
'no_leading_namespace_whitespace' => true,
- 'single_blank_line_before_namespace' => true,
'no_homoglyph_names' => true,
'operator_linebreak' => true,
'standardize_increment' => true,
'standardize_not_equals' => true,
- 'ternary_operator_spaces' => true,
'ternary_to_elvis_operator' => true,
'ternary_to_null_coalescing' => true,
'unary_operator_spaces' => true,
'array_indentation' => true,
'blank_line_before_statement' => ['statements' => ['return', 'exit']],
- 'compact_nullable_typehint' => true,
'method_chaining_indentation' => true,
'no_extra_blank_lines' => ['tokens' => ['case', 'continue', 'curly_brace_block', 'default', 'extra', 'parenthesis_brace_block', 'square_brace_block', 'switch', 'throw', 'use']],
'no_spaces_around_offset' => true,
<?xml version="1.0"?>
-<ruleset>
+<ruleset
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd"
+>
<file>files/</file>
<exclude-pattern>*/vendor/*</exclude-pattern>
<arg name="extensions" value="php" />
<?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/2019/fileDelete.xsd">
<delete>
+ <file>acp/database/update_com.woltlab.wcf.conversation_5.5_step1.php</file>
+ <file>acp/database/update_com.woltlab.wcf.conversation_5.5_step2.php</file>
<file>acp/install_com.woltlab.wcf.conversation.php</file>
<file>acp/install_com.woltlab.wcf.conversation_2.0.0.php</file>
<file>acp/update_com.woltlab.wcf.conversation_3.0_dropColumns.php</file>
<file>acp/update_com.woltlab.wcf.conversation_3.1_addColumn.php</file>
<file>acp/update_com.woltlab.wcf.conversation_5.2.php</file>
<file>acp/update_com.woltlab.wcf.conversation_5.4_deleteLanguageItems.php</file>
+ <file>acp/update_com.woltlab.wcf.conversation_5.5_cleanup_orphaned_attachments.php</file>
<file>js/WoltLab/Conversation/UI/Participant/Add.js</file>
<file>js/WoltLab/Conversation/Ui/Participant/Add.js</file>
<file>js/require.build.min.js</file>
+++ /dev/null
-<?php
-
-/**
- * @author Tim Duesterhus
- * @copyright 2001-2020 WoltLab GmbH
- * @license WoltLab License <http://www.woltlab.com/license-agreement.html>
- */
-
-// Reuse the install script to create the indices with the correct names.
-
-return require(__DIR__ . '/install_com.woltlab.wcf.conversation.php');
+++ /dev/null
-<?php
-
-/**
- * @author Tim Duesterhus
- * @copyright 2001-2021 WoltLab GmbH
- * @license WoltLab License <http://www.woltlab.com/license-agreement.html>
- */
-
-use wcf\system\database\table\index\DatabaseTableIndex;
-use wcf\system\database\table\index\DatabaseTablePrimaryIndex;
-use wcf\system\database\table\PartialDatabaseTable;
-
-// 1) Generate a blueprint to fill in the generated index names.
-
-$blueprint = [
- PartialDatabaseTable::create('wcf1_conversation')
- ->indices([
- // DatabaseTablePrimaryIndex::create()
- // ->columns(['conversationID']),
- DatabaseTableIndex::create()
- ->columns(['userID', 'isDraft']),
- ]),
- PartialDatabaseTable::create('wcf1_conversation_to_user')
- ->indices([
- DatabaseTableIndex::create()
- ->columns(['participantID', 'conversationID'])
- ->type(DatabaseTableIndex::UNIQUE_TYPE),
- // DatabaseTableIndex::create()
- // ->columns(['participantID', 'hideConversation']),
- ]),
- PartialDatabaseTable::create('wcf1_conversation_message')
- ->indices([
- // DatabaseTablePrimaryIndex::create()
- // ->columns(['messageID']),
- DatabaseTableIndex::create()
- ->columns(['conversationID', 'userID']),
- DatabaseTableIndex::create()
- ->columns(['ipAddress']),
- ]),
- PartialDatabaseTable::create('wcf1_conversation_label')
- ->indices([
- // DatabaseTablePrimaryIndex::create()
- // ->columns(['labelID']),
- ]),
- PartialDatabaseTable::create('wcf1_conversation_label_to_object')
- ->indices([
- DatabaseTableIndex::create()
- ->columns(['labelID', 'conversationID'])
- ->type(DatabaseTableIndex::UNIQUE_TYPE),
- ]),
-];
-
-// 2) Use this blueprint to recreate the index objects with ->generatedName() set to false.
-// Simply dropping the indices with ->generatedName() set to true does not work, because it will
-// also remove named indices as the fact that a name was generated does not persist to the database.
-
-$data = [];
-foreach ($blueprint as $blueprintTable) {
- $data[] = PartialDatabaseTable::create($blueprintTable->getName())
- ->indices(\array_map(static function ($index) {
- \assert($index instanceof DatabaseTableIndex);
-
- return DatabaseTableIndex::create($index->getName())
- ->columns($index->getColumns())
- ->type($index->getType())
- ->drop();
- }, $blueprintTable->getIndices()));
-}
-
-return $data;
+++ /dev/null
-<?php
-
-/**
- * Deletes orphaned attachments.
- *
- * @author Tim Duesterhus
- * @copyright 2001-2022 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core
- */
-
-use wcf\data\attachment\AttachmentAction;
-use wcf\data\object\type\ObjectTypeCache;
-use wcf\system\package\SplitNodeException;
-use wcf\system\WCF;
-
-$objectType = ObjectTypeCache::getInstance()
- ->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', 'com.woltlab.wcf.conversation.message');
-
-$sql = "SELECT attachmentID
- FROM wcf1_attachment
- WHERE objectTypeID = ?
- AND objectID NOT IN (
- SELECT messageID
- FROM wcf1_conversation_message
- )";
-$statement = WCF::getDB()->prepare($sql, 100);
-$statement->execute([$objectType->objectTypeID]);
-$attachmentIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
-
-if (empty($attachmentIDs)) {
- return;
-}
-
-(new AttachmentAction($attachmentIDs, 'delete'))->executeAction();
-
-// If we reached this location we processed at least one attachment.
-// If this was the final attachment the next iteration will abort this
-// script early, thus not splitting the node.
-throw new SplitNodeException();
switch (key) {
case 'close':
- $('<li><span class="icon icon16 fa-lock jsTooltip jsIconLock" title="' + WCF.Language.get('wcf.global.state.closed') + '" /></li>').prependTo($conversation.find('.statusIcons'));
+ $(`<li>
+ <span class="jsTooltip jsIconLock" title="${WCF.Language.get('wcf.global.state.closed')}">
+ <fa-icon size="16" name="lock"></fa-icon>
+ </span>
+ </li>`).prependTo($conversation.find('.statusIcons'));
this._attributes[conversationID].isClosed = 1;
break;
switch (key) {
case 'close':
- $('<li><span class="icon icon16 fa-lock jsIconLock" /> ' + WCF.Language.get('wcf.global.state.closed') + '</li>').appendTo(container);
+ $(`<li>
+ <fa-icon size="16" name="lock"></fa-icon>
+ ${WCF.Language.get('wcf.global.state.closed')}
+ </li>`).appendTo(container);
this._attributes[conversationID].isClosed = 1;
break;
var availableLabels = this.getAvailableLabels();
if (!labelList.length) {
- labelList = $('<li><span class="icon icon16 fa-tags"></span> <ul class="labelList"></ul></li>').prependTo(container);
+ labelList = $(`<li>
+ <fa-icon size="16" name="tags"></fa-icon>
+ <ul class="labelList"></ul>
+ </li>`).prependTo(container);
labelList = labelList.children('ul');
}
}
});
-/**
- * Provides methods to remove participants from conversations.
- *
- * @see WCF.Action.Delete
- * @deprecated 5.4 Handled via `WoltLabSuite/Core/Ui/Object/Action`.
- */
-WCF.Conversation.RemoveParticipant = WCF.Action.Delete.extend({
- /**
- * conversation id
- * @var integer
- */
- _conversationID: 0,
-
- /**
- * @see WCF.Action.Delete.init()
- */
- init: function(conversationID) {
- this._conversationID = conversationID;
- this._super('wcf\\data\\conversation\\ConversationAction', '.jsParticipant');
- },
-
- /**
- * @see WCF.Action.Delete._sendRequest()
- */
- _sendRequest: function(object) {
- this.proxy.setOption('data', {
- actionName: 'removeParticipant',
- className: this._className,
- objectIDs: [ this._conversationID ],
- parameters: {
- userID: $(object).data('objectID')
- }
- });
-
- this.proxy.sendRequest();
- },
-
- /**
- * @see WCF.Action.Delete._success()
- */
- _success: function(data, textStatus, jqXHR) {
- var $userID = data.returnValues.userID;
-
- for (var $index in this._containers) {
- var $container = $('#' + this._containers[$index]);
- if ($container.find('.jsDeleteButton').data('objectID') == $userID) {
- $container.find('.userLink').addClass('conversationLeft');
- $container.find('.jsDeleteButton').remove();
- }
- }
- }
-});
-
/**
* Namespace for label-related classes.
*/
}
});
-/**
- * Provides a flexible conversation preview.
- *
- * @see WCF.Popover
- * @deprecated 5.3 handled via `WoltLabSuite/Core/Controller/Popover`
- */
-WCF.Conversation.Preview = WCF.Popover.extend({
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * @see WCF.Popover.init()
- */
- init: function() {
- this._super('.conversationLink');
-
- // init proxy
- this._proxy = new WCF.Action.Proxy({
- showLoadingOverlay: false
- });
-
- WCF.DOMNodeInsertedHandler.addCallback('WCF.Conversation.Preview', $.proxy(this._initContainers, this));
- },
-
- /**
- * @see WCF.Popover._loadContent()
- */
- _loadContent: function() {
- var $link = $('#' + this._activeElementID);
-
- this._proxy.setOption('data', {
- actionName: 'getMessagePreview',
- className: 'wcf\\data\\conversation\\ConversationAction',
- objectIDs: [ $link.data('conversationID') ]
- });
-
- var $elementID = this._activeElementID;
- var self = this;
- this._proxy.setOption('success', function(data, textStatus, jqXHR) {
- self._insertContent($elementID, data.returnValues.template, true);
- });
- this._proxy.sendRequest();
- }
-});
-
-/**
- * Marks one conversation as read.
- */
-WCF.Conversation.MarkAsRead = Class.extend({
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * Initializes the mark as read for conversations.
- */
- init: function() {
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- $(document).on('dblclick', '.conversationList .new .columnAvatar', $.proxy(this._dblclick, this));
- },
-
- /**
- * Handles double clicks on avatar.
- *
- * @param object event
- */
- _dblclick: function(event) {
- this._proxy.setOption('data', {
- actionName: 'markAsRead',
- className: 'wcf\\data\\conversation\\ConversationAction',
- objectIDs: [ $(event.currentTarget).parents('ol:eq(0)').data('conversationID') ]
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Handles successful AJAX requests.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- $('.conversationList .new').each(function(index, element) {
- var $element = $(element);
- if (WCF.inArray($element.data('conversationID'), data.objectIDs)) {
- // remove new class
- $element.removeClass('new');
-
- // hide arrows
- $element.find('.firstNewPost').parent().remove();
-
- // remove event
- $element.find('.columnAvatar').off('dblclick');
- }
- });
- }
-});
-
-/**
- * Marks all conversations as read.
- */
-WCF.Conversation.MarkAllAsRead = Class.extend({
- /**
- * action proxy
- * @var WCF.Action.Proxy
- */
- _proxy: null,
-
- /**
- * Initializes the WCF.Conversation.MarkAllAsRead class.
- */
- init: function() {
- this._proxy = new WCF.Action.Proxy({
- success: $.proxy(this._success, this)
- });
-
- $('.markAllAsReadButton').click($.proxy(this._click, this));
- },
-
- /**
- * Handles clicks.
- *
- * @param object event
- */
- _click: function(event) {
- event.preventDefault();
-
- this._proxy.setOption('data', {
- actionName: 'markAllAsRead',
- className: 'wcf\\data\\conversation\\ConversationAction'
- });
- this._proxy.sendRequest();
- },
-
- /**
- * Marks all conversations as read.
- *
- * @param object data
- * @param string textStatus
- * @param jQuery jqXHR
- */
- _success: function(data, textStatus, jqXHR) {
- // fix dropdown
- WCF.System.Event.fireEvent('com.woltlab.wcf.conversation.userPanel', 'reset');
-
- // fix conversation list
- var $conversationList = $('.conversationList');
- $conversationList.find('.new').removeClass('new');
- $conversationList.find('.columnAvatar').off('dblclick');
-
- new WCF.System.Notification().show();
- }
-});
-
/**
* Namespace for conversation messages.
*/
return 'wcf\\data\\conversation\\message\\ConversationMessageAction';
}
});
-
-/**
- * @deprecated 5.5, use `WoltLabSuite/Core/Conversation/Ui/Message/Quote` instead
- */
-WCF.Conversation.Message.QuoteHandler = WCF.Message.Quote.Handler.extend({
- /**
- * @see WCF.Message.QuoteManager.init()
- */
- init: function(quoteManager) {
- require(["WoltLabSuite/Core/Conversation/Ui/Message/Quote"], ({ UiConversationMessageQuote }) => {
- new UiConversationMessageQuote(quoteManager);
- });
- }
-});
-WCF.Conversation={},WCF.Conversation.EditorHandler=Class.extend({_attributes:{},_conversations:{},_permissions:{},init:function(availableLabels){this._conversations={};var self=this;$(".conversation").each((function(index,conversation){var $labelIDs,$conversation=$(conversation),$conversationID=$conversation.data("conversationID");self._conversations[$conversationID]||(self._conversations[$conversationID]=$conversation,$labelIDs=eval($conversation.data("labelIDs")),self._attributes[$conversationID]={isClosed:!!$conversation.data("isClosed"),labelIDs:$labelIDs},self._permissions[$conversationID]={canAddParticipants:!!$conversation.data("canAddParticipants"),canCloseConversation:!!$conversation.data("canCloseConversation")})}))},getPermission:function(e,a){return void 0!==this._permissions[e][a]&&!!this._permissions[e][a]},getValue:function(e,a){switch(a){case"labelIDs":return void 0===this._attributes[e].labelIDs&&(this._attributes[e].labelIDs=[]),this._attributes[e].labelIDs;case"isClosed":return!!this._attributes[e].isClosed}},countAvailableLabels:function(){return this.getAvailableLabels().length},getAvailableLabels:function(){var e=[];return WCF.Dropdown.getDropdownMenu("conversationLabelFilter").children(".scrollableDropdownMenu").children("li").each((function(a,t){var n,s=$(t);if(s.hasClass("dropdownDivider"))return!1;n=s.find("span"),e.push({cssClassName:n.data("cssClassName"),labelID:n.data("labelID"),label:n.text()})})),e},update:function(e,a,t){var n,s,i,o,l,r;if(this._conversations[e]){switch(n=this._conversations[e],a){case"close":$('<li><span class="icon icon16 fa-lock jsTooltip jsIconLock" title="'+WCF.Language.get("wcf.global.state.closed")+'" /></li>').prependTo(n.find(".statusIcons")),this._attributes[e].isClosed=1;break;case"labelIDs":if(s={},WCF.Dropdown.getDropdownMenu("conversationLabelFilter").find("li > a > span").each((function(e,a){var t=$(a);s[t.data("labelID")]={cssClassName:t.data("cssClassName"),label:t.text(),url:t.parent().attr("href")}})),i=n.find(".columnSubject > .labelList"),t.length)for(i.length||(i=$('<ul class="labelList" />').prependTo(n.find(".columnSubject"))),i.empty(),o=0,l=t.length;o<l;o++)r=s[t[o]],$('<li><a href="'+r.url+'" class="badge label'+(r.cssClassName?" "+r.cssClassName:"")+'">'+WCF.String.escapeHTML(r.label)+"</a></li>").appendTo(i);else i.length&&i.remove();break;case"open":n.find(".statusIcons li").each((function(e,a){var t=$(a);if(t.children("span.jsIconLock").length)return t.remove(),!1})),this._attributes[e].isClosed=0}WCF.Clipboard.reload()}else console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '"+e+"'")}}),WCF.Conversation.EditorHandlerConversation=WCF.Conversation.EditorHandler.extend({_availableLabels:null,init:function(e){this._availableLabels=e||[],this._super()},getAvailableLabels:function(){return this._availableLabels},update:function(e,a,t){var n,s,i,o;if(this._conversations[e])switch(n=$(".contentHeaderTitle > .contentHeaderMetaData"),a){case"close":$('<li><span class="icon icon16 fa-lock jsIconLock" /> '+WCF.Language.get("wcf.global.state.closed")+"</li>").appendTo(n),this._attributes[e].isClosed=1;break;case"labelIDs":s=n.find(".labelList"),t.length?(i=this.getAvailableLabels(),s.length||(s=(s=$('<li><span class="icon icon16 fa-tags"></span> <ul class="labelList"></ul></li>').prependTo(n)).children("ul")),o="",t.forEach((function(e){i.forEach((function(a){a.labelID==e&&(o+='<li><span class="label badge'+(a.cssClassName?" "+a.cssClassName:"")+'">'+a.label+"</span></li>")}))})),s[0].innerHTML=o):s.parent().remove();break;case"open":n.find(".jsIconLock").parent().remove(),this._attributes[e].isClosed=0}else console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '"+e+"'")}}),WCF.Conversation.Clipboard=Class.extend({_editorHandler:null,init:function(e){this._editorHandler=e,WCF.System.Event.addListener("com.woltlab.wcf.clipboard","com.woltlab.wcf.conversation.conversation",function(e){null===e.responseData?this._execute(e.data.actionName,e.data.parameters):this._evaluateResponse(e.data.actionName,e.responseData)}.bind(this))},_execute:function(e,a){"com.woltlab.wcf.conversation.conversation.assignLabel"===e&&new WCF.Conversation.Label.Editor(this._editorHandler,null,a.objectIDs)},_evaluateResponse:function(e,a){var t,n;switch(e){case"com.woltlab.wcf.conversation.conversation.leave":case"com.woltlab.wcf.conversation.conversation.leavePermanently":case"com.woltlab.wcf.conversation.conversation.markAsRead":case"com.woltlab.wcf.conversation.conversation.restore":window.location.reload();break;case"com.woltlab.wcf.conversation.conversation.close":case"com.woltlab.wcf.conversation.conversation.open":for(t in a.returnValues.conversationData)a.returnValues.conversationData.hasOwnProperty(t)&&(n=a.returnValues.conversationData[t],this._editorHandler.update(t,n.isClosed?"close":"open",n))}}}),WCF.Conversation.InlineEditor=WCF.InlineEditor.extend({_editorHandler:null,_environment:"conversation",_setOptions:function(){this._options=[{label:WCF.Language.get("wcf.conversation.edit.subject"),optionName:"editSubject"},{label:WCF.Language.get("wcf.conversation.edit.close"),optionName:"close"},{label:WCF.Language.get("wcf.conversation.edit.open"),optionName:"open"},{label:WCF.Language.get("wcf.conversation.edit.assignLabel"),optionName:"assignLabel"},{optionName:"divider"},{label:WCF.Language.get("wcf.conversation.edit.addParticipants"),optionName:"addParticipants"},{label:WCF.Language.get("wcf.conversation.edit.leave"),optionName:"leave"},{label:WCF.Language.get("wcf.global.button.edit"),optionName:"edit",isQuickOption:!0}]},setEditorHandler:function(e,a){this._editorHandler=e,this._environment="list"==a?"list":"conversation"},_getTriggerElement:function(e){return e.find(".jsConversationInlineEditor")},_validate:function(e,a){var t=$("#"+e).data("conversationID");switch(a){case"addParticipants":return this._editorHandler.getPermission(t,"canAddParticipants");case"assignLabel":return!!this._editorHandler.countAvailableLabels();case"editSubject":return!!this._editorHandler.getPermission(t,"canCloseConversation");case"close":case"open":return!!this._editorHandler.getPermission(t,"canCloseConversation")&&("close"===a?!this._editorHandler.getValue(t,"isClosed"):this._editorHandler.getValue(t,"isClosed"));case"leave":return!0;case"edit":return!!$("#"+e).data("isDraft")}return!1},_execute:function(e,a){if(!this._validate(e,a))return!1;switch(a){case"addParticipants":require(["WoltLabSuite/Core/Conversation/Ui/Participant/Add"],(function(a){new a(elData(elById(e),"conversation-id"))}));break;case"assignLabel":new WCF.Conversation.Label.Editor(this._editorHandler,e);break;case"editSubject":require(["WoltLabSuite/Core/Conversation/Ui/Subject/Editor"],(function(a){a.beginEdit(elData(elById(e),"conversation-id"))}));break;case"close":case"open":this._updateConversation(e,a,{isClosed:"close"===a?1:0});break;case"leave":new WCF.Conversation.Leave([$("#"+e).data("conversationID")],this._environment);break;case"edit":window.location=this._getTriggerElement($("#"+e)).prop("href")}},_updateConversation:function(e,a,t){var n=this._elements[e].data("conversationID");switch(a){case"close":case"editSubject":case"open":this._updateData.push({elementID:e,optionName:a,data:t}),this._proxy.setOption("data",{actionName:a,className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[n]}),this._proxy.sendRequest()}},_updateState:function(){var e,a,t,n;for(e=0,a=this._updateData.length;e<a;e++)switch(t=this._updateData[e],n=this._elements[t.elementID].data("conversationID"),t.optionName){case"close":case"editSubject":case"open":this._editorHandler.update(n,t.optionName,t.data)}}}),WCF.Conversation.Leave=Class.extend({_conversationIDs:[],_dialog:null,_environment:"",_proxy:null,init:function(e,a){this._conversationIDs=e,this._dialog=null,this._environment=a,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._loadDialog()},_loadDialog:function(){this._proxy.setOption("data",{actionName:"getLeaveForm",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:this._conversationIDs}),this._proxy.sendRequest()},_success:function(e,a,t){switch(e.returnValues.actionName){case"getLeaveForm":this._showDialog(e);break;case"hideConversation":"conversation"===this._environment?window.location=e.returnValues.redirectURL:window.location.reload()}},_showDialog:function(e){null===this._dialog&&(this._dialog=$("#leaveDialog"),this._dialog.length||(this._dialog=$('<div id="leaveDialog" />').hide().appendTo(document.body))),this._dialog.html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.leave.title")}),this._dialog.wcfDialog("render"),this._dialog.find("#hideConversation").click($.proxy(this._click,this))},_click:function(){var e=this._dialog.find("input[type=radio]:checked");1===e.length&&(this._proxy.setOption("data",{actionName:"hideConversation",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:this._conversationIDs,parameters:{hideConversation:e.val()}}),this._proxy.sendRequest())}}),WCF.Conversation.RemoveParticipant=WCF.Action.Delete.extend({_conversationID:0,init:function(e){this._conversationID=e,this._super("wcf\\data\\conversation\\ConversationAction",".jsParticipant")},_sendRequest:function(e){this.proxy.setOption("data",{actionName:"removeParticipant",className:this._className,objectIDs:[this._conversationID],parameters:{userID:$(e).data("objectID")}}),this.proxy.sendRequest()},_success:function(e,a,t){var n,s,i=e.returnValues.userID;for(n in this._containers)(s=$("#"+this._containers[n])).find(".jsDeleteButton").data("objectID")==i&&(s.find(".userLink").addClass("conversationLeft"),s.find(".jsDeleteButton").remove())}}),WCF.Conversation.Label={},WCF.Conversation.Label.Editor=Class.extend({_conversationIDs:0,_dialog:null,_editorHandler:null,_notification:null,_proxy:null,init:function(e,a,t){this._conversationIDs=a?[$("#"+a).data("conversationID")]:t,this._dialog=null,this._editorHandler=e,this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success.edit")),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._loadDialog()},_loadDialog:function(){this._proxy.setOption("data",{actionName:"getLabelForm",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{conversationIDs:this._conversationIDs}}),this._proxy.sendRequest()},_success:function(e,a,t){switch(e.returnValues.actionName){case"assignLabel":this._assignLabels(e);break;case"getLabelForm":this._renderDialog(e)}},_renderDialog:function(e){null===this._dialog&&(this._dialog=$("#conversationLabelForm"),this._dialog.length||(this._dialog=$('<div id="conversationLabelForm" />').hide().appendTo(document.body))),this._dialog.html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.label.assignLabels")}),this._dialog.wcfDialog("render"),$("#assignLabels").click($.proxy(this._save,this))},_save:function(){var e=[];this._dialog.find("input").each((function(a,t){var n=$(t);n.is(":checked")&&e.push(n.data("labelID"))})),this._proxy.setOption("data",{actionName:"assignLabel",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{conversationIDs:this._conversationIDs,labelIDs:e}}),this._proxy.sendRequest()},_assignLabels:function(e){for(var a=0,t=this._conversationIDs.length;a<t;a++)this._editorHandler.update(this._conversationIDs[a],"labelIDs",e.returnValues.labelIDs);this._dialog.wcfDialog("close"),this._notification.show()}}),WCF.Conversation.Label.Manager=Class.extend({_deletedLabelID:0,_dialog:null,_labels:null,_link:"",_notification:"",_proxy:null,_maxLabels:0,_labelCount:0,init:function(e){this._deletedLabelID=0,this._maxLabels=0,this._labelCount=0,this._link=e,this._labels=WCF.Dropdown.getDropdownMenu("conversationLabelFilter").children(".scrollableDropdownMenu"),$("#manageLabel").click($.proxy(this._click,this)),this._notification=new WCF.System.Notification(WCF.Language.get("wcf.conversation.label.management.addLabel.success")),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},_click:function(){this._proxy.setOption("data",{actionName:"getLabelManagement",className:"wcf\\data\\conversation\\ConversationAction"}),this._proxy.sendRequest()},_success:function(e,a,t){if(null===this._dialog&&(this._dialog=$('<div id="labelManagement" />').hide().appendTo(document.body)),e.returnValues&&e.returnValues.actionName)switch(e.returnValues.actionName){case"add":this._insertLabel(e);break;case"getLabelManagement":this._maxLabels=parseInt(e.returnValues.maxLabels),this._labelCount=parseInt(e.returnValues.labelCount),this._dialog.empty().html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.label.management")}),this._dialog.wcfDialog("render"),this._bindListener()}else if(this._deletedLabelID){var n=new RegExp("(\\?|&)labelID="+this._deletedLabelID);window.location=window.location.toString().replace(n,"")}else window.location.reload()},_insertLabel:function(e){var a=$('<li><a href="'+this._link+"&labelID="+e.returnValues.labelID+'"><span class="badge label'+(e.returnValues.cssClassName?" "+e.returnValues.cssClassName:"")+'">'+e.returnValues.label+"</span></a></li>");a.find("a > span").data("labelID",e.returnValues.labelID).data("cssClassName",e.returnValues.cssClassName),this._labels.append(a),this._notification.show(),this._labelCount++,this._labelCount>=this._maxLabels&&$("#conversationLabelManagementForm").hide()},_bindListener:function(){$("#labelName").on("keyup keydown keypress",$.proxy(this._updateLabels,this)),$.browser.mozilla&&$.browser.touch&&$("#labelName").on("input",$.proxy(this._updateLabels,this)),this._labelCount>=this._maxLabels&&($("#conversationLabelManagementForm").hide(),this._dialog.wcfDialog("render")),$("#addLabel").disable().click($.proxy(this._addLabel,this)),$("#editLabel").disable(),this._dialog.find(".conversationLabelList a.label").click($.proxy(this._edit,this))},_edit:function(e){var a,t,n;this._labelCount>=this._maxLabels&&($("#conversationLabelManagementForm").show(),this._dialog.wcfDialog("render")),a=$(e.currentTarget),t=WCF.Language.get("wcf.conversation.label.management.editLabel").replace(/#labelName#/,WCF.String.escapeHTML(a.text())),$("#conversationLabelManagementForm").data("labelID",a.data("labelID")).children(".sectionTitle").html(t),$("#labelName").val(a.text()).trigger("keyup"),n=a.data("cssClassName"),$("#labelManagementList input").each((function(e,a){var t=$(a);t.val()==n&&t.attr("checked","checked")})),$("#addLabel").hide(),$("#editLabel").show().click($.proxy(this._editLabel,this)),$("#deleteLabel").show().click($.proxy(this._deleteLabel,this))},_editLabel:function(){this._proxy.setOption("data",{actionName:"update",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",objectIDs:[$("#conversationLabelManagementForm").data("labelID")],parameters:{data:{cssClassName:$("#labelManagementList input:checked").val(),label:$("#labelName").val()}}}),this._proxy.sendRequest()},_deleteLabel:function(){var e=WCF.Language.get("wcf.conversation.label.management.deleteLabel.confirmMessage").replace(/#labelName#/,$("#labelName").val());WCF.System.Confirmation.show(e,$.proxy((function(e){"confirm"===e&&(this._proxy.setOption("data",{actionName:"delete",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",objectIDs:[$("#conversationLabelManagementForm").data("labelID")]}),this._proxy.sendRequest(),this._deletedLabelID=$("#conversationLabelManagementForm").data("labelID"))}),this),void 0,void 0,!0)},_updateLabels:function(){var e=$.trim($("#labelName").val());e?$("#addLabel, #editLabel").enable():($("#addLabel, #editLabel").disable(),e=WCF.Language.get("wcf.conversation.label.placeholder")),$("#labelManagementList").find("span.label").text(e)},_addLabel:function(){var e=$("#labelName").val(),a=$("#labelManagementList input:checked").val();this._proxy.setOption("data",{actionName:"add",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{data:{cssClassName:a,labelName:e}}}),this._proxy.sendRequest(),this._dialog.wcfDialog("close")}}),WCF.Conversation.Preview=WCF.Popover.extend({_proxy:null,init:function(){this._super(".conversationLink"),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1}),WCF.DOMNodeInsertedHandler.addCallback("WCF.Conversation.Preview",$.proxy(this._initContainers,this))},_loadContent:function(){var e,a,t=$("#"+this._activeElementID);this._proxy.setOption("data",{actionName:"getMessagePreview",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[t.data("conversationID")]}),e=this._activeElementID,a=this,this._proxy.setOption("success",(function(t,n,s){a._insertContent(e,t.returnValues.template,!0)})),this._proxy.sendRequest()}}),WCF.Conversation.MarkAsRead=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(document).on("dblclick",".conversationList .new .columnAvatar",$.proxy(this._dblclick,this))},_dblclick:function(e){this._proxy.setOption("data",{actionName:"markAsRead",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[$(e.currentTarget).parents("ol:eq(0)").data("conversationID")]}),this._proxy.sendRequest()},_success:function(e,a,t){$(".conversationList .new").each((function(a,t){var n=$(t);WCF.inArray(n.data("conversationID"),e.objectIDs)&&(n.removeClass("new"),n.find(".firstNewPost").parent().remove(),n.find(".columnAvatar").off("dblclick"))}))}}),WCF.Conversation.MarkAllAsRead=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".markAllAsReadButton").click($.proxy(this._click,this))},_click:function(e){e.preventDefault(),this._proxy.setOption("data",{actionName:"markAllAsRead",className:"wcf\\data\\conversation\\ConversationAction"}),this._proxy.sendRequest()},_success:function(e,a,t){WCF.System.Event.fireEvent("com.woltlab.wcf.conversation.userPanel","reset");var n=$(".conversationList");n.find(".new").removeClass("new"),n.find(".columnAvatar").off("dblclick"),(new WCF.System.Notification).show()}}),WCF.Conversation.Message={},WCF.Conversation.Message.InlineEditor=WCF.Message.InlineEditor.extend({init:function(e,a){this._super(e,!0,a)},_getClassName:function(){return"wcf\\data\\conversation\\message\\ConversationMessageAction"}}),WCF.Conversation.Message.QuoteHandler=WCF.Message.Quote.Handler.extend({init:function(e){require(["WoltLabSuite/Core/Conversation/Ui/Message/Quote"],(({UiConversationMessageQuote:a})=>{new a(e)}))}});
\ No newline at end of file
+WCF.Conversation={},WCF.Conversation.EditorHandler=Class.extend({_attributes:{},_conversations:{},_permissions:{},init:function(availableLabels){this._conversations={};var self=this;$(".conversation").each((function(index,conversation){var $labelIDs,$conversation=$(conversation),$conversationID=$conversation.data("conversationID");self._conversations[$conversationID]||(self._conversations[$conversationID]=$conversation,$labelIDs=eval($conversation.data("labelIDs")),self._attributes[$conversationID]={isClosed:!!$conversation.data("isClosed"),labelIDs:$labelIDs},self._permissions[$conversationID]={canAddParticipants:!!$conversation.data("canAddParticipants"),canCloseConversation:!!$conversation.data("canCloseConversation")})}))},getPermission:function(e,a){return void 0!==this._permissions[e][a]&&!!this._permissions[e][a]},getValue:function(e,a){switch(a){case"labelIDs":return void 0===this._attributes[e].labelIDs&&(this._attributes[e].labelIDs=[]),this._attributes[e].labelIDs;case"isClosed":return!!this._attributes[e].isClosed}},countAvailableLabels:function(){return this.getAvailableLabels().length},getAvailableLabels:function(){var e=[];return WCF.Dropdown.getDropdownMenu("conversationLabelFilter").children(".scrollableDropdownMenu").children("li").each((function(a,t){var n,s=$(t);if(s.hasClass("dropdownDivider"))return!1;n=s.find("span"),e.push({cssClassName:n.data("cssClassName"),labelID:n.data("labelID"),label:n.text()})})),e},update:function(e,a,t){var n,s,i,o,l,r;if(this._conversations[e]){switch(n=this._conversations[e],a){case"close":$(`<li>\n\t\t\t\t\t<span class="jsTooltip jsIconLock" title="${WCF.Language.get("wcf.global.state.closed")}">\n\t\t\t\t\t\t<fa-icon size="16" name="lock"></fa-icon>\n\t\t\t\t\t</span>\n\t\t\t\t</li>`).prependTo(n.find(".statusIcons")),this._attributes[e].isClosed=1;break;case"labelIDs":if(s={},WCF.Dropdown.getDropdownMenu("conversationLabelFilter").find("li > a > span").each((function(e,a){var t=$(a);s[t.data("labelID")]={cssClassName:t.data("cssClassName"),label:t.text(),url:t.parent().attr("href")}})),i=n.find(".columnSubject > .labelList"),t.length)for(i.length||(i=$('<ul class="labelList" />').prependTo(n.find(".columnSubject"))),i.empty(),o=0,l=t.length;o<l;o++)r=s[t[o]],$('<li><a href="'+r.url+'" class="badge label'+(r.cssClassName?" "+r.cssClassName:"")+'">'+WCF.String.escapeHTML(r.label)+"</a></li>").appendTo(i);else i.length&&i.remove();break;case"open":n.find(".statusIcons li").each((function(e,a){var t=$(a);if(t.children("span.jsIconLock").length)return t.remove(),!1})),this._attributes[e].isClosed=0}WCF.Clipboard.reload()}else console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '"+e+"'")}}),WCF.Conversation.EditorHandlerConversation=WCF.Conversation.EditorHandler.extend({_availableLabels:null,init:function(e){this._availableLabels=e||[],this._super()},getAvailableLabels:function(){return this._availableLabels},update:function(e,a,t){var n,s,i,o;if(this._conversations[e])switch(n=$(".contentHeaderTitle > .contentHeaderMetaData"),a){case"close":$(`<li>\n\t\t\t\t\t<fa-icon size="16" name="lock"></fa-icon>\n\t\t\t\t\t${WCF.Language.get("wcf.global.state.closed")}\n\t\t\t\t</li>`).appendTo(n),this._attributes[e].isClosed=1;break;case"labelIDs":s=n.find(".labelList"),t.length?(i=this.getAvailableLabels(),s.length||(s=(s=$('<li>\n\t\t\t\t\t\t\t<fa-icon size="16" name="tags"></fa-icon>\n\t\t\t\t\t\t\t<ul class="labelList"></ul>\n\t\t\t\t\t\t</li>').prependTo(n)).children("ul")),o="",t.forEach((function(e){i.forEach((function(a){a.labelID==e&&(o+='<li><span class="label badge'+(a.cssClassName?" "+a.cssClassName:"")+'">'+a.label+"</span></li>")}))})),s[0].innerHTML=o):s.parent().remove();break;case"open":n.find(".jsIconLock").parent().remove(),this._attributes[e].isClosed=0}else console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '"+e+"'")}}),WCF.Conversation.Clipboard=Class.extend({_editorHandler:null,init:function(e){this._editorHandler=e,WCF.System.Event.addListener("com.woltlab.wcf.clipboard","com.woltlab.wcf.conversation.conversation",function(e){null===e.responseData?this._execute(e.data.actionName,e.data.parameters):this._evaluateResponse(e.data.actionName,e.responseData)}.bind(this))},_execute:function(e,a){"com.woltlab.wcf.conversation.conversation.assignLabel"===e&&new WCF.Conversation.Label.Editor(this._editorHandler,null,a.objectIDs)},_evaluateResponse:function(e,a){var t,n;switch(e){case"com.woltlab.wcf.conversation.conversation.leave":case"com.woltlab.wcf.conversation.conversation.leavePermanently":case"com.woltlab.wcf.conversation.conversation.markAsRead":case"com.woltlab.wcf.conversation.conversation.restore":window.location.reload();break;case"com.woltlab.wcf.conversation.conversation.close":case"com.woltlab.wcf.conversation.conversation.open":for(t in a.returnValues.conversationData)a.returnValues.conversationData.hasOwnProperty(t)&&(n=a.returnValues.conversationData[t],this._editorHandler.update(t,n.isClosed?"close":"open",n))}}}),WCF.Conversation.InlineEditor=WCF.InlineEditor.extend({_editorHandler:null,_environment:"conversation",_setOptions:function(){this._options=[{label:WCF.Language.get("wcf.conversation.edit.subject"),optionName:"editSubject"},{label:WCF.Language.get("wcf.conversation.edit.close"),optionName:"close"},{label:WCF.Language.get("wcf.conversation.edit.open"),optionName:"open"},{label:WCF.Language.get("wcf.conversation.edit.assignLabel"),optionName:"assignLabel"},{optionName:"divider"},{label:WCF.Language.get("wcf.conversation.edit.addParticipants"),optionName:"addParticipants"},{label:WCF.Language.get("wcf.conversation.edit.leave"),optionName:"leave"},{label:WCF.Language.get("wcf.global.button.edit"),optionName:"edit",isQuickOption:!0}]},setEditorHandler:function(e,a){this._editorHandler=e,this._environment="list"==a?"list":"conversation"},_getTriggerElement:function(e){return e.find(".jsConversationInlineEditor")},_validate:function(e,a){var t=$("#"+e).data("conversationID");switch(a){case"addParticipants":return this._editorHandler.getPermission(t,"canAddParticipants");case"assignLabel":return!!this._editorHandler.countAvailableLabels();case"editSubject":return!!this._editorHandler.getPermission(t,"canCloseConversation");case"close":case"open":return!!this._editorHandler.getPermission(t,"canCloseConversation")&&("close"===a?!this._editorHandler.getValue(t,"isClosed"):this._editorHandler.getValue(t,"isClosed"));case"leave":return!0;case"edit":return!!$("#"+e).data("isDraft")}return!1},_execute:function(e,a){if(!this._validate(e,a))return!1;switch(a){case"addParticipants":require(["WoltLabSuite/Core/Conversation/Ui/Participant/Add"],(function(a){new a(elData(elById(e),"conversation-id"))}));break;case"assignLabel":new WCF.Conversation.Label.Editor(this._editorHandler,e);break;case"editSubject":require(["WoltLabSuite/Core/Conversation/Ui/Subject/Editor"],(function(a){a.beginEdit(elData(elById(e),"conversation-id"))}));break;case"close":case"open":this._updateConversation(e,a,{isClosed:"close"===a?1:0});break;case"leave":new WCF.Conversation.Leave([$("#"+e).data("conversationID")],this._environment);break;case"edit":window.location=this._getTriggerElement($("#"+e)).prop("href")}},_updateConversation:function(e,a,t){var n=this._elements[e].data("conversationID");switch(a){case"close":case"editSubject":case"open":this._updateData.push({elementID:e,optionName:a,data:t}),this._proxy.setOption("data",{actionName:a,className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[n]}),this._proxy.sendRequest()}},_updateState:function(){var e,a,t,n;for(e=0,a=this._updateData.length;e<a;e++)switch(t=this._updateData[e],n=this._elements[t.elementID].data("conversationID"),t.optionName){case"close":case"editSubject":case"open":this._editorHandler.update(n,t.optionName,t.data)}}}),WCF.Conversation.Leave=Class.extend({_conversationIDs:[],_dialog:null,_environment:"",_proxy:null,init:function(e,a){this._conversationIDs=e,this._dialog=null,this._environment=a,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._loadDialog()},_loadDialog:function(){this._proxy.setOption("data",{actionName:"getLeaveForm",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:this._conversationIDs}),this._proxy.sendRequest()},_success:function(e,a,t){switch(e.returnValues.actionName){case"getLeaveForm":this._showDialog(e);break;case"hideConversation":"conversation"===this._environment?window.location=e.returnValues.redirectURL:window.location.reload()}},_showDialog:function(e){null===this._dialog&&(this._dialog=$("#leaveDialog"),this._dialog.length||(this._dialog=$('<div id="leaveDialog" />').hide().appendTo(document.body))),this._dialog.html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.leave.title")}),this._dialog.wcfDialog("render"),this._dialog.find("#hideConversation").click($.proxy(this._click,this))},_click:function(){var e=this._dialog.find("input[type=radio]:checked");1===e.length&&(this._proxy.setOption("data",{actionName:"hideConversation",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:this._conversationIDs,parameters:{hideConversation:e.val()}}),this._proxy.sendRequest())}}),WCF.Conversation.Label={},WCF.Conversation.Label.Editor=Class.extend({_conversationIDs:0,_dialog:null,_editorHandler:null,_notification:null,_proxy:null,init:function(e,a,t){this._conversationIDs=a?[$("#"+a).data("conversationID")]:t,this._dialog=null,this._editorHandler=e,this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success.edit")),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._loadDialog()},_loadDialog:function(){this._proxy.setOption("data",{actionName:"getLabelForm",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{conversationIDs:this._conversationIDs}}),this._proxy.sendRequest()},_success:function(e,a,t){switch(e.returnValues.actionName){case"assignLabel":this._assignLabels(e);break;case"getLabelForm":this._renderDialog(e)}},_renderDialog:function(e){null===this._dialog&&(this._dialog=$("#conversationLabelForm"),this._dialog.length||(this._dialog=$('<div id="conversationLabelForm" />').hide().appendTo(document.body))),this._dialog.html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.label.assignLabels")}),this._dialog.wcfDialog("render"),$("#assignLabels").click($.proxy(this._save,this))},_save:function(){var e=[];this._dialog.find("input").each((function(a,t){var n=$(t);n.is(":checked")&&e.push(n.data("labelID"))})),this._proxy.setOption("data",{actionName:"assignLabel",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{conversationIDs:this._conversationIDs,labelIDs:e}}),this._proxy.sendRequest()},_assignLabels:function(e){for(var a=0,t=this._conversationIDs.length;a<t;a++)this._editorHandler.update(this._conversationIDs[a],"labelIDs",e.returnValues.labelIDs);this._dialog.wcfDialog("close"),this._notification.show()}}),WCF.Conversation.Label.Manager=Class.extend({_deletedLabelID:0,_dialog:null,_labels:null,_link:"",_notification:"",_proxy:null,_maxLabels:0,_labelCount:0,init:function(e){this._deletedLabelID=0,this._maxLabels=0,this._labelCount=0,this._link=e,this._labels=WCF.Dropdown.getDropdownMenu("conversationLabelFilter").children(".scrollableDropdownMenu"),$("#manageLabel").click($.proxy(this._click,this)),this._notification=new WCF.System.Notification(WCF.Language.get("wcf.conversation.label.management.addLabel.success")),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},_click:function(){this._proxy.setOption("data",{actionName:"getLabelManagement",className:"wcf\\data\\conversation\\ConversationAction"}),this._proxy.sendRequest()},_success:function(e,a,t){if(null===this._dialog&&(this._dialog=$('<div id="labelManagement" />').hide().appendTo(document.body)),e.returnValues&&e.returnValues.actionName)switch(e.returnValues.actionName){case"add":this._insertLabel(e);break;case"getLabelManagement":this._maxLabels=parseInt(e.returnValues.maxLabels),this._labelCount=parseInt(e.returnValues.labelCount),this._dialog.empty().html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.label.management")}),this._dialog.wcfDialog("render"),this._bindListener()}else if(this._deletedLabelID){var n=new RegExp("(\\?|&)labelID="+this._deletedLabelID);window.location=window.location.toString().replace(n,"")}else window.location.reload()},_insertLabel:function(e){var a=$('<li><a href="'+this._link+"&labelID="+e.returnValues.labelID+'"><span class="badge label'+(e.returnValues.cssClassName?" "+e.returnValues.cssClassName:"")+'">'+e.returnValues.label+"</span></a></li>");a.find("a > span").data("labelID",e.returnValues.labelID).data("cssClassName",e.returnValues.cssClassName),this._labels.append(a),this._notification.show(),this._labelCount++,this._labelCount>=this._maxLabels&&$("#conversationLabelManagementForm").hide()},_bindListener:function(){$("#labelName").on("keyup keydown keypress",$.proxy(this._updateLabels,this)),$.browser.mozilla&&$.browser.touch&&$("#labelName").on("input",$.proxy(this._updateLabels,this)),this._labelCount>=this._maxLabels&&($("#conversationLabelManagementForm").hide(),this._dialog.wcfDialog("render")),$("#addLabel").disable().click($.proxy(this._addLabel,this)),$("#editLabel").disable(),this._dialog.find(".conversationLabelList a.label").click($.proxy(this._edit,this))},_edit:function(e){var a,t,n;this._labelCount>=this._maxLabels&&($("#conversationLabelManagementForm").show(),this._dialog.wcfDialog("render")),a=$(e.currentTarget),t=WCF.Language.get("wcf.conversation.label.management.editLabel").replace(/#labelName#/,WCF.String.escapeHTML(a.text())),$("#conversationLabelManagementForm").data("labelID",a.data("labelID")).children(".sectionTitle").html(t),$("#labelName").val(a.text()).trigger("keyup"),n=a.data("cssClassName"),$("#labelManagementList input").each((function(e,a){var t=$(a);t.val()==n&&t.attr("checked","checked")})),$("#addLabel").hide(),$("#editLabel").show().click($.proxy(this._editLabel,this)),$("#deleteLabel").show().click($.proxy(this._deleteLabel,this))},_editLabel:function(){this._proxy.setOption("data",{actionName:"update",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",objectIDs:[$("#conversationLabelManagementForm").data("labelID")],parameters:{data:{cssClassName:$("#labelManagementList input:checked").val(),label:$("#labelName").val()}}}),this._proxy.sendRequest()},_deleteLabel:function(){var e=WCF.Language.get("wcf.conversation.label.management.deleteLabel.confirmMessage").replace(/#labelName#/,$("#labelName").val());WCF.System.Confirmation.show(e,$.proxy((function(e){"confirm"===e&&(this._proxy.setOption("data",{actionName:"delete",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",objectIDs:[$("#conversationLabelManagementForm").data("labelID")]}),this._proxy.sendRequest(),this._deletedLabelID=$("#conversationLabelManagementForm").data("labelID"))}),this),void 0,void 0,!0)},_updateLabels:function(){var e=$.trim($("#labelName").val());e?$("#addLabel, #editLabel").enable():($("#addLabel, #editLabel").disable(),e=WCF.Language.get("wcf.conversation.label.placeholder")),$("#labelManagementList").find("span.label").text(e)},_addLabel:function(){var e=$("#labelName").val(),a=$("#labelManagementList input:checked").val();this._proxy.setOption("data",{actionName:"add",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{data:{cssClassName:a,labelName:e}}}),this._proxy.sendRequest(),this._dialog.wcfDialog("close")}}),WCF.Conversation.Message={},WCF.Conversation.Message.InlineEditor=WCF.Message.InlineEditor.extend({init:function(e,a){this._super(e,!0,a)},_getClassName:function(){return"wcf\\data\\conversation\\message\\ConversationMessageAction"}});
\ No newline at end of file
-WCF.Conversation={},WCF.Conversation.EditorHandler=Class.extend({_attributes:{},_conversations:{},_permissions:{},init:function(availableLabels){this._conversations={};var self=this;$(".conversation").each((function(index,conversation){var $labelIDs,$conversation=$(conversation),$conversationID=$conversation.data("conversationID");self._conversations[$conversationID]||(self._conversations[$conversationID]=$conversation,$labelIDs=eval($conversation.data("labelIDs")),self._attributes[$conversationID]={isClosed:!!$conversation.data("isClosed"),labelIDs:$labelIDs},self._permissions[$conversationID]={canAddParticipants:!!$conversation.data("canAddParticipants"),canCloseConversation:!!$conversation.data("canCloseConversation")})}))},getPermission:function(e,a){return void 0!==this._permissions[e][a]&&!!this._permissions[e][a]},getValue:function(e,a){switch(a){case"labelIDs":return void 0===this._attributes[e].labelIDs&&(this._attributes[e].labelIDs=[]),this._attributes[e].labelIDs;case"isClosed":return!!this._attributes[e].isClosed}},countAvailableLabels:function(){return this.getAvailableLabels().length},getAvailableLabels:function(){var e=[];return WCF.Dropdown.getDropdownMenu("conversationLabelFilter").children(".scrollableDropdownMenu").children("li").each((function(a,t){var n,s=$(t);if(s.hasClass("dropdownDivider"))return!1;n=s.find("span"),e.push({cssClassName:n.data("cssClassName"),labelID:n.data("labelID"),label:n.text()})})),e},update:function(e,a,t){var n,s,i,o,l,r;if(this._conversations[e]){switch(n=this._conversations[e],a){case"close":$('<li><span class="icon icon16 fa-lock jsTooltip jsIconLock" title="'+WCF.Language.get("wcf.global.state.closed")+'" /></li>').prependTo(n.find(".statusIcons")),this._attributes[e].isClosed=1;break;case"labelIDs":if(s={},WCF.Dropdown.getDropdownMenu("conversationLabelFilter").find("li > a > span").each((function(e,a){var t=$(a);s[t.data("labelID")]={cssClassName:t.data("cssClassName"),label:t.text(),url:t.parent().attr("href")}})),i=n.find(".columnSubject > .labelList"),t.length)for(i.length||(i=$('<ul class="labelList" />').prependTo(n.find(".columnSubject"))),i.empty(),o=0,l=t.length;o<l;o++)r=s[t[o]],$('<li><a href="'+r.url+'" class="badge label'+(r.cssClassName?" "+r.cssClassName:"")+'">'+WCF.String.escapeHTML(r.label)+"</a></li>").appendTo(i);else i.length&&i.remove();break;case"open":n.find(".statusIcons li").each((function(e,a){var t=$(a);if(t.children("span.jsIconLock").length)return t.remove(),!1})),this._attributes[e].isClosed=0}WCF.Clipboard.reload()}else console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '"+e+"'")}}),WCF.Conversation.EditorHandlerConversation=WCF.Conversation.EditorHandler.extend({_availableLabels:null,init:function(e){this._availableLabels=e||[],this._super()},getAvailableLabels:function(){return this._availableLabels},update:function(e,a,t){var n,s,i,o;if(this._conversations[e])switch(n=$(".contentHeaderTitle > .contentHeaderMetaData"),a){case"close":$('<li><span class="icon icon16 fa-lock jsIconLock" /> '+WCF.Language.get("wcf.global.state.closed")+"</li>").appendTo(n),this._attributes[e].isClosed=1;break;case"labelIDs":s=n.find(".labelList"),t.length?(i=this.getAvailableLabels(),s.length||(s=(s=$('<li><span class="icon icon16 fa-tags"></span> <ul class="labelList"></ul></li>').prependTo(n)).children("ul")),o="",t.forEach((function(e){i.forEach((function(a){a.labelID==e&&(o+='<li><span class="label badge'+(a.cssClassName?" "+a.cssClassName:"")+'">'+a.label+"</span></li>")}))})),s[0].innerHTML=o):s.parent().remove();break;case"open":n.find(".jsIconLock").parent().remove(),this._attributes[e].isClosed=0}else console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '"+e+"'")}}),WCF.Conversation.Clipboard=Class.extend({_editorHandler:null,init:function(e){this._editorHandler=e,WCF.System.Event.addListener("com.woltlab.wcf.clipboard","com.woltlab.wcf.conversation.conversation",function(e){null===e.responseData?this._execute(e.data.actionName,e.data.parameters):this._evaluateResponse(e.data.actionName,e.responseData)}.bind(this))},_execute:function(e,a){"com.woltlab.wcf.conversation.conversation.assignLabel"===e&&new WCF.Conversation.Label.Editor(this._editorHandler,null,a.objectIDs)},_evaluateResponse:function(e,a){var t,n;switch(e){case"com.woltlab.wcf.conversation.conversation.leave":case"com.woltlab.wcf.conversation.conversation.leavePermanently":case"com.woltlab.wcf.conversation.conversation.markAsRead":case"com.woltlab.wcf.conversation.conversation.restore":window.location.reload();break;case"com.woltlab.wcf.conversation.conversation.close":case"com.woltlab.wcf.conversation.conversation.open":for(t in a.returnValues.conversationData)a.returnValues.conversationData.hasOwnProperty(t)&&(n=a.returnValues.conversationData[t],this._editorHandler.update(t,n.isClosed?"close":"open",n))}}}),WCF.Conversation.InlineEditor=WCF.InlineEditor.extend({_editorHandler:null,_environment:"conversation",_setOptions:function(){this._options=[{label:WCF.Language.get("wcf.conversation.edit.subject"),optionName:"editSubject"},{label:WCF.Language.get("wcf.conversation.edit.close"),optionName:"close"},{label:WCF.Language.get("wcf.conversation.edit.open"),optionName:"open"},{label:WCF.Language.get("wcf.conversation.edit.assignLabel"),optionName:"assignLabel"},{optionName:"divider"},{label:WCF.Language.get("wcf.conversation.edit.addParticipants"),optionName:"addParticipants"},{label:WCF.Language.get("wcf.conversation.edit.leave"),optionName:"leave"},{label:WCF.Language.get("wcf.global.button.edit"),optionName:"edit",isQuickOption:!0}]},setEditorHandler:function(e,a){this._editorHandler=e,this._environment="list"==a?"list":"conversation"},_getTriggerElement:function(e){return e.find(".jsConversationInlineEditor")},_validate:function(e,a){var t=$("#"+e).data("conversationID");switch(a){case"addParticipants":return this._editorHandler.getPermission(t,"canAddParticipants");case"assignLabel":return!!this._editorHandler.countAvailableLabels();case"editSubject":return!!this._editorHandler.getPermission(t,"canCloseConversation");case"close":case"open":return!!this._editorHandler.getPermission(t,"canCloseConversation")&&("close"===a?!this._editorHandler.getValue(t,"isClosed"):this._editorHandler.getValue(t,"isClosed"));case"leave":return!0;case"edit":return!!$("#"+e).data("isDraft")}return!1},_execute:function(e,a){if(!this._validate(e,a))return!1;switch(a){case"addParticipants":require(["WoltLabSuite/Core/Conversation/Ui/Participant/Add"],(function(a){new a(elData(elById(e),"conversation-id"))}));break;case"assignLabel":new WCF.Conversation.Label.Editor(this._editorHandler,e);break;case"editSubject":require(["WoltLabSuite/Core/Conversation/Ui/Subject/Editor"],(function(a){a.beginEdit(elData(elById(e),"conversation-id"))}));break;case"close":case"open":this._updateConversation(e,a,{isClosed:"close"===a?1:0});break;case"leave":new WCF.Conversation.Leave([$("#"+e).data("conversationID")],this._environment);break;case"edit":window.location=this._getTriggerElement($("#"+e)).prop("href")}},_updateConversation:function(e,a,t){var n=this._elements[e].data("conversationID");switch(a){case"close":case"editSubject":case"open":this._updateData.push({elementID:e,optionName:a,data:t}),this._proxy.setOption("data",{actionName:a,className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[n]}),this._proxy.sendRequest()}},_updateState:function(){var e,a,t,n;for(e=0,a=this._updateData.length;e<a;e++)switch(t=this._updateData[e],n=this._elements[t.elementID].data("conversationID"),t.optionName){case"close":case"editSubject":case"open":this._editorHandler.update(n,t.optionName,t.data)}}}),WCF.Conversation.Leave=Class.extend({_conversationIDs:[],_dialog:null,_environment:"",_proxy:null,init:function(e,a){this._conversationIDs=e,this._dialog=null,this._environment=a,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._loadDialog()},_loadDialog:function(){this._proxy.setOption("data",{actionName:"getLeaveForm",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:this._conversationIDs}),this._proxy.sendRequest()},_success:function(e,a,t){switch(e.returnValues.actionName){case"getLeaveForm":this._showDialog(e);break;case"hideConversation":"conversation"===this._environment?window.location=e.returnValues.redirectURL:window.location.reload()}},_showDialog:function(e){null===this._dialog&&(this._dialog=$("#leaveDialog"),this._dialog.length||(this._dialog=$('<div id="leaveDialog" />').hide().appendTo(document.body))),this._dialog.html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.leave.title")}),this._dialog.wcfDialog("render"),this._dialog.find("#hideConversation").click($.proxy(this._click,this))},_click:function(){var e=this._dialog.find("input[type=radio]:checked");1===e.length&&(this._proxy.setOption("data",{actionName:"hideConversation",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:this._conversationIDs,parameters:{hideConversation:e.val()}}),this._proxy.sendRequest())}}),WCF.Conversation.RemoveParticipant=WCF.Action.Delete.extend({_conversationID:0,init:function(e){this._conversationID=e,this._super("wcf\\data\\conversation\\ConversationAction",".jsParticipant")},_sendRequest:function(e){this.proxy.setOption("data",{actionName:"removeParticipant",className:this._className,objectIDs:[this._conversationID],parameters:{userID:$(e).data("objectID")}}),this.proxy.sendRequest()},_success:function(e,a,t){var n,s,i=e.returnValues.userID;for(n in this._containers)(s=$("#"+this._containers[n])).find(".jsDeleteButton").data("objectID")==i&&(s.find(".userLink").addClass("conversationLeft"),s.find(".jsDeleteButton").remove())}}),WCF.Conversation.Label={},WCF.Conversation.Label.Editor=Class.extend({_conversationIDs:0,_dialog:null,_editorHandler:null,_notification:null,_proxy:null,init:function(e,a,t){this._conversationIDs=a?[$("#"+a).data("conversationID")]:t,this._dialog=null,this._editorHandler=e,this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success.edit")),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._loadDialog()},_loadDialog:function(){this._proxy.setOption("data",{actionName:"getLabelForm",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{conversationIDs:this._conversationIDs}}),this._proxy.sendRequest()},_success:function(e,a,t){switch(e.returnValues.actionName){case"assignLabel":this._assignLabels(e);break;case"getLabelForm":this._renderDialog(e)}},_renderDialog:function(e){null===this._dialog&&(this._dialog=$("#conversationLabelForm"),this._dialog.length||(this._dialog=$('<div id="conversationLabelForm" />').hide().appendTo(document.body))),this._dialog.html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.label.assignLabels")}),this._dialog.wcfDialog("render"),$("#assignLabels").click($.proxy(this._save,this))},_save:function(){var e=[];this._dialog.find("input").each((function(a,t){var n=$(t);n.is(":checked")&&e.push(n.data("labelID"))})),this._proxy.setOption("data",{actionName:"assignLabel",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{conversationIDs:this._conversationIDs,labelIDs:e}}),this._proxy.sendRequest()},_assignLabels:function(e){for(var a=0,t=this._conversationIDs.length;a<t;a++)this._editorHandler.update(this._conversationIDs[a],"labelIDs",e.returnValues.labelIDs);this._dialog.wcfDialog("close"),this._notification.show()}}),WCF.Conversation.Label.Manager=Class.extend({_deletedLabelID:0,_dialog:null,_labels:null,_link:"",_notification:"",_proxy:null,_maxLabels:0,_labelCount:0,init:function(e){this._deletedLabelID=0,this._maxLabels=0,this._labelCount=0,this._link=e,this._labels=WCF.Dropdown.getDropdownMenu("conversationLabelFilter").children(".scrollableDropdownMenu"),$("#manageLabel").click($.proxy(this._click,this)),this._notification=new WCF.System.Notification(WCF.Language.get("wcf.conversation.label.management.addLabel.success")),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},_click:function(){this._proxy.setOption("data",{actionName:"getLabelManagement",className:"wcf\\data\\conversation\\ConversationAction"}),this._proxy.sendRequest()},_success:function(e,a,t){if(null===this._dialog&&(this._dialog=$('<div id="labelManagement" />').hide().appendTo(document.body)),e.returnValues&&e.returnValues.actionName)switch(e.returnValues.actionName){case"add":this._insertLabel(e);break;case"getLabelManagement":this._maxLabels=parseInt(e.returnValues.maxLabels),this._labelCount=parseInt(e.returnValues.labelCount),this._dialog.empty().html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.label.management")}),this._dialog.wcfDialog("render"),this._bindListener()}else if(this._deletedLabelID){var n=new RegExp("(\\?|&)labelID="+this._deletedLabelID);window.location=window.location.toString().replace(n,"")}else window.location.reload()},_insertLabel:function(e){var a=$('<li><a href="'+this._link+"&labelID="+e.returnValues.labelID+'"><span class="badge label'+(e.returnValues.cssClassName?" "+e.returnValues.cssClassName:"")+'">'+e.returnValues.label+"</span></a></li>");a.find("a > span").data("labelID",e.returnValues.labelID).data("cssClassName",e.returnValues.cssClassName),this._labels.append(a),this._notification.show(),this._labelCount++,this._labelCount>=this._maxLabels&&$("#conversationLabelManagementForm").hide()},_bindListener:function(){$("#labelName").on("keyup keydown keypress",$.proxy(this._updateLabels,this)),$.browser.mozilla&&$.browser.touch&&$("#labelName").on("input",$.proxy(this._updateLabels,this)),this._labelCount>=this._maxLabels&&($("#conversationLabelManagementForm").hide(),this._dialog.wcfDialog("render")),$("#addLabel").disable().click($.proxy(this._addLabel,this)),$("#editLabel").disable(),this._dialog.find(".conversationLabelList a.label").click($.proxy(this._edit,this))},_edit:function(e){var a,t,n;this._labelCount>=this._maxLabels&&($("#conversationLabelManagementForm").show(),this._dialog.wcfDialog("render")),a=$(e.currentTarget),t=WCF.Language.get("wcf.conversation.label.management.editLabel").replace(/#labelName#/,WCF.String.escapeHTML(a.text())),$("#conversationLabelManagementForm").data("labelID",a.data("labelID")).children(".sectionTitle").html(t),$("#labelName").val(a.text()).trigger("keyup"),n=a.data("cssClassName"),$("#labelManagementList input").each((function(e,a){var t=$(a);t.val()==n&&t.attr("checked","checked")})),$("#addLabel").hide(),$("#editLabel").show().click($.proxy(this._editLabel,this)),$("#deleteLabel").show().click($.proxy(this._deleteLabel,this))},_editLabel:function(){this._proxy.setOption("data",{actionName:"update",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",objectIDs:[$("#conversationLabelManagementForm").data("labelID")],parameters:{data:{cssClassName:$("#labelManagementList input:checked").val(),label:$("#labelName").val()}}}),this._proxy.sendRequest()},_deleteLabel:function(){var e=WCF.Language.get("wcf.conversation.label.management.deleteLabel.confirmMessage").replace(/#labelName#/,$("#labelName").val());WCF.System.Confirmation.show(e,$.proxy((function(e){"confirm"===e&&(this._proxy.setOption("data",{actionName:"delete",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",objectIDs:[$("#conversationLabelManagementForm").data("labelID")]}),this._proxy.sendRequest(),this._deletedLabelID=$("#conversationLabelManagementForm").data("labelID"))}),this),void 0,void 0,!0)},_updateLabels:function(){var e=$.trim($("#labelName").val());e?$("#addLabel, #editLabel").enable():($("#addLabel, #editLabel").disable(),e=WCF.Language.get("wcf.conversation.label.placeholder")),$("#labelManagementList").find("span.label").text(e)},_addLabel:function(){var e=$("#labelName").val(),a=$("#labelManagementList input:checked").val();this._proxy.setOption("data",{actionName:"add",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{data:{cssClassName:a,labelName:e}}}),this._proxy.sendRequest(),this._dialog.wcfDialog("close")}}),WCF.Conversation.Preview=WCF.Popover.extend({_proxy:null,init:function(){this._super(".conversationLink"),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1}),WCF.DOMNodeInsertedHandler.addCallback("WCF.Conversation.Preview",$.proxy(this._initContainers,this))},_loadContent:function(){var e,a,t=$("#"+this._activeElementID);this._proxy.setOption("data",{actionName:"getMessagePreview",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[t.data("conversationID")]}),e=this._activeElementID,a=this,this._proxy.setOption("success",(function(t,n,s){a._insertContent(e,t.returnValues.template,!0)})),this._proxy.sendRequest()}}),WCF.Conversation.MarkAsRead=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(document).on("dblclick",".conversationList .new .columnAvatar",$.proxy(this._dblclick,this))},_dblclick:function(e){this._proxy.setOption("data",{actionName:"markAsRead",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[$(e.currentTarget).parents("ol:eq(0)").data("conversationID")]}),this._proxy.sendRequest()},_success:function(e,a,t){$(".conversationList .new").each((function(a,t){var n=$(t);WCF.inArray(n.data("conversationID"),e.objectIDs)&&(n.removeClass("new"),n.find(".firstNewPost").parent().remove(),n.find(".columnAvatar").off("dblclick"))}))}}),WCF.Conversation.MarkAllAsRead=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".markAllAsReadButton").click($.proxy(this._click,this))},_click:function(e){e.preventDefault(),this._proxy.setOption("data",{actionName:"markAllAsRead",className:"wcf\\data\\conversation\\ConversationAction"}),this._proxy.sendRequest()},_success:function(e,a,t){WCF.System.Event.fireEvent("com.woltlab.wcf.conversation.userPanel","reset");var n=$(".conversationList");n.find(".new").removeClass("new"),n.find(".columnAvatar").off("dblclick"),(new WCF.System.Notification).show()}}),WCF.Conversation.Message={},WCF.Conversation.Message.InlineEditor=WCF.Message.InlineEditor.extend({init:function(e,a){this._super(e,!0,a)},_getClassName:function(){return"wcf\\data\\conversation\\message\\ConversationMessageAction"}}),WCF.Conversation.Message.QuoteHandler=WCF.Message.Quote.Handler.extend({init:function(e){require(["WoltLabSuite/Core/Conversation/Ui/Message/Quote"],(({UiConversationMessageQuote:a})=>{new a(e)}))}});
\ No newline at end of file
+WCF.Conversation={},WCF.Conversation.EditorHandler=Class.extend({_attributes:{},_conversations:{},_permissions:{},init:function(availableLabels){this._conversations={};var self=this;$(".conversation").each((function(index,conversation){var $labelIDs,$conversation=$(conversation),$conversationID=$conversation.data("conversationID");self._conversations[$conversationID]||(self._conversations[$conversationID]=$conversation,$labelIDs=eval($conversation.data("labelIDs")),self._attributes[$conversationID]={isClosed:!!$conversation.data("isClosed"),labelIDs:$labelIDs},self._permissions[$conversationID]={canAddParticipants:!!$conversation.data("canAddParticipants"),canCloseConversation:!!$conversation.data("canCloseConversation")})}))},getPermission:function(e,a){return void 0!==this._permissions[e][a]&&!!this._permissions[e][a]},getValue:function(e,a){switch(a){case"labelIDs":return void 0===this._attributes[e].labelIDs&&(this._attributes[e].labelIDs=[]),this._attributes[e].labelIDs;case"isClosed":return!!this._attributes[e].isClosed}},countAvailableLabels:function(){return this.getAvailableLabels().length},getAvailableLabels:function(){var e=[];return WCF.Dropdown.getDropdownMenu("conversationLabelFilter").children(".scrollableDropdownMenu").children("li").each((function(a,t){var n,s=$(t);if(s.hasClass("dropdownDivider"))return!1;n=s.find("span"),e.push({cssClassName:n.data("cssClassName"),labelID:n.data("labelID"),label:n.text()})})),e},update:function(e,a,t){var n,s,i,o,l,r;if(this._conversations[e]){switch(n=this._conversations[e],a){case"close":$(`<li>\n\t\t\t\t\t<span class="jsTooltip jsIconLock" title="${WCF.Language.get("wcf.global.state.closed")}">\n\t\t\t\t\t\t<fa-icon size="16" name="lock"></fa-icon>\n\t\t\t\t\t</span>\n\t\t\t\t</li>`).prependTo(n.find(".statusIcons")),this._attributes[e].isClosed=1;break;case"labelIDs":if(s={},WCF.Dropdown.getDropdownMenu("conversationLabelFilter").find("li > a > span").each((function(e,a){var t=$(a);s[t.data("labelID")]={cssClassName:t.data("cssClassName"),label:t.text(),url:t.parent().attr("href")}})),i=n.find(".columnSubject > .labelList"),t.length)for(i.length||(i=$('<ul class="labelList" />').prependTo(n.find(".columnSubject"))),i.empty(),o=0,l=t.length;o<l;o++)r=s[t[o]],$('<li><a href="'+r.url+'" class="badge label'+(r.cssClassName?" "+r.cssClassName:"")+'">'+WCF.String.escapeHTML(r.label)+"</a></li>").appendTo(i);else i.length&&i.remove();break;case"open":n.find(".statusIcons li").each((function(e,a){var t=$(a);if(t.children("span.jsIconLock").length)return t.remove(),!1})),this._attributes[e].isClosed=0}WCF.Clipboard.reload()}else console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '"+e+"'")}}),WCF.Conversation.EditorHandlerConversation=WCF.Conversation.EditorHandler.extend({_availableLabels:null,init:function(e){this._availableLabels=e||[],this._super()},getAvailableLabels:function(){return this._availableLabels},update:function(e,a,t){var n,s,i,o;if(this._conversations[e])switch(n=$(".contentHeaderTitle > .contentHeaderMetaData"),a){case"close":$(`<li>\n\t\t\t\t\t<fa-icon size="16" name="lock"></fa-icon>\n\t\t\t\t\t${WCF.Language.get("wcf.global.state.closed")}\n\t\t\t\t</li>`).appendTo(n),this._attributes[e].isClosed=1;break;case"labelIDs":s=n.find(".labelList"),t.length?(i=this.getAvailableLabels(),s.length||(s=(s=$('<li>\n\t\t\t\t\t\t\t<fa-icon size="16" name="tags"></fa-icon>\n\t\t\t\t\t\t\t<ul class="labelList"></ul>\n\t\t\t\t\t\t</li>').prependTo(n)).children("ul")),o="",t.forEach((function(e){i.forEach((function(a){a.labelID==e&&(o+='<li><span class="label badge'+(a.cssClassName?" "+a.cssClassName:"")+'">'+a.label+"</span></li>")}))})),s[0].innerHTML=o):s.parent().remove();break;case"open":n.find(".jsIconLock").parent().remove(),this._attributes[e].isClosed=0}else console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '"+e+"'")}}),WCF.Conversation.Clipboard=Class.extend({_editorHandler:null,init:function(e){this._editorHandler=e,WCF.System.Event.addListener("com.woltlab.wcf.clipboard","com.woltlab.wcf.conversation.conversation",function(e){null===e.responseData?this._execute(e.data.actionName,e.data.parameters):this._evaluateResponse(e.data.actionName,e.responseData)}.bind(this))},_execute:function(e,a){"com.woltlab.wcf.conversation.conversation.assignLabel"===e&&new WCF.Conversation.Label.Editor(this._editorHandler,null,a.objectIDs)},_evaluateResponse:function(e,a){var t,n;switch(e){case"com.woltlab.wcf.conversation.conversation.leave":case"com.woltlab.wcf.conversation.conversation.leavePermanently":case"com.woltlab.wcf.conversation.conversation.markAsRead":case"com.woltlab.wcf.conversation.conversation.restore":window.location.reload();break;case"com.woltlab.wcf.conversation.conversation.close":case"com.woltlab.wcf.conversation.conversation.open":for(t in a.returnValues.conversationData)a.returnValues.conversationData.hasOwnProperty(t)&&(n=a.returnValues.conversationData[t],this._editorHandler.update(t,n.isClosed?"close":"open",n))}}}),WCF.Conversation.InlineEditor=WCF.InlineEditor.extend({_editorHandler:null,_environment:"conversation",_setOptions:function(){this._options=[{label:WCF.Language.get("wcf.conversation.edit.subject"),optionName:"editSubject"},{label:WCF.Language.get("wcf.conversation.edit.close"),optionName:"close"},{label:WCF.Language.get("wcf.conversation.edit.open"),optionName:"open"},{label:WCF.Language.get("wcf.conversation.edit.assignLabel"),optionName:"assignLabel"},{optionName:"divider"},{label:WCF.Language.get("wcf.conversation.edit.addParticipants"),optionName:"addParticipants"},{label:WCF.Language.get("wcf.conversation.edit.leave"),optionName:"leave"},{label:WCF.Language.get("wcf.global.button.edit"),optionName:"edit",isQuickOption:!0}]},setEditorHandler:function(e,a){this._editorHandler=e,this._environment="list"==a?"list":"conversation"},_getTriggerElement:function(e){return e.find(".jsConversationInlineEditor")},_validate:function(e,a){var t=$("#"+e).data("conversationID");switch(a){case"addParticipants":return this._editorHandler.getPermission(t,"canAddParticipants");case"assignLabel":return!!this._editorHandler.countAvailableLabels();case"editSubject":return!!this._editorHandler.getPermission(t,"canCloseConversation");case"close":case"open":return!!this._editorHandler.getPermission(t,"canCloseConversation")&&("close"===a?!this._editorHandler.getValue(t,"isClosed"):this._editorHandler.getValue(t,"isClosed"));case"leave":return!0;case"edit":return!!$("#"+e).data("isDraft")}return!1},_execute:function(e,a){if(!this._validate(e,a))return!1;switch(a){case"addParticipants":require(["WoltLabSuite/Core/Conversation/Ui/Participant/Add"],(function(a){new a(elData(elById(e),"conversation-id"))}));break;case"assignLabel":new WCF.Conversation.Label.Editor(this._editorHandler,e);break;case"editSubject":require(["WoltLabSuite/Core/Conversation/Ui/Subject/Editor"],(function(a){a.beginEdit(elData(elById(e),"conversation-id"))}));break;case"close":case"open":this._updateConversation(e,a,{isClosed:"close"===a?1:0});break;case"leave":new WCF.Conversation.Leave([$("#"+e).data("conversationID")],this._environment);break;case"edit":window.location=this._getTriggerElement($("#"+e)).prop("href")}},_updateConversation:function(e,a,t){var n=this._elements[e].data("conversationID");switch(a){case"close":case"editSubject":case"open":this._updateData.push({elementID:e,optionName:a,data:t}),this._proxy.setOption("data",{actionName:a,className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[n]}),this._proxy.sendRequest()}},_updateState:function(){var e,a,t,n;for(e=0,a=this._updateData.length;e<a;e++)switch(t=this._updateData[e],n=this._elements[t.elementID].data("conversationID"),t.optionName){case"close":case"editSubject":case"open":this._editorHandler.update(n,t.optionName,t.data)}}}),WCF.Conversation.Leave=Class.extend({_conversationIDs:[],_dialog:null,_environment:"",_proxy:null,init:function(e,a){this._conversationIDs=e,this._dialog=null,this._environment=a,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._loadDialog()},_loadDialog:function(){this._proxy.setOption("data",{actionName:"getLeaveForm",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:this._conversationIDs}),this._proxy.sendRequest()},_success:function(e,a,t){switch(e.returnValues.actionName){case"getLeaveForm":this._showDialog(e);break;case"hideConversation":"conversation"===this._environment?window.location=e.returnValues.redirectURL:window.location.reload()}},_showDialog:function(e){null===this._dialog&&(this._dialog=$("#leaveDialog"),this._dialog.length||(this._dialog=$('<div id="leaveDialog" />').hide().appendTo(document.body))),this._dialog.html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.leave.title")}),this._dialog.wcfDialog("render"),this._dialog.find("#hideConversation").click($.proxy(this._click,this))},_click:function(){var e=this._dialog.find("input[type=radio]:checked");1===e.length&&(this._proxy.setOption("data",{actionName:"hideConversation",className:"wcf\\data\\conversation\\ConversationAction",objectIDs:this._conversationIDs,parameters:{hideConversation:e.val()}}),this._proxy.sendRequest())}}),WCF.Conversation.Label={},WCF.Conversation.Label.Editor=Class.extend({_conversationIDs:0,_dialog:null,_editorHandler:null,_notification:null,_proxy:null,init:function(e,a,t){this._conversationIDs=a?[$("#"+a).data("conversationID")]:t,this._dialog=null,this._editorHandler=e,this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success.edit")),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._loadDialog()},_loadDialog:function(){this._proxy.setOption("data",{actionName:"getLabelForm",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{conversationIDs:this._conversationIDs}}),this._proxy.sendRequest()},_success:function(e,a,t){switch(e.returnValues.actionName){case"assignLabel":this._assignLabels(e);break;case"getLabelForm":this._renderDialog(e)}},_renderDialog:function(e){null===this._dialog&&(this._dialog=$("#conversationLabelForm"),this._dialog.length||(this._dialog=$('<div id="conversationLabelForm" />').hide().appendTo(document.body))),this._dialog.html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.label.assignLabels")}),this._dialog.wcfDialog("render"),$("#assignLabels").click($.proxy(this._save,this))},_save:function(){var e=[];this._dialog.find("input").each((function(a,t){var n=$(t);n.is(":checked")&&e.push(n.data("labelID"))})),this._proxy.setOption("data",{actionName:"assignLabel",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{conversationIDs:this._conversationIDs,labelIDs:e}}),this._proxy.sendRequest()},_assignLabels:function(e){for(var a=0,t=this._conversationIDs.length;a<t;a++)this._editorHandler.update(this._conversationIDs[a],"labelIDs",e.returnValues.labelIDs);this._dialog.wcfDialog("close"),this._notification.show()}}),WCF.Conversation.Label.Manager=Class.extend({_deletedLabelID:0,_dialog:null,_labels:null,_link:"",_notification:"",_proxy:null,_maxLabels:0,_labelCount:0,init:function(e){this._deletedLabelID=0,this._maxLabels=0,this._labelCount=0,this._link=e,this._labels=WCF.Dropdown.getDropdownMenu("conversationLabelFilter").children(".scrollableDropdownMenu"),$("#manageLabel").click($.proxy(this._click,this)),this._notification=new WCF.System.Notification(WCF.Language.get("wcf.conversation.label.management.addLabel.success")),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},_click:function(){this._proxy.setOption("data",{actionName:"getLabelManagement",className:"wcf\\data\\conversation\\ConversationAction"}),this._proxy.sendRequest()},_success:function(e,a,t){if(null===this._dialog&&(this._dialog=$('<div id="labelManagement" />').hide().appendTo(document.body)),e.returnValues&&e.returnValues.actionName)switch(e.returnValues.actionName){case"add":this._insertLabel(e);break;case"getLabelManagement":this._maxLabels=parseInt(e.returnValues.maxLabels),this._labelCount=parseInt(e.returnValues.labelCount),this._dialog.empty().html(e.returnValues.template),this._dialog.wcfDialog({title:WCF.Language.get("wcf.conversation.label.management")}),this._dialog.wcfDialog("render"),this._bindListener()}else if(this._deletedLabelID){var n=new RegExp("(\\?|&)labelID="+this._deletedLabelID);window.location=window.location.toString().replace(n,"")}else window.location.reload()},_insertLabel:function(e){var a=$('<li><a href="'+this._link+"&labelID="+e.returnValues.labelID+'"><span class="badge label'+(e.returnValues.cssClassName?" "+e.returnValues.cssClassName:"")+'">'+e.returnValues.label+"</span></a></li>");a.find("a > span").data("labelID",e.returnValues.labelID).data("cssClassName",e.returnValues.cssClassName),this._labels.append(a),this._notification.show(),this._labelCount++,this._labelCount>=this._maxLabels&&$("#conversationLabelManagementForm").hide()},_bindListener:function(){$("#labelName").on("keyup keydown keypress",$.proxy(this._updateLabels,this)),$.browser.mozilla&&$.browser.touch&&$("#labelName").on("input",$.proxy(this._updateLabels,this)),this._labelCount>=this._maxLabels&&($("#conversationLabelManagementForm").hide(),this._dialog.wcfDialog("render")),$("#addLabel").disable().click($.proxy(this._addLabel,this)),$("#editLabel").disable(),this._dialog.find(".conversationLabelList a.label").click($.proxy(this._edit,this))},_edit:function(e){var a,t,n;this._labelCount>=this._maxLabels&&($("#conversationLabelManagementForm").show(),this._dialog.wcfDialog("render")),a=$(e.currentTarget),t=WCF.Language.get("wcf.conversation.label.management.editLabel").replace(/#labelName#/,WCF.String.escapeHTML(a.text())),$("#conversationLabelManagementForm").data("labelID",a.data("labelID")).children(".sectionTitle").html(t),$("#labelName").val(a.text()).trigger("keyup"),n=a.data("cssClassName"),$("#labelManagementList input").each((function(e,a){var t=$(a);t.val()==n&&t.attr("checked","checked")})),$("#addLabel").hide(),$("#editLabel").show().click($.proxy(this._editLabel,this)),$("#deleteLabel").show().click($.proxy(this._deleteLabel,this))},_editLabel:function(){this._proxy.setOption("data",{actionName:"update",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",objectIDs:[$("#conversationLabelManagementForm").data("labelID")],parameters:{data:{cssClassName:$("#labelManagementList input:checked").val(),label:$("#labelName").val()}}}),this._proxy.sendRequest()},_deleteLabel:function(){var e=WCF.Language.get("wcf.conversation.label.management.deleteLabel.confirmMessage").replace(/#labelName#/,$("#labelName").val());WCF.System.Confirmation.show(e,$.proxy((function(e){"confirm"===e&&(this._proxy.setOption("data",{actionName:"delete",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",objectIDs:[$("#conversationLabelManagementForm").data("labelID")]}),this._proxy.sendRequest(),this._deletedLabelID=$("#conversationLabelManagementForm").data("labelID"))}),this),void 0,void 0,!0)},_updateLabels:function(){var e=$.trim($("#labelName").val());e?$("#addLabel, #editLabel").enable():($("#addLabel, #editLabel").disable(),e=WCF.Language.get("wcf.conversation.label.placeholder")),$("#labelManagementList").find("span.label").text(e)},_addLabel:function(){var e=$("#labelName").val(),a=$("#labelManagementList input:checked").val();this._proxy.setOption("data",{actionName:"add",className:"wcf\\data\\conversation\\label\\ConversationLabelAction",parameters:{data:{cssClassName:a,labelName:e}}}),this._proxy.sendRequest(),this._dialog.wcfDialog("close")}}),WCF.Conversation.Message={},WCF.Conversation.Message.InlineEditor=WCF.Message.InlineEditor.extend({init:function(e,a){this._super(e,!0,a)},_getClassName:function(){return"wcf\\data\\conversation\\message\\ConversationMessageAction"}});
\ No newline at end of file
-define("WoltLabSuite/Core/Conversation/Ui/Message/Quote",["require","exports","WoltLabSuite/Core/Ui/Message/Quote"],(function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.UiConversationMessageQuote=void 0;class o extends i.UiMessageQuote{constructor(t){super(t,"wcf\\data\\conversation\\message\\ConversationMessageAction","com.woltlab.wcf.conversation.message",".message",".messageBody",".messageBody > div > div.messageText",!0)}}e.UiConversationMessageQuote=o,e.default=o})),define("WoltLabSuite/Core/Conversation/Ui/Participant/Add",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Dom/Util","WoltLabSuite/Core/Ui/Dialog","WoltLabSuite/Core/Ui/Notification","WoltLabSuite/Core/Ui/ItemList/User","WoltLabSuite/Core/Language"],(function(t,e,i,o,n,s,a,r,u){"use strict";o=i.__importStar(o),n=i.__importDefault(n),s=i.__importDefault(s),a=i.__importStar(a),r=i.__importStar(r),u=i.__importStar(u);return class{constructor(t){this.conversationId=t,o.api(this,{actionName:"getAddParticipantsForm"})}_ajaxSetup(){return{data:{className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[this.conversationId]}}}_ajaxSuccess(t){switch(t.actionName){case"addParticipants":this.handleResponse(t);break;case"getAddParticipantsForm":this.render(t)}}handleResponse(t){"errorMessage"in t.returnValues?n.default.innerError(document.getElementById("participantsInput").closest(".inputItemList"),t.returnValues.errorMessage):("count"in t.returnValues&&a.show(t.returnValues.successMessage,(()=>{window.location.reload()})),s.default.close(this))}render(t){s.default.open(this,t.returnValues.template);const e=document.getElementById("addParticipants");e.disabled=!0,r.init("participantsInput",{callbackChange:(t,i)=>{e.disabled=0===i.length},excludedSearchValues:t.returnValues.excludedSearchValues,maxItems:t.returnValues.maxItems,includeUserGroups:t.returnValues.canAddGroupParticipants&&t.returnValues.restrictUserGroupIDs.length>0,restrictUserGroupIDs:t.returnValues.restrictUserGroupIDs,csvPerType:!0}),e.addEventListener("click",(()=>{this.submit()}))}submit(){const t=[],e=[];r.getValues("participantsInput").forEach((i=>{"group"===i.type?e.push(i.objectId):t.push(i.value)}));const i={participants:t,participantsGroupIDs:e,visibility:null},n=s.default.getDialog(this).content.querySelector('input[name="messageVisibility"]:checked, input[name="messageVisibility"][type="hidden"]');n&&(i.visibility=n.value),o.api(this,{actionName:"addParticipants",parameters:i})}_dialogSetup(){return{id:"conversationAddParticipants",options:{title:u.get("wcf.conversation.edit.addParticipants")},source:null}}}})),define("WoltLabSuite/Core/Conversation/Ui/Subject/Editor",["require","exports","tslib","WoltLabSuite/Core/Ui/Dialog","WoltLabSuite/Core/Dom/Util","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Language","WoltLabSuite/Core/Ui/Notification"],(function(t,e,i,o,n,s,a,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.beginEdit=void 0,o=i.__importDefault(o),n=i.__importDefault(n),s=i.__importStar(s),a=i.__importStar(a),r=i.__importStar(r);class u{constructor(t){this.objectId=t}show(){o.default.open(this)}saveEdit(t){t.preventDefault();const e=this.subject.value.trim();""===e?n.default.innerError(this.subject,a.get("wcf.global.form.error.empty")):(n.default.innerError(this.subject,""),s.api(this,{parameters:{subject:e},objectIDs:[this.objectId]}))}getCurrentValue(){return Array.from(document.querySelectorAll(`.jsConversationSubject[data-conversation-id="${this.objectId}"], .conversationLink[data-object-id="${this.objectId}"]`)).map((t=>t.textContent)).slice(-1)[0]}_ajaxSuccess(t){o.default.close(this),document.querySelectorAll(`.jsConversationSubject[data-conversation-id="${this.objectId}"], .conversationLink[data-object-id="${this.objectId}"]`).forEach((e=>{e.textContent=t.returnValues.subject})),r.show()}_dialogSetup(){return{id:"dialogConversationSubjectEditor",options:{onSetup:t=>{this.subject=document.getElementById("jsConversationSubject"),this.subject.addEventListener("keyup",(t=>{"Enter"===t.key&&this.saveEdit(t)})),t.querySelector(".jsButtonSave").addEventListener("click",(t=>{this.saveEdit(t)}))},onShow:()=>{this.subject.value=this.getCurrentValue()},title:a.get("wcf.conversation.edit.subject")},source:`\n <dl>\n <dt>\n <label for="jsConversationSubject">${a.get("wcf.global.subject")}</label>\n </dt>\n <dd>\n <input type="text" id="jsConversationSubject" class="long" maxlength="255">\n </dd>\n </dl>\n <div class="formSubmit">\n <button class="buttonPrimary jsButtonSave">${a.get("wcf.global.button.save")}</button>\n </div>\n `}}_ajaxSetup(){return{data:{actionName:"editSubject",className:"wcf\\data\\conversation\\ConversationAction"}}}}let c;e.beginEdit=function(t){c=new u(t),c.show()}})),define("WoltLabSuite/Core/Conversation/Ui/Object/Action/RemoveParticipant",["require","exports","tslib","WoltLabSuite/Core/Ui/Object/Action/Handler"],(function(t,e,i,o){"use strict";function n(t){t.objectElement.querySelector(".userLink").classList.add("conversationLeft"),t.objectElement.querySelector(".jsObjectAction[data-object-action='removeParticipant']").remove()}Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,o=i.__importDefault(o),e.setup=function(){new o.default("removeParticipant",[],n)}})),define("WoltLabSuite/Core/Conversation/Ui/User/Menu/Data/Conversation",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Ui/User/Menu/View","WoltLabSuite/Core/Ui/User/Menu/Manager"],(function(t,e,i,o,n,s){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,n=i.__importDefault(n);class a{constructor(t,e){this.counter=0,this.stale=!0,this.view=void 0,this.button=t,this.options=e;const i=t.querySelector(".badge");if(i){const t=parseInt(i.textContent.trim());t&&(this.counter=t)}}getPanelButton(){return this.button}getMenuButtons(){const t=[];return this.options.canStartConversation&&t.push({icon:'<span class="icon icon24 fa-plus"></span>',link:this.options.newConversationLink,name:"newConversation",title:this.options.newConversationTitle}),t}getIdentifier(){return"com.woltlab.wcf.conversation.conversations"}async getData(){const t=await(0,o.dboAction)("getConversations","wcf\\data\\conversation\\ConversationAction").disableLoadingIndicator().dispatch();return this.updateCounter(t.totalCount),this.stale=!1,t.items}getFooter(){return{link:this.options.showAllLink,title:this.options.showAllTitle}}getTitle(){return this.options.title}getView(){return void 0===this.view&&(this.view=new n.default(this)),this.view}getEmptyViewMessage(){return this.options.noItems}hasPlainTitle(){return!0}hasUnreadContent(){return this.counter>0}isStale(){if(this.stale)return!0;const t=this.getView().getItems().filter((t=>"true"===t.dataset.isUnread));return this.counter!==t.length}async markAsRead(t){const e=await(0,o.dboAction)("markAsRead","wcf\\data\\conversation\\ConversationAction").objectIds([t]).dispatch();this.updateCounter(e.totalCount)}async markAllAsRead(){await(0,o.dboAction)("markAllAsRead","wcf\\data\\conversation\\ConversationAction").dispatch(),this.updateCounter(0)}updateCounter(t){let e=this.button.querySelector(".badge");null===e&&t>0&&(e=document.createElement("span"),e.classList.add("badge","badgeUpdate"),this.button.querySelector("a").append(e)),e&&(0===t?e.remove():e.textContent=t.toString()),this.counter=t}}let r=!1;e.setup=function(t){if(!r){const e=document.getElementById("unreadConversations");if(null!==e){const i=new a(e,t);(0,s.registerProvider)(i)}r=!0}}}));
\ No newline at end of file
+define("WoltLabSuite/Core/Conversation/Ui/MarkAllAsRead",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Ui/Notification"],(function(t,e,o,i,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,n=o.__importStar(n),e.setup=function(){document.querySelectorAll(".markAllAsReadButton").forEach((t=>{t.addEventListener("click",(t=>{t.preventDefault(),async function(){await(0,i.dboAction)("markAllAsRead","wcf\\data\\conversation\\ConversationAction").dispatch(),document.querySelectorAll(".conversationList .new").forEach((t=>{t.classList.remove("new")})),document.querySelector("#unreadConversations .badgeUpdate")?.remove(),n.show()}()}))}))}})),define("WoltLabSuite/Core/Conversation/Ui/MarkAsRead",["require","exports","WoltLabSuite/Core/Ajax"],(function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0;const i=new WeakSet;e.setup=function(){document.querySelectorAll(".conversationList .new .columnAvatar").forEach((t=>{i.has(t)||(i.add(t),t.addEventListener("dblclick",(e=>{e.preventDefault();const i=t.closest(".conversation");i.classList.contains("new")&&async function(t){const e=parseInt(t.dataset.conversationId,10);await(0,o.dboAction)("markAsRead","wcf\\data\\conversation\\ConversationAction").objectIds([e]).dispatch(),t.classList.remove("new"),t.querySelector(".columnAvatar p")?.removeAttribute("title")}(i)}),{once:!0}))}))}})),define("WoltLabSuite/Core/Conversation/Ui/Message/Quote",["require","exports","WoltLabSuite/Core/Ui/Message/Quote"],(function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.UiConversationMessageQuote=void 0;class i extends o.UiMessageQuote{constructor(t){super(t,"wcf\\data\\conversation\\message\\ConversationMessageAction","com.woltlab.wcf.conversation.message",".message",".messageBody",".messageBody > div > div.messageText",!0)}}e.UiConversationMessageQuote=i,e.default=i})),define("WoltLabSuite/Core/Conversation/Ui/Participant/Add",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Dom/Util","WoltLabSuite/Core/Ui/Dialog","WoltLabSuite/Core/Ui/Notification","WoltLabSuite/Core/Ui/ItemList/User","WoltLabSuite/Core/Language"],(function(t,e,o,i,n,a,s,r,c){"use strict";return i=o.__importStar(i),n=o.__importDefault(n),a=o.__importDefault(a),s=o.__importStar(s),r=o.__importStar(r),c=o.__importStar(c),class{conversationId;constructor(t){this.conversationId=t,i.api(this,{actionName:"getAddParticipantsForm"})}_ajaxSetup(){return{data:{className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[this.conversationId]}}}_ajaxSuccess(t){switch(t.actionName){case"addParticipants":this.handleResponse(t);break;case"getAddParticipantsForm":this.render(t)}}handleResponse(t){"errorMessage"in t.returnValues?n.default.innerError(document.getElementById("participantsInput").closest(".inputItemList"),t.returnValues.errorMessage):("count"in t.returnValues&&s.show(t.returnValues.successMessage,(()=>{window.location.reload()})),a.default.close(this))}render(t){a.default.open(this,t.returnValues.template);const e=document.getElementById("addParticipants");e.disabled=!0,r.init("participantsInput",{callbackChange:(t,o)=>{e.disabled=0===o.length},excludedSearchValues:t.returnValues.excludedSearchValues,maxItems:t.returnValues.maxItems,includeUserGroups:t.returnValues.canAddGroupParticipants&&t.returnValues.restrictUserGroupIDs.length>0,restrictUserGroupIDs:t.returnValues.restrictUserGroupIDs,csvPerType:!0}),e.addEventListener("click",(()=>{this.submit()}))}submit(){const t=[],e=[];r.getValues("participantsInput").forEach((o=>{"group"===o.type?e.push(o.objectId):t.push(o.value)}));const o={participants:t,participantsGroupIDs:e,visibility:null},n=a.default.getDialog(this).content.querySelector('input[name="messageVisibility"]:checked, input[name="messageVisibility"][type="hidden"]');n&&(o.visibility=n.value),i.api(this,{actionName:"addParticipants",parameters:o})}_dialogSetup(){return{id:"conversationAddParticipants",options:{title:c.get("wcf.conversation.edit.addParticipants")},source:null}}}})),define("WoltLabSuite/Core/Conversation/Ui/Subject/Editor",["require","exports","tslib","WoltLabSuite/Core/Ui/Dialog","WoltLabSuite/Core/Dom/Util","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Language","WoltLabSuite/Core/Ui/Notification"],(function(t,e,o,i,n,a,s,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.beginEdit=void 0,i=o.__importDefault(i),n=o.__importDefault(n),a=o.__importStar(a),s=o.__importStar(s),r=o.__importStar(r);class c{objectId;subject;constructor(t){this.objectId=t}show(){i.default.open(this)}saveEdit(t){t.preventDefault();const e=this.subject.value.trim();""===e?n.default.innerError(this.subject,s.get("wcf.global.form.error.empty")):(n.default.innerError(this.subject,""),a.api(this,{parameters:{subject:e},objectIDs:[this.objectId]}))}getCurrentValue(){return Array.from(document.querySelectorAll(`.jsConversationSubject[data-conversation-id="${this.objectId}"], .conversationLink[data-object-id="${this.objectId}"]`)).map((t=>t.textContent)).slice(-1)[0]}_ajaxSuccess(t){i.default.close(this),document.querySelectorAll(`.jsConversationSubject[data-conversation-id="${this.objectId}"], .conversationLink[data-object-id="${this.objectId}"]`).forEach((e=>{e.textContent=t.returnValues.subject})),r.show()}_dialogSetup(){return{id:"dialogConversationSubjectEditor",options:{onSetup:t=>{this.subject=document.getElementById("jsConversationSubject"),this.subject.addEventListener("keyup",(t=>{"Enter"===t.key&&this.saveEdit(t)})),t.querySelector(".jsButtonSave").addEventListener("click",(t=>{this.saveEdit(t)}))},onShow:()=>{this.subject.value=this.getCurrentValue()},title:s.get("wcf.conversation.edit.subject")},source:`\n <dl>\n <dt>\n <label for="jsConversationSubject">${s.get("wcf.global.subject")}</label>\n </dt>\n <dd>\n <input type="text" id="jsConversationSubject" class="long" maxlength="255">\n </dd>\n </dl>\n <div class="formSubmit">\n <button type="button" class="button buttonPrimary jsButtonSave">${s.get("wcf.global.button.save")}</button>\n </div>\n `}}_ajaxSetup(){return{data:{actionName:"editSubject",className:"wcf\\data\\conversation\\ConversationAction"}}}}let u;e.beginEdit=function(t){u=new c(t),u.show()}})),define("WoltLabSuite/Core/Conversation/Ui/Object/Action/RemoveParticipant",["require","exports","tslib","WoltLabSuite/Core/Ui/Object/Action/Handler"],(function(t,e,o,i){"use strict";function n(t){t.objectElement.querySelector(".userLink").classList.add("conversationLeft"),t.objectElement.querySelector(".jsObjectAction[data-object-action='removeParticipant']").remove()}Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,i=o.__importDefault(i),e.setup=function(){new i.default("removeParticipant",[],n)}})),define("WoltLabSuite/Core/Conversation/Ui/User/Menu/Data/Conversation",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Ui/User/Menu/View","WoltLabSuite/Core/Ui/User/Menu/Manager"],(function(t,e,o,i,n,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,n=o.__importDefault(n);class s{button;counter=0;options;stale=!0;view=void 0;constructor(t,e){this.button=t,this.options=e;const o=t.querySelector(".badge");if(o){const t=parseInt(o.textContent.trim());t&&(this.counter=t)}}getPanelButton(){return this.button}getMenuButtons(){const t=[];return this.options.canStartConversation&&t.push({icon:'<fa-icon size="24" name="plus"></fa-icon>',link:this.options.newConversationLink,name:"newConversation",title:this.options.newConversationTitle}),t}getIdentifier(){return"com.woltlab.wcf.conversation.conversations"}async getData(){const t=await(0,i.dboAction)("getConversations","wcf\\data\\conversation\\ConversationAction").disableLoadingIndicator().dispatch();return this.updateCounter(t.totalCount),this.stale=!1,t.items}getFooter(){return{link:this.options.showAllLink,title:this.options.showAllTitle}}getTitle(){return this.options.title}getView(){return void 0===this.view&&(this.view=new n.default(this)),this.view}getEmptyViewMessage(){return this.options.noItems}hasPlainTitle(){return!0}hasUnreadContent(){return this.counter>0}isStale(){if(this.stale)return!0;const t=this.getView().getItems().filter((t=>"true"===t.dataset.isUnread));return this.counter!==t.length}async markAsRead(t){const e=await(0,i.dboAction)("markAsRead","wcf\\data\\conversation\\ConversationAction").objectIds([t]).dispatch();this.updateCounter(e.totalCount)}async markAllAsRead(){await(0,i.dboAction)("markAllAsRead","wcf\\data\\conversation\\ConversationAction").dispatch(),this.updateCounter(0)}updateCounter(t){let e=this.button.querySelector(".badge");null===e&&t>0&&(e=document.createElement("span"),e.classList.add("badge","badgeUpdate"),this.button.querySelector("a").append(e)),e&&(0===t?e.remove():e.textContent=t.toString()),this.counter=t}}let r=!1;e.setup=function(t){if(!r){const e=document.getElementById("unreadConversations");if(null!==e){const o=new s(e,t);(0,a.registerProvider)(o)}r=!0}}}));
\ No newline at end of file
-define("WoltLabSuite/Core/Conversation/Ui/Message/Quote",["require","exports","WoltLabSuite/Core/Ui/Message/Quote"],(function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.UiConversationMessageQuote=void 0;class o extends i.UiMessageQuote{constructor(t){super(t,"wcf\\data\\conversation\\message\\ConversationMessageAction","com.woltlab.wcf.conversation.message",".message",".messageBody",".messageBody > div > div.messageText",!0)}}e.UiConversationMessageQuote=o,e.default=o})),define("WoltLabSuite/Core/Conversation/Ui/Participant/Add",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Dom/Util","WoltLabSuite/Core/Ui/Dialog","WoltLabSuite/Core/Ui/Notification","WoltLabSuite/Core/Ui/ItemList/User","WoltLabSuite/Core/Language"],(function(t,e,i,o,n,s,a,r,u){"use strict";o=i.__importStar(o),n=i.__importDefault(n),s=i.__importDefault(s),a=i.__importStar(a),r=i.__importStar(r),u=i.__importStar(u);return class{constructor(t){this.conversationId=t,o.api(this,{actionName:"getAddParticipantsForm"})}_ajaxSetup(){return{data:{className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[this.conversationId]}}}_ajaxSuccess(t){switch(t.actionName){case"addParticipants":this.handleResponse(t);break;case"getAddParticipantsForm":this.render(t)}}handleResponse(t){"errorMessage"in t.returnValues?n.default.innerError(document.getElementById("participantsInput").closest(".inputItemList"),t.returnValues.errorMessage):("count"in t.returnValues&&a.show(t.returnValues.successMessage,(()=>{window.location.reload()})),s.default.close(this))}render(t){s.default.open(this,t.returnValues.template);const e=document.getElementById("addParticipants");e.disabled=!0,r.init("participantsInput",{callbackChange:(t,i)=>{e.disabled=0===i.length},excludedSearchValues:t.returnValues.excludedSearchValues,maxItems:t.returnValues.maxItems,includeUserGroups:t.returnValues.canAddGroupParticipants&&t.returnValues.restrictUserGroupIDs.length>0,restrictUserGroupIDs:t.returnValues.restrictUserGroupIDs,csvPerType:!0}),e.addEventListener("click",(()=>{this.submit()}))}submit(){const t=[],e=[];r.getValues("participantsInput").forEach((i=>{"group"===i.type?e.push(i.objectId):t.push(i.value)}));const i={participants:t,participantsGroupIDs:e,visibility:null},n=s.default.getDialog(this).content.querySelector('input[name="messageVisibility"]:checked, input[name="messageVisibility"][type="hidden"]');n&&(i.visibility=n.value),o.api(this,{actionName:"addParticipants",parameters:i})}_dialogSetup(){return{id:"conversationAddParticipants",options:{title:u.get("wcf.conversation.edit.addParticipants")},source:null}}}})),define("WoltLabSuite/Core/Conversation/Ui/Subject/Editor",["require","exports","tslib","WoltLabSuite/Core/Ui/Dialog","WoltLabSuite/Core/Dom/Util","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Language","WoltLabSuite/Core/Ui/Notification"],(function(t,e,i,o,n,s,a,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.beginEdit=void 0,o=i.__importDefault(o),n=i.__importDefault(n),s=i.__importStar(s),a=i.__importStar(a),r=i.__importStar(r);class u{constructor(t){this.objectId=t}show(){o.default.open(this)}saveEdit(t){t.preventDefault();const e=this.subject.value.trim();""===e?n.default.innerError(this.subject,a.get("wcf.global.form.error.empty")):(n.default.innerError(this.subject,""),s.api(this,{parameters:{subject:e},objectIDs:[this.objectId]}))}getCurrentValue(){return Array.from(document.querySelectorAll(`.jsConversationSubject[data-conversation-id="${this.objectId}"], .conversationLink[data-object-id="${this.objectId}"]`)).map((t=>t.textContent)).slice(-1)[0]}_ajaxSuccess(t){o.default.close(this),document.querySelectorAll(`.jsConversationSubject[data-conversation-id="${this.objectId}"], .conversationLink[data-object-id="${this.objectId}"]`).forEach((e=>{e.textContent=t.returnValues.subject})),r.show()}_dialogSetup(){return{id:"dialogConversationSubjectEditor",options:{onSetup:t=>{this.subject=document.getElementById("jsConversationSubject"),this.subject.addEventListener("keyup",(t=>{"Enter"===t.key&&this.saveEdit(t)})),t.querySelector(".jsButtonSave").addEventListener("click",(t=>{this.saveEdit(t)}))},onShow:()=>{this.subject.value=this.getCurrentValue()},title:a.get("wcf.conversation.edit.subject")},source:`\n <dl>\n <dt>\n <label for="jsConversationSubject">${a.get("wcf.global.subject")}</label>\n </dt>\n <dd>\n <input type="text" id="jsConversationSubject" class="long" maxlength="255">\n </dd>\n </dl>\n <div class="formSubmit">\n <button class="buttonPrimary jsButtonSave">${a.get("wcf.global.button.save")}</button>\n </div>\n `}}_ajaxSetup(){return{data:{actionName:"editSubject",className:"wcf\\data\\conversation\\ConversationAction"}}}}let c;e.beginEdit=function(t){c=new u(t),c.show()}})),define("WoltLabSuite/Core/Conversation/Ui/Object/Action/RemoveParticipant",["require","exports","tslib","WoltLabSuite/Core/Ui/Object/Action/Handler"],(function(t,e,i,o){"use strict";function n(t){t.objectElement.querySelector(".userLink").classList.add("conversationLeft"),t.objectElement.querySelector(".jsObjectAction[data-object-action='removeParticipant']").remove()}Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,o=i.__importDefault(o),e.setup=function(){new o.default("removeParticipant",[],n)}})),define("WoltLabSuite/Core/Conversation/Ui/User/Menu/Data/Conversation",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Ui/User/Menu/View","WoltLabSuite/Core/Ui/User/Menu/Manager"],(function(t,e,i,o,n,s){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,n=i.__importDefault(n);class a{constructor(t,e){this.counter=0,this.stale=!0,this.view=void 0,this.button=t,this.options=e;const i=t.querySelector(".badge");if(i){const t=parseInt(i.textContent.trim());t&&(this.counter=t)}}getPanelButton(){return this.button}getMenuButtons(){const t=[];return this.options.canStartConversation&&t.push({icon:'<span class="icon icon24 fa-plus"></span>',link:this.options.newConversationLink,name:"newConversation",title:this.options.newConversationTitle}),t}getIdentifier(){return"com.woltlab.wcf.conversation.conversations"}async getData(){const t=await(0,o.dboAction)("getConversations","wcf\\data\\conversation\\ConversationAction").disableLoadingIndicator().dispatch();return this.updateCounter(t.totalCount),this.stale=!1,t.items}getFooter(){return{link:this.options.showAllLink,title:this.options.showAllTitle}}getTitle(){return this.options.title}getView(){return void 0===this.view&&(this.view=new n.default(this)),this.view}getEmptyViewMessage(){return this.options.noItems}hasPlainTitle(){return!0}hasUnreadContent(){return this.counter>0}isStale(){if(this.stale)return!0;const t=this.getView().getItems().filter((t=>"true"===t.dataset.isUnread));return this.counter!==t.length}async markAsRead(t){const e=await(0,o.dboAction)("markAsRead","wcf\\data\\conversation\\ConversationAction").objectIds([t]).dispatch();this.updateCounter(e.totalCount)}async markAllAsRead(){await(0,o.dboAction)("markAllAsRead","wcf\\data\\conversation\\ConversationAction").dispatch(),this.updateCounter(0)}updateCounter(t){let e=this.button.querySelector(".badge");null===e&&t>0&&(e=document.createElement("span"),e.classList.add("badge","badgeUpdate"),this.button.querySelector("a").append(e)),e&&(0===t?e.remove():e.textContent=t.toString()),this.counter=t}}let r=!1;e.setup=function(t){if(!r){const e=document.getElementById("unreadConversations");if(null!==e){const i=new a(e,t);(0,s.registerProvider)(i)}r=!0}}}));
\ No newline at end of file
+define("WoltLabSuite/Core/Conversation/Ui/MarkAllAsRead",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Ui/Notification"],(function(t,e,o,i,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,n=o.__importStar(n),e.setup=function(){document.querySelectorAll(".markAllAsReadButton").forEach((t=>{t.addEventListener("click",(t=>{t.preventDefault(),async function(){await(0,i.dboAction)("markAllAsRead","wcf\\data\\conversation\\ConversationAction").dispatch(),document.querySelectorAll(".conversationList .new").forEach((t=>{t.classList.remove("new")})),document.querySelector("#unreadConversations .badgeUpdate")?.remove(),n.show()}()}))}))}})),define("WoltLabSuite/Core/Conversation/Ui/MarkAsRead",["require","exports","WoltLabSuite/Core/Ajax"],(function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0;const i=new WeakSet;e.setup=function(){document.querySelectorAll(".conversationList .new .columnAvatar").forEach((t=>{i.has(t)||(i.add(t),t.addEventListener("dblclick",(e=>{e.preventDefault();const i=t.closest(".conversation");i.classList.contains("new")&&async function(t){const e=parseInt(t.dataset.conversationId,10);await(0,o.dboAction)("markAsRead","wcf\\data\\conversation\\ConversationAction").objectIds([e]).dispatch(),t.classList.remove("new"),t.querySelector(".columnAvatar p")?.removeAttribute("title")}(i)}),{once:!0}))}))}})),define("WoltLabSuite/Core/Conversation/Ui/Message/Quote",["require","exports","WoltLabSuite/Core/Ui/Message/Quote"],(function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.UiConversationMessageQuote=void 0;class i extends o.UiMessageQuote{constructor(t){super(t,"wcf\\data\\conversation\\message\\ConversationMessageAction","com.woltlab.wcf.conversation.message",".message",".messageBody",".messageBody > div > div.messageText",!0)}}e.UiConversationMessageQuote=i,e.default=i})),define("WoltLabSuite/Core/Conversation/Ui/Participant/Add",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Dom/Util","WoltLabSuite/Core/Ui/Dialog","WoltLabSuite/Core/Ui/Notification","WoltLabSuite/Core/Ui/ItemList/User","WoltLabSuite/Core/Language"],(function(t,e,o,i,n,a,s,r,c){"use strict";return i=o.__importStar(i),n=o.__importDefault(n),a=o.__importDefault(a),s=o.__importStar(s),r=o.__importStar(r),c=o.__importStar(c),class{conversationId;constructor(t){this.conversationId=t,i.api(this,{actionName:"getAddParticipantsForm"})}_ajaxSetup(){return{data:{className:"wcf\\data\\conversation\\ConversationAction",objectIDs:[this.conversationId]}}}_ajaxSuccess(t){switch(t.actionName){case"addParticipants":this.handleResponse(t);break;case"getAddParticipantsForm":this.render(t)}}handleResponse(t){"errorMessage"in t.returnValues?n.default.innerError(document.getElementById("participantsInput").closest(".inputItemList"),t.returnValues.errorMessage):("count"in t.returnValues&&s.show(t.returnValues.successMessage,(()=>{window.location.reload()})),a.default.close(this))}render(t){a.default.open(this,t.returnValues.template);const e=document.getElementById("addParticipants");e.disabled=!0,r.init("participantsInput",{callbackChange:(t,o)=>{e.disabled=0===o.length},excludedSearchValues:t.returnValues.excludedSearchValues,maxItems:t.returnValues.maxItems,includeUserGroups:t.returnValues.canAddGroupParticipants&&t.returnValues.restrictUserGroupIDs.length>0,restrictUserGroupIDs:t.returnValues.restrictUserGroupIDs,csvPerType:!0}),e.addEventListener("click",(()=>{this.submit()}))}submit(){const t=[],e=[];r.getValues("participantsInput").forEach((o=>{"group"===o.type?e.push(o.objectId):t.push(o.value)}));const o={participants:t,participantsGroupIDs:e,visibility:null},n=a.default.getDialog(this).content.querySelector('input[name="messageVisibility"]:checked, input[name="messageVisibility"][type="hidden"]');n&&(o.visibility=n.value),i.api(this,{actionName:"addParticipants",parameters:o})}_dialogSetup(){return{id:"conversationAddParticipants",options:{title:c.get("wcf.conversation.edit.addParticipants")},source:null}}}})),define("WoltLabSuite/Core/Conversation/Ui/Subject/Editor",["require","exports","tslib","WoltLabSuite/Core/Ui/Dialog","WoltLabSuite/Core/Dom/Util","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Language","WoltLabSuite/Core/Ui/Notification"],(function(t,e,o,i,n,a,s,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.beginEdit=void 0,i=o.__importDefault(i),n=o.__importDefault(n),a=o.__importStar(a),s=o.__importStar(s),r=o.__importStar(r);class c{objectId;subject;constructor(t){this.objectId=t}show(){i.default.open(this)}saveEdit(t){t.preventDefault();const e=this.subject.value.trim();""===e?n.default.innerError(this.subject,s.get("wcf.global.form.error.empty")):(n.default.innerError(this.subject,""),a.api(this,{parameters:{subject:e},objectIDs:[this.objectId]}))}getCurrentValue(){return Array.from(document.querySelectorAll(`.jsConversationSubject[data-conversation-id="${this.objectId}"], .conversationLink[data-object-id="${this.objectId}"]`)).map((t=>t.textContent)).slice(-1)[0]}_ajaxSuccess(t){i.default.close(this),document.querySelectorAll(`.jsConversationSubject[data-conversation-id="${this.objectId}"], .conversationLink[data-object-id="${this.objectId}"]`).forEach((e=>{e.textContent=t.returnValues.subject})),r.show()}_dialogSetup(){return{id:"dialogConversationSubjectEditor",options:{onSetup:t=>{this.subject=document.getElementById("jsConversationSubject"),this.subject.addEventListener("keyup",(t=>{"Enter"===t.key&&this.saveEdit(t)})),t.querySelector(".jsButtonSave").addEventListener("click",(t=>{this.saveEdit(t)}))},onShow:()=>{this.subject.value=this.getCurrentValue()},title:s.get("wcf.conversation.edit.subject")},source:`\n <dl>\n <dt>\n <label for="jsConversationSubject">${s.get("wcf.global.subject")}</label>\n </dt>\n <dd>\n <input type="text" id="jsConversationSubject" class="long" maxlength="255">\n </dd>\n </dl>\n <div class="formSubmit">\n <button type="button" class="button buttonPrimary jsButtonSave">${s.get("wcf.global.button.save")}</button>\n </div>\n `}}_ajaxSetup(){return{data:{actionName:"editSubject",className:"wcf\\data\\conversation\\ConversationAction"}}}}let u;e.beginEdit=function(t){u=new c(t),u.show()}})),define("WoltLabSuite/Core/Conversation/Ui/Object/Action/RemoveParticipant",["require","exports","tslib","WoltLabSuite/Core/Ui/Object/Action/Handler"],(function(t,e,o,i){"use strict";function n(t){t.objectElement.querySelector(".userLink").classList.add("conversationLeft"),t.objectElement.querySelector(".jsObjectAction[data-object-action='removeParticipant']").remove()}Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,i=o.__importDefault(i),e.setup=function(){new i.default("removeParticipant",[],n)}})),define("WoltLabSuite/Core/Conversation/Ui/User/Menu/Data/Conversation",["require","exports","tslib","WoltLabSuite/Core/Ajax","WoltLabSuite/Core/Ui/User/Menu/View","WoltLabSuite/Core/Ui/User/Menu/Manager"],(function(t,e,o,i,n,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setup=void 0,n=o.__importDefault(n);class s{button;counter=0;options;stale=!0;view=void 0;constructor(t,e){this.button=t,this.options=e;const o=t.querySelector(".badge");if(o){const t=parseInt(o.textContent.trim());t&&(this.counter=t)}}getPanelButton(){return this.button}getMenuButtons(){const t=[];return this.options.canStartConversation&&t.push({icon:'<fa-icon size="24" name="plus"></fa-icon>',link:this.options.newConversationLink,name:"newConversation",title:this.options.newConversationTitle}),t}getIdentifier(){return"com.woltlab.wcf.conversation.conversations"}async getData(){const t=await(0,i.dboAction)("getConversations","wcf\\data\\conversation\\ConversationAction").disableLoadingIndicator().dispatch();return this.updateCounter(t.totalCount),this.stale=!1,t.items}getFooter(){return{link:this.options.showAllLink,title:this.options.showAllTitle}}getTitle(){return this.options.title}getView(){return void 0===this.view&&(this.view=new n.default(this)),this.view}getEmptyViewMessage(){return this.options.noItems}hasPlainTitle(){return!0}hasUnreadContent(){return this.counter>0}isStale(){if(this.stale)return!0;const t=this.getView().getItems().filter((t=>"true"===t.dataset.isUnread));return this.counter!==t.length}async markAsRead(t){const e=await(0,i.dboAction)("markAsRead","wcf\\data\\conversation\\ConversationAction").objectIds([t]).dispatch();this.updateCounter(e.totalCount)}async markAllAsRead(){await(0,i.dboAction)("markAllAsRead","wcf\\data\\conversation\\ConversationAction").dispatch(),this.updateCounter(0)}updateCounter(t){let e=this.button.querySelector(".badge");null===e&&t>0&&(e=document.createElement("span"),e.classList.add("badge","badgeUpdate"),this.button.querySelector("a").append(e)),e&&(0===t?e.remove():e.textContent=t.toString()),this.counter=t}}let r=!1;e.setup=function(t){if(!r){const e=document.getElementById("unreadConversations");if(null!==e){const o=new s(e,t);(0,a.registerProvider)(o)}r=!0}}}));
\ No newline at end of file
--- /dev/null
+/**
+ * Marks all conversations as read.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2022 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since 6.0
+ */
+define(["require", "exports", "tslib", "WoltLabSuite/Core/Ajax", "WoltLabSuite/Core/Ui/Notification"], function (require, exports, tslib_1, Ajax_1, UiNotification) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.setup = void 0;
+ UiNotification = tslib_1.__importStar(UiNotification);
+ async function markAllAsRead() {
+ await (0, Ajax_1.dboAction)("markAllAsRead", "wcf\\data\\conversation\\ConversationAction").dispatch();
+ document.querySelectorAll(".conversationList .new").forEach((el) => {
+ el.classList.remove("new");
+ });
+ document.querySelector("#unreadConversations .badgeUpdate")?.remove();
+ UiNotification.show();
+ }
+ function setup() {
+ document.querySelectorAll(".markAllAsReadButton").forEach((el) => {
+ el.addEventListener("click", (event) => {
+ event.preventDefault();
+ void markAllAsRead();
+ });
+ });
+ }
+ exports.setup = setup;
+});
--- /dev/null
+/**
+ * Handles the mark as read button for single conversations.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2022 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since 6.0
+ */
+define(["require", "exports", "WoltLabSuite/Core/Ajax"], function (require, exports, Ajax_1) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.setup = void 0;
+ const unreadConversations = new WeakSet();
+ async function markAsRead(conversation) {
+ const conversationId = parseInt(conversation.dataset.conversationId, 10);
+ await (0, Ajax_1.dboAction)("markAsRead", "wcf\\data\\conversation\\ConversationAction").objectIds([conversationId]).dispatch();
+ conversation.classList.remove("new");
+ conversation.querySelector(".columnAvatar p")?.removeAttribute("title");
+ }
+ function setup() {
+ document.querySelectorAll(".conversationList .new .columnAvatar").forEach((el) => {
+ if (!unreadConversations.has(el)) {
+ unreadConversations.add(el);
+ el.addEventListener("dblclick", (event) => {
+ event.preventDefault();
+ const conversation = el.closest(".conversation");
+ if (!conversation.classList.contains("new")) {
+ return;
+ }
+ void markAsRead(conversation);
+ }, { once: true });
+ }
+ });
+ }
+ exports.setup = setup;
+});
* @author Matthias Schmidt
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Conversation/Ui/Message/Quote
* @woltlabExcludeBundle tiny
*/
define(["require", "exports", "WoltLabSuite/Core/Ui/Message/Quote"], function (require, exports, Quote_1) {
* @author Matthias Schmidt
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Conversation/Ui/Object/Action/RemoveParticipant
*/
define(["require", "exports", "tslib", "WoltLabSuite/Core/Ui/Object/Action/Handler"], function (require, exports, tslib_1, Handler_1) {
"use strict";
* @author Alexander Ebert
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Conversation/Ui/Participant/Add
*/
define(["require", "exports", "tslib", "WoltLabSuite/Core/Ajax", "WoltLabSuite/Core/Dom/Util", "WoltLabSuite/Core/Ui/Dialog", "WoltLabSuite/Core/Ui/Notification", "WoltLabSuite/Core/Ui/ItemList/User", "WoltLabSuite/Core/Language"], function (require, exports, tslib_1, Ajax, Util_1, Dialog_1, UiNotification, UiItemListUser, Language) {
"use strict";
UiItemListUser = tslib_1.__importStar(UiItemListUser);
Language = tslib_1.__importStar(Language);
class UiParticipantAdd {
+ conversationId;
constructor(conversationId) {
this.conversationId = conversationId;
Ajax.api(this, {
Language = tslib_1.__importStar(Language);
UiNotification = tslib_1.__importStar(UiNotification);
class UiSubjectEditor {
+ objectId;
+ subject;
constructor(objectId) {
this.objectId = objectId;
}
</dd>
</dl>
<div class="formSubmit">
- <button class="buttonPrimary jsButtonSave">${Language.get("wcf.global.button.save")}</button>
+ <button type="button" class="button buttonPrimary jsButtonSave">${Language.get("wcf.global.button.save")}</button>
</div>
`,
};
* @author Alexander Ebert
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Ui/User/Menu/Data/Notification
* @woltlabExcludeBundle tiny
*/
define(["require", "exports", "tslib", "WoltLabSuite/Core/Ajax", "WoltLabSuite/Core/Ui/User/Menu/View", "WoltLabSuite/Core/Ui/User/Menu/Manager"], function (require, exports, tslib_1, Ajax_1, View_1, Manager_1) {
exports.setup = void 0;
View_1 = tslib_1.__importDefault(View_1);
class UserMenuDataConversation {
+ button;
+ counter = 0;
+ options;
+ stale = true;
+ view = undefined;
constructor(button, options) {
- this.counter = 0;
- this.stale = true;
- this.view = undefined;
this.button = button;
this.options = options;
const badge = button.querySelector(".badge");
const buttons = [];
if (this.options.canStartConversation) {
buttons.push({
- icon: '<span class="icon icon24 fa-plus"></span>',
+ icon: '<fa-icon size="24" name="plus"></fa-icon>',
link: this.options.newConversationLink,
name: "newConversation",
title: this.options.newConversationTitle,
--- /dev/null
+<?php
+
+use wcf\system\event\EventHandler;
+use wcf\system\worker\event\RebuildWorkerCollecting;
+
+return static function (): void {
+ $eventHandler = EventHandler::getInstance();
+
+ $eventHandler->register(RebuildWorkerCollecting::class, static function (RebuildWorkerCollecting $event) {
+ $event->register(\wcf\system\worker\ConversationMessageRebuildDataWorker::class, -5);
+ $event->register(\wcf\system\worker\ConversationRebuildDataWorker::class, 0);
+ $event->register(\wcf\system\worker\ConversationMessageSearchIndexRebuildDataWorker::class, 300);
+ });
+};
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*
* @property-read int $conversationID unique id of the conversation
* @property-read string $subject subject of the conversation
* default participation state
* @var int
*/
- const STATE_DEFAULT = 0;
+ public const STATE_DEFAULT = 0;
/**
* conversation is hidden but returns visible upon new message
* @var int
*/
- const STATE_HIDDEN = 1;
+ public const STATE_HIDDEN = 1;
/**
* conversation was left permanently
* @var int
*/
- const STATE_LEFT/*4DEAD*/ = 2;
+ public const STATE_LEFT/*4DEAD*/ = 2;
/**
* true if the current user can add users without limitations
/**
* @inheritDoc
*/
- public function getTitle()
+ public function getTitle(): string
{
return $this->subject;
}
/**
* @inheritDoc
*/
- public function getLink()
+ public function getLink(): string
{
return LinkHandler::getInstance()->getLink('Conversation', [
'object' => $this,
/**
* Returns true if this conversation is new for the active user.
- *
- * @return bool
*/
- public function isNew()
+ public function isNew(): bool
{
if (!$this->isDraft && $this->lastPostTime > $this->lastVisitTime) {
return true;
/**
* Returns true if the active user doesn't have read the given message.
- *
- * @param ConversationMessage $message
- * @return bool
*/
- public function isNewMessage(ConversationMessage $message)
+ public function isNewMessage(ConversationMessage $message): bool
{
if (!$this->isDraft && $message->time > $this->lastVisitTime) {
return true;
/**
* Returns true if the conversation is not closed or the user was not removed.
- *
- * @return bool
*/
- public function canReply()
+ public function canReply(): bool
{
if (!$this->canRead()) {
return false;
/**
* Returns true if the active user has the permission to read this conversation.
- *
- * @return bool
*/
- public function canRead()
+ public function canRead(): bool
{
if (!WCF::getUser()->userID) {
return false;
/**
* Returns true if the current user can add new participants to this conversation.
- *
- * @return bool
*/
- public function canAddParticipants()
+ public function canAddParticipants(): bool
{
if ($this->isDraft) {
return false;
/**
* Returns true if the current user can add participants without limitations.
- *
- * @return bool
*/
- public function canAddParticipantsUnrestricted()
+ public function canAddParticipantsUnrestricted(): bool
{
if ($this->canAddUnrestricted === null) {
$this->canAddUnrestricted = false;
/**
* Returns false if the active user is the last participant of this conversation.
- *
- * @return bool
*/
- public function hasOtherParticipants()
+ public function hasOtherParticipants(): bool
{
if ($this->userID == WCF::getUser()->userID) {
// author
/**
* Returns true if the current user is an active participant of this conversation.
- *
- * @return bool
*/
- public function isActiveParticipant()
+ public function isActiveParticipant(): bool
{
if ($this->isActiveParticipant === null) {
$sql = "SELECT leftAt
/**
* @inheritDoc
*/
- public function getPopoverLinkClass()
+ public function getPopoverLinkClass(): string
{
return 'conversationLink';
}
*
* @param int[] $conversationIDs
* @param int $userID
- * @return bool
*/
- public static function isParticipant(array $conversationIDs, $userID = null)
+ public static function isParticipant(array $conversationIDs, $userID = null): bool
{
if ($userID === null) {
$userID = WCF::getUser()->userID;
use wcf\system\log\modification\ConversationModificationLogHandler;
use wcf\system\request\LinkHandler;
use wcf\system\search\SearchIndexManager;
+use wcf\system\style\FontAwesomeIcon;
use wcf\system\user\notification\object\ConversationUserNotificationObject;
use wcf\system\user\notification\UserNotificationHandler;
use wcf\system\user\storage\UserStorageHandler;
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*
* @method ConversationEditor[] getObjects()
* @method ConversationEditor getSingleObject()
];
}
- /**
- * Validates parameters to return the mixed conversation list.
- *
- * @deprecated 5.5
- */
- public function validateGetMixedConversationList()
- {
- // does nothing
- }
-
- /**
- * Returns a mixed conversation list with up to 10 unread conversations.
- *
- * @return mixed[][]
- * @deprecated 5.5 This method provided the data for the legacy user panel implementation.
- */
- public function getMixedConversationList()
- {
- $sqlSelect = ' , (
- SELECT participantID
- FROM wcf' . WCF_N . '_conversation_to_user
- WHERE conversationID = conversation.conversationID
- AND participantID <> conversation.userID
- AND isInvisible = 0
- ORDER BY username, participantID
- LIMIT 1
- ) AS otherParticipantID
- , (
- SELECT username
- FROM wcf' . WCF_N . '_conversation_to_user
- WHERE conversationID = conversation.conversationID
- AND participantID <> conversation.userID
- AND isInvisible = 0
- ORDER BY username, participantID
- LIMIT 1
- ) AS otherParticipant';
-
- $unreadConversationList = new UserConversationList(WCF::getUser()->userID);
- $unreadConversationList->sqlSelects .= $sqlSelect;
- $unreadConversationList->getConditionBuilder()->add('conversation_to_user.lastVisitTime < lastPostTime');
- $unreadConversationList->sqlLimit = 10;
- $unreadConversationList->sqlOrderBy = 'lastPostTime DESC';
- $unreadConversationList->readObjects();
-
- $conversations = [];
- $count = 0;
- foreach ($unreadConversationList as $conversation) {
- $conversations[] = $conversation;
- $count++;
- }
-
- if ($count < 10) {
- $conversationList = new UserConversationList(WCF::getUser()->userID);
- $conversationList->sqlSelects .= $sqlSelect;
- $conversationList->getConditionBuilder()->add('conversation_to_user.lastVisitTime >= lastPostTime');
- $conversationList->sqlLimit = (10 - $count);
- $conversationList->sqlOrderBy = 'lastPostTime DESC';
- $conversationList->readObjects();
-
- foreach ($conversationList as $conversation) {
- $conversations[] = $conversation;
- }
- }
-
- WCF::getTPL()->assign([
- 'conversations' => $conversations,
- ]);
-
- $totalCount = ConversationHandler::getInstance()->getUnreadConversationCount();
- if ($count < 10 && $count < $totalCount) {
- UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadConversationCount');
- }
-
- return [
- 'template' => WCF::getTPL()->fetch('conversationListUserPanel'),
- 'totalCount' => $totalCount,
- ];
- }
-
/**
* @since 5.5
*/
$conversations = \array_map(static function (ViewableConversation $conversation) {
if ($conversation->userID === WCF::getUser()->userID) {
if ($conversation->participants > 1) {
- $image = '<span class="icon icon48 fa-users"></span>';
+ $image = FontAwesomeIcon::fromValues('users')->toHtml(48);
$usernames = \array_column($conversation->getParticipantSummary(), 'username');
} else {
$image = $conversation->getOtherParticipantProfile()->getAvatar()->getImageTag(48);
}
} else {
if ($conversation->participants > 1) {
- $image = '<span class="icon icon48 fa-users"></span>';
+ $image = FontAwesomeIcon::fromValues('users')->toHtml(48);
$usernames = \array_filter($conversation->getParticipantNames(), static function ($username) use ($conversation) {
return $username !== $conversation->getUserProfile()->username;
});
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*
* @method static Conversation create(array $parameters = [])
* @method Conversation getDecoratedObject()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*
* @method Conversation current()
* @method Conversation[] getObjects()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*/
class ConversationParticipantList extends UserProfileList
{
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*
* @method Conversation getDecoratedObject()
* @mixin Conversation
/**
* @inheritDoc
*/
- public function getLink()
+ public function getLink(): string
{
return LinkHandler::getInstance()->getLink('Conversation', [
'object' => $this->getDecoratedObject(),
/**
* @inheritDoc
*/
- public function getTitle()
+ public function getTitle(): string
{
return $this->getDecoratedObject()->getTitle();
}
/**
* @inheritDoc
*/
- public function getFormattedMessage()
+ public function getFormattedMessage(): string
{
return '';
}
/**
* @inheritDoc
*/
- public function getMessage()
+ public function getMessage(): string
{
return '';
}
/**
* @inheritDoc
*/
- public function getExcerpt($maxLength = 255)
+ public function getExcerpt($maxLength = 255): string
{
return '';
}
/**
* @inheritDoc
*/
- public function getUsername()
+ public function getUsername(): string
{
return $this->getDecoratedObject()->lastPoster;
}
/**
* @inheritDoc
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getFormattedMessage();
}
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*
* @method FeedConversation current()
* @method FeedConversation[] getObjects()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*
* @method ViewableConversation current()
* @method ViewableConversation[] getObjects()
conversation.*,
(CASE
WHEN conversation_to_user.leftAt <> 0
+ AND conversation.lastPostTime > conversation_to_user.leftAt
THEN conversation_to_user.leftAt
ELSE conversation.lastPostTime
END) AS lastPostTime";
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation
*
* @method Conversation getDecoratedObject()
* @mixin Conversation
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Label
*
* @property-read int $labelID unique id of the conversation label
* @property-read int $userID id of the user who created the conversation label
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Label
*
* @method ConversationLabel create()
* @method ConversationLabelEditor[] getObjects()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Label
*
* @method static ConversationLabel create(array $parameters = [])
* @method ConversationLabel getDecoratedObject()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Label
*
* @method ConversationLabel current()
* @method ConversationLabel[] getObjects()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*
* @property-read int $messageID unique id of the conversation message
* @property-read int $conversationID id of the conversation the conversation message belongs to
/**
* @inheritDoc
*/
- public function getFormattedMessage()
+ public function getFormattedMessage(): string
{
$processor = new HtmlOutputProcessor();
$processor->process($this->message, 'com.woltlab.wcf.conversation.message', $this->messageID);
/**
* Returns a simplified version of the formatted message.
- *
- * @return string
*/
- public function getSimplifiedFormattedMessage()
+ public function getSimplifiedFormattedMessage(): string
{
$processor = new HtmlOutputProcessor();
$processor->setOutputType('text/simplified-html');
/**
* @inheritDoc
*/
- public function getExcerpt($maxLength = 255)
+ public function getExcerpt($maxLength = 255): string
{
return StringUtil::truncateHTML($this->getSimplifiedFormattedMessage(), $maxLength);
}
* Returns a version of this message optimized for use in emails.
*
* @param string $mimeType Either 'text/plain' or 'text/html'
- * @return string
*/
- public function getMailText($mimeType = 'text/plain')
+ public function getMailText($mimeType = 'text/plain'): string
{
switch ($mimeType) {
case 'text/plain':
/**
* Returns true if current user may edit this message.
- *
- * @return bool
*/
- public function canEdit()
+ public function canEdit(): bool
{
return WCF::getUser()->userID == $this->userID
&& (
/**
* @inheritDoc
*/
- public function getMessage()
+ public function getMessage(): string
{
return $this->message;
}
/**
* @inheritDoc
*/
- public function getLink()
+ public function getLink(): string
{
return LinkHandler::getInstance()->getLink('Conversation', [
'object' => $this->getConversation(),
/**
* @inheritDoc
*/
- public function getTitle()
+ public function getTitle(): string
{
if ($this->messageID == $this->getConversation()->firstMessageID) {
return $this->getConversation()->subject;
/**
* @inheritDoc
*/
- public function isVisible()
+ public function isVisible(): bool
{
return true;
}
/**
* @inheritDoc
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getFormattedMessage();
}
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*
* @method ConversationMessageEditor[] getObjects()
* @method ConversationMessageEditor getSingleObject()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*
* @method static ConversationMessage create(array $parameters = [])
* @method ConversationMessage getDecoratedObject()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*
* @method ConversationMessage current()
* @method ConversationMessage[] getObjects()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*
* @property-read string|null $subject
*/
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*
* @method SearchResultConversationMessage current()
* @method SearchResultConversationMessage[] getObjects()
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*/
class SimplifiedViewableConversationMessageList extends ViewableConversationMessageList
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*
* @method ConversationMessage getDecoratedObject()
* @mixin ConversationMessage
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Conversation\Message
*
* @method ViewableConversationMessage current()
* @method ViewableConversationMessage[] getObjects()
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Modification\Log
*
* @method ViewableConversationModificationLog current()
* @method ViewableConversationModificationLog[] getObjects()
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data\Modification\Log
*
* @method ModificationLog getDecoratedObject()
* @mixin ModificationLog
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Form
*/
class ConversationAddForm extends MessageForm
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Form
*/
class ConversationDraftEditForm extends ConversationAddForm
{
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Page
*/
class ConversationFeedPage extends AbstractFeedPage
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Page
*
* @property UserConversationList $objectList
*/
if (!empty($userIDs)) {
// The condition is split into two branches in order to account for invisible participants.
// Invisible participants are only visible to the conversation starter and remain invisible
- // until the write their first message.
+ // until they write their first message.
//
// We need to protect these users from being exposed as participants by including them for
// any conversation that the current user has started. For all other conversations, users
use wcf\system\user\signature\SignatureCache;
use wcf\system\WCF;
use wcf\util\HeaderUtil;
-use wcf\util\StringUtil;
/**
* Shows a conversation.
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Page
*
* @property ViewableConversationMessageList $objectList
*/
MessageQuoteManager::getInstance()->assignVariables();
- $tmpHash = StringUtil::getRandomID();
+ $tmpHash = \sha1(\implode("\0", [
+ // Use class name + conversation ID to match the autosave scoping.
+ self::class,
+ $this->conversation->conversationID,
+ // Bind the tmpHash to the current session to make it unguessable.
+ WCF::getSession()->sessionID,
+ ]));
$attachmentHandler = new AttachmentHandler('com.woltlab.wcf.conversation.message', 0, $tmpHash, 0);
WCF::getTPL()->assign([
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Attachment
*
* @method ConversationMessage getObject($objectID)
*/
* @author Matthias Schmidt
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Cache\Runtime
* @since 3.0
*
* @method Conversation[] getCachedObjects()
* @author Matthias Schmidt
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Cache\Runtime
* @since 3.0
*
* @method Conversation[] getCachedObjects()
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Clipboard\Action
*/
class ConversationClipboardAction extends AbstractClipboardAction
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Conversation
*/
class ConversationHandler extends SingletonFactory
{
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Event\Listener
* @since 5.2
*/
class ConversationPruneIpAddressesCronjobListener implements IParameterizedEventListener
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Event\Listener
*/
class ConversationUserActionRenameListener extends AbstractUserActionRenameListener
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Event\Listener
*/
class ConversationUserMergeListener extends AbstractUserMergeListener
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Event\Listener
*/
class UserGroupAddCanBeAddedAsConversationParticipantListener implements IParameterizedEventListener
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Importer
*/
class ConversationAttachmentImporter extends AbstractAttachmentImporter
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Importer
*/
class ConversationImporter extends AbstractImporter
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Importer
*/
class ConversationLabelImporter extends AbstractImporter
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Importer
*/
class ConversationMessageImporter extends AbstractImporter
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Importer
*/
class ConversationUserImporter extends AbstractImporter
{
}
$data['participantID'] = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.user', $data['participantID']);
- $sql = "INSERT INTO wcf" . WCF_N . "_conversation_to_user
+ $sql = "INSERT INTO wcf1_conversation_to_user
(conversationID, participantID, username, hideConversation, isInvisible, lastVisitTime)
VALUES (?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE hideConversation = IF(hideConversation > 0 AND hideConversation = VALUES(hideConversation),hideConversation,0),
isInvisible = IF(isInvisible AND VALUES(isInvisible),1,0),
lastVisitTime = GREATEST(lastVisitTime,VALUES(lastVisitTime))";
- $statement = WCF::getDB()->prepareStatement($sql);
+ $statement = WCF::getDB()->prepare($sql);
$statement->execute([
$data['conversationID'],
$data['participantID'],
// save labels
if ($data['participantID'] && !empty($additionalData['labelIDs'])) {
- $sql = "INSERT IGNORE INTO wcf" . WCF_N . "_conversation_label_to_object
+ $sql = "INSERT IGNORE INTO wcf1_conversation_label_to_object
(labelID, conversationID)
VALUES (?, ?)";
- $statement = WCF::getDB()->prepareStatement($sql);
+ $statement = WCF::getDB()->prepare($sql);
foreach ($additionalData['labelIDs'] as $labelID) {
$labelID = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.conversation.label', $labelID);
if ($labelID) {
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Log\Modification
*/
class ConversationModificationLogHandler extends VoidExtendedModificationLogHandler
{
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Message\Quote
*/
class ConversationMessageQuoteHandler extends AbstractMessageQuoteHandler
{
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Moderation\Queue
*/
class ConversationMessageModerationQueueReportHandler extends AbstractModerationQueueHandler implements
IModerationQueueReportHandler
* @author Matthias Schmidt
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Page\Handler
* @since 3.0
*/
class ConversationListPageHandler extends AbstractMenuPageHandler
* @author Matthias Schmidt
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Page\Handler
* @since 3.0
*/
class DefaultConversationRelatedPageHandler extends AbstractMenuPageHandler implements IOnlineLocationPageHandler
* @author Matthias Schmidt
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Page\Handler
* @since 3.0
*/
trait TConversationOnlineLocationPageHandler
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Search
*/
final class ConversationMessageSearch extends AbstractSearchProvider
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Stat
*/
class ConversationMessageStatDailyHandler extends AbstractStatDailyHandler
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Stat
*/
class ConversationStatDailyHandler extends AbstractStatDailyHandler
{
* @author Joshua Ruesweg
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Content\Provider
* @since 5.2
*/
class ConversationMessageUserContentProvider extends AbstractDatabaseUserContentProvider
* @author Joshua Ruesweg
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Content\Provider
* @since 5.2
*/
class ConversationUserContentProvider extends AbstractDatabaseUserContentProvider
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Notification\Event
*
* @method ConversationMessageUserNotificationObject getUserNotificationObject()
*/
/**
* @inheritDoc
*/
- public function getTitle()
+ public function getTitle(): string
{
$count = \count($this->getAuthors());
if ($count > 1) {
/**
* @inheritDoc
*/
- public function getMessage()
+ public function getMessage(): string
{
$authors = \array_values($this->getAuthors());
$count = \count($authors);
* @inheritDoc
* @since 5.2
*/
- public function getEmailTitle()
+ public function getEmailTitle(): string
{
if (\count($this->getAuthors()) > 1) {
return parent::getEmailTitle();
/**
* @inheritDoc
*/
- public function getLink()
+ public function getLink(): string
{
return $this->getUserNotificationObject()->getLink();
}
/**
* @inheritDoc
*/
- public function getEventHash()
+ public function getEventHash(): string
{
return \sha1($this->eventID . '-' . $this->getUserNotificationObject()->conversationID);
}
/**
* @inheritDoc
*/
- public function checkAccess()
+ public function checkAccess(): bool
{
return $this->getUserNotificationObject()->getConversation()->canRead();
}
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Notification\Event
*
* @method ConversationUserNotificationObject getUserNotificationObject()
*/
/**
* @inheritDoc
*/
- public function getTitle()
+ public function getTitle(): string
{
return $this->getLanguage()->get('wcf.user.notification.conversation.title');
}
/**
* @inheritDoc
*/
- public function getMessage()
+ public function getMessage(): string
{
return $this->getLanguage()->getDynamicVariable('wcf.user.notification.conversation.message', [
'author' => $this->author,
* @inheritDoc
* @since 5.2
*/
- public function getEmailTitle()
+ public function getEmailTitle(): string
{
return $this->getLanguage()->getDynamicVariable('wcf.user.notification.conversation.mail.title', [
'author' => $this->author,
/**
* @inheritDoc
*/
- public function getLink()
+ public function getLink(): string
{
return $this->getUserNotificationObject()->getLink();
}
/**
* @inheritDoc
*/
- public function checkAccess()
+ public function checkAccess(): bool
{
return $this->getUserNotificationObject()->canRead();
}
* @author Matthias Schmidt
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Notification\Event
* @since 3.1
*/
trait TTestableConversationRelatedUserNotificationEvent
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Notification\Object
*
* @method ConversationMessage getDecoratedObject()
* @mixin ConversationMessage
/**
* @inheritDoc
*/
- public function getTitle()
+ public function getTitle(): string
{
return $this->getConversation()->subject;
}
/**
* @inheritDoc
*/
- public function getURL()
+ public function getURL(): string
{
return $this->getLink();
}
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Notification\Object
*
* @method Conversation getDecoratedObject()
* @mixin Conversation
/**
* @inheritDoc
*/
- public function getTitle()
+ public function getTitle(): string
{
return $this->subject;
}
/**
* @inheritDoc
*/
- public function getURL()
+ public function getURL(): string
{
return $this->getLink();
}
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Notification\Object\Type
*/
class ConversationMessageNotificationObjectType extends AbstractUserNotificationObjectType
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\User\Notification\Object\Type
*/
class ConversationNotificationObjectType extends AbstractUserNotificationObjectType
{
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Worker
*
* @method ConversationMessageList getObjectList()
*/
if ($this->count === null) {
$this->count = 0;
$sql = "SELECT MAX(messageID) AS messageID
- FROM wcf" . WCF_N . "_conversation_message";
- $statement = WCF::getDB()->prepareStatement($sql);
+ FROM wcf1_conversation_message";
+ $statement = WCF::getDB()->prepare($sql);
$statement->execute();
$row = $statement->fetchArray();
if ($row !== false) {
$attachmentObjectType = ObjectTypeCache::getInstance()
->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', 'com.woltlab.wcf.conversation.message');
$sql = "SELECT COUNT(*) AS attachments
- FROM wcf" . WCF_N . "_attachment
+ FROM wcf1_attachment
WHERE objectTypeID = ?
AND objectID = ?";
- $attachmentStatement = WCF::getDB()->prepareStatement($sql);
+ $attachmentStatement = WCF::getDB()->prepare($sql);
// retrieve permissions
$userIDs = [];
$updateData[$message->messageID] = $data;
}
- $sql = "UPDATE wcf" . WCF_N . "_conversation_message
+ $sql = "UPDATE wcf1_conversation_message
SET attachments = ?,
message = ?,
enableHtml = ?,
hasEmbeddedObjects = ?
WHERE messageID = ?";
- $statement = WCF::getDB()->prepareStatement($sql);
+ $statement = WCF::getDB()->prepare($sql);
WCF::getDB()->beginTransaction();
foreach ($updateData as $messageID => $data) {
* @author Tim Duesterhus
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Worker
*
* @method ConversationMessageList getObjectList()
*/
if ($this->count === null) {
$this->count = 0;
$sql = "SELECT MAX(messageID) AS messageID
- FROM wcf" . WCF_N . "_conversation_message";
- $statement = WCF::getDB()->prepareStatement($sql);
+ FROM wcf1_conversation_message";
+ $statement = WCF::getDB()->prepare($sql);
$statement->execute();
$row = $statement->fetchArray();
if ($row !== false) {
* @author Marcel Werk
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\System\Worker
*
* @method ConversationList getObjectList()
*/
if ($this->count === null) {
$this->count = 0;
$sql = "SELECT MAX(conversationID) AS conversationID
- FROM wcf" . WCF_N . "_conversation";
- $statement = WCF::getDB()->prepareStatement($sql);
+ FROM wcf1_conversation";
+ $statement = WCF::getDB()->prepare($sql);
$statement->execute();
$row = $statement->fetchArray();
if ($row !== false) {
// prepare statements
$sql = "SELECT messageID, time, userID, username
- FROM wcf" . WCF_N . "_conversation_message
+ FROM wcf1_conversation_message
WHERE conversationID = ?
ORDER BY time";
- $firstMessageStatement = WCF::getDB()->prepareStatement($sql, 1);
+ $firstMessageStatement = WCF::getDB()->prepare($sql, 1);
$sql = "SELECT time, userID, username
- FROM wcf" . WCF_N . "_conversation_message
+ FROM wcf1_conversation_message
WHERE conversationID = ?
ORDER BY time DESC";
- $lastMessageStatement = WCF::getDB()->prepareStatement($sql, 1);
+ $lastMessageStatement = WCF::getDB()->prepare($sql, 1);
$sql = "SELECT COUNT(*) AS messages,
SUM(attachments) AS attachments
- FROM wcf" . WCF_N . "_conversation_message
+ FROM wcf1_conversation_message
WHERE conversationID = ?";
- $statsStatement = WCF::getDB()->prepareStatement($sql);
+ $statsStatement = WCF::getDB()->prepare($sql);
$sql = "SELECT COUNT(*) AS participants
- FROM wcf" . WCF_N . "_conversation_to_user conversation_to_user
+ FROM wcf1_conversation_to_user conversation_to_user
WHERE conversation_to_user.conversationID = ?
AND conversation_to_user.hideConversation <> ?
AND conversation_to_user.participantID <> ?
AND conversation_to_user.isInvisible = ?";
- $participantCounterStatement = WCF::getDB()->prepareStatement($sql);
+ $participantCounterStatement = WCF::getDB()->prepare($sql);
$sql = "SELECT conversation_to_user.participantID AS userID, conversation_to_user.hideConversation, user_table.username
- FROM wcf" . WCF_N . "_conversation_to_user conversation_to_user
- LEFT JOIN wcf" . WCF_N . "_user user_table
+ FROM wcf1_conversation_to_user conversation_to_user
+ LEFT JOIN wcf1_user user_table
ON user_table.userID = conversation_to_user.participantID
WHERE conversation_to_user.conversationID = ?
AND conversation_to_user.participantID <> ?
AND conversation_to_user.isInvisible = ?
ORDER BY user_table.username";
- $participantStatement = WCF::getDB()->prepareStatement($sql, 5);
+ $participantStatement = WCF::getDB()->prepare($sql, 5);
$sql = "SELECT COUNT(*) AS participants
- FROM wcf" . WCF_N . "_conversation_to_user
+ FROM wcf1_conversation_to_user
WHERE conversationID = ?
AND hideConversation <> ?
AND participantID IS NOT NULL";
- $existingParticipantStatement = WCF::getDB()->prepareStatement($sql);
+ $existingParticipantStatement = WCF::getDB()->prepare($sql);
$obsoleteConversations = [];
$updateData = [];
$updateData[$conversation->conversationID] = $data;
}
- $sql = "UPDATE wcf" . WCF_N . "_conversation
+ $sql = "UPDATE wcf1_conversation
SET firstMessageID = ?,
lastPostTime = ?,
lastPosterID = ?,
participants = ?,
participantSummary = ?
WHERE conversationID = ?";
- $statement = WCF::getDB()->prepareStatement($sql);
+ $statement = WCF::getDB()->prepare($sql);
WCF::getDB()->beginTransaction();
foreach ($updateData as $conversationID => $data) {
.sidebar .box.conversationQuota .boxContent {
text-align: center;
}
-.conversationUsageBar {
- background-color: rgba(165, 223, 65, 1);
- height: 5px;
-
- > span {
- background-color: rgba(76, 169, 22, 1);
- color: transparent;
- display: block;
- height: 100%;
- }
-
- &.yellow {
- background-color: rgba(254, 207, 35, 1);
-
- > span {
- background-color: rgba(253, 146, 21, 1);
- }
- }
-
- &.red {
- background-color: rgba(255, 205, 210, 1);
-
- > span {
- background-color: rgba(244, 67, 54, 1);
- }
- }
+.conversationQuotaMeter {
+ width: 100%;
}
.conversationItem {
<item name="wcf.acp.option.module_conversation"><![CDATA[Konversationen]]></item>
</category>
<category name="wcf.acp.rebuildData">
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation"><![CDATA[Konversationen aktualisieren]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.description"><![CDATA[Aktualisiert Zähler der Konversationen]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message"><![CDATA[Konversationsnachrichten aktualisieren]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.description"><![CDATA[Aktualisiert Zähler der Konversationsnachrichten]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.search.index"><![CDATA[Suchindex für Konversationsnachrichten aktualisieren]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.search.index.description"><![CDATA[Warnung: Die Ausführung dieser Aktion kann bei größeren Foren sehr lange dauern.]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationRebuildDataWorker"><![CDATA[Konversationen aktualisieren]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationRebuildDataWorker.description"><![CDATA[Aktualisiert Zähler der Konversationen]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationMessageRebuildDataWorker"><![CDATA[Konversationsnachrichten aktualisieren]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationMessageRebuildDataWorker.description"><![CDATA[Aktualisiert Zähler der Konversationsnachrichten]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationMessageSearchIndexRebuildDataWorker"><![CDATA[Suchindex für Konversationsnachrichten aktualisieren]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationMessageSearchIndexRebuildDataWorker.description"><![CDATA[Warnung: Die Ausführung dieser Aktion kann bei größeren Foren sehr lange dauern.]]></item>
</category>
<category name="wcf.acp.stat">
<item name="wcf.acp.stat.com.woltlab.wcf.conversation"><![CDATA[Konversationen]]></item>
<item name="wcf.conversation.participants.other"><![CDATA[und {if $conversation->participants - $participantSummaryCount == 1}ein weiterer{else}{#$conversation->participants-$participantSummaryCount} weitere{/if}]]></item>
<item name="wcf.conversation.attachments"><![CDATA[Diese Konversation enthält {if $conversation->attachments == 1}einen Dateianhang{else}{#$conversation->attachments} Dateianhänge{/if}.]]></item>
<item name="wcf.conversation.error.mailboxIsFull"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} das zulässige Limit für Konversationen bereits erreicht und {if LANGUAGE_USE_INFORMAL_VARIANT}kannst{else}können{/if} keine neuen Konversationen starten.]]></item>
- <item name="wcf.conversation.message.editNote"><![CDATA[{$message->username} hat diese Nachricht {#$message->editCount} Mal editiert, zuletzt: {@$message->lastEditTime|time}.]]></item>
+ <item name="wcf.conversation.message.editNote"><![CDATA[{$message->username} hat diese Nachricht {#$message->editCount} Mal editiert, zuletzt: {time time=$message->lastEditTime}.]]></item>
<item name="wcf.conversation.noParticipantsWarning"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du bist{else}Sie sind{/if} dabei, auf eine Konversation ohne weitere Teilnehmer zu antworten. Alle anderen Teilnehmer haben diese Konversation verlassen. Niemand wird {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Nachricht lesen!]]></item>
<item name="wcf.conversation.message.permalink"><![CDATA[Permalink zur {#$startIndex}. Nachricht]]></item>
<item name="wcf.conversation.markAsRead.doubleClick"><![CDATA[Konversation durch Doppelklick als gelesen markieren]]></item>
<item name="wcf.conversation.visibility.previousMessages"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du wurdest{else}Sie wurden{/if} einer laufenden Konversation hinzugefügt, vorherige Nachrichten werden {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if} nicht angezeigt.]]></item>
<item name="wcf.conversation.time"><![CDATA[Erstellung]]></item>
<item name="wcf.conversation.username"><![CDATA[Autor]]></item>
- <item name="wcf.conversation.error.floodControl"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} innerhalb der letzten 24 Stunden bereits {if $limit == 1}eine Konversation{else}{#$limit} Konversationen{/if} gestartet. Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}warte{else}warten Sie{/if} bis zum <strong>{@$notBefore|time}</strong>, bevor {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} eine neue Konversation {if LANGUAGE_USE_INFORMAL_VARIANT}startest{else}starten{/if}.]]></item>
+ <item name="wcf.conversation.error.floodControl"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} innerhalb der letzten 24 Stunden bereits {if $limit == 1}eine Konversation{else}{#$limit} Konversationen{/if} gestartet. Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}warte{else}warten Sie{/if} bis zum <strong>{time time=$notBefore type='plainTime'}</strong>, bevor {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} eine neue Konversation {if LANGUAGE_USE_INFORMAL_VARIANT}startest{else}starten{/if}.]]></item>
<item name="wcf.conversation.message.error.floodControl"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} bereits eine Nachricht innerhalb der letzten {plural value=$__wcf->getSession()->getPermission('user.conversation.floodControlTime') 1='Sekunde' other='# Sekunden'} versendet. {if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} erst in {plural value=$waitTime 1='einer Sekunde' other='# Sekunden'} eine neue Nachricht verfassen.]]></item>
</category>
<category name="wcf.conversation.edit">
<item name="wcf.conversation.log.conversation.open"><![CDATA[Hat die Konversation wieder geöffnet.]]></item>
<item name="wcf.conversation.log.conversation.close"><![CDATA[Hat die Konversation für neue Nachrichten geschlossen.]]></item>
<item name="wcf.conversation.log.conversation.leave"><![CDATA[Hat die Konversation verlassen.]]></item>
- <item name="wcf.conversation.log.conversation.addParticipants"><![CDATA[Hat folgende Teilnehmer hinzugefügt: {implode from=$additionalData[participants] item=participant}<a href="{link controller='User' id=$participant[userID] title=$participant[username]}{/link}" class="userLink" data-object-id="{@$participant[userID]}">{$participant[username]}</a>{/implode}]]></item>
- <item name="wcf.conversation.log.conversation.removeParticipant"><![CDATA[Hat folgenden Teilnehmer entfernt: <a href="{link controller='User' id=$additionalData[userID] title=$additionalData[username]}{/link}" class="userLink" data-object-id="{@$additionalData[userID]}">{$additionalData[username]}</a>]]></item>
+ <item name="wcf.conversation.log.conversation.addParticipants"><![CDATA[Hat folgende Teilnehmer hinzugefügt: {implode from=$additionalData[participants] item=participant}<a href="{link controller='User' id=$participant[userID] title=$participant[username]}{/link}" class="userLink" data-object-id="{$participant[userID]}">{$participant[username]}</a>{/implode}]]></item>
+ <item name="wcf.conversation.log.conversation.removeParticipant"><![CDATA[Hat folgenden Teilnehmer entfernt: <a href="{link controller='User' id=$additionalData[userID] title=$additionalData[username]}{/link}" class="userLink" data-object-id="{$additionalData[userID]}">{$additionalData[username]}</a>]]></item>
</category>
<category name="wcf.acp.dataImport">
<item name="wcf.acp.dataImport.data.com.woltlab.wcf.conversation"><![CDATA[Konversationen]]></item>
<item name="wcf.user.notification.conversation.title"><![CDATA[Neue Konversation]]></item>
<item name="wcf.user.notification.conversation.mail.plaintext"><![CDATA[{@$author} hat die Konversation „{@$conversation->getTitle()}“ [URL:{@$conversation->getLink()}] gestartet:]]></item>
<item name="wcf.user.notification.conversation.mail.html"><![CDATA[<p><strong>{$author}</strong> hat die Konversation <a href="{$conversation->getLink()}">{$conversation->getTitle()}</a> gestartet:</p>]]></item>
- <item name="wcf.user.notification.conversation.mail.title"><![CDATA[Neue Konversation von "{@$author->username}"]]></item>
+ <item name="wcf.user.notification.conversation.mail.title"><![CDATA["{@$author}" hat die Konversation "{@$conversation->getTitle()}" gestartet]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.conversation"><![CDATA[Konversationen]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.conversation.notification.conversation"><![CDATA[Neue Konversation]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.conversation.message.notification.conversationMessage"><![CDATA[Antwort auf bestehende Konversation]]></item>
</category>
</import>
<delete>
- <item name="wcf.conversation.markAllAsRead" />
+ <item name="wbb.conversation.gotoFirstNewPost"/>
+ <item name="wbb.conversation.gotoLastPost"/>
+ <item name="wcf.acp.group.canBeAddedAsParticipant"/>
+ <item name="wcf.acp.group.option.user.conversation.allowedAttachmentExtensions.description"/>
+ <item name="wcf.acp.option.conversation_reply_show_messages_max"/>
+ <item name="wcf.acp.option.conversation_reply_show_messages_max.description"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.description"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.description"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.search.index"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.search.index.description"/>
+ <item name="wcf.clipboard.item.conversation.assignLabel"/>
+ <item name="wcf.clipboard.item.conversation.close"/>
+ <item name="wcf.clipboard.item.conversation.leave"/>
+ <item name="wcf.clipboard.item.conversation.leavePermanently"/>
+ <item name="wcf.clipboard.item.conversation.open"/>
+ <item name="wcf.clipboard.item.conversation.restore"/>
+ <item name="wcf.clipboard.label.conversation.marked"/>
+ <item name="wcf.conversation.gotoFirstNewPost"/>
+ <item name="wcf.conversation.log"/>
+ <item name="wcf.conversation.log.action"/>
+ <item name="wcf.conversation.log.noEntries"/>
+ <item name="wcf.conversation.log.time"/>
+ <item name="wcf.conversation.log.title"/>
+ <item name="wcf.conversation.markAllAsRead"/>
+ <item name="wcf.conversation.markAllAsRead.confirmMessage"/>
+ <item name="wcf.conversation.message.add"/>
+ <item name="wcf.conversation.message.add.previousPosts"/>
+ <item name="wcf.conversation.message.new"/>
+ <item name="wcf.conversation.subject"/>
+ <item name="wcf.page.category.com.woltlab.wcf.conversation"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.Conversation"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationAdd"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationAddForm"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationList"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationListPage"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationMessageAdd"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationMessageAddForm"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationMessageEdit"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationMessageEditForm"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationPage"/>
+ <item name="wcf.page.onlineLocation.com.woltlab.wcf.conversation.ConversationAdd"/>
+ <item name="wcf.page.onlineLocation.com.woltlab.wcf.conversation.ConversationList"/>
+ <item name="wcf.page.onlineLocation.com.woltlab.wcf.conversation.ConversationMessageAdd"/>
+ <item name="wcf.page.onlineLocation.com.woltlab.wcf.conversation.ConversationMessageEdit"/>
+ <item name="wcf.user.notification.com.woltlab.wcf.conversation.conversation"/>
+ <item name="wcf.user.notification.com.woltlab.wcf.conversation.conversationMessage"/>
+ <item name="wcf.user.notification.conversation.mail"/>
+ <item name="wcf.user.notification.conversation.message.mail"/>
+ <item name="wcf.user.notification.conversation.message.output"/>
+ <item name="wcf.user.notification.conversation.message.shortOutput"/>
+ <item name="wcf.user.notification.conversation.output"/>
+ <item name="wcf.user.notification.conversation.shortOutput"/>
+ <item name="wcf.user.usersOnline.location.ConversationAddForm"/>
+ <item name="wcf.user.usersOnline.location.ConversationListPage"/>
+ <item name="wcf.user.usersOnline.location.ConversationMessageAddForm"/>
+ <item name="wcf.user.usersOnline.location.ConversationMessageEditForm"/>
+ <item name="wcf.user.usersOnline.location.ConversationPage"/>
</delete>
</language>
<item name="wcf.acp.option.module_conversation"><![CDATA[Conversations]]></item>
</category>
<category name="wcf.acp.rebuildData">
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation"><![CDATA[Rebuild Conversations]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.description"><![CDATA[Rebuilds the conversation counters.]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message"><![CDATA[Rebuild Conversation Messages]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.description"><![CDATA[Rebuilds the conversation message counters.]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.search.index"><![CDATA[Rebuild Conversation Message Search Index]]></item>
- <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.search.index.description"><![CDATA[Warning: This action can take a while to complete on large forums.]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationRebuildDataWorker"><![CDATA[Rebuild Conversations]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationRebuildDataWorker.description"><![CDATA[Rebuilds the conversation counters.]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationMessageRebuildDataWorker"><![CDATA[Rebuild Conversation Messages]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationMessageRebuildDataWorker.description"><![CDATA[Rebuilds the conversation message counters.]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationMessageSearchIndexRebuildDataWorker"><![CDATA[Rebuild Conversation Message Search Index]]></item>
+ <item name="wcf.acp.rebuildData.wcf_system_worker_ConversationMessageSearchIndexRebuildDataWorker.description"><![CDATA[Warning: This action can take a while to complete on large forums.]]></item>
</category>
<category name="wcf.acp.stat">
<item name="wcf.acp.stat.com.woltlab.wcf.conversation"><![CDATA[Conversations]]></item>
<item name="wcf.conversation.searchConversation"><![CDATA[Search This Conversation Only]]></item>
<item name="wcf.conversation.searchedConversation"><![CDATA[Only search conversation <a href="{link controller='Conversation' object=$searchedConversation}{/link}">{$searchedConversation->getTitle()}</a>]]></item>
<item name="wcf.conversation.participants.other"><![CDATA[and {if $conversation->participants - $participantSummaryCount == 1}one other{else}{#$conversation->participants-$participantSummaryCount} others{/if}]]></item>
- <item name="wcf.conversation.attachments"><![CDATA[Conversation contains {#$conversation->attachments} attachment{if $conversation->attachments != 1}s{/if}]]></item>
+ <item name="wcf.conversation.attachments"><![CDATA[Conversation Contains {#$conversation->attachments} Attachment{if $conversation->attachments != 1}s{/if}]]></item>
<item name="wcf.conversation.error.mailboxIsFull"><![CDATA[You have reached your maximum conversations limit and cannot create new conversations.]]></item>
- <item name="wcf.conversation.message.editNote"><![CDATA[{$message->username} edited this message {#$message->editCount} times, last: {@$message->lastEditTime|time}.]]></item>
+ <item name="wcf.conversation.message.editNote"><![CDATA[{$message->username} edited this message {#$message->editCount} times, last: {time time=$message->lastEditTime}.]]></item>
<item name="wcf.conversation.noParticipantsWarning"><![CDATA[You are about to reply to a conversation without other participants, nobody is going to read your message!]]></item>
<item name="wcf.conversation.message.permalink"><![CDATA[Permalink to {#$startIndex}. message]]></item>
<item name="wcf.conversation.markAsRead.doubleClick"><![CDATA[Double-Click to Mark This Conversation Read]]></item>
<item name="wcf.conversation.visibility.previousMessages"><![CDATA[You have been added to an existing conversation, previously written messages are hidden.]]></item>
<item name="wcf.conversation.time"><![CDATA[Creation]]></item>
<item name="wcf.conversation.username"><![CDATA[Author]]></item>
- <item name="wcf.conversation.error.floodControl"><![CDATA[You have already started {if $limit == 1}one conversation{else}{#$limit} conversations{/if} in the past 24 hours. Please wait until <strong>{@$notBefore|time}</strong> before you start a new conversation.]]></item>
+ <item name="wcf.conversation.error.floodControl"><![CDATA[You have already started {if $limit == 1}one conversation{else}{#$limit} conversations{/if} in the past 24 hours. Please wait until <strong>{time time=$notBefore type='plainTime'}</strong> before you start a new conversation.]]></item>
<item name="wcf.conversation.message.error.floodControl"><![CDATA[You have already sent a message within the last {plural value=$__wcf->getSession()->getPermission('user.conversation.floodControlTime') 1='second' other='# seconds'}. You must wait at least {plural value=$waitTime 1='one second' other='# seconds'} before attempting to write a new message.]]></item>
</category>
<category name="wcf.conversation.edit">
<item name="wcf.conversation.log.conversation.open"><![CDATA[Opened the conversation again.]]></item>
<item name="wcf.conversation.log.conversation.close"><![CDATA[Closed the conversation for new replies.]]></item>
<item name="wcf.conversation.log.conversation.leave"><![CDATA[Left the conversation.]]></item>
- <item name="wcf.conversation.log.conversation.addParticipants"><![CDATA[Added the following participants: {implode from=$additionalData[participants] item=participant}<a href="{link controller='User' id=$participant[userID] title=$participant[username]}{/link}" class="userLink" data-object-id="{@$participant[userID]}">{$participant[username]}</a>{/implode}.]]></item>
- <item name="wcf.conversation.log.conversation.removeParticipant"><![CDATA[Removed a participant: <a href="{link controller='User' id=$additionalData[userID] title=$additionalData[username]}{/link}" class="userLink" data-object-id="{@$additionalData[userID]}">{$additionalData[username]}</a>.]]></item>
+ <item name="wcf.conversation.log.conversation.addParticipants"><![CDATA[Added the following participants: {implode from=$additionalData[participants] item=participant}<a href="{link controller='User' id=$participant[userID] title=$participant[username]}{/link}" class="userLink" data-object-id="{$participant[userID]}">{$participant[username]}</a>{/implode}.]]></item>
+ <item name="wcf.conversation.log.conversation.removeParticipant"><![CDATA[Removed a participant: <a href="{link controller='User' id=$additionalData[userID] title=$additionalData[username]}{/link}" class="userLink" data-object-id="{$additionalData[userID]}">{$additionalData[username]}</a>.]]></item>
</category>
<category name="wcf.acp.dataImport">
<item name="wcf.acp.dataImport.data.com.woltlab.wcf.conversation"><![CDATA[Conversations]]></item>
<item name="wcf.user.notification.conversation.title"><![CDATA[New Conversation]]></item>
<item name="wcf.user.notification.conversation.mail.plaintext"><![CDATA[{@$author} started the conversation “{@$conversation->getTitle()}” [URL:{@$conversation->getLink()}]:]]></item>
<item name="wcf.user.notification.conversation.mail.html"><![CDATA[<p><strong>{$author}</strong> started the conversation <a href="{$conversation->getLink()}">{$conversation->getTitle()}</a>:</p>]]></item>
- <item name="wcf.user.notification.conversation.mail.title"><![CDATA[New Conversation from "{@$author->username}"]]></item>
+ <item name="wcf.user.notification.conversation.mail.title"><![CDATA["{@$author}" started the conversation "{@$conversation->getTitle()}"]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.conversation"><![CDATA[Conversations]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.conversation.notification.conversation"><![CDATA[Notify me of new conversations]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.conversation.message.notification.conversationMessage"><![CDATA[Notify me of new replies in conversations]]></item>
</category>
</import>
<delete>
- <item name="wcf.conversation.markAllAsRead" />
+ <item name="wcf.acp.group.canBeAddedAsParticipant"/>
+ <item name="wcf.acp.group.option.user.conversation.allowedAttachmentExtensions.description"/>
+ <item name="wcf.acp.option.conversation_reply_show_messages_max"/>
+ <item name="wcf.acp.option.conversation_reply_show_messages_max.description"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.description"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.description"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.search.index"/>
+ <item name="wcf.acp.rebuildData.com.woltlab.wcf.conversation.message.search.index.description"/>
+ <item name="wcf.clipboard.item.conversation.assignLabel"/>
+ <item name="wcf.clipboard.item.conversation.close"/>
+ <item name="wcf.clipboard.item.conversation.leave"/>
+ <item name="wcf.clipboard.item.conversation.leavePermanently"/>
+ <item name="wcf.clipboard.item.conversation.open"/>
+ <item name="wcf.clipboard.item.conversation.restore"/>
+ <item name="wcf.clipboard.label.conversation.marked"/>
+ <item name="wcf.conversation.gotoFirstNewPost"/>
+ <item name="wcf.conversation.markAllAsRead"/>
+ <item name="wcf.conversation.markAllAsRead.confirmMessage"/>
+ <item name="wcf.conversation.message.add"/>
+ <item name="wcf.conversation.message.add.previousPosts"/>
+ <item name="wcf.conversation.message.new"/>
+ <item name="wcf.conversation.subject"/>
+ <item name="wcf.page.category.com.woltlab.wcf.conversation"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.Conversation"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationAdd"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationAddForm"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationList"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationListPage"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationMessageAdd"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationMessageAddForm"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationMessageEdit"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationMessageEditForm"/>
+ <item name="wcf.page.com.woltlab.wcf.conversation.ConversationPage"/>
+ <item name="wcf.page.onlineLocation.com.woltlab.wcf.conversation.ConversationAdd"/>
+ <item name="wcf.page.onlineLocation.com.woltlab.wcf.conversation.ConversationList"/>
+ <item name="wcf.page.onlineLocation.com.woltlab.wcf.conversation.ConversationMessageAdd"/>
+ <item name="wcf.page.onlineLocation.com.woltlab.wcf.conversation.ConversationMessageEdit"/>
+ <item name="wcf.user.notification.conversation.mail"/>
+ <item name="wcf.user.notification.conversation.message.mail"/>
+ <item name="wcf.user.notification.conversation.message.output"/>
+ <item name="wcf.user.notification.conversation.message.shortOutput"/>
+ <item name="wcf.user.notification.conversation.output"/>
+ <item name="wcf.user.notification.conversation.shortOutput"/>
+ <item name="wcf.user.usersOnline.location.ConversationAddForm"/>
+ <item name="wcf.user.usersOnline.location.ConversationListPage"/>
+ <item name="wcf.user.usersOnline.location.ConversationMessageAddForm"/>
+ <item name="wcf.user.usersOnline.location.ConversationMessageEditForm"/>
+ <item name="wcf.user.usersOnline.location.ConversationPage"/>
</delete>
</language>
</type>
<!-- /importers -->
<!-- rebuild data workers -->
- <type>
- <name>com.woltlab.wcf.conversation</name>
- <definitionname>com.woltlab.wcf.rebuildData</definitionname>
- <classname>wcf\system\worker\ConversationRebuildDataWorker</classname>
- </type>
- <type>
- <name>com.woltlab.wcf.conversation.message</name>
- <definitionname>com.woltlab.wcf.rebuildData</definitionname>
- <classname>wcf\system\worker\ConversationMessageRebuildDataWorker</classname>
- <nicevalue>-5</nicevalue>
- </type>
- <type>
- <name>com.woltlab.wcf.conversation.message.search.index</name>
- <definitionname>com.woltlab.wcf.rebuildData</definitionname>
- <classname>wcf\system\worker\ConversationMessageSearchIndexRebuildDataWorker</classname>
- <nicevalue>121</nicevalue>
- </type>
+
<!-- /rebuild data workers -->
<!-- stat handlers -->
<type>
<definitionname>com.woltlab.wcf.floodControl</definitionname>
</type>
</import>
+ <delete>
+ <type name="com.woltlab.wcf.conversation">
+ <definitionname>com.woltlab.wcf.rebuildData</definitionname>
+ <classname>wcf\system\worker\ConversationRebuildDataWorker</classname>
+ </type>
+ <type name="com.woltlab.wcf.conversation.message">
+ <definitionname>com.woltlab.wcf.rebuildData</definitionname>
+ <classname>wcf\system\worker\ConversationMessageRebuildDataWorker</classname>
+ <nicevalue>-5</nicevalue>
+ </type>
+ <type name="com.woltlab.wcf.conversation.message.search.index">
+ <definitionname>com.woltlab.wcf.rebuildData</definitionname>
+ <classname>wcf\system\worker\ConversationMessageSearchIndexRebuildDataWorker</classname>
+ <nicevalue>121</nicevalue>
+ </type>
+ </delete>
</data>
"packages": {
"": {
"dependencies": {
- "@woltlab/wcf": "https://github.com/WoltLab/WCF.git#5ed76b3a3267dfbffdf19405822d22510ad2bc7d"
+ "@woltlab/d.ts": "https://github.com/WoltLab/d.ts.git#c08648e9f82c381bd18b91ac1072c430e58e71f1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.5.0",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"prettier": "^3.0.3",
- "tslib": "^2.6.0",
"typescript": "^5.2.2"
}
},
"node": ">=0.10.0"
}
},
+ "node_modules/@ckeditor/ckeditor5-alignment": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-alignment/-/ckeditor5-alignment-39.0.2.tgz",
+ "integrity": "sha512-TjM+9h3tFn1wgnF4RJg0WaA758kT5VGSaVi0Ti6NECckPGXnccJpIQ7ZMSKAe4zCfaRSmNQsNYc20iq7w7+leg==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-autosave": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autosave/-/ckeditor5-autosave-39.0.2.tgz",
+ "integrity": "sha512-2YZwsPSFVwhqVoxU6HtQppmn8+TPnm7LmSKYt+7ESc72oqmWIcFGTkCmP5/gIt4oqz5twtJZ/v5lBg+92i3PyQ==",
+ "dependencies": {
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-basic-styles": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-39.0.2.tgz",
+ "integrity": "sha512-sp5sfE4d8Tng/zIssBK+SgaEkPfGcbmoGkjbHhPlWYAoQB9ONwvWkRZy9s3C+H0gfsEj3EqqxUKY70Us0yT8rA==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-block-quote": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-39.0.2.tgz",
+ "integrity": "sha512-ykxkLWJ1nuu5vVBnvHKKgKleudUNTjt/2zDsvUAiBbl4iN0rnOqhLbSL54fY4130p/DvE1CVoozqNiv7L83Vjw==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-clipboard": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-39.0.2.tgz",
+ "integrity": "sha512-SSuanBiQ4lWznXSGyeV5vqQweVWZ1+iZG1/atmrZSb/BOWa3XD6EGPu9tuzdm9MCjk2OxBuyMT07Cw+WzXFosQ==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "@ckeditor/ckeditor5-widget": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-code-block": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-39.0.2.tgz",
+ "integrity": "sha512-VlG/+VqxrR/JWQZVsGzemr3caOgQLB5OmSsFKPBEzoMI+05zf2UM232DyBVBUfA6UJ5L/ZMkT9YdUi+XhFnhAQ==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-core": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-39.0.2.tgz",
+ "integrity": "sha512-/xtor5vIXgwBVsAj+yO/wyzezQUmXabdkb/T8aSXtO2665zeOVbDbtSsJ1Ov7Tz5A4Ia1pA9d7iDCt7E8Kva7A==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-editor-classic": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-39.0.2.tgz",
+ "integrity": "sha512-zDDFe70junUJT5VltMsVdBqSZUew4fCe8fmi9JMI2m2MAwNwARAOkOy9mQMMTJlrD+P3CfD/Y9QpromEjLOnYA==",
+ "dependencies": {
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-engine": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-39.0.2.tgz",
+ "integrity": "sha512-ERcEpIrmTML0/uhukkC+ZJSOx4mRaPbNG5vPEBXIentfDpzu1NrmUhGZRGXaw5lltL+NJbuTI0wjEINap0Hl3w==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-enter": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-39.0.2.tgz",
+ "integrity": "sha512-7yeZI/mzJH4/yryXFQemrueZA/UNGkfnauN8Mu6XFMykoRNo6l+cASz0x4iGb3pWumV3g+tUeX6AJmuwXkRb5A==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-essentials": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-39.0.2.tgz",
+ "integrity": "sha512-5Nf3XeuB0thXTJS2M2JYrlW2uuSujNOhwW7L05e7Z5JP4nUSkopBHdvymX9feZKMzGPOw6SVhk8gQIDYV7S28A==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-font": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-font/-/ckeditor5-font-39.0.2.tgz",
+ "integrity": "sha512-6sGgo9X23gAllVjzGH1gOkjIEHkvm2O40IqUKCBwzn0K6Ry6St4R4QtcQeFV5jxAMKn0eD7blPuhItVrjmN0hw==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-heading": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-39.0.2.tgz",
+ "integrity": "sha512-P1ogDMAsTZB/TfuNwifNv1H9KHaMSPRaPfd+clhhLV/GAdt2rGMeH0HKuSke54cZYB6qMQP7Za8Xsfi2ufY0GA==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-highlight": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-highlight/-/ckeditor5-highlight-39.0.2.tgz",
+ "integrity": "sha512-WlinrcgNRgTMPCtg3ZfirEdbVpP+xSQdYGA/kmMTcjEnzfEUZv5ceecAF367158+hQNhY06p7Zpvxot8z6pobA==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-horizontal-line": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-horizontal-line/-/ckeditor5-horizontal-line-39.0.2.tgz",
+ "integrity": "sha512-lKPqiOwmuX/9s5TclET7cywcQ76TJh/w+6u3BK8buzlmyWzdeYXUyljNqWCgiS0i2yyY4w5XaJxXB/Ey7Ks8/w==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-html-embed": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-html-embed/-/ckeditor5-html-embed-39.0.2.tgz",
+ "integrity": "sha512-51dt9ndDl8Ba1ETmBDwAM0u82/yyF1uY5bXnHrkfrcYwGn+pHojKMTysilmniY35fo9Rn2TaV8eBsp/2h/tYMg==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-image": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-image/-/ckeditor5-image-39.0.2.tgz",
+ "integrity": "sha512-sp7ce+j/UqRW4kmhMX8DfZKPbNs5HgiEQY8ChQUPOKghstEjBrPpGFYCJ++NMPmWguDTzLxVAVuo2k+VOt+swA==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-indent": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-39.0.2.tgz",
+ "integrity": "sha512-wU/1jBqgkK068fxkZDxnZM5iACunABXBVtpgfXqe2S6cMPVQyhiLzo955Yt7BhqN7Mkor59xESO2+Npj/vwB7w==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-inspector": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-inspector/-/ckeditor5-inspector-4.1.0.tgz",
+ "integrity": "sha512-yKoIFpaSVQQIhgFEyoltwG40OSsWX5psYdYvNxW84nfxgrs90DJrbMQDtdchVZNMXBu6CkJfPiPG0WBLU9su3g==",
+ "engines": {
+ "node": ">=14.0.0",
+ "npm": ">=5.7.1"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-link": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-link/-/ckeditor5-link-39.0.2.tgz",
+ "integrity": "sha512-UKSamaD+yGaLPo/7pLS6bi+h2pRpX7qFSe4isVvmC8PfhN4YAm6ZYpIXpnktzfv2+/Jx6P9HzfjOnJPPT5PRdQ==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-list": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-list/-/ckeditor5-list-39.0.2.tgz",
+ "integrity": "sha512-XRcp67PuDK/mP0sL8g+TFLIr/MigVHKATwO+7OAJZlGAGxr73V/eRw3G6ZAe6Lh0lVQPRA54r+h5DHG5P+KRRg==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-mention": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-mention/-/ckeditor5-mention-39.0.2.tgz",
+ "integrity": "sha512-uTRenNKntYlzqnK5urqtwWRS5Frn888tne6YRJsHUJINX1h9kxgQ44svYx6QF9ZMdStmkEbKJfjZwNfnwWd95g==",
+ "dependencies": {
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-paragraph": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-39.0.2.tgz",
+ "integrity": "sha512-is0+G3ghz+6EwoNT5ciySiPt05FI0I/lxPksSDl4QG9BcGUwkN94fJalCxgXuMlGulojm/YZ3dCmJPnLMrAnUA==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-paste-from-office": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-39.0.2.tgz",
+ "integrity": "sha512-Y9O1C+9BpFCtvYI80AJzm/BkZWMedhreCaZcSCsEUUIo6vrIwehatTvgqWZJLwKZwL+4iy5/Kv9OfUhvO10I8Q==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-remove-format": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-remove-format/-/ckeditor5-remove-format-39.0.2.tgz",
+ "integrity": "sha512-gCoWMMUyvqjtQs+EUr7JpO8LEF2Ip7qXmCuSwLTteet79a8sQyllPY6O3UOUEuFMO2GtT36+jtQ93pQh7onn+g==",
+ "dependencies": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-select-all": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-39.0.2.tgz",
+ "integrity": "sha512-/zTPZ14sfsL6E7LHcdOSW5JR7A5tsaSO2KNlQ/jm77XWSeQ7HZ4I7hoLXWksvcseubQ+xExWrzMQIjIOGqBLcQ==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-table": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-table/-/ckeditor5-table-39.0.2.tgz",
+ "integrity": "sha512-IpI53KPEOj1F1vbMYUHLkOeoQoQV/q3pfiJxXXHZja1QaIEnqZT7YcSvJQbCyiuQw4UCZqU5x84c8GcyIZlBhg==",
+ "dependencies": {
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-theme-lark": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-theme-lark/-/ckeditor5-theme-lark-39.0.2.tgz",
+ "integrity": "sha512-v6S3++hkoKgqV71BCafKWYmPA6o/X44kUzdahnFs1rYBM5WS87y9Jb0W8Rv8FXXD5QD0H2axtySw9S6HfYspQw==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-ui": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-typing": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-39.0.2.tgz",
+ "integrity": "sha512-ylkBumukIRe/8jQTanVYNcExvoraXX9TIX3POwiug2F+c/POKjoHgeq8+Wf/JEl7/ydtXZKT5tROqOe9haSteA==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-ui": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-39.0.2.tgz",
+ "integrity": "sha512-OHYasdPXG1Vy1tR5hcGeffeqg6ujWzCEbRczuU+0sC3ttYkxrnFk6qYe7gjA+BoqD61otk1au+rhCVux8dy0hQ==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "color-convert": "2.0.1",
+ "color-parse": "1.4.2",
+ "lodash-es": "4.17.21",
+ "vanilla-colorful": "0.7.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-undo": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-39.0.2.tgz",
+ "integrity": "sha512-DSy7rRtnpVPpzZYOoQJNZ/6Zx4LEk3WVf8VG8wJDgpuxbRrE59DsNwVEqGEvDyVGlgzbuWZrfkkcL4hjcoYHCw==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-upload": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-39.0.2.tgz",
+ "integrity": "sha512-6LLU9lJDlnE4RT1GBzK1V6gsIv/+4NiWVojblzET9AlyMI4BRTn3/PPxZRWyPPKH96AeuIWoyj32D/a24yQujg==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-utils": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-39.0.2.tgz",
+ "integrity": "sha512-aqiGhPJxEihSLW21lGWcAvjVTTwJYxEbfMk1eLf/BEY3euy6iltRC6EqbXkyJDcKGU7cQtk6JXAIkH+D2FF87g==",
+ "dependencies": {
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-watchdog": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-39.0.2.tgz",
+ "integrity": "sha512-9E7BNp9c+nj/01JWF4lBVcDwJI2lN/Vgerw+ex4l/nTRl7crLzckSy3DWhYlpQPjJzsrkFjGQ+zCG4C/Vevl3Q==",
+ "dependencies": {
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@ckeditor/ckeditor5-widget": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-39.0.2.tgz",
+ "integrity": "sha512-bGs8iKD3c+r3/JCqhXoh/MPJut0JcdUdxDSgS+xYu1UJ03b/K39/0QbdVjT1I6oNRSDb4IUwBO2Xc3zTMl/qTw==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-enter": "39.0.2",
+ "@ckeditor/ckeditor5-typing": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/@googlemaps/markerclusterer": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.4.1.tgz",
+ "integrity": "sha512-ETBWYVLrBiBwDYG7gBmfwSlBluYfqq469I0Lz2qnJt3bGSI6cNAfIi8qjJChcjt4fM7s7OTxGSNlylzmql0BVQ==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "supercluster": "^8.0.1"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
"integrity": "sha512-CxTLMVtZsgrj9Ven5Pn1vcFumCFs+CG8Jfc63xWq/8b9e6uWjGyZlMnvQk7lIVn97Zd1vpu0ZK/OFWAoap0RCw=="
},
"node_modules/@types/google.maps": {
- "version": "3.51.1",
- "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.51.1.tgz",
- "integrity": "sha512-Wtl6PUL26jEbC1NBqJi7uoyYZo1/I3EDCd9pZk9EN6ZDvKaO28M5+nIQGyYomzvkMpMHnfywpTzalhwr76/oAg=="
+ "version": "3.54.0",
+ "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.54.0.tgz",
+ "integrity": "sha512-b1MBy2eGrZoEFLnzq1RrlHbfzuWHz+Nitgqbb5N+MFA0kAUv0kYPmAXtczpb4dHlFZyu58EYzcKXtWNqSInyXg=="
},
"node_modules/@types/jquery": {
- "version": "3.5.14",
- "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.14.tgz",
- "integrity": "sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==",
+ "version": "3.5.16",
+ "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.16.tgz",
+ "integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==",
"dependencies": {
"@types/sizzle": "*"
}
"integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==",
"dev": true
},
- "node_modules/@types/perfect-scrollbar": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/@types/perfect-scrollbar/-/perfect-scrollbar-0.7.0.tgz",
- "integrity": "sha512-hz9JUDS872oHDuRxi1Wqa3sdqxhZ3NkQk/T/+2Pz/nsPA6Lajf54kxocRLj6Ofi99YqzlSkDI7TrRc1qtbvzYQ==",
- "dependencies": {
- "@types/jquery": "*"
- }
- },
"node_modules/@types/pica": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/@types/pica/-/pica-5.1.3.tgz",
"resolved": "https://registry.npmjs.org/@types/twitter-for-web/-/twitter-for-web-0.0.2.tgz",
"integrity": "sha512-fDg882G9KHOkVxyJFkZ1hIOHxgj1vHLZnMJshF9W+8C2f9lzkIc/DeD1Ed2q1SWaHD/hdooaFIWTDhgL8zzpYg=="
},
+ "node_modules/@types/zxcvbn": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.2.tgz",
+ "integrity": "sha512-T7SEL8b/eN7AEhHQ8oFt7c6Y+l3p8OpH7KwJIe+5oBOPLMMioPeMsUTB3huNgEnXhiittV8Ohdw21Jg8E/f70Q=="
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz",
"url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/@woltlab/wcf": {
- "version": "5.4.0",
- "resolved": "git+ssh://git@github.com/WoltLab/WCF.git#5ed76b3a3267dfbffdf19405822d22510ad2bc7d",
- "integrity": "sha512-RFdoxbASRY4VpBSZkGhI6Vovf49YR4D9bjdxweJgobf+rPAcJAXmE5idzwk3osKrUS+yH2STewzsxZ6Bpak5cQ==",
+ "node_modules/@woltlab/d.ts": {
+ "resolved": "git+ssh://git@github.com/WoltLab/d.ts.git#c08648e9f82c381bd18b91ac1072c430e58e71f1",
+ "integrity": "sha512-cqNfrQOmIb3rX7qc/NtLQ/abvV5nxY8IS5ybE2h15q0X/jskjwdnSdGfX44bAbNKmjC9bQvi8LdZSzY0PNGHMw==",
"dependencies": {
+ "@ckeditor/ckeditor5-inspector": "^4.1.0",
+ "@googlemaps/markerclusterer": "^2.0.15",
"@types/facebook-js-sdk": "^3.3.6",
- "@types/google.maps": "^3.51.1",
- "@types/jquery": "^3.5.14",
- "@types/perfect-scrollbar": "^0.7.0",
+ "@types/google.maps": "^3.54.0",
+ "@types/jquery": "^3.5.16",
"@types/pica": "^5.1.3",
- "@types/prismjs": "^1.16.6",
+ "@types/prismjs": "^1.26.0",
"@types/twitter-for-web": "0.0.2",
- "focus-trap": "^6.9.4",
+ "@woltlab/editor": "git+https://github.com/WoltLab/editor.git#c407a8efe4f3ad08d7777cd71dce30b4dd2a523a",
+ "@woltlab/zxcvbn": "git+https://github.com/WoltLab/zxcvbn.git#5b582b24e437f1883ccad3c37dae7c3c5f1e7da3",
+ "focus-trap": "^7.5.2",
+ "html-parsed-element": "^0.4.1",
+ "perfect-scrollbar": "^1.5.5",
"qr-creator": "^1.0.0",
- "tabbable": "^5.3.3",
- "tslib": "^2.5.0"
+ "reflect-metadata": "^0.1.13",
+ "tabbable": "^6.2.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@woltlab/editor": {
+ "resolved": "git+ssh://git@github.com/WoltLab/editor.git#c407a8efe4f3ad08d7777cd71dce30b4dd2a523a",
+ "integrity": "sha512-ArKFz4h0uCEt+hPzhQN9rjJ1cQzXyASQiRlmubi4q9mYqc2ZAh1EQWUiVoaHAMPglcz0607712zJR0MQa9UYeg==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-alignment": "^39.0.2",
+ "@ckeditor/ckeditor5-autosave": "^39.0.2",
+ "@ckeditor/ckeditor5-basic-styles": "^39.0.2",
+ "@ckeditor/ckeditor5-block-quote": "^39.0.2",
+ "@ckeditor/ckeditor5-code-block": "^39.0.2",
+ "@ckeditor/ckeditor5-editor-classic": "^39.0.2",
+ "@ckeditor/ckeditor5-engine": "^39.0.2",
+ "@ckeditor/ckeditor5-essentials": "^39.0.2",
+ "@ckeditor/ckeditor5-font": "^39.0.2",
+ "@ckeditor/ckeditor5-heading": "^39.0.2",
+ "@ckeditor/ckeditor5-highlight": "^39.0.2",
+ "@ckeditor/ckeditor5-horizontal-line": "^39.0.2",
+ "@ckeditor/ckeditor5-html-embed": "^39.0.2",
+ "@ckeditor/ckeditor5-image": "^39.0.2",
+ "@ckeditor/ckeditor5-indent": "^39.0.2",
+ "@ckeditor/ckeditor5-link": "^39.0.2",
+ "@ckeditor/ckeditor5-list": "^39.0.2",
+ "@ckeditor/ckeditor5-mention": "^39.0.2",
+ "@ckeditor/ckeditor5-paragraph": "^39.0.2",
+ "@ckeditor/ckeditor5-paste-from-office": "^39.0.2",
+ "@ckeditor/ckeditor5-remove-format": "^39.0.2",
+ "@ckeditor/ckeditor5-table": "^39.0.2",
+ "@ckeditor/ckeditor5-theme-lark": "^39.0.2",
+ "@ckeditor/ckeditor5-ui": "^39.0.2",
+ "@ckeditor/ckeditor5-undo": "^39.0.2",
+ "@ckeditor/ckeditor5-utils": "^39.0.2",
+ "@ckeditor/ckeditor5-widget": "^39.0.2"
+ }
+ },
+ "node_modules/@woltlab/zxcvbn": {
+ "version": "4.4.2",
+ "resolved": "git+ssh://git@github.com/WoltLab/zxcvbn.git#5b582b24e437f1883ccad3c37dae7c3c5f1e7da3",
+ "integrity": "sha512-gi/PpP8I5YmaZV6oH8I6JfkKJhUfuKVGu6IkvQYMx3qXHXxzaCS1wSdy9WXIUG185PVRk9ca+RysLAcXd6lhYA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/zxcvbn": "^4.4.1"
}
},
"node_modules/acorn": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/ckeditor5": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-39.0.2.tgz",
+ "integrity": "sha512-7wuhb5LYeAZ9PaEZlNNAOnfDLWozt3+tOdc1St7AYR4PO1UW/5crWHvs+6jejxB56Zk6LUaHUS6ECecdapihmA==",
+ "dependencies": {
+ "@ckeditor/ckeditor5-clipboard": "39.0.2",
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-enter": "39.0.2",
+ "@ckeditor/ckeditor5-paragraph": "39.0.2",
+ "@ckeditor/ckeditor5-select-all": "39.0.2",
+ "@ckeditor/ckeditor5-typing": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-undo": "39.0.2",
+ "@ckeditor/ckeditor5-upload": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "@ckeditor/ckeditor5-watchdog": "39.0.2",
+ "@ckeditor/ckeditor5-widget": "39.0.2"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/color-parse": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-1.4.2.tgz",
+ "integrity": "sha512-RI7s49/8yqDj3fECFZjUI1Yi0z/Gq1py43oNJivAIIDSyJiOZLfYCRQEgn8HEVAj++PcRe8AnL2XF0fRJ3BTnA==",
+ "dependencies": {
+ "color-name": "^1.0.0"
+ }
},
"node_modules/concat-map": {
"version": "0.0.1",
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-glob": {
"version": "3.3.1",
"dev": true
},
"node_modules/focus-trap": {
- "version": "6.9.4",
- "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-6.9.4.tgz",
- "integrity": "sha512-v2NTsZe2FF59Y+sDykKY+XjqZ0cPfhq/hikWVL88BqLivnNiEffAsac6rP6H45ff9wG9LL5ToiDqrLEP9GX9mw==",
+ "version": "7.5.2",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz",
+ "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==",
"dependencies": {
- "tabbable": "^5.3.3"
+ "tabbable": "^6.2.0"
}
},
"node_modules/fs.realpath": {
"node": ">=8"
}
},
+ "node_modules/html-parsed-element": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/html-parsed-element/-/html-parsed-element-0.4.1.tgz",
+ "integrity": "sha512-uRNt6oVAFAQ/PBS9JZiURMpR2Me0KR11mOG6sbamJl1PIX7qMX1h/ck2EhY11RPU4m39o9x9XvOs5KaLneaxGA=="
+ },
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
+ "node_modules/kdbush": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
+ "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"node": ">=8"
}
},
+ "node_modules/perfect-scrollbar": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz",
+ "integrity": "sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g=="
+ },
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
}
]
},
+ "node_modules/reflect-metadata": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
+ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/supercluster": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
+ "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
+ "dependencies": {
+ "kdbush": "^4.0.2"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
}
},
"node_modules/tabbable": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz",
- "integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA=="
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
},
"node_modules/text-table": {
"version": "0.2.0",
}
},
"node_modules/tslib": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
- "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA=="
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/type-check": {
"version": "0.4.0",
"punycode": "^2.1.0"
}
},
+ "node_modules/vanilla-colorful": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/vanilla-colorful/-/vanilla-colorful-0.7.2.tgz",
+ "integrity": "sha512-z2YZusTFC6KnLERx1cgoIRX2CjPRP0W75N+3CC6gbvdX5Ch47rZkEMGO2Xnf+IEmi3RiFLxS18gayMA27iU7Kg=="
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
"dev": true
},
+ "@ckeditor/ckeditor5-alignment": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-alignment/-/ckeditor5-alignment-39.0.2.tgz",
+ "integrity": "sha512-TjM+9h3tFn1wgnF4RJg0WaA758kT5VGSaVi0Ti6NECckPGXnccJpIQ7ZMSKAe4zCfaRSmNQsNYc20iq7w7+leg==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-autosave": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autosave/-/ckeditor5-autosave-39.0.2.tgz",
+ "integrity": "sha512-2YZwsPSFVwhqVoxU6HtQppmn8+TPnm7LmSKYt+7ESc72oqmWIcFGTkCmP5/gIt4oqz5twtJZ/v5lBg+92i3PyQ==",
+ "requires": {
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-basic-styles": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-39.0.2.tgz",
+ "integrity": "sha512-sp5sfE4d8Tng/zIssBK+SgaEkPfGcbmoGkjbHhPlWYAoQB9ONwvWkRZy9s3C+H0gfsEj3EqqxUKY70Us0yT8rA==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-block-quote": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-39.0.2.tgz",
+ "integrity": "sha512-ykxkLWJ1nuu5vVBnvHKKgKleudUNTjt/2zDsvUAiBbl4iN0rnOqhLbSL54fY4130p/DvE1CVoozqNiv7L83Vjw==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-clipboard": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-39.0.2.tgz",
+ "integrity": "sha512-SSuanBiQ4lWznXSGyeV5vqQweVWZ1+iZG1/atmrZSb/BOWa3XD6EGPu9tuzdm9MCjk2OxBuyMT07Cw+WzXFosQ==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "@ckeditor/ckeditor5-widget": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-code-block": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-39.0.2.tgz",
+ "integrity": "sha512-VlG/+VqxrR/JWQZVsGzemr3caOgQLB5OmSsFKPBEzoMI+05zf2UM232DyBVBUfA6UJ5L/ZMkT9YdUi+XhFnhAQ==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-core": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-39.0.2.tgz",
+ "integrity": "sha512-/xtor5vIXgwBVsAj+yO/wyzezQUmXabdkb/T8aSXtO2665zeOVbDbtSsJ1Ov7Tz5A4Ia1pA9d7iDCt7E8Kva7A==",
+ "requires": {
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-editor-classic": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-39.0.2.tgz",
+ "integrity": "sha512-zDDFe70junUJT5VltMsVdBqSZUew4fCe8fmi9JMI2m2MAwNwARAOkOy9mQMMTJlrD+P3CfD/Y9QpromEjLOnYA==",
+ "requires": {
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-engine": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-39.0.2.tgz",
+ "integrity": "sha512-ERcEpIrmTML0/uhukkC+ZJSOx4mRaPbNG5vPEBXIentfDpzu1NrmUhGZRGXaw5lltL+NJbuTI0wjEINap0Hl3w==",
+ "requires": {
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-enter": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-39.0.2.tgz",
+ "integrity": "sha512-7yeZI/mzJH4/yryXFQemrueZA/UNGkfnauN8Mu6XFMykoRNo6l+cASz0x4iGb3pWumV3g+tUeX6AJmuwXkRb5A==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-essentials": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-39.0.2.tgz",
+ "integrity": "sha512-5Nf3XeuB0thXTJS2M2JYrlW2uuSujNOhwW7L05e7Z5JP4nUSkopBHdvymX9feZKMzGPOw6SVhk8gQIDYV7S28A==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-font": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-font/-/ckeditor5-font-39.0.2.tgz",
+ "integrity": "sha512-6sGgo9X23gAllVjzGH1gOkjIEHkvm2O40IqUKCBwzn0K6Ry6St4R4QtcQeFV5jxAMKn0eD7blPuhItVrjmN0hw==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-heading": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-39.0.2.tgz",
+ "integrity": "sha512-P1ogDMAsTZB/TfuNwifNv1H9KHaMSPRaPfd+clhhLV/GAdt2rGMeH0HKuSke54cZYB6qMQP7Za8Xsfi2ufY0GA==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-highlight": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-highlight/-/ckeditor5-highlight-39.0.2.tgz",
+ "integrity": "sha512-WlinrcgNRgTMPCtg3ZfirEdbVpP+xSQdYGA/kmMTcjEnzfEUZv5ceecAF367158+hQNhY06p7Zpvxot8z6pobA==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-horizontal-line": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-horizontal-line/-/ckeditor5-horizontal-line-39.0.2.tgz",
+ "integrity": "sha512-lKPqiOwmuX/9s5TclET7cywcQ76TJh/w+6u3BK8buzlmyWzdeYXUyljNqWCgiS0i2yyY4w5XaJxXB/Ey7Ks8/w==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-html-embed": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-html-embed/-/ckeditor5-html-embed-39.0.2.tgz",
+ "integrity": "sha512-51dt9ndDl8Ba1ETmBDwAM0u82/yyF1uY5bXnHrkfrcYwGn+pHojKMTysilmniY35fo9Rn2TaV8eBsp/2h/tYMg==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-image": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-image/-/ckeditor5-image-39.0.2.tgz",
+ "integrity": "sha512-sp7ce+j/UqRW4kmhMX8DfZKPbNs5HgiEQY8ChQUPOKghstEjBrPpGFYCJ++NMPmWguDTzLxVAVuo2k+VOt+swA==",
+ "requires": {
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-indent": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-39.0.2.tgz",
+ "integrity": "sha512-wU/1jBqgkK068fxkZDxnZM5iACunABXBVtpgfXqe2S6cMPVQyhiLzo955Yt7BhqN7Mkor59xESO2+Npj/vwB7w==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-inspector": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-inspector/-/ckeditor5-inspector-4.1.0.tgz",
+ "integrity": "sha512-yKoIFpaSVQQIhgFEyoltwG40OSsWX5psYdYvNxW84nfxgrs90DJrbMQDtdchVZNMXBu6CkJfPiPG0WBLU9su3g=="
+ },
+ "@ckeditor/ckeditor5-link": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-link/-/ckeditor5-link-39.0.2.tgz",
+ "integrity": "sha512-UKSamaD+yGaLPo/7pLS6bi+h2pRpX7qFSe4isVvmC8PfhN4YAm6ZYpIXpnktzfv2+/Jx6P9HzfjOnJPPT5PRdQ==",
+ "requires": {
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-list": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-list/-/ckeditor5-list-39.0.2.tgz",
+ "integrity": "sha512-XRcp67PuDK/mP0sL8g+TFLIr/MigVHKATwO+7OAJZlGAGxr73V/eRw3G6ZAe6Lh0lVQPRA54r+h5DHG5P+KRRg==",
+ "requires": {
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-mention": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-mention/-/ckeditor5-mention-39.0.2.tgz",
+ "integrity": "sha512-uTRenNKntYlzqnK5urqtwWRS5Frn888tne6YRJsHUJINX1h9kxgQ44svYx6QF9ZMdStmkEbKJfjZwNfnwWd95g==",
+ "requires": {
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-paragraph": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-39.0.2.tgz",
+ "integrity": "sha512-is0+G3ghz+6EwoNT5ciySiPt05FI0I/lxPksSDl4QG9BcGUwkN94fJalCxgXuMlGulojm/YZ3dCmJPnLMrAnUA==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-paste-from-office": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-39.0.2.tgz",
+ "integrity": "sha512-Y9O1C+9BpFCtvYI80AJzm/BkZWMedhreCaZcSCsEUUIo6vrIwehatTvgqWZJLwKZwL+4iy5/Kv9OfUhvO10I8Q==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-remove-format": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-remove-format/-/ckeditor5-remove-format-39.0.2.tgz",
+ "integrity": "sha512-gCoWMMUyvqjtQs+EUr7JpO8LEF2Ip7qXmCuSwLTteet79a8sQyllPY6O3UOUEuFMO2GtT36+jtQ93pQh7onn+g==",
+ "requires": {
+ "ckeditor5": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-select-all": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-39.0.2.tgz",
+ "integrity": "sha512-/zTPZ14sfsL6E7LHcdOSW5JR7A5tsaSO2KNlQ/jm77XWSeQ7HZ4I7hoLXWksvcseubQ+xExWrzMQIjIOGqBLcQ==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-table": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-table/-/ckeditor5-table-39.0.2.tgz",
+ "integrity": "sha512-IpI53KPEOj1F1vbMYUHLkOeoQoQV/q3pfiJxXXHZja1QaIEnqZT7YcSvJQbCyiuQw4UCZqU5x84c8GcyIZlBhg==",
+ "requires": {
+ "ckeditor5": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-theme-lark": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-theme-lark/-/ckeditor5-theme-lark-39.0.2.tgz",
+ "integrity": "sha512-v6S3++hkoKgqV71BCafKWYmPA6o/X44kUzdahnFs1rYBM5WS87y9Jb0W8Rv8FXXD5QD0H2axtySw9S6HfYspQw==",
+ "requires": {
+ "@ckeditor/ckeditor5-ui": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-typing": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-39.0.2.tgz",
+ "integrity": "sha512-ylkBumukIRe/8jQTanVYNcExvoraXX9TIX3POwiug2F+c/POKjoHgeq8+Wf/JEl7/ydtXZKT5tROqOe9haSteA==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-ui": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-39.0.2.tgz",
+ "integrity": "sha512-OHYasdPXG1Vy1tR5hcGeffeqg6ujWzCEbRczuU+0sC3ttYkxrnFk6qYe7gjA+BoqD61otk1au+rhCVux8dy0hQ==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "color-convert": "2.0.1",
+ "color-parse": "1.4.2",
+ "lodash-es": "4.17.21",
+ "vanilla-colorful": "0.7.2"
+ }
+ },
+ "@ckeditor/ckeditor5-undo": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-39.0.2.tgz",
+ "integrity": "sha512-DSy7rRtnpVPpzZYOoQJNZ/6Zx4LEk3WVf8VG8wJDgpuxbRrE59DsNwVEqGEvDyVGlgzbuWZrfkkcL4hjcoYHCw==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-upload": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-39.0.2.tgz",
+ "integrity": "sha512-6LLU9lJDlnE4RT1GBzK1V6gsIv/+4NiWVojblzET9AlyMI4BRTn3/PPxZRWyPPKH96AeuIWoyj32D/a24yQujg==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2"
+ }
+ },
+ "@ckeditor/ckeditor5-utils": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-39.0.2.tgz",
+ "integrity": "sha512-aqiGhPJxEihSLW21lGWcAvjVTTwJYxEbfMk1eLf/BEY3euy6iltRC6EqbXkyJDcKGU7cQtk6JXAIkH+D2FF87g==",
+ "requires": {
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-watchdog": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-39.0.2.tgz",
+ "integrity": "sha512-9E7BNp9c+nj/01JWF4lBVcDwJI2lN/Vgerw+ex4l/nTRl7crLzckSy3DWhYlpQPjJzsrkFjGQ+zCG4C/Vevl3Q==",
+ "requires": {
+ "lodash-es": "4.17.21"
+ }
+ },
+ "@ckeditor/ckeditor5-widget": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-39.0.2.tgz",
+ "integrity": "sha512-bGs8iKD3c+r3/JCqhXoh/MPJut0JcdUdxDSgS+xYu1UJ03b/K39/0QbdVjT1I6oNRSDb4IUwBO2Xc3zTMl/qTw==",
+ "requires": {
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-enter": "39.0.2",
+ "@ckeditor/ckeditor5-typing": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "lodash-es": "4.17.21"
+ }
+ },
"@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
"integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==",
"dev": true
},
+ "@googlemaps/markerclusterer": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.4.1.tgz",
+ "integrity": "sha512-ETBWYVLrBiBwDYG7gBmfwSlBluYfqq469I0Lz2qnJt3bGSI6cNAfIi8qjJChcjt4fM7s7OTxGSNlylzmql0BVQ==",
+ "requires": {
+ "fast-deep-equal": "^3.1.3",
+ "supercluster": "^8.0.1"
+ }
+ },
"@humanwhocodes/config-array": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
"integrity": "sha512-CxTLMVtZsgrj9Ven5Pn1vcFumCFs+CG8Jfc63xWq/8b9e6uWjGyZlMnvQk7lIVn97Zd1vpu0ZK/OFWAoap0RCw=="
},
"@types/google.maps": {
- "version": "3.51.1",
- "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.51.1.tgz",
- "integrity": "sha512-Wtl6PUL26jEbC1NBqJi7uoyYZo1/I3EDCd9pZk9EN6ZDvKaO28M5+nIQGyYomzvkMpMHnfywpTzalhwr76/oAg=="
+ "version": "3.54.0",
+ "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.54.0.tgz",
+ "integrity": "sha512-b1MBy2eGrZoEFLnzq1RrlHbfzuWHz+Nitgqbb5N+MFA0kAUv0kYPmAXtczpb4dHlFZyu58EYzcKXtWNqSInyXg=="
},
"@types/jquery": {
- "version": "3.5.14",
- "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.14.tgz",
- "integrity": "sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==",
+ "version": "3.5.16",
+ "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.16.tgz",
+ "integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==",
"requires": {
"@types/sizzle": "*"
}
"integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==",
"dev": true
},
- "@types/perfect-scrollbar": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/@types/perfect-scrollbar/-/perfect-scrollbar-0.7.0.tgz",
- "integrity": "sha512-hz9JUDS872oHDuRxi1Wqa3sdqxhZ3NkQk/T/+2Pz/nsPA6Lajf54kxocRLj6Ofi99YqzlSkDI7TrRc1qtbvzYQ==",
- "requires": {
- "@types/jquery": "*"
- }
- },
"@types/pica": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/@types/pica/-/pica-5.1.3.tgz",
"resolved": "https://registry.npmjs.org/@types/twitter-for-web/-/twitter-for-web-0.0.2.tgz",
"integrity": "sha512-fDg882G9KHOkVxyJFkZ1hIOHxgj1vHLZnMJshF9W+8C2f9lzkIc/DeD1Ed2q1SWaHD/hdooaFIWTDhgL8zzpYg=="
},
+ "@types/zxcvbn": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.2.tgz",
+ "integrity": "sha512-T7SEL8b/eN7AEhHQ8oFt7c6Y+l3p8OpH7KwJIe+5oBOPLMMioPeMsUTB3huNgEnXhiittV8Ohdw21Jg8E/f70Q=="
+ },
"@typescript-eslint/eslint-plugin": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz",
"eslint-visitor-keys": "^3.4.1"
}
},
- "@woltlab/wcf": {
- "version": "git+ssh://git@github.com/WoltLab/WCF.git#5ed76b3a3267dfbffdf19405822d22510ad2bc7d",
- "integrity": "sha512-RFdoxbASRY4VpBSZkGhI6Vovf49YR4D9bjdxweJgobf+rPAcJAXmE5idzwk3osKrUS+yH2STewzsxZ6Bpak5cQ==",
- "from": "@woltlab/wcf@https://github.com/WoltLab/WCF.git#5ed76b3a3267dfbffdf19405822d22510ad2bc7d",
+ "@woltlab/d.ts": {
+ "version": "git+ssh://git@github.com/WoltLab/d.ts.git#c08648e9f82c381bd18b91ac1072c430e58e71f1",
+ "integrity": "sha512-cqNfrQOmIb3rX7qc/NtLQ/abvV5nxY8IS5ybE2h15q0X/jskjwdnSdGfX44bAbNKmjC9bQvi8LdZSzY0PNGHMw==",
+ "from": "@woltlab/d.ts@https://github.com/WoltLab/d.ts.git#c08648e9f82c381bd18b91ac1072c430e58e71f1",
"requires": {
+ "@ckeditor/ckeditor5-inspector": "^4.1.0",
+ "@googlemaps/markerclusterer": "^2.0.15",
"@types/facebook-js-sdk": "^3.3.6",
- "@types/google.maps": "^3.51.1",
- "@types/jquery": "^3.5.14",
- "@types/perfect-scrollbar": "^0.7.0",
+ "@types/google.maps": "^3.54.0",
+ "@types/jquery": "^3.5.16",
"@types/pica": "^5.1.3",
- "@types/prismjs": "^1.16.6",
+ "@types/prismjs": "^1.26.0",
"@types/twitter-for-web": "0.0.2",
- "focus-trap": "^6.9.4",
+ "@woltlab/editor": "git+https://github.com/WoltLab/editor.git#c407a8efe4f3ad08d7777cd71dce30b4dd2a523a",
+ "@woltlab/zxcvbn": "git+https://github.com/WoltLab/zxcvbn.git#5b582b24e437f1883ccad3c37dae7c3c5f1e7da3",
+ "focus-trap": "^7.5.2",
+ "html-parsed-element": "^0.4.1",
+ "perfect-scrollbar": "^1.5.5",
"qr-creator": "^1.0.0",
- "tabbable": "^5.3.3",
- "tslib": "^2.5.0"
+ "reflect-metadata": "^0.1.13",
+ "tabbable": "^6.2.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "@woltlab/editor": {
+ "version": "git+ssh://git@github.com/WoltLab/editor.git#c407a8efe4f3ad08d7777cd71dce30b4dd2a523a",
+ "integrity": "sha512-ArKFz4h0uCEt+hPzhQN9rjJ1cQzXyASQiRlmubi4q9mYqc2ZAh1EQWUiVoaHAMPglcz0607712zJR0MQa9UYeg==",
+ "from": "@woltlab/editor@git+https://github.com/WoltLab/editor.git#c407a8efe4f3ad08d7777cd71dce30b4dd2a523a",
+ "requires": {
+ "@ckeditor/ckeditor5-alignment": "^39.0.2",
+ "@ckeditor/ckeditor5-autosave": "^39.0.2",
+ "@ckeditor/ckeditor5-basic-styles": "^39.0.2",
+ "@ckeditor/ckeditor5-block-quote": "^39.0.2",
+ "@ckeditor/ckeditor5-code-block": "^39.0.2",
+ "@ckeditor/ckeditor5-editor-classic": "^39.0.2",
+ "@ckeditor/ckeditor5-engine": "^39.0.2",
+ "@ckeditor/ckeditor5-essentials": "^39.0.2",
+ "@ckeditor/ckeditor5-font": "^39.0.2",
+ "@ckeditor/ckeditor5-heading": "^39.0.2",
+ "@ckeditor/ckeditor5-highlight": "^39.0.2",
+ "@ckeditor/ckeditor5-horizontal-line": "^39.0.2",
+ "@ckeditor/ckeditor5-html-embed": "^39.0.2",
+ "@ckeditor/ckeditor5-image": "^39.0.2",
+ "@ckeditor/ckeditor5-indent": "^39.0.2",
+ "@ckeditor/ckeditor5-link": "^39.0.2",
+ "@ckeditor/ckeditor5-list": "^39.0.2",
+ "@ckeditor/ckeditor5-mention": "^39.0.2",
+ "@ckeditor/ckeditor5-paragraph": "^39.0.2",
+ "@ckeditor/ckeditor5-paste-from-office": "^39.0.2",
+ "@ckeditor/ckeditor5-remove-format": "^39.0.2",
+ "@ckeditor/ckeditor5-table": "^39.0.2",
+ "@ckeditor/ckeditor5-theme-lark": "^39.0.2",
+ "@ckeditor/ckeditor5-ui": "^39.0.2",
+ "@ckeditor/ckeditor5-undo": "^39.0.2",
+ "@ckeditor/ckeditor5-utils": "^39.0.2",
+ "@ckeditor/ckeditor5-widget": "^39.0.2"
+ }
+ },
+ "@woltlab/zxcvbn": {
+ "version": "git+ssh://git@github.com/WoltLab/zxcvbn.git#5b582b24e437f1883ccad3c37dae7c3c5f1e7da3",
+ "integrity": "sha512-gi/PpP8I5YmaZV6oH8I6JfkKJhUfuKVGu6IkvQYMx3qXHXxzaCS1wSdy9WXIUG185PVRk9ca+RysLAcXd6lhYA==",
+ "from": "@woltlab/zxcvbn@git+https://github.com/WoltLab/zxcvbn.git#5b582b24e437f1883ccad3c37dae7c3c5f1e7da3",
+ "requires": {
+ "@types/zxcvbn": "^4.4.1"
}
},
"acorn": {
"supports-color": "^7.1.0"
}
},
+ "ckeditor5": {
+ "version": "39.0.2",
+ "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-39.0.2.tgz",
+ "integrity": "sha512-7wuhb5LYeAZ9PaEZlNNAOnfDLWozt3+tOdc1St7AYR4PO1UW/5crWHvs+6jejxB56Zk6LUaHUS6ECecdapihmA==",
+ "requires": {
+ "@ckeditor/ckeditor5-clipboard": "39.0.2",
+ "@ckeditor/ckeditor5-core": "39.0.2",
+ "@ckeditor/ckeditor5-engine": "39.0.2",
+ "@ckeditor/ckeditor5-enter": "39.0.2",
+ "@ckeditor/ckeditor5-paragraph": "39.0.2",
+ "@ckeditor/ckeditor5-select-all": "39.0.2",
+ "@ckeditor/ckeditor5-typing": "39.0.2",
+ "@ckeditor/ckeditor5-ui": "39.0.2",
+ "@ckeditor/ckeditor5-undo": "39.0.2",
+ "@ckeditor/ckeditor5-upload": "39.0.2",
+ "@ckeditor/ckeditor5-utils": "39.0.2",
+ "@ckeditor/ckeditor5-watchdog": "39.0.2",
+ "@ckeditor/ckeditor5-widget": "39.0.2"
+ }
+ },
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"requires": {
"color-name": "~1.1.4"
}
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "color-parse": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-1.4.2.tgz",
+ "integrity": "sha512-RI7s49/8yqDj3fECFZjUI1Yi0z/Gq1py43oNJivAIIDSyJiOZLfYCRQEgn8HEVAj++PcRe8AnL2XF0fRJ3BTnA==",
+ "requires": {
+ "color-name": "^1.0.0"
+ }
},
"concat-map": {
"version": "0.0.1",
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-glob": {
"version": "3.3.1",
"dev": true
},
"focus-trap": {
- "version": "6.9.4",
- "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-6.9.4.tgz",
- "integrity": "sha512-v2NTsZe2FF59Y+sDykKY+XjqZ0cPfhq/hikWVL88BqLivnNiEffAsac6rP6H45ff9wG9LL5ToiDqrLEP9GX9mw==",
+ "version": "7.5.2",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz",
+ "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==",
"requires": {
- "tabbable": "^5.3.3"
+ "tabbable": "^6.2.0"
}
},
"fs.realpath": {
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
+ "html-parsed-element": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/html-parsed-element/-/html-parsed-element-0.4.1.tgz",
+ "integrity": "sha512-uRNt6oVAFAQ/PBS9JZiURMpR2Me0KR11mOG6sbamJl1PIX7qMX1h/ck2EhY11RPU4m39o9x9XvOs5KaLneaxGA=="
+ },
"ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
+ "kdbush": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
+ "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="
+ },
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"p-locate": "^5.0.0"
}
},
+ "lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+ },
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true
},
+ "perfect-scrollbar": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz",
+ "integrity": "sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g=="
+ },
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true
},
+ "reflect-metadata": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
+ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
+ },
"resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
+ "supercluster": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
+ "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
+ "requires": {
+ "kdbush": "^4.0.2"
+ }
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
}
},
"tabbable": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz",
- "integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA=="
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
},
"text-table": {
"version": "0.2.0",
"requires": {}
},
"tslib": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
- "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA=="
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"type-check": {
"version": "0.4.0",
"punycode": "^2.1.0"
}
},
+ "vanilla-colorful": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/vanilla-colorful/-/vanilla-colorful-0.7.2.tgz",
+ "integrity": "sha512-z2YZusTFC6KnLERx1cgoIRX2CjPRP0W75N+3CC6gbvdX5Ch47rZkEMGO2Xnf+IEmi3RiFLxS18gayMA27iU7Kg=="
+ },
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"prettier": "^3.0.3",
- "tslib": "^2.6.0",
"typescript": "^5.2.2"
},
"dependencies": {
- "@woltlab/wcf": "https://github.com/WoltLab/WCF.git#5ed76b3a3267dfbffdf19405822d22510ad2bc7d"
+ "@woltlab/d.ts": "https://github.com/WoltLab/d.ts.git#c08648e9f82c381bd18b91ac1072c430e58e71f1"
}
}
<packageinformation>
<packagename>WoltLab Suite Core: Conversations</packagename>
<packagename language="de">WoltLab Suite Core: Konversationen</packagename>
- <packagedescription>Private conversations between multiple users</packagedescription>
- <packagedescription language="de">Private Konversationen zwischen mehreren Benutzern</packagedescription>
- <version>5.5.17</version>
- <date>2023-09-26</date>
+ <packagedescription>Private conversations between multiple users.</packagedescription>
+ <packagedescription language="de">Private Konversationen zwischen mehreren Benutzern.</packagedescription>
+ <version>6.0.0 RC 1</version>
+ <date>2023-09-15</date>
</packageinformation>
<authorinformation>
</authorinformation>
<requiredpackages>
- <requiredpackage minversion="5.5.17">com.woltlab.wcf</requiredpackage>
+ <requiredpackage minversion="6.0.0 RC 1">com.woltlab.wcf</requiredpackage>
</requiredpackages>
<excludedpackages>
- <excludedpackage version="5.6.0 Alpha 1">com.woltlab.wcf</excludedpackage>
+ <excludedpackage version="6.1.0 Alpha 1">com.woltlab.wcf</excludedpackage>
</excludedpackages>
<instructions type="install">
<instruction type="eventListener" />
<instruction type="page" />
</instructions>
-
- <instructions type="update" fromversion="5.5.16">
- <instruction type="file"/>
+
+ <instructions type="update" fromversion="5.5.*">
+ <instruction type="file" />
+ <instruction type="database">acp/database/install_com.woltlab.wcf.conversation.php</instruction>
+ <instruction type="userGroupOption" />
+ <instruction type="template" />
+ <instruction type="acpTemplate" />
+ <instruction type="option" />
+ <instruction type="templateListener" />
+ <instruction type="language" />
+ <instruction type="objectType" />
+ <instruction type="clipboardAction" />
+ <instruction type="coreObject" />
+ <instruction type="userNotificationEvent" />
+ <instruction type="userOption" />
+ <instruction type="eventListener" />
+ <instruction type="page" />
+
+ <instruction type="fileDelete" />
+ <instruction type="templateDelete" />
+ </instructions>
+
+ <instructions type="update" fromversion="6.0.0 Beta 1">
+ <void/>
</instructions>
</package>
<?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/2019/templateDelete.xsd">
<delete>
- <template>__userStartConversation</template>
- <template>conversationListUnread</template>
- <template>conversationLog</template>
- <template>conversationMessageAdd</template>
- <template>conversationMessageEdit</template>
- <template>searchResultConversationMessage</template>
+ <template>conversationListUserPanel</template>
</delete>
</data>
<eventname>menuInteraction</eventname>
<templatecode><![CDATA[{include file='__userProfileStartConversation'}]]></templatecode>
</templatelistener>
- <templatelistener name="mobileMenuConversation">
- <environment>user</environment>
- <templatename>pageMenuMobile</templatename>
- <eventname>userMenuItems</eventname>
- <templatecode><![CDATA[{include file='__mobileMenuConversation'}]]></templatecode>
- </templatelistener>
<templatelistener name="userGroupAddCanBeAddedAsConversationParticipant">
<environment>admin</environment>
<templatename>userGroupAdd</templatename>
<templatecode><![CDATA[{include file='__userGroupAddCanBeAddedAsConversationParticipant'}]]></templatecode>
</templatelistener>
</import>
+ <delete>
+ <templatelistener name="mobileMenuConversation">
+ <environment>user</environment>
+ <templatename>pageMenuMobile</templatename>
+ <eventname>userMenuItems</eventname>
+ <templatecode><![CDATA[{include file='__mobileMenuConversation'}]]></templatecode>
+ </templatelistener>
+ </delete>
</data>
+++ /dev/null
-{if MODULE_CONVERSATION && $__wcf->user->userID && $__wcf->session->getPermission('user.conversation.canUseConversation')}
- <li class="menuOverlayItem" data-more="com.woltlab.wcf.conversation">
- <a href="{link controller='ConversationList'}{/link}" class="menuOverlayItemLink menuOverlayItemBadge box24" data-badge-identifier="unreadConversations">
- <span class="icon icon24 fa-comments"></span>
- <span class="menuOverlayItemTitle">{lang}wcf.conversation.conversations{/lang}</span>
- {if $__wcf->getConversationHandler()->getUnreadConversationCount()}<span class="badge badgeUpdate">{#$__wcf->getConversationHandler()->getUnreadConversationCount()}</span>{/if}
- </a>
- </li>
-{/if}
-{if $__searchAreaInitialized|empty && $templateName|substr:0:12 == 'conversation'}
+{if $__searchAreaInitialized|empty && $templateName|str_starts_with:'conversation'}
{assign var='__searchObjectTypeName' value='com.woltlab.wcf.conversation.message'}
{if $__wcf->getActivePage()->identifier == 'com.woltlab.wcf.conversation.Conversation'}
{capture assign='__searchTypeLabel'}{lang}wcf.search.type.com.woltlab.wcf.conversation{/lang}{/capture}
- {capture assign='__searchTypesScoped'}<li><a href="#" data-extended-link="{link controller='Search'}extended=1&type=com.woltlab.wcf.conversation.message{/link}" data-object-type="com.woltlab.wcf.conversation.message" data-parameters='{ "conversationID": {@$conversation->conversationID} }'>{lang}wcf.search.type.com.woltlab.wcf.conversation{/lang}</a></li>{/capture}
+ {capture assign='__searchTypesScoped'}<li><a href="#" data-extended-link="{link controller='Search'}extended=1&type=com.woltlab.wcf.conversation.message{/link}" data-object-type="com.woltlab.wcf.conversation.message" data-parameters='{ "conversationID": {$conversation->conversationID} }'>{lang}wcf.search.type.com.woltlab.wcf.conversation{/lang}</a></li>{/capture}
{/if}
{/if}
{if MODULE_CONVERSATION && $__wcf->user->userID && $__wcf->session->getPermission('user.conversation.canUseConversation') && $__wcf->session->getPermission('user.conversation.canStartConversation') && $user->userID != $__wcf->user->userID}
- <li><a class="jsTooltip" href="{link controller='ConversationAdd'}userID={@$user->userID}{/link}" title="{lang}wcf.conversation.button.add{/lang}"><span class="icon icon16 fa-comments"></span> <span class="invisible">{lang}wcf.conversation.button.add{/lang}</span></a></li>
-{/if}
\ No newline at end of file
+ <li>
+ <a class="jsTooltip" href="{link controller='ConversationAdd'}userID={@$user->userID}{/link}" title="{lang}wcf.conversation.button.add{/lang}">
+ {icon name='comments' type='solid'}
+ <span class="invisible">{lang}wcf.conversation.button.add{/lang}</span>
+ </a>
+ </li>
+{/if}
aria-haspopup="true"
aria-expanded="false"
>
- <span class="icon icon32 fa-comments"></span> <span>{lang}wcf.conversation.conversations{/lang}</span> {if $__wcf->getConversationHandler()->getUnreadConversationCount()}<span class="badge badgeUpdate">{#$__wcf->getConversationHandler()->getUnreadConversationCount()}</span>{/if}
+ {icon size=32 name='comments' type='solid'}
+ <span>{lang}wcf.conversation.conversations{/lang}</span>
+ {if $__wcf->getConversationHandler()->getUnreadConversationCount()}
+ <span class="badge badgeUpdate">{#$__wcf->getConversationHandler()->getUnreadConversationCount()}</span>
+ {/if}
</a>
{if !OFFLINE || $__wcf->session->getPermission('admin.general.canViewPageDuringOfflineMode')}
- <script data-relocate="true" src="{@$__wcf->getPath()}js/WCF.Conversation{if !ENABLE_DEBUG_MODE}.min{/if}.js?v={@LAST_UPDATE_TIME}"></script>
+ <script data-relocate="true" src="{$__wcf->getPath()}js/WCF.Conversation{if !ENABLE_DEBUG_MODE}.min{/if}.js?v={@LAST_UPDATE_TIME}"></script>
<script data-relocate="true">
require(["WoltLabSuite/Core/Conversation/Ui/User/Menu/Data/Conversation"], ({ setup }) => {
setup({
</div>
<div class="contentHeaderTitle">
- <h1 class="contentTitle jsConversationSubject" data-conversation-id="{@$conversation->conversationID}">{$conversation->subject}</h1>
+ <h1 class="contentTitle jsConversationSubject" data-conversation-id="{$conversation->conversationID}">{$conversation->subject}</h1>
<ul class="inlineList contentHeaderMetaData">
{hascontent}
<li>
- <span class="icon icon16 fa-tags"></span>
+ {icon name='tags'}
<ul class="labelList">
{content}
{foreach from=$conversation->getAssignedLabels() item=label}
{/hascontent}
<li>
- <span class="icon icon16 fa-user"></span>
+ {icon name='user'}
{user object=$conversation->getUserProfile()}
</li>
<li>
- <span class="icon icon16 fa-clock-o"></span>
- <a href="{$conversation->getLink()}">{@$conversation->time|time}</a>
+ {icon name='clock'}
+ <a href="{$conversation->getLink()}">{time time=$conversation->time}</a>
</li>
{if $conversation->isClosed}
<li>
- <span class="icon icon16 fa-lock jsIconLock"></span>
+ <span class="jsIconLock">
+ {icon name='lock'}
+ </span>
{lang}wcf.global.state.closed{/lang}
</li>
{/if}
<nav class="contentHeaderNavigation">
<ul>
{content}
- {if $conversation->canReply()}<li class="jsOnly"><a href="#" class="button buttonPrimary jsQuickReply"><span class="icon icon16 fa-reply"></span> <span>{lang}wcf.conversation.message.button.add{/lang}</span></a></li>{/if}
+ {if $conversation->canReply()}
+ <li class="jsOnly">
+ <button type="button" class="button buttonPrimary jsQuickReply">
+ {icon name='reply'}
+ <span>{lang}wcf.conversation.message.button.add{/lang}</span>
+ </button>
+ </li>
+ {/if}
{event name='contentHeaderNavigation'}
{/content}
</ul>
{/capture}
{capture assign='contentInteractionButtons'}
- <div class="conversation jsConversationInlineEditorContainer contentInteractionButton" data-conversation-id="{@$conversation->conversationID}" data-label-ids="[ {implode from=$conversation->getAssignedLabels() item=label}{@$label->labelID}{/implode} ]" data-is-closed="{@$conversation->isClosed}" data-can-close-conversation="{if $conversation->userID == $__wcf->getUser()->userID}1{else}0{/if}" data-can-add-participants="{if $conversation->canAddParticipants()}1{else}0{/if}" data-is-draft="{if $conversation->isDraft}1{else}0{/if}">
- <a href="{if $conversation->isDraft}{link controller='ConversationDraftEdit' id=$conversation->conversationID}{/link}{else}#{/if}" class="button small jsConversationInlineEditor"><span class="icon icon16 fa-pencil"></span> <span>{lang}wcf.global.button.edit{/lang}</span></a>
+ <div class="conversation jsConversationInlineEditorContainer contentInteractionButton" data-conversation-id="{$conversation->conversationID}" data-label-ids="[ {implode from=$conversation->getAssignedLabels() item=label}{$label->labelID}{/implode} ]" data-is-closed="{$conversation->isClosed}" data-can-close-conversation="{if $conversation->userID == $__wcf->getUser()->userID}1{else}0{/if}" data-can-add-participants="{if $conversation->canAddParticipants()}1{else}0{/if}" data-is-draft="{if $conversation->isDraft}1{else}0{/if}">
+ {if $conversation->isDraft}
+ <a href="{link controller='ConversationDraftEdit' id=$conversation->conversationID}{/link}" class="button small jsConversationInlineEditor">
+ {icon name='pencil'}
+ <span>{lang}wcf.global.button.edit{/lang}</span>
+ </a>
+ {else}
+ <button type="button" class="button small jsConversationInlineEditor">
+ {icon name='pencil'}
+ <span>{lang}wcf.global.button.edit{/lang}</span>
+ </button>
+ {/if}
</div>
{/capture}
<ul class="containerBoxList tripleColumned conversationParticipantList jsObjectActionContainer" data-object-action-class-name="wcf\data\conversation\ConversationAction">
{foreach from=$participants item=participant}
- <li class="jsParticipant jsObjectActionObject{if !$participant->userID || $participant->hideConversation == 2 || $participant->leftAt > 0} conversationLeft{/if}" data-object-id="{@$conversation->getObjectID()}">
+ <li class="jsParticipant jsObjectActionObject{if !$participant->userID || $participant->hideConversation == 2 || $participant->leftAt > 0} conversationLeft{/if}" data-object-id="{$conversation->getObjectID()}">
<div class="box24">
{user object=$participant type='avatar24' ariaHidden='true' tabindex='-1'}
<div>
{user object=$participant}
{if $participant->isInvisible}<small>({lang}wcf.conversation.invisible{/lang})</small>{/if}
{if $participant->userID && ($conversation->userID == $__wcf->getUser()->userID) && ($participant->userID != $__wcf->getUser()->userID) && $participant->hideConversation != 2 && $participant->leftAt == 0}
- <a href="#" class="jsObjectAction jsTooltip jsOnly" data-object-action="removeParticipant" title="{lang}wcf.conversation.participants.removeParticipant{/lang}" data-confirm-message="{lang __encode=true}wcf.conversation.participants.removeParticipant.confirmMessage{/lang}" data-object-action-parameter-user-id="{@$participant->getObjectID()}"><span class="icon icon16 fa-times"></span></a>
+ <button
+ type="button"
+ class="jsObjectAction jsTooltip jsOnly"
+ data-object-action="removeParticipant"
+ title="{lang}wcf.conversation.participants.removeParticipant{/lang}"
+ data-confirm-message="{lang __encode=true}wcf.conversation.participants.removeParticipant.confirmMessage{/lang}"
+ data-object-action-parameter-user-id="{$participant->getObjectID()}"
+ >
+ {icon name='xmark'}
+ </button>
{/if}
</p>
<dl class="plain inlineDataList small">
<dt>{lang}wcf.conversation.lastVisitTime{/lang}</dt>
- <dd>{if $participant->lastVisitTime}{@$participant->lastVisitTime|time}{else}-{/if}</dd>
+ <dd>{if $participant->lastVisitTime}{time time=$participant->lastVisitTime}{else}-{/if}</dd>
</dl>
</div>
</div>
</ul>
</div>
-{if !ENABLE_DEBUG_MODE}<script src="{@$__wcf->getPath()}js/WoltLabSuite.Core.Conversation.min.js?v={@LAST_UPDATE_TIME}"></script>{/if}
-<script data-relocate="true" src="{@$__wcf->getPath()}js/WCF.Conversation{if !ENABLE_DEBUG_MODE}.min{/if}.js?v={@LAST_UPDATE_TIME}"></script>
+{if !ENABLE_DEBUG_MODE}<script src="{$__wcf->getPath()}js/WoltLabSuite.Core.Conversation.min.js?v={@LAST_UPDATE_TIME}"></script>{/if}
+<script data-relocate="true" src="{$__wcf->getPath()}js/WCF.Conversation{if !ENABLE_DEBUG_MODE}.min{/if}.js?v={@LAST_UPDATE_TIME}"></script>
<script data-relocate="true">
$(function() {
WCF.Language.addObject({
'wcf.global.subject': '{jslang}wcf.global.subject{/jslang}',
'wcf.message.bbcode.code.copy': '{jslang}wcf.message.bbcode.code.copy{/jslang}',
'wcf.message.error.editorAlreadyInUse': '{jslang}wcf.message.error.editorAlreadyInUse{/jslang}',
- 'wcf.moderation.report.reportContent': '{jslang}wcf.moderation.report.reportContent{/jslang}',
- 'wcf.moderation.report.success': '{jslang}wcf.moderation.report.success{/jslang}',
'wcf.conversation.label.assignLabels': '{jslang}wcf.conversation.label.assignLabels{/jslang}'
});
- var $availableLabels = [ {implode from=$labelList item=label}{ cssClassName: '{if $label->cssClassName}{@$label->cssClassName}{/if}', labelID: {@$label->labelID}, label: '{$label->label|encodeJS}' }{/implode} ];
+ var $availableLabels = [ {implode from=$labelList item=label}{ cssClassName: '{if $label->cssClassName}{@$label->cssClassName|encodeJS}{/if}', labelID: {@$label->labelID}, label: '{$label->label|encodeJS}' }{/implode} ];
var $editorHandler = new WCF.Conversation.EditorHandlerConversation($availableLabels);
var $inlineEditor = new WCF.Conversation.InlineEditor('.conversation');
$inlineEditor.setEditorHandler($editorHandler);
});
});
{/if}
-
- {if $__wcf->session->getPermission('user.profile.canReportContent')}
- new WCF.Moderation.Report.Content('com.woltlab.wcf.conversation.message', '.jsReportConversationMessage');
- {/if}
});
require(['WoltLabSuite/Core/Conversation/Ui/Object/Action/RemoveParticipant'], (UiObjectActionRemoveParticipant) => {
<dl{if $errorField == 'subject'} class="formError"{/if}>
<dt><label for="subject">{lang}wcf.global.subject{/lang}</label></dt>
<dd>
- <input type="text" id="subject" name="subject" value="{$subject}" required maxlength="255" class="long">
+ <input type="text" id="subject" name="subject" value="{$subject}" required autofocus maxlength="255" class="long">
{if $errorField == 'subject'}
<small class="innerError">
{if $errorType == 'empty'}
<div class="formSubmit">
<input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
- <button name="draft" accesskey="d" value="1">{lang}wcf.conversation.button.saveAsDraft{/lang}</button>
+ <button type="submit" class="button" name="draft" accesskey="d" value="1">{lang}wcf.conversation.button.saveAsDraft{/lang}</button>
{include file='messageFormPreviewButton' previewMessageObjectType='com.woltlab.wcf.conversation.message' previewMessageObjectID=0}
{csrfToken}
</div>
{/if}
<div class="formSubmit">
- <button id="addParticipants" class="buttonPrimary">{lang}wcf.global.button.submit{/lang}</button>
+ <button type="button" id="addParticipants" class="button buttonPrimary">{lang}wcf.global.button.submit{/lang}</button>
</div>
\ No newline at end of file
{foreach from=$labelList item=label}
<li>
<label>
- <input type="checkbox"{if $label->labelID|in_array:$assignedLabels} checked{/if} data-label-id="{@$label->labelID}">
- <span class="badge label{if $label->cssClassName} {@$label->cssClassName}{/if}">{$label->label}</span>
+ <input type="checkbox"{if $label->labelID|in_array:$assignedLabels} checked{/if} data-label-id="{$label->labelID}">
+ <span class="badge label{if $label->cssClassName} {$label->cssClassName}{/if}">{$label->label}</span>
</label>
</li>
{/foreach}
</ul>
<div class="formSubmit">
- <button class="buttonPrimary" id="assignLabels">{lang}wcf.global.button.save{/lang}</button>
+ <button type="button" class="button buttonPrimary" id="assignLabels">{lang}wcf.global.button.save{/lang}</button>
</div>
<ul class="conversationLabelList">
{content}
{foreach from=$labelList item=label}
- <li><a class="badge label{if $label->cssClassName} {@$label->cssClassName}{/if}" data-label-id="{@$label->labelID}" data-css-class-name="{if $label->cssClassName}{@$label->cssClassName}{else}none{/if}">{$label->label}</a></li>
+ <li><a class="badge label{if $label->cssClassName} {$label->cssClassName}{/if}" data-label-id="{$label->labelID}" data-css-class-name="{if $label->cssClassName}{$label->cssClassName}{else}none{/if}">{$label->label}</a></li>
{/foreach}
{/content}
</ul>
<ul role="group" aria-label="{lang}wcf.conversation.label.cssClassName{/lang}" id="labelManagementList">
{foreach from=$cssClassNames item=cssClassName}
<li><label>
- <input type="radio" name="cssClassName" value="{@$cssClassName}"{if $cssClassName == 'none'} checked{/if}>
- <span class="badge label{if $cssClassName != 'none'} {@$cssClassName}{/if}">{lang}wcf.conversation.label.placeholder{/lang}</span>
+ <input type="radio" name="cssClassName" value="{$cssClassName}"{if $cssClassName == 'none'} checked{/if}>
+ <span class="badge label{if $cssClassName != 'none'} {$cssClassName}{/if}">{lang}wcf.conversation.label.placeholder{/lang}</span>
</label></li>
{/foreach}
</ul>
</dl>
<div class="formSubmit">
- <button id="addLabel" class="buttonPrimary">{lang}wcf.global.button.save{/lang}</button>
- <button id="editLabel" style="display: none;" class="buttonPrimary">{lang}wcf.global.button.save{/lang}</button>
- <button id="deleteLabel" style="display: none;">{lang}wcf.conversation.label.management.deleteLabel{/lang}</button>
+ <button type="button" id="addLabel" class="button buttonPrimary">{lang}wcf.global.button.save{/lang}</button>
+ <button type="button" id="editLabel" class="button" style="display: none;" class="buttonPrimary">{lang}wcf.global.button.save{/lang}</button>
+ <button type="button" id="deleteLabel" class="button" style="display: none;">{lang}wcf.conversation.label.management.deleteLabel{/lang}</button>
</div>
-</section>
\ No newline at end of file
+</section>
</dl>
<div class="formSubmit">
- <button id="hideConversation" class="buttonPrimary">{lang}wcf.global.button.submit{/lang}</button>
+ <button type="button" id="hideConversation" class="button buttonPrimary">{lang}wcf.global.button.submit{/lang}</button>
</div>
<nav class="contentHeaderNavigation">
<ul>
{content}
- {if $__wcf->session->getPermission('user.conversation.canStartConversation')}<li><a href="{link controller='ConversationAdd'}{/link}" title="{lang}wcf.conversation.add{/lang}" class="button buttonPrimary"><span class="icon icon16 fa-plus"></span> <span>{lang}wcf.conversation.button.add{/lang}</span></a></li>{/if}
+ {if $__wcf->session->getPermission('user.conversation.canStartConversation')}
+ <li>
+ <a href="{link controller='ConversationAdd'}{/link}" title="{lang}wcf.conversation.add{/lang}" class="button buttonPrimary">
+ {icon name='plus'}
+ <span>{lang}wcf.conversation.button.add{/lang}</span>
+ </a>
+ </li>
+ {/if}
{event name='contentHeaderNavigation'}
{/content}
</ul>
{if $labelID}
{foreach from=$labelList item=label}
{if $label->labelID == $labelID}
- <span class="badge label{if $label->cssClassName} {@$label->cssClassName}{/if}">{$label->label}</span>
+ <span class="badge label{if $label->cssClassName} {$label->cssClassName}{/if}">{$label->label}</span>
{/if}
{/foreach}
{else}
<div class="dropdownMenu">
<ul class="scrollableDropdownMenu">
{foreach from=$labelList item=label}
- <li><a href="{link controller='ConversationList'}{if $filter}filter={@$filter}&{/if}{if !$participants|empty}participants={implode from=$participants item=participant}{$participant|rawurlencode}{/implode}&{/if}sortField={$sortField}&sortOrder={$sortOrder}&pageNo={@$pageNo}&labelID={@$label->labelID}{/link}"><span class="badge label{if $label->cssClassName} {@$label->cssClassName}{/if}" data-css-class-name="{if $label->cssClassName}{@$label->cssClassName}{/if}" data-label-id="{@$label->labelID}">{$label->label}</span></a></li>
+ <li><a href="{link controller='ConversationList'}{if $filter}filter={@$filter}&{/if}{if !$participants|empty}participants={implode from=$participants item=participant}{$participant|rawurlencode}{/implode}&{/if}sortField={$sortField}&sortOrder={$sortOrder}&pageNo={@$pageNo}&labelID={@$label->labelID}{/link}"><span class="badge label{if $label->cssClassName} {@$label->cssClassName}{/if}" data-css-class-name="{if $label->cssClassName}{@$label->cssClassName}{/if}" data-label-id="{$label->labelID}">{$label->label}</span></a></li>
{/foreach}
</ul>
<ul>
</div>
<div class="boxContent">
- <button id="manageLabel">{lang}wcf.conversation.label.management{/lang}</button>
+ <button type="button" id="manageLabel" class="button">{lang}wcf.conversation.label.management{/lang}</button>
</div>
</section>
<div class="boxContent">
{assign var='conversationCount' value=$__wcf->getConversationHandler()->getConversationCount()}
{assign var='maxConversationCount' value=$__wcf->session->getPermission('user.conversation.maxConversations')}
- <p class="conversationUsageBar{if $conversationCount/$maxConversationCount >= 1.0} red{elseif $conversationCount/$maxConversationCount > 0.9} yellow{/if}">
- <span style="width: {if $conversationCount/$maxConversationCount < 1.0}{@$conversationCount/$maxConversationCount*100|round:0}{else}100{/if}%">{#$conversationCount/$maxConversationCount*100}%</span>
- </p>
+ {assign var='conversationCountValue' value=$conversationCount/$maxConversationCount*100}
+ <meter class="conversationQuotaMeter" min="0" max="100" low="90" high="99" value="{$conversationCountValue|ceil}" aria-label="{lang}wcf.conversation.quota{/lang}">
+ {#$conversationCountValue} %
+ </meter>
<p><small>{lang}wcf.conversation.quota.description{/lang}</small></p>
</div>
</section>
{/capture}
{capture assign='contentInteractionButtons'}
- <a href="#" class="markAllAsReadButton contentInteractionButton button small jsOnly"><span class="icon icon16 fa-check"></span> <span>{lang}wcf.global.button.markAllAsRead{/lang}</span></a>
+ <button type="button" class="markAllAsReadButton contentInteractionButton button small jsOnly">
+ {icon name='check'}
+ <span>{lang}wcf.global.button.markAllAsRead{/lang}</span>
+ </button>
{/capture}
{capture assign='contentInteractionDropdownItems'}
<ul class="inlineList">
<li>
<a rel="nofollow" href="{link controller='ConversationList'}{if $filter}filter={@$filter}&{/if}{if !$participants|empty}participants={implode from=$participants item=participant}{$participant|rawurlencode}{/implode}&{/if}pageNo={@$pageNo}&sortField={$sortField}&sortOrder={if $sortOrder == 'ASC'}DESC{else}ASC{/if}{if $labelID}&labelID={@$labelID}{/if}{/link}">
- <span class="icon icon16 fa-sort-amount-{$sortOrder|strtolower} jsTooltip" title="{lang}wcf.global.sorting{/lang} ({lang}wcf.global.sortOrder.{if $sortOrder === 'ASC'}ascending{else}descending{/if}{/lang})"></span>
+ {if $sortOrder === 'ASC'}
+ <span class="jsTooltip" title="{lang}wcf.global.sorting{/lang} ({lang}wcf.global.sortOrder.ascending{/lang})">
+ {icon name='arrow-down-wide-short'}
+ </span>
+ {else}
+ <span class="jsTooltip" title="{lang}wcf.global.sorting{/lang} ({lang}wcf.global.sortOrder.descending{/lang})">
+ {icon name='arrow-down-short-wide'}
+ </span>
+ {/if}
</a>
</li>
<li>
{foreach from=$objects item=conversation}
<li class="tabularListRow">
- <ol class="tabularListColumns messageGroup conversation jsClipboardObject{if $conversation->isNew()} new{/if}" data-conversation-id="{@$conversation->conversationID}" data-label-ids="[ {implode from=$conversation->getAssignedLabels() item=label}{@$label->labelID}{/implode} ]" data-is-closed="{@$conversation->isClosed}" data-can-close-conversation="{if $conversation->userID == $__wcf->getUser()->userID}1{else}0{/if}" data-can-add-participants="{if $conversation->canAddParticipants()}1{else}0{/if}">
+ <ol class="tabularListColumns messageGroup conversation jsClipboardObject{if $conversation->isNew()} new{/if}" data-conversation-id="{$conversation->conversationID}" data-label-ids="[ {implode from=$conversation->getAssignedLabels() item=label}{$label->labelID}{/implode} ]" data-is-closed="{$conversation->isClosed}" data-can-close-conversation="{if $conversation->userID == $__wcf->getUser()->userID}1{else}0{/if}" data-can-add-participants="{if $conversation->canAddParticipants()}1{else}0{/if}">
<li class="columnMark jsOnly">
- <label><input type="checkbox" class="jsClipboardItem" data-object-id="{@$conversation->conversationID}"></label>
+ <label><input type="checkbox" class="jsClipboardItem" data-object-id="{$conversation->conversationID}"></label>
</li>
<li class="columnIcon columnAvatar">
{if $conversation->getUserProfile()->getAvatar()}
{/hascontent}
<h3>
- <a href="{if $conversation->isNew()}{link controller='Conversation' object=$conversation}action=firstNew{/link}{else}{$conversation->getLink()}{/if}" class="conversationLink messageGroupLink" data-object-id="{@$conversation->conversationID}">{$conversation->subject}</a>
+ <a href="{if $conversation->isNew()}{link controller='Conversation' object=$conversation}action=firstNew{/link}{else}{$conversation->getLink()}{/if}" class="conversationLink messageGroupLink" data-object-id="{$conversation->conversationID}">{$conversation->subject}</a>
{if $conversation->replies}
<span class="badge messageGroupCounterMobile">{@$conversation->replies|shortUnit}</span>
{/if}
<aside class="statusDisplay" role="presentation">
<ul class="statusIcons">
- {if $conversation->isClosed}<li><span class="icon icon16 fa-lock jsIconLock jsTooltip" title="{lang}wcf.global.state.closed{/lang}"></span></li>{/if}
- {if $conversation->attachments}<li><span class="icon icon16 fa-paperclip jsIconAttachment jsTooltip" title="{lang}wcf.conversation.attachments{/lang}"></span></li>{/if}
+ {if $conversation->isClosed}
+ <li>
+ <span class="jsIconLock jsTooltip" title="{lang}wcf.global.state.closed{/lang}">
+ {icon name='lock'}
+ </span>
+ </li>
+ {/if}
+ {if $conversation->attachments}
+ <li>
+ <span class="jsIconAttachment jsTooltip" title="{lang}wcf.conversation.attachments{/lang}">
+ {icon name='paperclip'}
+ </span>
+ </li>
+ {/if}
</ul>
</aside>
<ul class="inlineList dotSeparated small messageGroupInfo">
<li class="messageGroupAuthor">{user object=$conversation->getUserProfile()}</li>
- <li class="messageGroupTime">{@$conversation->time|time}</li>
+ <li class="messageGroupTime">{time time=$conversation->time}</li>
<li class="messageGroupEditLink jsOnly"><a href="#" class="jsConversationInlineEditor">{lang}wcf.global.button.edit{/lang}</a></li>
{event name='messageGroupInfo'}
</ul>
<ul class="messageGroupInfoMobile">
<li class="messageGroupAuthorMobile">{$conversation->username}</li>
- <li class="messageGroupLastPostTimeMobile">{@$conversation->lastPostTime|time}</li>
+ <li class="messageGroupLastPostTimeMobile">{time time=$conversation->lastPostTime}</li>
</ul>
{if $conversation->getParticipantSummary()|count}
<small class="conversationParticipantSummary">
{assign var='participantSummaryCount' value=$conversation->getParticipantSummary()|count}
- {lang}wcf.conversation.participants{/lang}: {implode from=$conversation->getParticipantSummary() item=participant}<a href="{$participant->getLink()}" class="userLink{if $participant->hideConversation == 2} conversationLeft{/if}" data-object-id="{@$participant->userID}">{$participant->username}</a>{/implode}
+ {lang}wcf.conversation.participants{/lang}: {implode from=$conversation->getParticipantSummary() item=participant}<a href="{$participant->getLink()}" class="userLink{if $participant->hideConversation == 2} conversationLeft{/if}" data-object-id="{$participant->userID}">{$participant->username}</a>{/implode}
{if $participantSummaryCount < $conversation->participants}{lang}wcf.conversation.participants.other{/lang}{/if}
</small>
{/if}
<dd>{@$conversation->participants|shortUnit}</dd>
</dl>
- <div class="messageGroupListStatsSimple">{if $conversation->replies}<span class="icon icon16 fa-comment-o" aria-label="{lang}wcf.conversation.replies{/lang}"></span> {@$conversation->replies|shortUnit}{/if}</div>
+ <div class="messageGroupListStatsSimple">
+ {if $conversation->replies}
+ <span aria-label="{lang}wcf.conversation.replies{/lang}">
+ {icon name='comment'}
+ </span>
+ {@$conversation->replies|shortUnit}
+ {/if}
+ </div>
</li>
<li class="columnLastPost">
{if $conversation->replies != 0 && $conversation->lastPostTime}
<p>
{user object=$conversation->getLastPosterProfile()}
</p>
- <small>{@$conversation->lastPostTime|time}</small>
+ <small>{time time=$conversation->lastPostTime}</small>
</div>
</div>
{/if}
<nav class="contentFooterNavigation">
<ul>
{content}
- {if $__wcf->session->getPermission('user.conversation.canStartConversation')}<li><a href="{link controller='ConversationAdd'}{/link}" title="{lang}wcf.conversation.add{/lang}" class="button buttonPrimary"><span class="icon icon16 fa-plus"></span> <span>{lang}wcf.conversation.button.add{/lang}</span></a></li>{/if}
+ {if $__wcf->session->getPermission('user.conversation.canStartConversation')}
+ <li>
+ <a href="{link controller='ConversationAdd'}{/link}" title="{lang}wcf.conversation.add{/lang}" class="button buttonPrimary">
+ {icon name='plus'}
+ <span>{lang}wcf.conversation.button.add{/lang}</span>
+ </a>
+ </li>
+ {/if}
{event name='contentFooterNavigation'}
{/content}
</ul>
{/hascontent}
</footer>
-<script data-relocate="true" src="{@$__wcf->getPath()}js/WCF.Conversation{if !ENABLE_DEBUG_MODE}.min{/if}.js?v={@LAST_UPDATE_TIME}"></script>
+<script data-relocate="true" src="{$__wcf->getPath()}js/WCF.Conversation{if !ENABLE_DEBUG_MODE}.min{/if}.js?v={@LAST_UPDATE_TIME}"></script>
<script data-relocate="true">
require([
'WoltLabSuite/Core/Language',
new WCF.Conversation.Clipboard($editorHandler);
new WCF.Conversation.Label.Manager('{link controller='ConversationList' encode=false}{if $filter}filter={@$filter}&{/if}{if !$participants|empty}participants={implode from=$participants item=participant}{$participant|rawurlencode}{/implode}&{/if}sortField={$sortField}&sortOrder={$sortOrder}&pageNo={@$pageNo}{/link}');
- new WCF.Conversation.MarkAsRead();
- new WCF.Conversation.MarkAllAsRead();
// mobile safari hover workaround
if ($(window).width() <= 800) {
});
</script>
+<script data-relocate="true">
+ require(['WoltLabSuite/Core/Conversation/Ui/MarkAsRead'], (MarkAsRead) => {
+ MarkAsRead.setup();
+ });
+ require(['WoltLabSuite/Core/Conversation/Ui/MarkAllAsRead'], (MarkAllAsRead) => {
+ MarkAllAsRead.setup();
+ });
+</script>
+
{include file='footer'}
+++ /dev/null
-{foreach from=$conversations item=conversation}
- <li class="conversationItem{if $conversation->lastVisitTime < $conversation->lastPostTime} conversationItemUnread interactiveDropdownItemOutstanding{/if}" data-link="{link controller='Conversation' object=$conversation}action=firstNew{/link}" data-object-id="{@$conversation->conversationID}" data-is-read="{if $conversation->lastVisitTime < $conversation->lastPostTime}false{else}true{/if}">
- <div class="box48">
- <div>
- {if $conversation->userID == $__wcf->user->userID}
- {if $conversation->participants > 1}
- <span class="icon icon48 fa-users"></span>
- {else}
- {@$conversation->getOtherParticipantProfile()->getAvatar()->getImageTag(48)}
- {/if}
- {else}
- {@$conversation->getUserProfile()->getAvatar()->getImageTag(48)}
- {/if}
- </div>
- <div>
- <h3><a href="{link controller='Conversation' object=$conversation}action=firstNew{/link}">{$conversation->subject}</a></h3>
- <small class="conversationInfo">
- <span class="conversationParticipant">
- {if $conversation->userID == $__wcf->user->userID}
- {if $conversation->participants > 1}
- {assign var='participantSummaryCount' value=$conversation->getParticipantSummary()|count}
- {implode from=$conversation->getParticipantSummary() item=participant}<a href="{$participant->getLink()}" class="userLink{if $participant->hideConversation == 2} conversationLeft{/if}" data-object-id="{@$participant->userID}">{$participant->username}</a>{/implode}
- {if $participantSummaryCount < $conversation->participants}{lang}wcf.conversation.participants.other{/lang}{/if}
- {else}
- {user object=$conversation->getOtherParticipantProfile()}
- {/if}
- {else}
- {user object=$conversation->getUserProfile()}
- {/if}
- </span>
-
- <span class="conversationLastPostTime">{@$conversation->lastPostTime|time}</span>
- </small>
- </div>
- </div>
- </li>
-{/foreach}
{capture assign='wysiwygSelector'}messageEditor{@$message->messageID}{/capture}
<div class="messageInlineEditor">
<textarea id="{$wysiwygSelector}" class="wysiwygTextarea"
- data-autosave="com.woltlab.wcf.conversation.messageEdit-{@$message->messageID}"
+ data-autosave="com.woltlab.wcf.conversation.messageEdit-{$message->messageID}"
data-support-mention="true"
>{$message->message}</textarea>
{capture assign=wysiwygContainerID}messageEditor{@$message->messageID}{/capture}
{include file='messageFormTabsInline' inConversationInlineEdit=true wysiwygContainerID=$wysiwygContainerID}
<div class="formSubmit">
- <button class="buttonPrimary" data-type="save">{lang}wcf.global.button.save{/lang}</button>
+ <button type="button" class="button buttonPrimary" data-type="save">{lang}wcf.global.button.save{/lang}</button>
{include file='messageFormPreviewButton' previewMessageFieldID=$wysiwygSelector previewButtonID=$wysiwygSelector|concat:'_PreviewButton' previewMessageObjectType='com.woltlab.wcf.conversation.message' previewMessageObjectID=$message->messageID}
- <button data-type="cancel">{lang}wcf.global.button.cancel{/lang}</button>
+ <button type="button" class="button" data-type="cancel">{lang}wcf.global.button.cancel{/lang}</button>
</div>
{include file='wysiwyg' wysiwygEnableUpload=true}
{assign var='objectID' value=$message->messageID}
{assign var='userProfile' value=$message->getUserProfile()}
- <li id="message{@$message->messageID}" class="anchorFixedHeader{if $conversation->userID == $message->userID} messageGroupStarter{/if}">
- <article class="message messageSidebarOrientation{@$__wcf->getStyleHandler()->getStyle()->getVariable('messageSidebarOrientation')|ucfirst} jsMessage{if $userProfile->userOnlineGroupID} userOnlineGroupMarking{@$userProfile->userOnlineGroupID}{/if}" data-user-id="{@$message->userID}" data-can-edit="{if $message->canEdit()}1{else}0{/if}" data-object-id="{@$message->messageID}">
+ <li id="message{$message->messageID}" class="anchorFixedHeader{if $conversation->userID == $message->userID} messageGroupStarter{/if}">
+ <article class="message messageSidebarOrientation{$__wcf->getStyleHandler()->getStyle()->getVariable('messageSidebarOrientation')|ucfirst} jsMessage{if $userProfile->userOnlineGroupID} userOnlineGroupMarking{$userProfile->userOnlineGroupID}{/if}" data-user-id="{$message->userID}" data-can-edit="{if $message->canEdit()}1{else}0{/if}" data-object-id="{$message->messageID}">
{include file='messageSidebar'}
<div class="messageContent">
<header class="messageHeader">
<div class="messageHeaderBox">
<ul class="messageHeaderMetaData">
- <li><a href="{link controller='Conversation' object=$conversation}messageID={@$message->messageID}{/link}#message{@$message->messageID}" class="permalink messagePublicationTime">{@$message->time|time}</a></li>
+ <li><a href="{link controller='Conversation' object=$conversation}messageID={@$message->messageID}{/link}#message{$message->messageID}" class="permalink messagePublicationTime">{time time=$message->time}</a></li>
{event name='messageHeaderMetaData'}
</ul>
</div>
<ul class="messageQuickOptions">
- <li><a href="{link controller='Conversation' object=$conversation}messageID={@$message->messageID}{/link}#message{@$message->messageID}" class="jsTooltip" title="{lang}wcf.conversation.message.permalink{/lang}">#{#$startIndex}</a></li>
+ <li><a href="{link controller='Conversation' object=$conversation}messageID={@$message->messageID}{/link}#message{$message->messageID}" class="jsTooltip" title="{lang}wcf.conversation.message.permalink{/lang}">#{#$startIndex}</a></li>
{event name='messageQuickOptions'}
</ul>
<div class="messageFooterGroup">
<ul class="messageFooterButtons buttonList smallButtons jsMobileNavigation">
- {if $message->canEdit()}<li class="jsOnly"><a href="{if $conversation->isDraft && $message->messageID == $conversation->firstMessageID}{link controller='ConversationDraftEdit' id=$conversation->conversationID}{/link}{else}#{/if}" title="{lang}wcf.conversation.message.edit{/lang}" class="button{if !$conversation->isDraft || $message->messageID != $conversation->firstMessageID} jsMessageEditButton{/if}"><span class="icon icon16 fa-pencil"></span> <span>{lang}wcf.global.button.edit{/lang}</span></a></li>{/if}
- <li class="jsQuoteMessage" data-object-id="{@$message->messageID}" data-is-quoted="{if $__quoteFullQuote|isset && $message->messageID|in_array:$__quoteFullQuote}1{else}0{/if}"><a href="#" title="{lang}wcf.message.quote.quoteMessage{/lang}" class="button jsTooltip{if $__quoteFullQuote|isset && $message->messageID|in_array:$__quoteFullQuote} active{/if}"><span class="icon icon16 fa-quote-left"></span> <span class="invisible">{lang}wcf.message.quote.quoteMessage{/lang}</span></a></li>
- {if $message->userID != $__wcf->getUser()->userID && $__wcf->session->getPermission('user.profile.canReportContent')}<li class="jsReportConversationMessage jsOnly" data-object-id="{@$message->messageID}"><a href="#" title="{lang}wcf.moderation.report.reportContent{/lang}" class="button jsTooltip"><span class="icon icon16 fa-exclamation-triangle"></span> <span class="invisible">{lang}wcf.moderation.report.reportContent{/lang}</span></a></li>{/if}
+ {if $message->canEdit()}
+ <li class="jsOnly">
+ <a
+ href="{if $conversation->isDraft && $message->messageID == $conversation->firstMessageID}{link controller='ConversationDraftEdit' id=$conversation->conversationID}{/link}{else}#{/if}"
+ title="{lang}wcf.conversation.message.edit{/lang}"
+ class="button{if !$conversation->isDraft || $message->messageID != $conversation->firstMessageID} jsMessageEditButton{/if}"
+ >
+ {icon name='pencil'}
+ <span>{lang}wcf.global.button.edit{/lang}</span>
+ </a>
+ </li>
+ {/if}
+ <li
+ class="jsQuoteMessage"
+ data-object-id="{$message->messageID}"
+ data-is-quoted="{if $__quoteFullQuote|isset && $message->messageID|in_array:$__quoteFullQuote}1{else}0{/if}"
+ >
+ <a
+ href="#"
+ title="{lang}wcf.message.quote.quoteMessage{/lang}"
+ class="button jsTooltip{if $__quoteFullQuote|isset && $message->messageID|in_array:$__quoteFullQuote} active{/if}"
+ >
+ {icon name='quote-left' type='solid'}
+ <span class="invisible">{lang}wcf.message.quote.quoteMessage{/lang}</span>
+ </a>
+ </li>
+ {if $message->userID != $__wcf->getUser()->userID && $__wcf->session->getPermission('user.profile.canReportContent')}
+ <li>
+ <button
+ type="button"
+ title="{lang}wcf.moderation.report.reportContent{/lang}"
+ class="button jsTooltip"
+ data-report-content="com.woltlab.wcf.conversation.message"
+ data-object-id="{$message->messageID}"
+ >
+ {icon name='triangle-exclamation'}
+ <span class="invisible">{lang}wcf.moderation.report.reportContent{/lang}</span>
+ </button>
+ </li>
+ {/if}
{event name='messageFooterButtons'}
</ul>
</div>
<div class="messageHeaderBox">
<h2 class="messageTitle">
{user object=$modificationLogEntry->getUserProfile() class='username'}
- <small class="separatorLeft">{@$modificationLogEntry->time|time}</small>
+ <small class="separatorLeft">{time time=$modificationLogEntry->time}</small>
</h2>
<div>{@$modificationLogEntry}</div>
</div>
<div>
<div class="containerHeadline">
- <h3>{user object=$message->getUserProfile()} <small class="separatorLeft">{@$message->time|time}</small></h3>
+ <h3>{user object=$message->getUserProfile()} <small class="separatorLeft">{time time=$message->time}</small></h3>
</div>
<div>{@$message->getExcerpt()}</div>
-<li id="messageQuickReply" class="jsOnly{if $conversation->userID == $__wcf->getUser()->userID} messageGroupStarter{/if}{if $pageNo < $pages} messageQuickReplyCollapsed{/if}" data-object-id="{@$conversation->conversationID}" data-last-post-time="{@$conversation->lastPostTime}" data-page-no="{@$pageNo}">
- <article class="message messageSidebarOrientation{@$__wcf->getStyleHandler()->getStyle()->getVariable('messageSidebarOrientation')|ucfirst}{if $__wcf->getUserProfileHandler()->userOnlineGroupID} userOnlineGroupMarking{@$__wcf->getUserProfileHandler()->userOnlineGroupID}{/if}">
+<li id="messageQuickReply" class="jsOnly{if $conversation->userID == $__wcf->getUser()->userID} messageGroupStarter{/if}{if $pageNo < $pages} messageQuickReplyCollapsed{/if}" data-object-id="{$conversation->conversationID}" data-last-post-time="{$conversation->lastPostTime}" data-page-no="{$pageNo}">
+ <article class="message messageSidebarOrientation{$__wcf->getStyleHandler()->getStyle()->getVariable('messageSidebarOrientation')|ucfirst}{if $__wcf->getUserProfileHandler()->userOnlineGroupID} userOnlineGroupMarking{$__wcf->getUserProfileHandler()->userOnlineGroupID}{/if}">
{include file='messageSidebar' userProfile=$__wcf->getUserProfileHandler()->getUserProfile() isReply=true enableMicrodata=false}
<div class="messageContent messageQuickReplyContent"{if $pageNo < $pages} data-placeholder="{lang}wcf.conversation.reply{/lang}"{/if}>
{event name='beforeWysiwyg'}
<textarea id="text" name="text" class="wysiwygTextarea"
- data-autosave="com.woltlab.wcf.conversation.messageAdd-{@$conversation->conversationID}"
+ data-autosave="com.woltlab.wcf.conversation.messageAdd-{$conversation->conversationID}"
data-support-mention="true"
></textarea>
{include file='messageFormTabsInline' inConversationQuickReply=true}
<footer class="messageFooter">
<div class="formSubmit">
- <button class="buttonPrimary" data-type="save" accesskey="s">{lang}wcf.global.button.reply{/lang}</button>
+ <button class="button buttonPrimary" data-type="save" accesskey="s">{lang}wcf.global.button.reply{/lang}</button>
{include file='messageFormPreviewButton' previewMessageObjectType='com.woltlab.wcf.conversation.message' previewMessageObjectID=0}
</div>
</footer>
</article>
{include file='wysiwyg'}
-</li>
\ No newline at end of file
+</li>
{$message->username}
{/if}
·
- <a href="{$message->getLink()}"><small>{$message->time|plainTime}</small></a>
+ <a href="{$message->getLink()}"><small>{time time=$message->time type='plainTime'}</small></a>
</h3>
</div>
<div>
{$message->username}
{/if}
·
- <a href="{$message->getLink()}"><small>{$message->time|plainTime}</small></a>
+ <a href="{$message->getLink()}"><small>{time time=$message->time type='plainTime'}</small></a>
</h3>
</div>
<div>
{user object=$message->getUserProfile() type='avatar32' ariaHidden='true' tabindex='-1'}
<div class="messageHeaderBox">
- <h2 class="messageTitle">{if $message->getConversation()->canRead()}<a href="{@$message->getLink()}">{$message->getTitle()}</a>{else}{$message->getTitle()}{/if}</h2>
+ <h2 class="messageTitle">{if $message->getConversation()->canRead()}<a href="{$message->getLink()}">{$message->getTitle()}</a>{else}{$message->getTitle()}{/if}</h2>
<ul class="messageHeaderMetaData">
<li>{user object=$message->getUserProfile() class='username'}</li>
- <li><span class="messagePublicationTime">{@$message->getTime()|time}</span></li>
+ <li><span class="messagePublicationTime">{time time=$message->getTime()}</span></li>
{event name='messageHeaderMetaData'}
</ul>
{event name='afterMessageText'}
</div>
</div>
-</article>
\ No newline at end of file
+</article>
<dl>
<dt></dt>
- <dd><label><input type="checkbox" name="conversationID" value="{@$searchedConversation->conversationID}" checked> {lang}wcf.conversation.searchedConversation{/lang}</label></dd>
+ <dd><label><input type="checkbox" name="conversationID" value="{$searchedConversation->conversationID}" checked> {lang}wcf.conversation.searchedConversation{/lang}</label></dd>
</dl>
--- /dev/null
+/**
+ * Marks all conversations as read.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2022 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since 6.0
+ */
+
+import { dboAction } from "WoltLabSuite/Core/Ajax";
+import * as UiNotification from "WoltLabSuite/Core/Ui/Notification";
+
+async function markAllAsRead(): Promise<void> {
+ await dboAction("markAllAsRead", "wcf\\data\\conversation\\ConversationAction").dispatch();
+
+ document.querySelectorAll(".conversationList .new").forEach((el: HTMLElement) => {
+ el.classList.remove("new");
+ });
+ document.querySelector("#unreadConversations .badgeUpdate")?.remove();
+
+ UiNotification.show();
+}
+
+export function setup(): void {
+ document.querySelectorAll(".markAllAsReadButton").forEach((el: HTMLElement) => {
+ el.addEventListener("click", (event) => {
+ event.preventDefault();
+
+ void markAllAsRead();
+ });
+ });
+}
--- /dev/null
+/**
+ * Handles the mark as read button for single conversations.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2022 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since 6.0
+ */
+
+import { dboAction } from "WoltLabSuite/Core/Ajax";
+
+const unreadConversations = new WeakSet();
+
+async function markAsRead(conversation: HTMLElement): Promise<void> {
+ const conversationId = parseInt(conversation.dataset.conversationId!, 10);
+
+ await dboAction("markAsRead", "wcf\\data\\conversation\\ConversationAction").objectIds([conversationId]).dispatch();
+
+ conversation.classList.remove("new");
+ conversation.querySelector(".columnAvatar p")?.removeAttribute("title");
+}
+
+export function setup(): void {
+ document.querySelectorAll(".conversationList .new .columnAvatar").forEach((el: HTMLElement) => {
+ if (!unreadConversations.has(el)) {
+ unreadConversations.add(el);
+
+ el.addEventListener(
+ "dblclick",
+ (event) => {
+ event.preventDefault();
+
+ const conversation = el.closest<HTMLElement>(".conversation")!;
+ if (!conversation.classList.contains("new")) {
+ return;
+ }
+ void markAsRead(conversation);
+ },
+ { once: true },
+ );
+ }
+ });
+}
* @author Matthias Schmidt
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Conversation/Ui/Message/Quote
* @woltlabExcludeBundle tiny
*/
* @author Matthias Schmidt
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Conversation/Ui/Object/Action/RemoveParticipant
*/
import UiObjectActionHandler from "WoltLabSuite/Core/Ui/Object/Action/Handler";
* @author Alexander Ebert
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Conversation/Ui/Participant/Add
*/
import * as Ajax from "WoltLabSuite/Core/Ajax";
* @author Alexander Ebert
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Conversation/Ui/Subject/Editor
*/
import { DialogCallbackObject } from "WoltLabSuite/Core/Ui/Dialog/Data";
import UiDialog from "WoltLabSuite/Core/Ui/Dialog";
</dd>
</dl>
<div class="formSubmit">
- <button class="buttonPrimary jsButtonSave">${Language.get("wcf.global.button.save")}</button>
+ <button type="button" class="button buttonPrimary jsButtonSave">${Language.get(
+ "wcf.global.button.save",
+ )}</button>
</div>
`,
};
* @author Alexander Ebert
* @copyright 2001-2021 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Ui/User/Menu/Data/Notification
* @woltlabExcludeBundle tiny
*/
const buttons: UserMenuButton[] = [];
if (this.options.canStartConversation) {
buttons.push({
- icon: '<span class="icon icon24 fa-plus"></span>',
+ icon: '<fa-icon size="24" name="plus"></fa-icon>',
link: this.options.newConversationLink,
name: "newConversation",
title: this.options.newConversationTitle,
{
"include": [
- "node_modules/@woltlab/wcf/global.d.ts",
+ "node_modules/@woltlab/d.ts/global.d.ts",
"ts/**/*"
],
"compilerOptions": {
- "target": "es2017",
+ "target": "ES2022",
"module": "amd",
"rootDir": "ts/",
"outDir": "files/js/",
"lib": [
- "dom",
- "es2017"
+ "DOM",
+ "DOM.Iterable",
+ "ES2022"
],
"strictNullChecks": true,
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"*": [
- "node_modules/@woltlab/wcf/ts/*"
+ "node_modules/@woltlab/d.ts/*"
]
},
"importHelpers": true,