Commit | Line | Data |
---|---|---|
7f584dca AE |
1 | /** |
2 | * Namespace for conversations. | |
5e279c42 AE |
3 | * |
4 | * @author Alexander Ebert | |
ca7ac0d3 | 5 | * @copyright 2001-2018 WoltLab GmbH |
5e279c42 | 6 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
7f584dca AE |
7 | */ |
8 | WCF.Conversation = { }; | |
9 | ||
5e279c42 AE |
10 | /** |
11 | * Core editor handler for conversations. | |
5e279c42 | 12 | */ |
7f584dca | 13 | WCF.Conversation.EditorHandler = Class.extend({ |
5e279c42 AE |
14 | /** |
15 | * list of attributes per conversation | |
16 | * @var object | |
17 | */ | |
7f584dca | 18 | _attributes: { }, |
5e279c42 AE |
19 | |
20 | /** | |
21 | * list of conversations | |
22 | * @var object | |
23 | */ | |
7f584dca | 24 | _conversations: { }, |
5e279c42 AE |
25 | |
26 | /** | |
27 | * list of permissions per conversation | |
28 | * @var object | |
29 | */ | |
7f584dca AE |
30 | _permissions: { }, |
31 | ||
5e279c42 AE |
32 | /** |
33 | * Initializes the core editor handler for conversations. | |
5e279c42 | 34 | */ |
2e0bc870 | 35 | init: function(availableLabels) { |
7f584dca AE |
36 | this._conversations = { }; |
37 | ||
38 | var self = this; | |
39 | $('.conversation').each(function(index, conversation) { | |
40 | var $conversation = $(conversation); | |
41 | var $conversationID = $conversation.data('conversationID'); | |
42 | ||
43 | if (!self._conversations[$conversationID]) { | |
44 | self._conversations[$conversationID] = $conversation; | |
b89bd2bc | 45 | var $labelIDs = eval($conversation.data('labelIDs')); |
7f584dca AE |
46 | |
47 | // set attributes | |
48 | self._attributes[$conversationID] = { | |
b89bd2bc AE |
49 | isClosed: ($conversation.data('isClosed') ? true : false), |
50 | labelIDs: $labelIDs | |
7f584dca AE |
51 | }; |
52 | ||
53 | // set permissions | |
54 | self._permissions[$conversationID] = { | |
65b37bf6 | 55 | canAddParticipants: ($conversation.data('canAddParticipants') ? true : false), |
7f584dca AE |
56 | canCloseConversation: ($conversation.data('canCloseConversation') ? true : false) |
57 | }; | |
58 | } | |
59 | }); | |
60 | }, | |
61 | ||
5e279c42 AE |
62 | /** |
63 | * Returns a permission's value for given conversation id. | |
64 | * | |
65 | * @param integer conversationID | |
66 | * @param string permission | |
67 | * @return boolean | |
68 | */ | |
7f584dca AE |
69 | getPermission: function(conversationID, permission) { |
70 | if (this._permissions[conversationID][permission] === undefined) { | |
71 | return false; | |
72 | } | |
73 | ||
74 | return (this._permissions[conversationID][permission]) ? true : false; | |
75 | }, | |
76 | ||
5e279c42 AE |
77 | /** |
78 | * Returns an attribute's value for given conversation id. | |
79 | * | |
80 | * @param integer conversationID | |
81 | * @param string key | |
82 | * @return mixed | |
83 | */ | |
7f584dca AE |
84 | getValue: function(conversationID, key) { |
85 | switch (key) { | |
86 | case 'labelIDs': | |
87 | if (this._attributes[conversationID].labelIDs === undefined) { | |
7f584dca AE |
88 | this._attributes[conversationID].labelIDs = [ ]; |
89 | } | |
90 | ||
91 | return this._attributes[conversationID].labelIDs; | |
92 | break; | |
93 | ||
94 | case 'isClosed': | |
95 | return (this._attributes[conversationID].isClosed) ? true : false; | |
96 | break; | |
97 | } | |
98 | }, | |
99 | ||
5e279c42 AE |
100 | /** |
101 | * Counts available labels. | |
102 | * | |
103 | * @return integer | |
104 | */ | |
7f584dca | 105 | countAvailableLabels: function() { |
b89bd2bc AE |
106 | return (this.getAvailableLabels()).length; |
107 | }, | |
108 | ||
db864366 MS |
109 | /** |
110 | * Returns a list with the data of the available labels. | |
111 | * | |
112 | * @return array<object> | |
113 | */ | |
b89bd2bc AE |
114 | getAvailableLabels: function() { |
115 | var $labels = [ ]; | |
116 | ||
00eda4be | 117 | WCF.Dropdown.getDropdownMenu('conversationLabelFilter').children('.scrollableDropdownMenu').children('li').each(function(index, listItem) { |
b89bd2bc AE |
118 | var $listItem = $(listItem); |
119 | if ($listItem.hasClass('dropdownDivider')) { | |
120 | return false; | |
121 | } | |
122 | ||
123 | var $span = $listItem.find('span'); | |
124 | $labels.push({ | |
125 | cssClassName: $span.data('cssClassName'), | |
126 | labelID: $span.data('labelID'), | |
127 | label: $span.text() | |
128 | }); | |
129 | }); | |
130 | ||
131 | return $labels; | |
3990815c AE |
132 | }, |
133 | ||
134 | /** | |
135 | * Updates conversation data. | |
136 | * | |
137 | * @param integer conversationID | |
138 | * @param object data | |
139 | */ | |
140 | update: function(conversationID, key, data) { | |
141 | if (!this._conversations[conversationID]) { | |
142 | console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '" + conversationID + "'"); | |
143 | return; | |
144 | } | |
145 | var $conversation = this._conversations[conversationID]; | |
146 | ||
147 | switch (key) { | |
c78d591e | 148 | case 'close': |
7cd36813 | 149 | $('<li><span class="icon icon16 fa-lock jsTooltip jsIconLock" title="' + WCF.Language.get('wcf.global.state.closed') + '" /></li>').prependTo($conversation.find('.statusIcons')); |
c78d591e AE |
150 | |
151 | this._attributes[conversationID].isClosed = 1; | |
152 | break; | |
153 | ||
3990815c AE |
154 | case 'labelIDs': |
155 | var $labels = { }; | |
443fbc56 | 156 | WCF.Dropdown.getDropdownMenu('conversationLabelFilter').find('li > a > span').each(function(index, span) { |
3990815c AE |
157 | var $span = $(span); |
158 | ||
159 | $labels[$span.data('labelID')] = { | |
160 | cssClassName: $span.data('cssClassName'), | |
9bbe55ef AE |
161 | label: $span.text(), |
162 | url: $span.parent().attr('href') | |
3990815c AE |
163 | }; |
164 | }); | |
165 | ||
9cd031f5 | 166 | var $labelList = $conversation.find('.columnSubject > .labelList'); |
3990815c AE |
167 | if (!data.length) { |
168 | if ($labelList.length) $labelList.remove(); | |
169 | } | |
170 | else { | |
171 | // create label list if missing | |
172 | if (!$labelList.length) { | |
9cd031f5 | 173 | $labelList = $('<ul class="labelList" />').prependTo($conversation.find('.columnSubject')); |
3990815c AE |
174 | } |
175 | ||
176 | // remove all existing labels | |
177 | $labelList.empty(); | |
178 | ||
179 | // insert labels | |
180 | for (var $i = 0, $length = data.length; $i < $length; $i++) { | |
181 | var $label = $labels[data[$i]]; | |
f61e621c | 182 | $('<li><a href="' + $label.url + '" class="badge label' + ($label.cssClassName ? " " + $label.cssClassName : "") + '">' + WCF.String.escapeHTML($label.label) + '</a></li>').appendTo($labelList); |
3990815c AE |
183 | } |
184 | } | |
185 | break; | |
c78d591e AE |
186 | |
187 | case 'open': | |
188 | $conversation.find('.statusIcons li').each(function(index, listItem) { | |
189 | var $listItem = $(listItem); | |
caaf1cde | 190 | if ($listItem.children('span.jsIconLock').length) { |
c78d591e AE |
191 | $listItem.remove(); |
192 | return false; | |
193 | } | |
194 | }); | |
195 | ||
196 | this._attributes[conversationID].isClosed = 0; | |
197 | break; | |
3990815c | 198 | } |
ae0cf915 AE |
199 | |
200 | WCF.Clipboard.reload(); | |
7f584dca AE |
201 | } |
202 | }); | |
203 | ||
2e0bc870 AE |
204 | /** |
205 | * Conversation editor handler for conversation page. | |
206 | * | |
207 | * @see WCF.Conversation.EditorHandler | |
208 | * @param array<object> availableLabels | |
209 | */ | |
210 | WCF.Conversation.EditorHandlerConversation = WCF.Conversation.EditorHandler.extend({ | |
211 | /** | |
212 | * list of available labels | |
213 | * @var array<object> | |
214 | */ | |
215 | _availableLabels: null, | |
216 | ||
217 | /** | |
218 | * @see WCF.Conversation.EditorHandler.init() | |
219 | * | |
220 | * @param array<object> availableLabels | |
221 | */ | |
222 | init: function(availableLabels) { | |
223 | this._availableLabels = availableLabels || [ ]; | |
224 | ||
225 | this._super(); | |
226 | }, | |
227 | ||
228 | /** | |
229 | * @see WCF.Conversation.EditorHandler.getAvailableLabels() | |
230 | */ | |
231 | getAvailableLabels: function() { | |
232 | return this._availableLabels; | |
233 | }, | |
234 | ||
235 | /** | |
236 | * @see WCF.Conversation.EditorHandler.update() | |
237 | */ | |
238 | update: function(conversationID, key, data) { | |
239 | if (!this._conversations[conversationID]) { | |
240 | console.debug("[WCF.Conversation.EditorHandler] Unknown conversation id '" + conversationID + "'"); | |
241 | return; | |
242 | } | |
2e0bc870 | 243 | |
f61e621c AE |
244 | var container = $('.contentHeaderTitle > .contentHeaderMetaData'); |
245 | ||
2e0bc870 | 246 | switch (key) { |
a132491c | 247 | case 'close': |
f61e621c | 248 | $('<li><span class="icon icon16 fa-lock jsIconLock" /> ' + WCF.Language.get('wcf.global.state.closed') + '</li>').appendTo(container); |
a132491c AE |
249 | |
250 | this._attributes[conversationID].isClosed = 1; | |
251 | break; | |
252 | ||
2e0bc870 | 253 | case 'labelIDs': |
f61e621c | 254 | var labelList = container.find('.labelList'); |
2e0bc870 | 255 | if (!data.length) { |
f61e621c | 256 | labelList.parent().remove(); |
2e0bc870 AE |
257 | } |
258 | else { | |
f61e621c | 259 | var availableLabels = this.getAvailableLabels(); |
2e0bc870 | 260 | |
f61e621c AE |
261 | if (!labelList.length) { |
262 | labelList = $('<li><span class="icon icon16 fa-tags"></span> <ul class="labelList"></ul></li>').prependTo(container); | |
263 | labelList = labelList.children('ul'); | |
264 | } | |
2e0bc870 | 265 | |
f61e621c AE |
266 | var html = ''; |
267 | data.forEach(function(labelId) { | |
268 | availableLabels.forEach(function(label) { | |
269 | if (label.labelID == labelId) { | |
270 | html += '<li><span class="label badge' + (label.cssClassName ? ' ' + label.cssClassName : '') + '">' + label.label + '</span></li>'; | |
2e0bc870 | 271 | } |
f61e621c AE |
272 | }); |
273 | }); | |
274 | ||
275 | labelList[0].innerHTML = html; | |
2e0bc870 AE |
276 | } |
277 | break; | |
a132491c AE |
278 | |
279 | case 'open': | |
f61e621c | 280 | container.find('.jsIconLock').parent().remove(); |
a132491c AE |
281 | |
282 | this._attributes[conversationID].isClosed = 0; | |
283 | break; | |
2e0bc870 AE |
284 | } |
285 | } | |
286 | }); | |
287 | ||
6f1bbea0 | 288 | /** |
559c6734 | 289 | * Provides extended actions for conversation clipboard actions. |
6f1bbea0 AE |
290 | */ |
291 | WCF.Conversation.Clipboard = Class.extend({ | |
292 | /** | |
293 | * editor handler | |
294 | * @var WCF.Conversation.EditorHandler | |
295 | */ | |
296 | _editorHandler: null, | |
297 | ||
298 | /** | |
299 | * Initializes a new WCF.Conversation.Clipboard object. | |
300 | * | |
f61e621c | 301 | * @param {WCF.Conversation.EditorHandler} editorHandler |
6f1bbea0 AE |
302 | */ |
303 | init: function(editorHandler) { | |
304 | this._editorHandler = editorHandler; | |
305 | ||
f61e621c AE |
306 | WCF.System.Event.addListener('com.woltlab.wcf.clipboard', 'com.woltlab.wcf.conversation.conversation', (function (data) { |
307 | if (data.responseData === null) { | |
308 | this._execute(data.data.actionName, data.data.parameters); | |
309 | } | |
310 | else { | |
311 | this._evaluateResponse(data.data.actionName, data.responseData); | |
6f1bbea0 | 312 | } |
f61e621c | 313 | }).bind(this)); |
6f1bbea0 AE |
314 | }, |
315 | ||
316 | /** | |
317 | * Handles clipboard actions. | |
318 | * | |
f61e621c AE |
319 | * @param {string} actionName |
320 | * @param {Object} parameters | |
6f1bbea0 | 321 | */ |
f61e621c AE |
322 | _execute: function(actionName, parameters) { |
323 | if (actionName === 'com.woltlab.wcf.conversation.conversation.assignLabel') { | |
4981a270 | 324 | new WCF.Conversation.Label.Editor(this._editorHandler, null, parameters.objectIDs); |
6f1bbea0 | 325 | } |
e8fe47c2 AE |
326 | }, |
327 | ||
328 | /** | |
329 | * Evaluates AJAX responses. | |
330 | * | |
f61e621c AE |
331 | * @param {Object} data |
332 | * @param {string} actionName | |
e8fe47c2 | 333 | */ |
f61e621c | 334 | _evaluateResponse: function(actionName, data) { |
e8fe47c2 | 335 | switch (actionName) { |
d78f31a6 MS |
336 | case 'com.woltlab.wcf.conversation.conversation.leave': |
337 | case 'com.woltlab.wcf.conversation.conversation.leavePermanently': | |
4ca3137c | 338 | case 'com.woltlab.wcf.conversation.conversation.markAsRead': |
d78f31a6 | 339 | case 'com.woltlab.wcf.conversation.conversation.restore': |
e8fe47c2 AE |
340 | window.location.reload(); |
341 | break; | |
3d0a3f74 | 342 | |
d78f31a6 MS |
343 | case 'com.woltlab.wcf.conversation.conversation.close': |
344 | case 'com.woltlab.wcf.conversation.conversation.open': | |
f61e621c AE |
345 | //noinspection JSUnresolvedVariable |
346 | for (var conversationId in data.returnValues.conversationData) { | |
347 | //noinspection JSUnresolvedVariable | |
348 | if (data.returnValues.conversationData.hasOwnProperty(conversationId)) { | |
349 | //noinspection JSUnresolvedVariable | |
350 | var $data = data.returnValues.conversationData[conversationId]; | |
351 | ||
352 | this._editorHandler.update(conversationId, ($data.isClosed ? 'close' : 'open'), $data); | |
353 | } | |
3d0a3f74 AE |
354 | } |
355 | break; | |
e8fe47c2 | 356 | } |
6f1bbea0 AE |
357 | } |
358 | }); | |
359 | ||
5e279c42 AE |
360 | /** |
361 | * Inline editor implementation for conversations. | |
362 | * | |
363 | * @see WCF.Inline.Editor | |
364 | */ | |
7f584dca | 365 | WCF.Conversation.InlineEditor = WCF.InlineEditor.extend({ |
5e279c42 AE |
366 | /** |
367 | * editor handler object | |
368 | * @var WCF.Conversation.EditorHandler | |
369 | */ | |
7f584dca AE |
370 | _editorHandler: null, |
371 | ||
c78d591e AE |
372 | /** |
373 | * execution environment | |
374 | * @var string | |
375 | */ | |
376 | _environment: 'conversation', | |
377 | ||
7f584dca AE |
378 | /** |
379 | * @see WCF.InlineEditor._setOptions() | |
380 | */ | |
381 | _setOptions: function() { | |
382 | this._options = [ | |
4251df82 AE |
383 | // edit title |
384 | { label: WCF.Language.get('wcf.conversation.edit.subject'), optionName: 'editSubject' }, | |
385 | ||
7f584dca AE |
386 | // isClosed |
387 | { label: WCF.Language.get('wcf.conversation.edit.close'), optionName: 'close' }, | |
388 | { label: WCF.Language.get('wcf.conversation.edit.open'), optionName: 'open' }, | |
389 | ||
390 | // assign labels | |
391 | { label: WCF.Language.get('wcf.conversation.edit.assignLabel'), optionName: 'assignLabel' }, | |
392 | ||
393 | // divider | |
394 | { optionName: 'divider' }, | |
395 | ||
65b37bf6 AE |
396 | // add participants |
397 | { label: WCF.Language.get('wcf.conversation.edit.addParticipants'), optionName: 'addParticipants' }, | |
398 | ||
7f584dca | 399 | // leave conversation |
7d269a63 MW |
400 | { label: WCF.Language.get('wcf.conversation.edit.leave'), optionName: 'leave' }, |
401 | ||
402 | // edit draft | |
403 | { label: WCF.Language.get('wcf.global.button.edit'), optionName: 'edit', isQuickOption: true } | |
7f584dca AE |
404 | ]; |
405 | }, | |
406 | ||
5e279c42 AE |
407 | /** |
408 | * Sets editor handler object. | |
409 | * | |
410 | * @param WCF.Conversation.EditorHandler editorHandler | |
c78d591e | 411 | * @param string environment |
5e279c42 | 412 | */ |
c78d591e | 413 | setEditorHandler: function(editorHandler, environment) { |
7f584dca | 414 | this._editorHandler = editorHandler; |
c78d591e | 415 | this._environment = (environment == 'list') ? 'list' : 'conversation'; |
7f584dca AE |
416 | }, |
417 | ||
418 | /** | |
419 | * @see WCF.InlineEditor._getTriggerElement() | |
420 | */ | |
421 | _getTriggerElement: function(element) { | |
1a3cec9c | 422 | return element.find('.jsConversationInlineEditor'); |
7f584dca AE |
423 | }, |
424 | ||
425 | /** | |
426 | * @see WCF.InlineEditor._validate() | |
427 | */ | |
428 | _validate: function(elementID, optionName) { | |
429 | var $conversationID = $('#' + elementID).data('conversationID'); | |
430 | ||
431 | switch (optionName) { | |
65b37bf6 AE |
432 | case 'addParticipants': |
433 | return (this._editorHandler.getPermission($conversationID, 'canAddParticipants')); | |
434 | break; | |
435 | ||
7f584dca AE |
436 | case 'assignLabel': |
437 | return (this._editorHandler.countAvailableLabels()) ? true : false; | |
438 | break; | |
439 | ||
4251df82 AE |
440 | case 'editSubject': |
441 | return (!!this._editorHandler.getPermission($conversationID, 'canCloseConversation')); | |
442 | break; | |
443 | ||
7f584dca AE |
444 | case 'close': |
445 | case 'open': | |
446 | if (!this._editorHandler.getPermission($conversationID, 'canCloseConversation')) { | |
447 | return false; | |
448 | } | |
449 | ||
5cb8c349 AE |
450 | if (optionName === 'close') return !(this._editorHandler.getValue($conversationID, 'isClosed')); |
451 | else return (this._editorHandler.getValue($conversationID, 'isClosed')); | |
7f584dca AE |
452 | break; |
453 | ||
454 | case 'leave': | |
455 | return true; | |
456 | break; | |
7d269a63 MW |
457 | |
458 | case 'edit': | |
459 | return ($('#' + elementID).data('isDraft') ? true : false); | |
460 | break; | |
7f584dca AE |
461 | } |
462 | ||
463 | return false; | |
3990815c AE |
464 | }, |
465 | ||
466 | /** | |
467 | * @see WCF.InlineEditor._execute() | |
468 | */ | |
469 | _execute: function(elementID, optionName) { | |
470 | // abort if option is invalid or not accessible | |
471 | if (!this._validate(elementID, optionName)) { | |
472 | return false; | |
473 | } | |
474 | ||
475 | switch (optionName) { | |
65b37bf6 | 476 | case 'addParticipants': |
38340e3b | 477 | require(['WoltLabSuite/Core/Conversation/Ui/Participant/Add'], function(UiParticipantAdd) { |
4251df82 | 478 | new UiParticipantAdd(elData(elById(elementID), 'conversation-id')); |
368540c1 | 479 | }); |
65b37bf6 AE |
480 | break; |
481 | ||
3990815c AE |
482 | case 'assignLabel': |
483 | new WCF.Conversation.Label.Editor(this._editorHandler, elementID); | |
484 | break; | |
50cd21a1 | 485 | |
4251df82 AE |
486 | case 'editSubject': |
487 | require(['WoltLabSuite/Core/Conversation/Ui/Subject/Editor'], function (UiSubjectEditor) { | |
488 | UiSubjectEditor.beginEdit(elData(elById(elementID), 'conversation-id')); | |
489 | }); | |
490 | break; | |
491 | ||
2e0bc870 AE |
492 | case 'close': |
493 | case 'open': | |
494 | this._updateConversation(elementID, optionName, { isClosed: (optionName === 'close' ? 1 : 0) }); | |
495 | break; | |
496 | ||
50cd21a1 | 497 | case 'leave': |
b2e0a2ad | 498 | new WCF.Conversation.Leave([ $('#' + elementID).data('conversationID') ], this._environment); |
50cd21a1 | 499 | break; |
7d269a63 MW |
500 | |
501 | case 'edit': | |
502 | window.location = this._getTriggerElement($('#' + elementID)).prop('href'); | |
503 | break; | |
50cd21a1 | 504 | } |
2e0bc870 AE |
505 | }, |
506 | ||
507 | /** | |
508 | * Updates conversation properties. | |
509 | * | |
510 | * @param string elementID | |
511 | * @param string optionName | |
512 | * @param object data | |
513 | */ | |
514 | _updateConversation: function(elementID, optionName, data) { | |
515 | var $conversationID = this._elements[elementID].data('conversationID'); | |
516 | ||
517 | switch (optionName) { | |
518 | case 'close': | |
4251df82 | 519 | case 'editSubject': |
2e0bc870 | 520 | case 'open': |
c78d591e AE |
521 | this._updateData.push({ |
522 | elementID: elementID, | |
523 | optionName: optionName, | |
524 | data: data | |
2e0bc870 | 525 | }); |
c78d591e AE |
526 | |
527 | this._proxy.setOption('data', { | |
528 | actionName: optionName, | |
529 | className: 'wcf\\data\\conversation\\ConversationAction', | |
530 | objectIDs: [ $conversationID ] | |
531 | }); | |
532 | this._proxy.sendRequest(); | |
2e0bc870 AE |
533 | break; |
534 | } | |
c78d591e AE |
535 | }, |
536 | ||
537 | /** | |
538 | * @see WCF.InlineEditor._updateState() | |
539 | */ | |
540 | _updateState: function() { | |
541 | for (var $i = 0, $length = this._updateData.length; $i < $length; $i++) { | |
542 | var $data = this._updateData[$i]; | |
543 | var $conversationID = this._elements[$data.elementID].data('conversationID'); | |
544 | ||
545 | switch ($data.optionName) { | |
546 | case 'close': | |
4251df82 | 547 | case 'editSubject': |
c78d591e | 548 | case 'open': |
4251df82 | 549 | this._editorHandler.update($conversationID, $data.optionName, $data.data); |
c78d591e AE |
550 | break; |
551 | } | |
552 | } | |
50cd21a1 AE |
553 | } |
554 | }); | |
555 | ||
556 | /** | |
557 | * Provides a dialog for leaving or restoring conversation. | |
558 | * | |
559 | * @param array<integer> conversationIDs | |
560 | */ | |
561 | WCF.Conversation.Leave = Class.extend({ | |
562 | /** | |
563 | * list of conversation ids | |
564 | * @var array<integer> | |
565 | */ | |
566 | _conversationIDs: [ ], | |
567 | ||
568 | /** | |
569 | * dialog overlay | |
570 | * @var jQuery | |
571 | */ | |
572 | _dialog: null, | |
573 | ||
b2e0a2ad AE |
574 | /** |
575 | * environment name | |
576 | * @var string | |
577 | */ | |
578 | _environment: '', | |
579 | ||
50cd21a1 AE |
580 | /** |
581 | * action proxy | |
582 | * @var WCF.Action.Proxy | |
583 | */ | |
584 | _proxy: null, | |
585 | ||
586 | /** | |
587 | * Initializes the leave/restore dialog for conversations. | |
588 | * | |
589 | * @param array<integer> conversationIDs | |
b2e0a2ad | 590 | * @param string environment |
50cd21a1 | 591 | */ |
b2e0a2ad | 592 | init: function(conversationIDs, environment) { |
50cd21a1 AE |
593 | this._conversationIDs = conversationIDs; |
594 | this._dialog = null; | |
b2e0a2ad | 595 | this._environment = environment; |
50cd21a1 AE |
596 | |
597 | this._proxy = new WCF.Action.Proxy({ | |
598 | success: $.proxy(this._success, this) | |
599 | }); | |
600 | ||
601 | this._loadDialog(); | |
602 | }, | |
603 | ||
604 | /** | |
605 | * Loads the dialog overlay. | |
606 | */ | |
a480521b | 607 | _loadDialog: function() { |
50cd21a1 AE |
608 | this._proxy.setOption('data', { |
609 | actionName: 'getLeaveForm', | |
610 | className: 'wcf\\data\\conversation\\ConversationAction', | |
2f5b4859 | 611 | objectIDs: this._conversationIDs |
50cd21a1 AE |
612 | }); |
613 | this._proxy.sendRequest(); | |
614 | }, | |
615 | ||
616 | /** | |
617 | * Handles successful AJAX requests. | |
618 | * | |
619 | * @param object data | |
620 | * @param string textStatus | |
621 | * @param jQuery jqXHR | |
622 | */ | |
623 | _success: function(data, textStatus, jqXHR) { | |
624 | switch (data.returnValues.actionName) { | |
625 | case 'getLeaveForm': | |
626 | this._showDialog(data); | |
627 | break; | |
628 | ||
629 | case 'hideConversation': | |
b2e0a2ad AE |
630 | if (this._environment === 'conversation') { |
631 | window.location = data.returnValues.redirectURL; | |
632 | } | |
633 | else { | |
634 | window.location.reload(); | |
635 | } | |
50cd21a1 AE |
636 | break; |
637 | } | |
638 | }, | |
639 | ||
640 | /** | |
641 | * Displays the leave/restore conversation dialog overlay. | |
642 | * | |
643 | * @param object data | |
644 | */ | |
645 | _showDialog: function(data) { | |
646 | if (this._dialog === null) { | |
647 | this._dialog = $('#leaveDialog'); | |
648 | if (!this._dialog.length) { | |
649 | this._dialog = $('<div id="leaveDialog" />').hide().appendTo(document.body); | |
650 | } | |
651 | } | |
652 | ||
653 | // render dialog | |
654 | this._dialog.html(data.returnValues.template); | |
655 | this._dialog.wcfDialog({ | |
656 | title: WCF.Language.get('wcf.conversation.leave.title') | |
657 | }); | |
658 | ||
659 | this._dialog.wcfDialog('render'); | |
660 | ||
661 | // bind event listener | |
662 | this._dialog.find('#hideConversation').click($.proxy(this._click, this)); | |
663 | }, | |
664 | ||
665 | /** | |
666 | * Handles conversation state changes. | |
667 | */ | |
668 | _click: function() { | |
669 | var $input = this._dialog.find('input[type=radio]:checked'); | |
670 | if ($input.length === 1) { | |
671 | this._proxy.setOption('data', { | |
672 | actionName: 'hideConversation', | |
673 | className: 'wcf\\data\\conversation\\ConversationAction', | |
2f5b4859 | 674 | objectIDs: this._conversationIDs, |
50cd21a1 | 675 | parameters: { |
50cd21a1 AE |
676 | hideConversation: $input.val() |
677 | } | |
678 | }); | |
679 | this._proxy.sendRequest(); | |
3990815c AE |
680 | } |
681 | } | |
682 | }); | |
683 | ||
a208d1f4 AE |
684 | /** |
685 | * Provides methods to remove participants from conversations. | |
686 | * | |
687 | * @see WCF.Action.Delete | |
688 | */ | |
689 | WCF.Conversation.RemoveParticipant = WCF.Action.Delete.extend({ | |
690 | /** | |
691 | * conversation id | |
692 | * @var integer | |
693 | */ | |
694 | _conversationID: 0, | |
695 | ||
696 | /** | |
697 | * @see WCF.Action.Delete.init() | |
698 | */ | |
699 | init: function(conversationID) { | |
700 | this._conversationID = conversationID; | |
701 | this._super('wcf\\data\\conversation\\ConversationAction', '.jsParticipant'); | |
702 | }, | |
703 | ||
704 | /** | |
705 | * @see WCF.Action.Delete._sendRequest() | |
706 | */ | |
707 | _sendRequest: function(object) { | |
708 | this.proxy.setOption('data', { | |
709 | actionName: 'removeParticipant', | |
710 | className: this._className, | |
711 | objectIDs: [ this._conversationID ], | |
712 | parameters: { | |
713 | userID: $(object).data('objectID') | |
714 | } | |
715 | }); | |
716 | ||
717 | this.proxy.sendRequest(); | |
718 | }, | |
719 | ||
720 | /** | |
721 | * @see WCF.Action.Delete._success() | |
722 | */ | |
723 | _success: function(data, textStatus, jqXHR) { | |
e829b862 MW |
724 | var $userID = data.returnValues.userID; |
725 | ||
726 | for (var $index in this._containers) { | |
727 | var $container = $('#' + this._containers[$index]); | |
728 | if ($container.find('.jsDeleteButton').data('objectID') == $userID) { | |
729 | $container.find('.userLink').addClass('conversationLeft'); | |
730 | $container.find('.jsDeleteButton').remove(); | |
731 | } | |
732 | } | |
a208d1f4 AE |
733 | } |
734 | }); | |
735 | ||
3990815c AE |
736 | /** |
737 | * Namespace for label-related classes. | |
738 | */ | |
739 | WCF.Conversation.Label = { }; | |
740 | ||
741 | /** | |
742 | * Providers an editor for conversation labels. | |
743 | * | |
744 | * @param WCF.Conversation.EditorHandler editorHandler | |
745 | * @param string elementID | |
f26185f2 | 746 | * @param array<integer> conversationIDs |
3990815c AE |
747 | */ |
748 | WCF.Conversation.Label.Editor = Class.extend({ | |
749 | /** | |
f26185f2 AE |
750 | * list of conversation id |
751 | * @var array<integer> | |
3990815c | 752 | */ |
f26185f2 | 753 | _conversationIDs: 0, |
3990815c AE |
754 | |
755 | /** | |
756 | * dialog object | |
757 | * @var jQuery | |
758 | */ | |
759 | _dialog: null, | |
760 | ||
761 | /** | |
762 | * editor handler object | |
763 | * @var WCF.Conversation.EditorHandler | |
764 | */ | |
765 | _editorHandler: null, | |
766 | ||
767 | /** | |
768 | * system notification object | |
769 | * @var WCF.System.Notification | |
770 | */ | |
771 | _notification: null, | |
772 | ||
773 | /** | |
774 | * action proxy object | |
775 | * @var WCF.Action.Proxy | |
776 | */ | |
777 | _proxy: null, | |
778 | ||
779 | /** | |
780 | * Initializes the label editor for given conversation. | |
781 | * | |
782 | * @param WCF.Conversation.EditorHandler editorHandler | |
783 | * @param string elementID | |
f26185f2 | 784 | * @param array<integer> conversationIDs |
3990815c | 785 | */ |
f26185f2 AE |
786 | init: function(editorHandler, elementID, conversationIDs) { |
787 | if (elementID) { | |
788 | this._conversationIDs = [ $('#' + elementID).data('conversationID') ]; | |
789 | } | |
790 | else { | |
791 | this._conversationIDs = conversationIDs; | |
792 | } | |
793 | ||
3990815c AE |
794 | this._dialog = null; |
795 | this._editorHandler = editorHandler; | |
796 | ||
8ba68f57 | 797 | this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success.edit')); |
3990815c AE |
798 | this._proxy = new WCF.Action.Proxy({ |
799 | success: $.proxy(this._success, this) | |
800 | }); | |
801 | ||
802 | this._loadDialog(); | |
803 | }, | |
804 | ||
805 | /** | |
806 | * Loads label assignment dialog. | |
807 | */ | |
808 | _loadDialog: function() { | |
809 | this._proxy.setOption('data', { | |
810 | actionName: 'getLabelForm', | |
811 | className: 'wcf\\data\\conversation\\label\\ConversationLabelAction', | |
812 | parameters: { | |
f26185f2 | 813 | conversationIDs: this._conversationIDs |
3990815c AE |
814 | } |
815 | }); | |
816 | this._proxy.sendRequest(); | |
817 | }, | |
818 | ||
819 | /** | |
820 | * Handles successful AJAX requests. | |
821 | * | |
822 | * @param object data | |
823 | * @param string textStatus | |
824 | * @param jQuery jqXHR | |
825 | */ | |
826 | _success: function(data, textStatus, jqXHR) { | |
827 | switch (data.returnValues.actionName) { | |
828 | case 'assignLabel': | |
829 | this._assignLabels(data); | |
830 | break; | |
831 | ||
832 | case 'getLabelForm': | |
833 | this._renderDialog(data); | |
834 | break; | |
835 | } | |
836 | }, | |
837 | ||
838 | /** | |
839 | * Renders the label assignment form overlay. | |
840 | * | |
841 | * @param object data | |
842 | */ | |
843 | _renderDialog: function(data) { | |
844 | if (this._dialog === null) { | |
845 | this._dialog = $('#conversationLabelForm'); | |
846 | if (!this._dialog.length) { | |
847 | this._dialog = $('<div id="conversationLabelForm" />').hide().appendTo(document.body); | |
848 | } | |
849 | } | |
850 | ||
851 | this._dialog.html(data.returnValues.template); | |
852 | this._dialog.wcfDialog({ | |
853 | title: WCF.Language.get('wcf.conversation.label.assignLabels') | |
854 | }); | |
855 | this._dialog.wcfDialog('render'); | |
856 | ||
857 | $('#assignLabels').click($.proxy(this._save, this)); | |
858 | }, | |
859 | ||
860 | /** | |
861 | * Saves label assignments for current conversation id. | |
862 | */ | |
863 | _save: function() { | |
864 | var $labelIDs = [ ]; | |
865 | this._dialog.find('input').each(function(index, checkbox) { | |
866 | var $checkbox = $(checkbox); | |
867 | if ($checkbox.is(':checked')) { | |
868 | $labelIDs.push($checkbox.data('labelID')); | |
869 | } | |
870 | }); | |
871 | ||
872 | this._proxy.setOption('data', { | |
873 | actionName: 'assignLabel', | |
874 | className: 'wcf\\data\\conversation\\label\\ConversationLabelAction', | |
875 | parameters: { | |
f26185f2 | 876 | conversationIDs: this._conversationIDs, |
3990815c AE |
877 | labelIDs: $labelIDs |
878 | } | |
879 | }); | |
880 | this._proxy.sendRequest(); | |
881 | }, | |
882 | ||
883 | /** | |
884 | * Updates conversation labels. | |
885 | * | |
886 | * @param object data | |
887 | */ | |
888 | _assignLabels: function(data) { | |
889 | // update conversation | |
4981a270 | 890 | for (var $i = 0, $length = this._conversationIDs.length; $i < $length; $i++) { |
f26185f2 AE |
891 | this._editorHandler.update(this._conversationIDs[$i], 'labelIDs', data.returnValues.labelIDs); |
892 | } | |
3990815c AE |
893 | |
894 | // close dialog and show a 'success' notice | |
895 | this._dialog.wcfDialog('close'); | |
896 | this._notification.show(); | |
7f584dca | 897 | } |
5e279c42 AE |
898 | }); |
899 | ||
900 | /** | |
901 | * Label manager for conversations. | |
902 | * | |
903 | * @param string link | |
904 | */ | |
3990815c | 905 | WCF.Conversation.Label.Manager = Class.extend({ |
d4e2a0cc AE |
906 | /** |
907 | * deleted label id | |
908 | * @var integer | |
909 | */ | |
910 | _deletedLabelID: 0, | |
911 | ||
5e279c42 AE |
912 | /** |
913 | * dialog object | |
914 | * @var jQuery | |
915 | */ | |
916 | _dialog: null, | |
917 | ||
918 | /** | |
919 | * list of labels | |
920 | * @var jQuery | |
921 | */ | |
922 | _labels: null, | |
923 | ||
924 | /** | |
925 | * parsed label link | |
926 | * @var string | |
927 | */ | |
928 | _link: '', | |
929 | ||
72f75266 AE |
930 | /** |
931 | * system notification object | |
932 | * @var WCF.System.Notification | |
933 | */ | |
934 | _notification: '', | |
935 | ||
5e279c42 AE |
936 | /** |
937 | * action proxy object | |
938 | * @var WCF.Action.Proxy | |
939 | */ | |
940 | _proxy: null, | |
941 | ||
d8c52eb0 MS |
942 | /** |
943 | * maximum number of labels the user may create | |
944 | * @var integer | |
945 | */ | |
946 | _maxLabels: 0, | |
947 | ||
948 | /** | |
949 | * number of labels the user created | |
950 | * @var integer | |
951 | */ | |
952 | _labelCount: 0, | |
953 | ||
5e279c42 AE |
954 | /** |
955 | * Initializes the label manager for conversations. | |
956 | * | |
957 | * @param string link | |
958 | */ | |
959 | init: function(link) { | |
d4e2a0cc | 960 | this._deletedLabelID = 0; |
d8c52eb0 MS |
961 | this._maxLabels = 0; |
962 | this._labelCount = 0; | |
5e279c42 AE |
963 | this._link = link; |
964 | ||
e3fca11b | 965 | this._labels = WCF.Dropdown.getDropdownMenu('conversationLabelFilter').children('.scrollableDropdownMenu'); |
5e279c42 AE |
966 | $('#manageLabel').click($.proxy(this._click, this)); |
967 | ||
72f75266 | 968 | this._notification = new WCF.System.Notification(WCF.Language.get('wcf.conversation.label.management.addLabel.success')); |
5e279c42 AE |
969 | this._proxy = new WCF.Action.Proxy({ |
970 | success: $.proxy(this._success, this) | |
971 | }); | |
972 | }, | |
973 | ||
974 | /** | |
975 | * Handles clicks on the 'manage labels' button. | |
976 | */ | |
977 | _click: function() { | |
978 | this._proxy.setOption('data', { | |
979 | actionName: 'getLabelManagement', | |
980 | className: 'wcf\\data\\conversation\\ConversationAction' | |
981 | }); | |
982 | this._proxy.sendRequest(); | |
983 | }, | |
984 | ||
985 | /** | |
986 | * Handles successful AJAX requests. | |
987 | * | |
988 | * @param object data | |
989 | * @param string textStatus | |
990 | * @param jQuery jqXHR | |
991 | */ | |
992 | _success: function(data, textStatus, jqXHR) { | |
993 | if (this._dialog === null) { | |
994 | this._dialog = $('<div id="labelManagement" />').hide().appendTo(document.body); | |
995 | } | |
996 | ||
d4e2a0cc AE |
997 | if (data.returnValues && data.returnValues.actionName) { |
998 | switch (data.returnValues.actionName) { | |
999 | case 'add': | |
1000 | this._insertLabel(data); | |
1001 | break; | |
5e279c42 | 1002 | |
d4e2a0cc | 1003 | case 'getLabelManagement': |
d8c52eb0 MS |
1004 | this._maxLabels = parseInt(data.returnValues.maxLabels); |
1005 | this._labelCount = parseInt(data.returnValues.labelCount); | |
1006 | ||
d4e2a0cc AE |
1007 | // render dialog |
1008 | this._dialog.empty().html(data.returnValues.template); | |
1009 | this._dialog.wcfDialog({ | |
1010 | title: WCF.Language.get('wcf.conversation.label.management') | |
1011 | }); | |
1012 | this._dialog.wcfDialog('render'); | |
1013 | ||
1014 | // bind action listeners | |
1015 | this._bindListener(); | |
1016 | break; | |
1017 | } | |
1018 | } | |
1019 | else { | |
1020 | // check if delete label id is present within URL (causing an IllegalLinkException if reloading) | |
1021 | if (this._deletedLabelID) { | |
1022 | var $regex = new RegExp('(\\?|&)labelID=' + this._deletedLabelID); | |
1023 | window.location = window.location.toString().replace($regex, ''); | |
1024 | } | |
1025 | else { | |
72f75266 AE |
1026 | // reload page |
1027 | window.location.reload(); | |
d4e2a0cc | 1028 | } |
5e279c42 AE |
1029 | } |
1030 | }, | |
1031 | ||
1032 | /** | |
1033 | * Inserts a previously created label. | |
1034 | * | |
1035 | * @param object data | |
1036 | */ | |
72f75266 | 1037 | _insertLabel: function(data) { |
350145ef | 1038 | var $listItem = $('<li><a href="' + this._link + '&labelID=' + data.returnValues.labelID + '"><span class="badge label' + (data.returnValues.cssClassName ? ' ' + data.returnValues.cssClassName : '') + '">' + data.returnValues.label + '</span></a></li>'); |
9e1794f9 | 1039 | $listItem.find('a > span').data('labelID', data.returnValues.labelID).data('cssClassName', data.returnValues.cssClassName); |
5e279c42 | 1040 | |
e3fca11b | 1041 | this._labels.append($listItem); |
72f75266 AE |
1042 | |
1043 | this._notification.show(); | |
d8c52eb0 MS |
1044 | |
1045 | this._labelCount++; | |
1046 | ||
1047 | if (this._labelCount >= this._maxLabels) { | |
1048 | $('#conversationLabelManagementForm').hide(); | |
1049 | } | |
5e279c42 AE |
1050 | }, |
1051 | ||
1052 | /** | |
1053 | * Binds event listener for label management. | |
1054 | */ | |
1055 | _bindListener: function() { | |
5740132f | 1056 | $('#labelName').on('keyup keydown keypress', $.proxy(this._updateLabels, this)); |
67f16163 MS |
1057 | if ($.browser.mozilla && $.browser.touch) { |
1058 | $('#labelName').on('input', $.proxy(this._updateLabels, this)); | |
1059 | } | |
1060 | ||
d8c52eb0 MS |
1061 | if (this._labelCount >= this._maxLabels) { |
1062 | $('#conversationLabelManagementForm').hide(); | |
1063 | this._dialog.wcfDialog('render'); | |
1064 | } | |
1065 | ||
d4e2a0cc AE |
1066 | $('#addLabel').disable().click($.proxy(this._addLabel, this)); |
1067 | $('#editLabel').disable(); | |
72f75266 | 1068 | |
d4e2a0cc | 1069 | this._dialog.find('.conversationLabelList a.label').click($.proxy(this._edit, this)); |
72f75266 AE |
1070 | }, |
1071 | ||
1072 | /** | |
1073 | * Prepares a label for editing. | |
1074 | * | |
1075 | * @param object event | |
1076 | */ | |
1077 | _edit: function(event) { | |
d8c52eb0 MS |
1078 | if (this._labelCount >= this._maxLabels) { |
1079 | $('#conversationLabelManagementForm').show(); | |
1080 | this._dialog.wcfDialog('render'); | |
1081 | } | |
1082 | ||
72f75266 AE |
1083 | var $label = $(event.currentTarget); |
1084 | ||
1085 | // replace legends | |
3e5330c0 | 1086 | var $legend = WCF.Language.get('wcf.conversation.label.management.editLabel').replace(/#labelName#/, WCF.String.escapeHTML($label.text())); |
e2b79659 | 1087 | $('#conversationLabelManagementForm').data('labelID', $label.data('labelID')).children('.sectionTitle').html($legend); |
72f75266 AE |
1088 | |
1089 | // update text input | |
1090 | $('#labelName').val($label.text()).trigger('keyup'); | |
1091 | ||
1092 | // select css class name | |
1093 | var $cssClassName = $label.data('cssClassName'); | |
1094 | $('#labelManagementList input').each(function(index, input) { | |
1095 | var $input = $(input); | |
1096 | ||
1097 | if ($input.val() == $cssClassName) { | |
1098 | $input.attr('checked', 'checked'); | |
1099 | } | |
1100 | }); | |
1101 | ||
1102 | // toggle buttons | |
1103 | $('#addLabel').hide(); | |
1104 | $('#editLabel').show().click($.proxy(this._editLabel, this)); | |
1105 | $('#deleteLabel').show().click($.proxy(this._deleteLabel, this)); | |
1106 | }, | |
1107 | ||
1108 | /** | |
1109 | * Edits a label. | |
1110 | */ | |
1111 | _editLabel: function() { | |
1112 | this._proxy.setOption('data', { | |
1113 | actionName: 'update', | |
1114 | className: 'wcf\\data\\conversation\\label\\ConversationLabelAction', | |
d4e2a0cc | 1115 | objectIDs: [ $('#conversationLabelManagementForm').data('labelID') ], |
72f75266 AE |
1116 | parameters: { |
1117 | data: { | |
1118 | cssClassName: $('#labelManagementList input:checked').val(), | |
d4e2a0cc | 1119 | label: $('#labelName').val() |
72f75266 AE |
1120 | } |
1121 | } | |
1122 | }); | |
1123 | this._proxy.sendRequest(); | |
1124 | }, | |
1125 | ||
1126 | /** | |
1127 | * Deletes a label. | |
1128 | */ | |
1129 | _deleteLabel: function() { | |
1130 | var $title = WCF.Language.get('wcf.conversation.label.management.deleteLabel.confirmMessage').replace(/#labelName#/, $('#labelName').val()); | |
d4e2a0cc | 1131 | WCF.System.Confirmation.show($title, $.proxy(function(action) { |
72f75266 AE |
1132 | if (action === 'confirm') { |
1133 | this._proxy.setOption('data', { | |
1134 | actionName: 'delete', | |
1135 | className: 'wcf\\data\\conversation\\label\\ConversationLabelAction', | |
d4e2a0cc | 1136 | objectIDs: [ $('#conversationLabelManagementForm').data('labelID') ] |
72f75266 AE |
1137 | }); |
1138 | this._proxy.sendRequest(); | |
d4e2a0cc AE |
1139 | |
1140 | this._deletedLabelID = $('#conversationLabelManagementForm').data('labelID'); | |
72f75266 | 1141 | } |
b21bc4a1 | 1142 | }, this), undefined, undefined, true); |
5e279c42 AE |
1143 | }, |
1144 | ||
1145 | /** | |
1146 | * Updates label text within label management. | |
1147 | */ | |
1148 | _updateLabels: function() { | |
5740132f | 1149 | var $value = $.trim($('#labelName').val()); |
5e279c42 | 1150 | if ($value) { |
72f75266 | 1151 | $('#addLabel, #editLabel').enable(); |
5e279c42 AE |
1152 | } |
1153 | else { | |
1c942355 | 1154 | $('#addLabel, #editLabel').disable(); |
5e279c42 AE |
1155 | $value = WCF.Language.get('wcf.conversation.label.placeholder'); |
1156 | } | |
1157 | ||
1158 | $('#labelManagementList').find('span.label').text($value); | |
1159 | }, | |
1160 | ||
1161 | /** | |
1162 | * Sends an AJAX request to add a new label. | |
1163 | */ | |
1164 | _addLabel: function() { | |
1165 | var $labelName = $('#labelName').val(); | |
72f75266 | 1166 | var $cssClassName = $('#labelManagementList input:checked').val(); |
5e279c42 AE |
1167 | |
1168 | this._proxy.setOption('data', { | |
1169 | actionName: 'add', | |
1170 | className: 'wcf\\data\\conversation\\label\\ConversationLabelAction', | |
1171 | parameters: { | |
1172 | data: { | |
1173 | cssClassName: $cssClassName, | |
1174 | labelName: $labelName | |
1175 | } | |
1176 | } | |
1177 | }); | |
1178 | this._proxy.sendRequest(); | |
72f75266 AE |
1179 | |
1180 | // close dialog | |
1181 | this._dialog.wcfDialog('close'); | |
5e279c42 AE |
1182 | } |
1183 | }); | |
e2196ce0 MW |
1184 | |
1185 | /** | |
1186 | * Provides a flexible conversation preview. | |
1187 | * | |
1188 | * @see WCF.Popover | |
1189 | */ | |
1190 | WCF.Conversation.Preview = WCF.Popover.extend({ | |
1191 | /** | |
1192 | * action proxy | |
1193 | * @var WCF.Action.Proxy | |
1194 | */ | |
1195 | _proxy: null, | |
1196 | ||
1197 | /** | |
1198 | * @see WCF.Popover.init() | |
1199 | */ | |
1200 | init: function() { | |
1201 | this._super('.conversationLink'); | |
1202 | ||
1203 | // init proxy | |
1204 | this._proxy = new WCF.Action.Proxy({ | |
1205 | showLoadingOverlay: false | |
1206 | }); | |
1207 | ||
1208 | WCF.DOMNodeInsertedHandler.addCallback('WCF.Conversation.Preview', $.proxy(this._initContainers, this)); | |
1209 | }, | |
1210 | ||
1211 | /** | |
1212 | * @see WCF.Popover._loadContent() | |
1213 | */ | |
1214 | _loadContent: function() { | |
1215 | var $link = $('#' + this._activeElementID); | |
1216 | ||
1217 | this._proxy.setOption('data', { | |
1218 | actionName: 'getMessagePreview', | |
1219 | className: 'wcf\\data\\conversation\\ConversationAction', | |
1220 | objectIDs: [ $link.data('conversationID') ] | |
1221 | }); | |
1222 | ||
1223 | var $elementID = this._activeElementID; | |
1224 | var self = this; | |
1225 | this._proxy.setOption('success', function(data, textStatus, jqXHR) { | |
1226 | self._insertContent($elementID, data.returnValues.template, true); | |
1227 | }); | |
1228 | this._proxy.sendRequest(); | |
1229 | } | |
8b49562e | 1230 | }); |
742b8736 | 1231 | |
c61f0f25 AE |
1232 | /** |
1233 | * User Panel implementation for conversations. | |
1234 | * | |
1235 | * @see WCF.User.Panel.Abstract | |
1236 | */ | |
1237 | WCF.User.Panel.Conversation = WCF.User.Panel.Abstract.extend({ | |
1238 | /** | |
1239 | * @see WCF.User.Panel.Abstract.init() | |
1240 | */ | |
1241 | init: function(options) { | |
1242 | options.enableMarkAsRead = true; | |
1243 | ||
1244 | this._super($('#unreadConversations'), 'unreadConversations', options); | |
c7953aa4 AE |
1245 | |
1246 | WCF.System.Event.addListener('com.woltlab.wcf.conversation.userPanel', 'reset', (function() { | |
1247 | this.resetItems(); | |
1248 | this.updateBadge(0); | |
1249 | this._loadData = true; | |
1250 | }).bind(this)); | |
48f2f886 AE |
1251 | |
1252 | require(['EventHandler'], (function(EventHandler) { | |
1253 | EventHandler.add('com.woltlab.wcf.UserMenuMobile', 'more', (function(data) { | |
1254 | if (data.identifier === 'com.woltlab.wcf.conversation') { | |
1255 | this.toggle(); | |
1256 | } | |
1257 | }).bind(this)); | |
1258 | }).bind(this)); | |
c61f0f25 AE |
1259 | }, |
1260 | ||
1261 | /** | |
1262 | * @see WCF.User.Panel.Abstract._initDropdown() | |
1263 | */ | |
1264 | _initDropdown: function() { | |
1265 | var $dropdown = this._super(); | |
1266 | ||
0d511ff2 AE |
1267 | if (this._options.canStartConversation) { |
1268 | $('<li><a href="' + this._options.newConversationLink + '" title="' + this._options.newConversation + '" class="jsTooltip"><span class="icon icon24 fa-plus" /></a></li>').appendTo($dropdown.getLinkList()); | |
1269 | } | |
c61f0f25 AE |
1270 | |
1271 | return $dropdown; | |
1272 | }, | |
1273 | ||
1274 | /** | |
1275 | * @see WCF.User.Panel.Abstract._load() | |
1276 | */ | |
1277 | _load: function() { | |
1278 | this._proxy.setOption('data', { | |
1279 | actionName: 'getMixedConversationList', | |
1280 | className: 'wcf\\data\\conversation\\ConversationAction' | |
1281 | }); | |
1282 | this._proxy.sendRequest(); | |
1283 | }, | |
1284 | ||
1285 | /** | |
1286 | * @see WCF.User.Panel.Abstract._markAsRead() | |
1287 | */ | |
1288 | _markAsRead: function(event, objectID) { | |
1289 | this._proxy.setOption('data', { | |
1290 | actionName: 'markAsRead', | |
1291 | className: 'wcf\\data\\conversation\\ConversationAction', | |
1292 | objectIDs: [ objectID ] | |
1293 | }); | |
1294 | this._proxy.sendRequest(); | |
1295 | }, | |
1296 | ||
1297 | /** | |
1298 | * @see WCF.User.Panel.Abstract._markAllAsRead() | |
1299 | */ | |
1300 | _markAllAsRead: function(event) { | |
1301 | this._proxy.setOption('data', { | |
1302 | actionName: 'markAllAsRead', | |
1303 | className: 'wcf\\data\\conversation\\ConversationAction' | |
1304 | }); | |
1305 | this._proxy.sendRequest(); | |
c61f0f25 AE |
1306 | } |
1307 | }); | |
1308 | ||
7f75cde5 MW |
1309 | /** |
1310 | * Marks one conversation as read. | |
1311 | */ | |
1312 | WCF.Conversation.MarkAsRead = Class.extend({ | |
1313 | /** | |
1314 | * action proxy | |
1315 | * @var WCF.Action.Proxy | |
1316 | */ | |
1317 | _proxy: null, | |
1318 | ||
1319 | /** | |
1320 | * Initializes the mark as read for conversations. | |
1321 | */ | |
1322 | init: function() { | |
1323 | this._proxy = new WCF.Action.Proxy({ | |
1324 | success: $.proxy(this._success, this) | |
1325 | }); | |
1326 | ||
02ce3a8a | 1327 | $(document).on('dblclick', '.conversationList .new .columnAvatar', $.proxy(this._dblclick, this)); |
7f75cde5 MW |
1328 | }, |
1329 | ||
1330 | /** | |
1331 | * Handles double clicks on avatar. | |
1332 | * | |
1333 | * @param object event | |
1334 | */ | |
1335 | _dblclick: function(event) { | |
1336 | this._proxy.setOption('data', { | |
1337 | actionName: 'markAsRead', | |
1338 | className: 'wcf\\data\\conversation\\ConversationAction', | |
d7c80056 | 1339 | objectIDs: [ $(event.currentTarget).parents('ol:eq(0)').data('conversationID') ] |
7f75cde5 MW |
1340 | }); |
1341 | this._proxy.sendRequest(); | |
1342 | }, | |
1343 | ||
1344 | /** | |
1345 | * Handles successful AJAX requests. | |
1346 | * | |
1347 | * @param object data | |
1348 | * @param string textStatus | |
1349 | * @param jQuery jqXHR | |
1350 | */ | |
1351 | _success: function(data, textStatus, jqXHR) { | |
1352 | $('.conversationList .new').each(function(index, element) { | |
1353 | var $element = $(element); | |
1354 | if (WCF.inArray($element.data('conversationID'), data.objectIDs)) { | |
1355 | // remove new class | |
1356 | $element.removeClass('new'); | |
1357 | ||
1358 | // hide arrows | |
1359 | $element.find('.firstNewPost').parent().remove(); | |
1360 | ||
1361 | // remove event | |
1362 | $element.find('.columnAvatar').off('dblclick'); | |
1363 | } | |
1364 | }); | |
1365 | } | |
1366 | }); | |
1367 | ||
38cc68ad MW |
1368 | /** |
1369 | * Marks all conversations as read. | |
1370 | */ | |
1371 | WCF.Conversation.MarkAllAsRead = Class.extend({ | |
1372 | /** | |
1373 | * action proxy | |
1374 | * @var WCF.Action.Proxy | |
1375 | */ | |
1376 | _proxy: null, | |
1377 | ||
1378 | /** | |
1379 | * Initializes the WCF.Conversation.MarkAllAsRead class. | |
1380 | */ | |
1381 | init: function() { | |
1382 | this._proxy = new WCF.Action.Proxy({ | |
1383 | success: $.proxy(this._success, this) | |
1384 | }); | |
1385 | ||
6e576a66 | 1386 | $('.markAllAsReadButton').click($.proxy(this._click, this)); |
38cc68ad MW |
1387 | }, |
1388 | ||
1389 | /** | |
6e576a66 | 1390 | * Handles clicks. |
38cc68ad MW |
1391 | * |
1392 | * @param object event | |
1393 | */ | |
6e576a66 MW |
1394 | _click: function(event) { |
1395 | event.preventDefault(); | |
1396 | ||
38cc68ad MW |
1397 | this._proxy.setOption('data', { |
1398 | actionName: 'markAllAsRead', | |
1399 | className: 'wcf\\data\\conversation\\ConversationAction' | |
1400 | }); | |
1401 | this._proxy.sendRequest(); | |
1402 | }, | |
1403 | ||
1404 | /** | |
1405 | * Marks all conversations as read. | |
1406 | * | |
1407 | * @param object data | |
1408 | * @param string textStatus | |
1409 | * @param jQuery jqXHR | |
1410 | */ | |
1411 | _success: function(data, textStatus, jqXHR) { | |
1412 | // fix dropdown | |
c7953aa4 | 1413 | WCF.System.Event.fireEvent('com.woltlab.wcf.conversation.userPanel', 'reset'); |
38cc68ad MW |
1414 | |
1415 | // fix conversation list | |
1416 | var $conversationList = $('.conversationList'); | |
1417 | $conversationList.find('.new').removeClass('new'); | |
1418 | $conversationList.find('.columnAvatar').off('dblclick'); | |
1419 | } | |
1420 | }); | |
1421 | ||
a5bacc02 AE |
1422 | /** |
1423 | * Namespace for conversation messages. | |
1424 | */ | |
1425 | WCF.Conversation.Message = { }; | |
1426 | ||
1427 | /** | |
1428 | * Provides an inline editor for conversation messages. | |
1429 | * | |
1430 | * @see WCF.Message.InlineEditor | |
1431 | */ | |
1432 | WCF.Conversation.Message.InlineEditor = WCF.Message.InlineEditor.extend({ | |
b5ffaf76 AE |
1433 | /** |
1434 | * @see WCF.Message.InlineEditor.init() | |
1435 | */ | |
0109b481 AE |
1436 | init: function(containerID, quoteManager) { |
1437 | this._super(containerID, true, quoteManager); | |
b5ffaf76 AE |
1438 | }, |
1439 | ||
a5bacc02 AE |
1440 | /** |
1441 | * @see WCF.Message.InlineEditor._getClassName() | |
1442 | */ | |
1443 | _getClassName: function() { | |
1444 | return 'wcf\\data\\conversation\\message\\ConversationMessageAction'; | |
1445 | } | |
1446 | }); | |
19caa577 AE |
1447 | |
1448 | /** | |
1449 | * Provides the quote manager for conversation messages. | |
1450 | * | |
1451 | * @param WCF.Message.Quote.Manager quoteManager | |
1452 | * @see WCF.Message.Quote.Handler | |
1453 | */ | |
1454 | WCF.Conversation.Message.QuoteHandler = WCF.Message.Quote.Handler.extend({ | |
1455 | /** | |
1456 | * @see WCF.Message.QuoteManager.init() | |
1457 | */ | |
1458 | init: function(quoteManager) { | |
9ac36595 AE |
1459 | this._super( |
1460 | quoteManager, | |
1461 | 'wcf\\data\\conversation\\message\\ConversationMessageAction', | |
1462 | 'com.woltlab.wcf.conversation.message', | |
1463 | '.message', | |
1464 | '.messageBody', | |
1465 | '.messageBody > div > div.messageText', | |
1466 | true | |
1467 | ); | |
19caa577 AE |
1468 | } |
1469 | }); |