Commit | Line | Data |
---|---|---|
320f4a6d MW |
1 | /** |
2 | * User-related classes. | |
3 | * | |
4 | * @author Alexander Ebert | |
ca4ba303 | 5 | * @copyright 2001-2014 WoltLab GmbH |
320f4a6d MW |
6 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
7 | */ | |
8 | ||
9 | /** | |
10 | * User login | |
11 | * | |
12 | * @param boolean isQuickLogin | |
13 | */ | |
14 | WCF.User.Login = Class.extend({ | |
15 | /** | |
16 | * login button | |
17 | * @var jQuery | |
18 | */ | |
19 | _loginSubmitButton: null, | |
20 | ||
21 | /** | |
22 | * password input | |
23 | * @var jQuery | |
24 | */ | |
25 | _password: null, | |
26 | ||
27 | /** | |
28 | * password input container | |
29 | * @var jQuery | |
30 | */ | |
31 | _passwordContainer: null, | |
32 | ||
33 | /** | |
34 | * cookie input | |
35 | * @var jQuery | |
36 | */ | |
37 | _useCookies: null, | |
38 | ||
39 | /** | |
40 | * cookie input container | |
41 | * @var jQuery | |
42 | */ | |
43 | _useCookiesContainer: null, | |
44 | ||
45 | /** | |
46 | * Initializes the user login | |
47 | * | |
48 | * @param boolean isQuickLogin | |
49 | */ | |
50 | init: function(isQuickLogin) { | |
51 | this._loginSubmitButton = $('#loginSubmitButton'); | |
52 | this._password = $('#password'), | |
53 | this._passwordContainer = this._password.parents('dl'); | |
54 | this._useCookies = $('#useCookies'); | |
55 | this._useCookiesContainer = this._useCookies.parents('dl'); | |
56 | ||
57 | var $loginForm = $('#loginForm'); | |
58 | $loginForm.find('input[name=action]').change($.proxy(this._change, this)); | |
59 | ||
60 | if (isQuickLogin) { | |
61 | WCF.User.QuickLogin.init(); | |
62 | } | |
63 | }, | |
64 | ||
65 | /** | |
66 | * Handle toggle between login and register. | |
67 | * | |
68 | * @param object event | |
69 | */ | |
70 | _change: function(event) { | |
71 | if ($(event.currentTarget).val() === 'register') { | |
72 | this._setState(false, WCF.Language.get('wcf.user.button.register')); | |
73 | } | |
74 | else { | |
75 | this._setState(true, WCF.Language.get('wcf.user.button.login')); | |
76 | } | |
77 | }, | |
78 | ||
79 | /** | |
80 | * Sets form states. | |
81 | * | |
82 | * @param boolean enable | |
83 | * @param string buttonTitle | |
84 | */ | |
85 | _setState: function(enable, buttonTitle) { | |
86 | if (enable) { | |
87 | this._password.enable(); | |
88 | this._passwordContainer.removeClass('disabled'); | |
89 | this._useCookies.enable(); | |
90 | this._useCookiesContainer.removeClass('disabled'); | |
91 | } | |
92 | else { | |
93 | this._password.disable(); | |
94 | this._passwordContainer.addClass('disabled'); | |
95 | this._useCookies.disable(); | |
96 | this._useCookiesContainer.addClass('disabled'); | |
97 | } | |
98 | ||
99 | this._loginSubmitButton.val(buttonTitle); | |
100 | } | |
101 | }); | |
102 | ||
103 | /** | |
104 | * Quick login box | |
105 | */ | |
106 | WCF.User.QuickLogin = { | |
107 | /** | |
108 | * dialog overlay | |
109 | * @var jQuery | |
110 | */ | |
111 | _dialog: null, | |
112 | ||
113 | /** | |
114 | * login message container | |
115 | * @var jQuery | |
116 | */ | |
117 | _loginMessage: null, | |
118 | ||
119 | /** | |
120 | * Initializes the quick login box | |
121 | */ | |
122 | init: function() { | |
123 | $('.loginLink').click($.proxy(this._render, this)); | |
6e34696a AE |
124 | |
125 | // prepend protocol and hostname | |
126 | $('#loginForm input[name=url]').val(function(index, value) { | |
127 | return window.location.protocol + '//' + window.location.host + value; | |
128 | }); | |
320f4a6d MW |
129 | }, |
130 | ||
131 | /** | |
132 | * Displays the quick login box with a info message | |
133 | * | |
134 | * @param string message | |
135 | */ | |
136 | show: function(message) { | |
137 | if (message) { | |
138 | if (this._loginMessage === null) { | |
139 | this._loginMessage = $('<p class="info" />').hide().prependTo($('#loginForm > form')); | |
140 | } | |
141 | ||
142 | this._loginMessage.show().text(message); | |
143 | } | |
144 | else if (this._loginMessage !== null) { | |
145 | this._loginMessage.hide(); | |
146 | } | |
147 | ||
148 | this._render(); | |
149 | }, | |
150 | ||
151 | /** | |
152 | * Renders the dialog | |
153 | * | |
154 | * @param jQuery.Event event | |
155 | */ | |
156 | _render: function(event) { | |
157 | if (event !== undefined) { | |
158 | event.preventDefault(); | |
159 | } | |
160 | ||
161 | if (this._dialog === null) { | |
162 | this._dialog = $('#loginForm').wcfDialog({ | |
163 | title: WCF.Language.get('wcf.user.login') | |
164 | }); | |
165 | this._dialog.find('#username').focus(); | |
166 | } | |
167 | else { | |
168 | this._dialog.wcfDialog('open'); | |
169 | } | |
170 | } | |
171 | }; | |
172 | ||
173 | /** | |
174 | * UserProfile namespace | |
175 | */ | |
176 | WCF.User.Profile = {}; | |
177 | ||
178 | /** | |
179 | * Shows the activity point list for users. | |
180 | */ | |
181 | WCF.User.Profile.ActivityPointList = { | |
182 | /** | |
183 | * list of cached templates | |
184 | * @var object | |
185 | */ | |
186 | _cache: { }, | |
187 | ||
188 | /** | |
189 | * dialog overlay | |
190 | * @var jQuery | |
191 | */ | |
192 | _dialog: null, | |
193 | ||
194 | /** | |
195 | * initialization state | |
196 | * @var boolean | |
197 | */ | |
198 | _didInit: false, | |
199 | ||
200 | /** | |
201 | * action proxy | |
202 | * @var WCF.Action.Proxy | |
203 | */ | |
204 | _proxy: null, | |
205 | ||
206 | /** | |
207 | * Initializes the WCF.User.Profile.ActivityPointList class. | |
208 | */ | |
209 | init: function() { | |
210 | if (this._didInit) { | |
211 | return; | |
212 | } | |
213 | ||
214 | this._cache = { }; | |
215 | this._dialog = null; | |
216 | this._proxy = new WCF.Action.Proxy({ | |
217 | success: $.proxy(this._success, this) | |
218 | }); | |
219 | ||
220 | this._init(); | |
221 | ||
222 | WCF.DOMNodeInsertedHandler.addCallback('WCF.User.Profile.ActivityPointList', $.proxy(this._init, this)); | |
223 | ||
224 | this._didInit = true; | |
225 | }, | |
226 | ||
227 | /** | |
228 | * Initializes display for activity points. | |
229 | */ | |
230 | _init: function() { | |
231 | $('.activityPointsDisplay').removeClass('activityPointsDisplay').click($.proxy(this._click, this)); | |
232 | }, | |
233 | ||
234 | /** | |
235 | * Shows or loads the activity point for selected user. | |
236 | * | |
237 | * @param object event | |
238 | */ | |
239 | _click: function(event) { | |
240 | var $userID = $(event.currentTarget).data('userID'); | |
241 | ||
242 | if (this._cache[$userID] === undefined) { | |
243 | this._proxy.setOption('data', { | |
244 | actionName: 'getDetailedActivityPointList', | |
245 | className: 'wcf\\data\\user\\UserProfileAction', | |
246 | objectIDs: [ $userID ] | |
247 | }); | |
248 | this._proxy.sendRequest(); | |
249 | } | |
250 | else { | |
251 | this._show($userID); | |
252 | } | |
253 | }, | |
254 | ||
255 | /** | |
256 | * Displays activity points for given user. | |
257 | * | |
258 | * @param integer userID | |
259 | */ | |
260 | _show: function(userID) { | |
261 | if (this._dialog === null) { | |
262 | this._dialog = $('<div>' + this._cache[userID] + '</div>').hide().appendTo(document.body); | |
263 | this._dialog.wcfDialog({ | |
264 | title: WCF.Language.get('wcf.user.activityPoint') | |
265 | }); | |
266 | } | |
267 | else { | |
268 | this._dialog.html(this._cache[userID]); | |
269 | this._dialog.wcfDialog('open'); | |
270 | } | |
271 | }, | |
272 | ||
273 | /** | |
274 | * Handles successful AJAX requests. | |
275 | * | |
276 | * @param object data | |
277 | * @param string textStatus | |
278 | * @param jQuery jqXHR | |
279 | */ | |
280 | _success: function(data, textStatus, jqXHR) { | |
281 | this._cache[data.returnValues.userID] = data.returnValues.template; | |
282 | this._show(data.returnValues.userID); | |
283 | } | |
284 | }; | |
285 | ||
286 | /** | |
287 | * Provides methods to follow an user. | |
e3369fd2 | 288 | * |
320f4a6d MW |
289 | * @param integer userID |
290 | * @param boolean following | |
291 | */ | |
292 | WCF.User.Profile.Follow = Class.extend({ | |
293 | /** | |
294 | * follow button | |
295 | * @var jQuery | |
296 | */ | |
297 | _button: null, | |
298 | ||
299 | /** | |
300 | * true if following current user | |
301 | * @var boolean | |
302 | */ | |
303 | _following: false, | |
304 | ||
305 | /** | |
306 | * action proxy object | |
307 | * @var WCF.Action.Proxy | |
308 | */ | |
309 | _proxy: null, | |
310 | ||
311 | /** | |
312 | * user id | |
313 | * @var integer | |
314 | */ | |
315 | _userID: 0, | |
316 | ||
317 | /** | |
318 | * Creates a new follow object. | |
319 | * | |
320 | * @param integer userID | |
321 | * @param boolean following | |
322 | */ | |
323 | init: function (userID, following) { | |
324 | this._following = following; | |
325 | this._userID = userID; | |
326 | this._proxy = new WCF.Action.Proxy({ | |
327 | success: $.proxy(this._success, this) | |
328 | }); | |
329 | ||
330 | this._createButton(); | |
331 | this._showButton(); | |
332 | }, | |
333 | ||
334 | /** | |
335 | * Creates the (un-)follow button | |
336 | */ | |
337 | _createButton: function () { | |
338 | this._button = $('<li id="followUser"><a class="button jsTooltip" title="'+WCF.Language.get('wcf.user.button.'+(this._following ? 'un' : '')+'follow')+'"><span class="icon icon16 icon-plus"></span> <span class="invisible">'+WCF.Language.get('wcf.user.button.'+(this._following ? 'un' : '')+'follow')+'</span></a></li>').prependTo($('#profileButtonContainer')); | |
339 | this._button.click($.proxy(this._execute, this)); | |
340 | }, | |
341 | ||
342 | /** | |
343 | * Follows or unfollows an user. | |
344 | */ | |
345 | _execute: function () { | |
346 | var $actionName = (this._following) ? 'unfollow' : 'follow'; | |
347 | this._proxy.setOption('data', { | |
348 | 'actionName': $actionName, | |
349 | 'className': 'wcf\\data\\user\\follow\\UserFollowAction', | |
350 | 'parameters': { | |
351 | data: { | |
352 | userID: this._userID | |
353 | } | |
354 | } | |
355 | }); | |
356 | this._proxy.sendRequest(); | |
357 | }, | |
358 | ||
359 | /** | |
360 | * Displays current follow state. | |
361 | */ | |
362 | _showButton: function () { | |
363 | if (this._following) { | |
364 | this._button.find('.button').data('tooltip', WCF.Language.get('wcf.user.button.unfollow')).addClass('active').children('.icon').removeClass('icon-plus').addClass('icon-minus'); | |
365 | } | |
366 | else { | |
367 | this._button.find('.button').data('tooltip', WCF.Language.get('wcf.user.button.follow')).removeClass('active').children('.icon').removeClass('icon-minus').addClass('icon-plus'); | |
368 | } | |
369 | }, | |
370 | ||
371 | /** | |
372 | * Update object state on success. | |
373 | * | |
374 | * @param object data | |
375 | * @param string textStatus | |
376 | * @param jQuery jqXHR | |
377 | */ | |
378 | _success: function (data, textStatus, jqXHR) { | |
379 | this._following = data.returnValues.following; | |
380 | this._showButton(); | |
381 | ||
382 | var $notification = new WCF.System.Notification(); | |
383 | $notification.show(); | |
384 | } | |
385 | }); | |
386 | ||
387 | /** | |
388 | * Provides methods to manage ignored users. | |
389 | * | |
390 | * @param integer userID | |
391 | * @param boolean isIgnoredUser | |
392 | */ | |
393 | WCF.User.Profile.IgnoreUser = Class.extend({ | |
394 | /** | |
395 | * ignore button | |
396 | * @var jQuery | |
397 | */ | |
398 | _button: null, | |
399 | ||
400 | /** | |
401 | * ignore state | |
402 | * @var boolean | |
403 | */ | |
404 | _isIgnoredUser: false, | |
405 | ||
406 | /** | |
407 | * ajax proxy object | |
408 | * @var WCF.Action.Proxy | |
409 | */ | |
410 | _proxy: null, | |
411 | ||
412 | /** | |
413 | * target user id | |
414 | * @var integer | |
415 | */ | |
416 | _userID: 0, | |
417 | ||
418 | /** | |
419 | * Initializes methods to manage an ignored user. | |
420 | * | |
421 | * @param integer userID | |
422 | * @param boolean isIgnoredUser | |
423 | */ | |
424 | init: function(userID, isIgnoredUser) { | |
425 | this._userID = userID; | |
426 | this._isIgnoredUser = isIgnoredUser; | |
427 | ||
428 | // initialize proxy | |
429 | this._proxy = new WCF.Action.Proxy({ | |
430 | success: $.proxy(this._success, this) | |
431 | }); | |
432 | ||
433 | // handle button | |
434 | this._updateButton(); | |
435 | this._button.click($.proxy(this._click, this)); | |
436 | }, | |
437 | ||
438 | /** | |
439 | * Handle clicks, might cause 'ignore' or 'unignore' to be triggered. | |
440 | */ | |
441 | _click: function() { | |
442 | var $action = (this._isIgnoredUser) ? 'unignore' : 'ignore'; | |
443 | ||
444 | this._proxy.setOption('data', { | |
445 | actionName: $action, | |
446 | className: 'wcf\\data\\user\\ignore\\UserIgnoreAction', | |
447 | parameters: { | |
448 | data: { | |
449 | ignoreUserID: this._userID | |
450 | } | |
451 | } | |
452 | }); | |
453 | ||
454 | this._proxy.sendRequest(); | |
455 | }, | |
456 | ||
457 | /** | |
458 | * Updates button label and function upon successful request. | |
459 | * | |
460 | * @param object data | |
461 | * @param string textStatus | |
462 | * @param jQuery jqXHR | |
463 | */ | |
464 | _success: function(data, textStatus, jqXHR) { | |
465 | this._isIgnoredUser = data.returnValues.isIgnoredUser; | |
466 | this._updateButton(); | |
467 | ||
468 | var $notification = new WCF.System.Notification(); | |
469 | $notification.show(); | |
470 | }, | |
471 | ||
472 | /** | |
473 | * Updates button label and inserts it if not exists. | |
474 | */ | |
475 | _updateButton: function() { | |
476 | if (this._button === null) { | |
f2d4ebce | 477 | this._button = $('<li id="ignoreUser"><a class="button jsTooltip" title="'+WCF.Language.get('wcf.user.button.'+(this._isIgnoredUser ? 'un' : '')+'ignore')+'"><span class="icon icon16 icon-ban-circle"></span> <span class="invisible">'+WCF.Language.get('wcf.user.button.'+(this._isIgnoredUser ? 'un' : '')+'ignore')+'</span></a></li>').prependTo($('#profileButtonContainer')); |
320f4a6d MW |
478 | } |
479 | ||
480 | this._button.find('.button').data('tooltip', WCF.Language.get('wcf.user.button.' + (this._isIgnoredUser ? 'un' : '') + 'ignore')); | |
e200deac MW |
481 | if (this._isIgnoredUser) this._button.find('.button').addClass('active').children('.icon').removeClass('icon-ban-circle').addClass('icon-circle-blank'); |
482 | else this._button.find('.button').removeClass('active').children('.icon').removeClass('icon-circle-blank').addClass('icon-ban-circle'); | |
320f4a6d MW |
483 | } |
484 | }); | |
485 | ||
486 | /** | |
487 | * Provides methods to load tab menu content upon request. | |
488 | */ | |
489 | WCF.User.Profile.TabMenu = Class.extend({ | |
490 | /** | |
491 | * list of containers | |
492 | * @var object | |
493 | */ | |
494 | _hasContent: { }, | |
495 | ||
496 | /** | |
497 | * profile content | |
498 | * @var jQuery | |
499 | */ | |
500 | _profileContent: null, | |
501 | ||
502 | /** | |
503 | * action proxy | |
504 | * @var WCF.Action.Proxy | |
505 | */ | |
506 | _proxy: null, | |
507 | ||
508 | /** | |
509 | * target user id | |
510 | * @var integer | |
511 | */ | |
512 | _userID: 0, | |
513 | ||
514 | /** | |
515 | * Initializes the tab menu loader. | |
516 | * | |
517 | * @param integer userID | |
518 | */ | |
519 | init: function(userID) { | |
520 | this._profileContent = $('#profileContent'); | |
521 | this._userID = userID; | |
522 | ||
523 | var $activeMenuItem = this._profileContent.data('active'); | |
524 | var $enableProxy = false; | |
525 | ||
526 | // fetch content state | |
527 | this._profileContent.find('div.tabMenuContent').each($.proxy(function(index, container) { | |
528 | var $containerID = $(container).wcfIdentify(); | |
529 | ||
530 | if ($activeMenuItem === $containerID) { | |
531 | this._hasContent[$containerID] = true; | |
532 | } | |
533 | else { | |
534 | this._hasContent[$containerID] = false; | |
535 | $enableProxy = true; | |
536 | } | |
537 | }, this)); | |
538 | ||
539 | // enable loader if at least one container is empty | |
540 | if ($enableProxy) { | |
541 | this._proxy = new WCF.Action.Proxy({ | |
542 | success: $.proxy(this._success, this) | |
543 | }); | |
544 | ||
545 | this._profileContent.bind('wcftabsbeforeactivate', $.proxy(this._loadContent, this)); | |
546 | } | |
547 | }, | |
548 | ||
549 | /** | |
550 | * Prepares to load content once tabs are being switched. | |
551 | * | |
552 | * @param object event | |
553 | * @param object ui | |
554 | */ | |
555 | _loadContent: function(event, ui) { | |
556 | var $panel = $(ui.newPanel); | |
557 | var $containerID = $panel.attr('id'); | |
558 | ||
559 | if (!this._hasContent[$containerID]) { | |
560 | this._proxy.setOption('data', { | |
561 | actionName: 'getContent', | |
562 | className: 'wcf\\data\\user\\profile\\menu\\item\\UserProfileMenuItemAction', | |
563 | parameters: { | |
564 | data: { | |
565 | containerID: $containerID, | |
566 | menuItem: $panel.data('menuItem'), | |
567 | userID: this._userID | |
568 | } | |
569 | } | |
570 | }); | |
571 | this._proxy.sendRequest(); | |
572 | } | |
573 | }, | |
574 | ||
575 | /** | |
576 | * Shows previously requested content. | |
577 | * | |
578 | * @param object data | |
579 | * @param string textStatus | |
580 | * @param jQuery jqXHR | |
581 | */ | |
582 | _success: function(data, textStatus, jqXHR) { | |
583 | var $containerID = data.returnValues.containerID; | |
584 | this._hasContent[$containerID] = true; | |
585 | ||
586 | // insert content | |
587 | var $content = this._profileContent.find('#' + $containerID); | |
588 | $('<div>' + data.returnValues.template + '</div>').hide().appendTo($content); | |
589 | ||
590 | // slide in content | |
591 | $content.children('div').wcfBlindIn(); | |
592 | } | |
593 | }); | |
594 | ||
595 | /** | |
596 | * User profile inline editor. | |
597 | * | |
598 | * @param integer userID | |
599 | * @param boolean editOnInit | |
600 | */ | |
601 | WCF.User.Profile.Editor = Class.extend({ | |
602 | /** | |
603 | * current action | |
604 | * @var string | |
605 | */ | |
606 | _actionName: '', | |
607 | ||
608 | /** | |
609 | * list of interface buttons | |
610 | * @var object | |
611 | */ | |
612 | _buttons: { }, | |
613 | ||
614 | /** | |
615 | * cached tab content | |
616 | * @var string | |
617 | */ | |
618 | _cachedTemplate: '', | |
619 | ||
620 | /** | |
621 | * action proxy | |
622 | * @var WCF.Action.Proxy | |
623 | */ | |
624 | _proxy: null, | |
625 | ||
626 | /** | |
627 | * tab object | |
628 | * @var jQuery | |
629 | */ | |
630 | _tab: null, | |
631 | ||
632 | /** | |
633 | * target user id | |
634 | * @var integer | |
635 | */ | |
636 | _userID: 0, | |
637 | ||
638 | /** | |
639 | * Initializes the WCF.User.Profile.Editor object. | |
640 | * | |
641 | * @param integer userID | |
642 | * @param boolean editOnInit | |
643 | */ | |
644 | init: function(userID, editOnInit) { | |
645 | this._actionName = ''; | |
646 | this._cachedTemplate = ''; | |
647 | this._tab = $('#about'); | |
648 | this._userID = userID; | |
649 | this._proxy = new WCF.Action.Proxy({ | |
650 | success: $.proxy(this._success, this) | |
651 | }); | |
652 | ||
653 | this._initButtons(); | |
654 | ||
655 | // begin editing on page load | |
656 | if (editOnInit) { | |
657 | this._beginEdit(); | |
658 | } | |
659 | }, | |
660 | ||
661 | /** | |
662 | * Initializes interface buttons. | |
663 | */ | |
664 | _initButtons: function() { | |
665 | var $buttonContainer = $('#profileButtonContainer'); | |
666 | ||
667 | // create buttons | |
668 | this._buttons = { | |
669 | beginEdit: $('<li><a class="button"><span class="icon icon16 icon-pencil" /> <span>' + WCF.Language.get('wcf.user.editProfile') + '</span></a></li>').click($.proxy(this._beginEdit, this)).appendTo($buttonContainer) | |
670 | }; | |
671 | }, | |
672 | ||
673 | /** | |
674 | * Begins editing. | |
675 | */ | |
676 | _beginEdit: function() { | |
677 | this._actionName = 'beginEdit'; | |
678 | this._buttons.beginEdit.hide(); | |
679 | $('#profileContent').wcfTabs('select', 'about'); | |
680 | ||
681 | // load form | |
682 | this._proxy.setOption('data', { | |
683 | actionName: 'beginEdit', | |
684 | className: 'wcf\\data\\user\\UserProfileAction', | |
685 | objectIDs: [ this._userID ] | |
686 | }); | |
687 | this._proxy.sendRequest(); | |
688 | }, | |
689 | ||
690 | /** | |
691 | * Saves input values. | |
692 | */ | |
693 | _save: function() { | |
694 | this._actionName = 'save'; | |
695 | ||
696 | // collect values | |
697 | var $regExp = /values\[([a-zA-Z0-9._-]+)\]/; | |
698 | var $values = { }; | |
699 | this._tab.find('input, textarea, select').each(function(index, element) { | |
700 | var $element = $(element); | |
701 | ||
702 | if ($element.getTagName() === 'input') { | |
703 | var $type = $element.attr('type'); | |
704 | ||
705 | if (($type === 'radio' || $type === 'checkbox') && !$element.prop('checked')) { | |
706 | return; | |
707 | } | |
708 | } | |
709 | ||
710 | var $name = $element.attr('name'); | |
711 | if ($regExp.test($name)) { | |
712 | $values[RegExp.$1] = $element.val(); | |
713 | } | |
714 | }); | |
715 | ||
716 | this._proxy.setOption('data', { | |
717 | actionName: 'save', | |
718 | className: 'wcf\\data\\user\\UserProfileAction', | |
719 | objectIDs: [ this._userID ], | |
720 | parameters: { | |
721 | values: $values | |
722 | } | |
723 | }); | |
724 | this._proxy.sendRequest(); | |
725 | }, | |
726 | ||
727 | /** | |
728 | * Restores back to default view. | |
729 | */ | |
730 | _restore: function() { | |
731 | this._actionName = 'restore'; | |
732 | this._buttons.beginEdit.show(); | |
733 | ||
734 | this._destroyCKEditor(); | |
735 | ||
736 | this._tab.html(this._cachedTemplate).children().css({ height: 'auto' }); | |
737 | }, | |
738 | ||
739 | /** | |
740 | * Handles successful AJAX requests. | |
741 | * | |
742 | * @param object data | |
743 | * @param string textStatus | |
744 | * @param jQuery jqXHR | |
745 | */ | |
746 | _success: function(data, textStatus, jqXHR) { | |
747 | switch (this._actionName) { | |
748 | case 'beginEdit': | |
749 | this._prepareEdit(data); | |
750 | break; | |
751 | ||
752 | case 'save': | |
753 | // save was successful, show parsed template | |
754 | if (data.returnValues.success) { | |
755 | this._cachedTemplate = data.returnValues.template; | |
756 | this._restore(); | |
757 | } | |
758 | else { | |
759 | this._prepareEdit(data, true); | |
760 | } | |
761 | break; | |
762 | } | |
763 | }, | |
764 | ||
765 | /** | |
766 | * Prepares editing mode. | |
767 | * | |
768 | * @param object data | |
769 | * @param boolean disableCache | |
770 | */ | |
771 | _prepareEdit: function(data, disableCache) { | |
772 | this._destroyCKEditor(); | |
773 | ||
774 | // update template | |
775 | var self = this; | |
776 | this._tab.html(function(index, oldHTML) { | |
777 | if (disableCache !== true) { | |
778 | self._cachedTemplate = oldHTML; | |
779 | } | |
780 | ||
781 | return data.returnValues.template; | |
782 | }); | |
783 | ||
784 | // block autocomplete | |
785 | this._tab.find('input[type=text]').attr('autocomplete', 'off'); | |
786 | ||
787 | // bind event listener | |
788 | this._tab.find('.formSubmit > button[data-type=save]').click($.proxy(this._save, this)); | |
789 | this._tab.find('.formSubmit > button[data-type=restore]').click($.proxy(this._restore, this)); | |
790 | this._tab.find('input').keyup(function(event) { | |
791 | if (event.which === 13) { // Enter | |
792 | self._save(); | |
793 | ||
794 | event.preventDefault(); | |
795 | return false; | |
796 | } | |
797 | }); | |
798 | }, | |
799 | ||
800 | /** | |
801 | * Destroys all CKEditor instances within current tab. | |
802 | */ | |
803 | _destroyCKEditor: function() { | |
804 | // destroy all CKEditor instances | |
805 | this._tab.find('textarea + .cke').each(function(index, container) { | |
806 | var $instanceName = $(container).attr('id').replace(/cke_/, ''); | |
807 | if (CKEDITOR.instances[$instanceName]) { | |
808 | CKEDITOR.instances[$instanceName].destroy(); | |
809 | } | |
810 | }); | |
811 | } | |
812 | }); | |
813 | ||
320f4a6d MW |
814 | /** |
815 | * Namespace for registration functions. | |
816 | */ | |
817 | WCF.User.Registration = {}; | |
818 | ||
819 | /** | |
820 | * Validates the password. | |
821 | * | |
822 | * @param jQuery element | |
823 | * @param jQuery confirmElement | |
824 | * @param object options | |
825 | */ | |
826 | WCF.User.Registration.Validation = Class.extend({ | |
827 | /** | |
828 | * action name | |
829 | * @var string | |
830 | */ | |
831 | _actionName: '', | |
832 | ||
833 | /** | |
834 | * class name | |
835 | * @var string | |
836 | */ | |
837 | _className: '', | |
838 | ||
839 | /** | |
840 | * confirmation input element | |
841 | * @var jQuery | |
842 | */ | |
843 | _confirmElement: null, | |
844 | ||
845 | /** | |
846 | * input element | |
847 | * @var jQuery | |
848 | */ | |
849 | _element: null, | |
850 | ||
851 | /** | |
852 | * list of error messages | |
853 | * @var object | |
854 | */ | |
855 | _errorMessages: { }, | |
856 | ||
857 | /** | |
858 | * list of additional options | |
859 | * @var object | |
860 | */ | |
861 | _options: { }, | |
862 | ||
863 | /** | |
864 | * AJAX proxy | |
865 | * @var WCF.Action.Proxy | |
866 | */ | |
867 | _proxy: null, | |
868 | ||
869 | /** | |
870 | * Initializes the validation. | |
871 | * | |
872 | * @param jQuery element | |
873 | * @param jQuery confirmElement | |
874 | * @param object options | |
875 | */ | |
876 | init: function(element, confirmElement, options) { | |
877 | this._element = element; | |
878 | this._element.blur($.proxy(this._blur, this)); | |
879 | this._confirmElement = confirmElement || null; | |
880 | ||
881 | if (this._confirmElement !== null) { | |
882 | this._confirmElement.blur($.proxy(this._blurConfirm, this)); | |
883 | } | |
884 | ||
885 | options = options || { }; | |
886 | this._setOptions(options); | |
887 | ||
888 | this._proxy = new WCF.Action.Proxy({ | |
889 | success: $.proxy(this._success, this), | |
890 | showLoadingOverlay: false | |
891 | }); | |
892 | ||
893 | this._setErrorMessages(); | |
894 | }, | |
895 | ||
896 | /** | |
897 | * Sets additional options | |
898 | */ | |
899 | _setOptions: function(options) { }, | |
900 | ||
901 | /** | |
902 | * Sets error messages. | |
903 | */ | |
904 | _setErrorMessages: function() { | |
905 | this._errorMessages = { | |
906 | ajaxError: '', | |
907 | notEqual: '' | |
908 | }; | |
909 | }, | |
910 | ||
911 | /** | |
912 | * Validates once focus on input is lost. | |
913 | * | |
914 | * @param object event | |
915 | */ | |
916 | _blur: function(event) { | |
917 | var $value = this._element.val(); | |
918 | if (!$value) { | |
919 | return this._showError(this._element, WCF.Language.get('wcf.global.form.error.empty')); | |
920 | } | |
921 | ||
922 | if (this._confirmElement !== null) { | |
923 | var $confirmValue = this._confirmElement.val(); | |
924 | if ($confirmValue != '' && $value != $confirmValue) { | |
925 | return this._showError(this._confirmElement, this._errorMessages.notEqual); | |
926 | } | |
927 | } | |
928 | ||
929 | if (!this._validateOptions()) { | |
930 | return; | |
931 | } | |
932 | ||
933 | this._proxy.setOption('data', { | |
934 | actionName: this._actionName, | |
935 | className: this._className, | |
936 | parameters: this._getParameters() | |
937 | }); | |
938 | this._proxy.sendRequest(); | |
939 | }, | |
940 | ||
941 | /** | |
942 | * Returns a list of parameters. | |
943 | * | |
944 | * @return object | |
945 | */ | |
946 | _getParameters: function() { | |
947 | return { }; | |
948 | }, | |
949 | ||
950 | /** | |
951 | * Validates input by options. | |
952 | * | |
953 | * @return boolean | |
954 | */ | |
955 | _validateOptions: function() { | |
956 | return true; | |
957 | }, | |
958 | ||
959 | /** | |
960 | * Validates value once confirmation input focus is lost. | |
961 | * | |
962 | * @param object event | |
963 | */ | |
964 | _blurConfirm: function(event) { | |
965 | var $value = this._confirmElement.val(); | |
966 | if (!$value) { | |
967 | return this._showError(this._confirmElement, WCF.Language.get('wcf.global.form.error.empty')); | |
968 | } | |
969 | ||
970 | this._blur(event); | |
971 | }, | |
972 | ||
973 | /** | |
974 | * Handles AJAX responses. | |
975 | * | |
976 | * @param object data | |
977 | * @param string textStatus | |
978 | * @param jQuery jqXHR | |
979 | */ | |
980 | _success: function(data, textStatus, jqXHR) { | |
981 | if (data.returnValues.isValid) { | |
982 | this._showSuccess(this._element); | |
983 | if (this._confirmElement !== null && this._confirmElement.val()) { | |
984 | this._showSuccess(this._confirmElement); | |
985 | } | |
986 | } | |
987 | else { | |
988 | this._showError(this._element, WCF.Language.get(this._errorMessages.ajaxError + data.returnValues.error)); | |
989 | } | |
990 | }, | |
991 | ||
992 | /** | |
993 | * Shows an error message. | |
994 | * | |
995 | * @param jQuery element | |
996 | * @param string message | |
997 | */ | |
998 | _showError: function(element, message) { | |
999 | element.parent().parent().addClass('formError').removeClass('formSuccess'); | |
1000 | ||
1001 | var $innerError = element.parent().find('small.innerError'); | |
1002 | if (!$innerError.length) { | |
1003 | $innerError = $('<small />').addClass('innerError').insertAfter(element); | |
1004 | } | |
1005 | ||
1006 | $innerError.text(message); | |
1007 | }, | |
1008 | ||
1009 | /** | |
1010 | * Displays a success message. | |
1011 | * | |
1012 | * @param jQuery element | |
1013 | */ | |
1014 | _showSuccess: function(element) { | |
1015 | element.parent().parent().addClass('formSuccess').removeClass('formError'); | |
1016 | element.next('small.innerError').remove(); | |
1017 | } | |
1018 | }); | |
1019 | ||
1020 | /** | |
1021 | * Username validation for registration. | |
e3369fd2 | 1022 | * |
320f4a6d MW |
1023 | * @see WCF.User.Registration.Validation |
1024 | */ | |
1025 | WCF.User.Registration.Validation.Username = WCF.User.Registration.Validation.extend({ | |
1026 | /** | |
1027 | * @see WCF.User.Registration.Validation._actionName | |
1028 | */ | |
1029 | _actionName: 'validateUsername', | |
1030 | ||
1031 | /** | |
1032 | * @see WCF.User.Registration.Validation._className | |
1033 | */ | |
1034 | _className: 'wcf\\data\\user\\UserRegistrationAction', | |
1035 | ||
1036 | /** | |
1037 | * @see WCF.User.Registration.Validation._setOptions() | |
1038 | */ | |
1039 | _setOptions: function(options) { | |
1040 | this._options = $.extend(true, { | |
1041 | minlength: 3, | |
1042 | maxlength: 25 | |
1043 | }, options); | |
1044 | }, | |
1045 | ||
1046 | /** | |
1047 | * @see WCF.User.Registration.Validation._setErrorMessages() | |
1048 | */ | |
1049 | _setErrorMessages: function() { | |
1050 | this._errorMessages = { | |
1051 | ajaxError: 'wcf.user.username.error.' | |
1052 | }; | |
1053 | }, | |
1054 | ||
1055 | /** | |
1056 | * @see WCF.User.Registration.Validation._validateOptions() | |
1057 | */ | |
1058 | _validateOptions: function() { | |
1059 | var $value = this._element.val(); | |
1060 | if ($value.length < this._options.minlength || $value.length > this._options.maxlength) { | |
1061 | this._showError(this._element, WCF.Language.get('wcf.user.username.error.notValid')); | |
1062 | return false; | |
1063 | } | |
1064 | ||
1065 | return true; | |
1066 | }, | |
1067 | ||
1068 | /** | |
1069 | * @see WCF.User.Registration.Validation._getParameters() | |
1070 | */ | |
1071 | _getParameters: function() { | |
1072 | return { | |
1073 | username: this._element.val() | |
1074 | }; | |
1075 | } | |
1076 | }); | |
1077 | ||
1078 | /** | |
1079 | * Email validation for registration. | |
1080 | * | |
1081 | * @see WCF.User.Registration.Validation | |
1082 | */ | |
1083 | WCF.User.Registration.Validation.EmailAddress = WCF.User.Registration.Validation.extend({ | |
1084 | /** | |
1085 | * @see WCF.User.Registration.Validation._actionName | |
1086 | */ | |
1087 | _actionName: 'validateEmailAddress', | |
1088 | ||
1089 | /** | |
1090 | * @see WCF.User.Registration.Validation._className | |
1091 | */ | |
1092 | _className: 'wcf\\data\\user\\UserRegistrationAction', | |
1093 | ||
1094 | /** | |
1095 | * @see WCF.User.Registration.Validation._getParameters() | |
1096 | */ | |
1097 | _getParameters: function() { | |
1098 | return { | |
1099 | email: this._element.val() | |
1100 | }; | |
1101 | }, | |
1102 | ||
1103 | /** | |
1104 | * @see WCF.User.Registration.Validation._setErrorMessages() | |
1105 | */ | |
1106 | _setErrorMessages: function() { | |
1107 | this._errorMessages = { | |
1108 | ajaxError: 'wcf.user.email.error.', | |
1109 | notEqual: WCF.Language.get('wcf.user.confirmEmail.error.notEqual') | |
1110 | }; | |
1111 | } | |
1112 | }); | |
1113 | ||
1114 | /** | |
1115 | * Password validation for registration. | |
1116 | * | |
1117 | * @see WCF.User.Registration.Validation | |
1118 | */ | |
1119 | WCF.User.Registration.Validation.Password = WCF.User.Registration.Validation.extend({ | |
1120 | /** | |
1121 | * @see WCF.User.Registration.Validation._actionName | |
1122 | */ | |
1123 | _actionName: 'validatePassword', | |
1124 | ||
1125 | /** | |
1126 | * @see WCF.User.Registration.Validation._className | |
1127 | */ | |
1128 | _className: 'wcf\\data\\user\\UserRegistrationAction', | |
1129 | ||
1130 | /** | |
1131 | * @see WCF.User.Registration.Validation._getParameters() | |
1132 | */ | |
1133 | _getParameters: function() { | |
1134 | return { | |
1135 | password: this._element.val() | |
1136 | }; | |
1137 | }, | |
1138 | ||
1139 | /** | |
1140 | * @see WCF.User.Registration.Validation._setErrorMessages() | |
1141 | */ | |
1142 | _setErrorMessages: function() { | |
1143 | this._errorMessages = { | |
1144 | ajaxError: 'wcf.user.password.error.', | |
1145 | notEqual: WCF.Language.get('wcf.user.confirmPassword.error.notEqual') | |
1146 | }; | |
1147 | } | |
1148 | }); | |
1149 | ||
1150 | /** | |
1151 | * Toggles input fields for lost password form. | |
1152 | */ | |
1153 | WCF.User.Registration.LostPassword = Class.extend({ | |
1154 | /** | |
1155 | * email input | |
1156 | * @var jQuery | |
1157 | */ | |
1158 | _email: null, | |
1159 | ||
1160 | /** | |
1161 | * username input | |
1162 | * @var jQuery | |
1163 | */ | |
1164 | _username: null, | |
1165 | ||
1166 | /** | |
1167 | * Initializes LostPassword-form class. | |
1168 | */ | |
1169 | init: function() { | |
1170 | // bind input fields | |
1171 | this._email = $('#emailInput'); | |
1172 | this._username = $('#usernameInput'); | |
1173 | ||
1174 | // bind event listener | |
1175 | this._email.keyup($.proxy(this._checkEmail, this)); | |
1176 | this._username.keyup($.proxy(this._checkUsername, this)); | |
1177 | ||
b986ad3d MS |
1178 | if ($.browser.mozilla && $.browser.touch) { |
1179 | this._email.on('input', $.proxy(this._checkEmail, this)); | |
1180 | this._username.on('input', $.proxy(this._checkUsername, this)); | |
1181 | } | |
1182 | ||
320f4a6d MW |
1183 | // toggle fields on init |
1184 | this._checkEmail(); | |
1185 | this._checkUsername(); | |
1186 | }, | |
1187 | ||
1188 | /** | |
1189 | * Checks for content in email field and toggles username. | |
1190 | */ | |
1191 | _checkEmail: function() { | |
1192 | if (this._email.val() == '') { | |
1193 | this._username.enable(); | |
1194 | this._username.parents('dl:eq(0)').removeClass('disabled'); | |
1195 | } | |
1196 | else { | |
1197 | this._username.disable(); | |
1198 | this._username.parents('dl:eq(0)').addClass('disabled'); | |
1199 | } | |
1200 | }, | |
1201 | ||
1202 | /** | |
1203 | * Checks for content in username field and toggles email. | |
1204 | */ | |
1205 | _checkUsername: function() { | |
1206 | if (this._username.val() == '') { | |
1207 | this._email.enable(); | |
1208 | this._email.parents('dl:eq(0)').removeClass('disabled'); | |
1209 | } | |
1210 | else { | |
1211 | this._email.disable(); | |
1212 | this._email.parents('dl:eq(0)').addClass('disabled'); | |
1213 | } | |
1214 | } | |
1215 | }); | |
1216 | ||
1217 | /** | |
1218 | * Notification system for WCF. | |
1219 | * | |
1220 | * @author Alexander Ebert | |
ca4ba303 | 1221 | * @copyright 2001-2014 WoltLab GmbH |
320f4a6d MW |
1222 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
1223 | */ | |
1224 | WCF.Notification = {}; | |
1225 | ||
1226 | /** | |
1227 | * Loads notification for the user panel. | |
1228 | * | |
1229 | * @see WCF.UserPanel | |
1230 | */ | |
1231 | WCF.Notification.UserPanel = WCF.UserPanel.extend({ | |
1232 | /** | |
1233 | * action proxy | |
1234 | * @var WCF.Action.Proxy | |
1235 | */ | |
1236 | _proxy: null, | |
1237 | ||
1238 | /** | |
1239 | * link to show all notifications | |
1240 | * @var string | |
1241 | */ | |
1242 | _showAllLink: '', | |
1243 | ||
1244 | /** | |
1245 | * @see WCF.UserPanel.init() | |
1246 | */ | |
1247 | init: function(showAllLink) { | |
1248 | this._noItems = 'wcf.user.notification.noMoreNotifications'; | |
1249 | this._proxy = new WCF.Action.Proxy({ | |
1250 | success: $.proxy(this._success, this) | |
1251 | }); | |
1252 | this._showAllLink = showAllLink; | |
1253 | ||
1254 | this._super('userNotifications'); | |
1255 | ||
1256 | // update page title | |
1257 | if (this._container.data('count')) { | |
1258 | document.title = '(' + this._container.data('count') + ') ' + document.title; | |
1259 | } | |
1260 | }, | |
1261 | ||
1262 | /** | |
1263 | * @see WCF.UserPanel._addDefaultItems() | |
1264 | */ | |
1265 | _addDefaultItems: function(dropdownMenu) { | |
1266 | this._addDivider(dropdownMenu); | |
d0b141cb | 1267 | if (this._container.data('count')) { |
1268 | $('<li><a href="' + this._showAllLink + '">' + WCF.Language.get('wcf.user.notification.showAll') + '</a></li>').appendTo(dropdownMenu); | |
1269 | this._addDivider(dropdownMenu); | |
1270 | } | |
320f4a6d MW |
1271 | $('<li id="userNotificationsMarkAllAsConfirmed"><a>' + WCF.Language.get('wcf.user.notification.markAllAsConfirmed') + '</a></li>').click($.proxy(this._markAllAsConfirmed, this)).appendTo(dropdownMenu); |
1272 | }, | |
1273 | ||
1274 | /** | |
1275 | * @see WCF.UserPanel._getParameters() | |
1276 | */ | |
1277 | _getParameters: function() { | |
1278 | return { | |
1279 | actionName: 'getOutstandingNotifications', | |
1280 | className: 'wcf\\data\\user\\notification\\UserNotificationAction' | |
1281 | }; | |
1282 | }, | |
1283 | ||
1284 | /** | |
1285 | * @see WCF.UserPanel._after() | |
1286 | */ | |
1287 | _after: function(dropdownMenu) { | |
541f30ea | 1288 | WCF.Dropdown.getDropdownMenu(this._container.wcfIdentify()).children('li.jsNotificationItem').click($.proxy(this._markAsConfirmed, this)); |
320f4a6d MW |
1289 | }, |
1290 | ||
1291 | /** | |
1292 | * Marks a notification as confirmed. | |
1293 | * | |
1294 | * @param object event | |
1295 | */ | |
1296 | _markAsConfirmed: function(event) { | |
1297 | this._proxy.setOption('data', { | |
1298 | actionName: 'markAsConfirmed', | |
1299 | className: 'wcf\\data\\user\\notification\\UserNotificationAction', | |
1300 | parameters: { | |
1301 | notificationID: $(event.currentTarget).data('notificationID') | |
1302 | } | |
1303 | }); | |
1304 | this._proxy.sendRequest(); | |
1305 | }, | |
1306 | ||
1307 | /** | |
1308 | * Marks all notifications as confirmed. | |
1309 | */ | |
1310 | _markAllAsConfirmed: function() { | |
1311 | WCF.System.Confirmation.show(WCF.Language.get('wcf.user.notification.markAllAsConfirmed.confirmMessage'), $.proxy(function(action) { | |
1312 | if (action === 'confirm') { | |
1313 | this._proxy.setOption('data', { | |
1314 | actionName: 'markAllAsConfirmed', | |
1315 | className: 'wcf\\data\\user\\notification\\UserNotificationAction' | |
1316 | }); | |
1317 | this._proxy.sendRequest(); | |
1318 | } | |
1319 | }, this)); | |
1320 | }, | |
1321 | ||
1322 | /** | |
1323 | * @see WCF.UserPanel._success() | |
1324 | */ | |
1325 | _success: function(data, textStatus, jqXHR) { | |
1326 | switch (data.actionName) { | |
1327 | case 'markAllAsConfirmed': | |
1328 | $('.jsNotificationItem').remove(); | |
1329 | // remove notification count | |
1330 | document.title = document.title.replace(/^\(([0-9]+)\) /, ''); | |
1331 | // fall through | |
1332 | case 'getOutstandingNotifications': | |
1333 | if (!data.returnValues || !data.returnValues.template) { | |
1334 | $('#userNotificationsMarkAllAsConfirmed').prev('.dropdownDivider').remove(); | |
1335 | $('#userNotificationsMarkAllAsConfirmed').remove(); | |
1336 | } | |
1337 | ||
1338 | this._super(data, textStatus, jqXHR); | |
1339 | break; | |
1340 | ||
1341 | case 'markAsConfirmed': | |
541f30ea | 1342 | WCF.Dropdown.getDropdownMenu(this._container.wcfIdentify()).children('li.jsNotificationItem').each(function(index, item) { |
320f4a6d MW |
1343 | var $item = $(item); |
1344 | if (data.returnValues.notificationID == $item.data('notificationID')) { | |
1345 | window.location = $item.data('link'); | |
1346 | return false; | |
1347 | } | |
1348 | }); | |
1349 | break; | |
1350 | } | |
1351 | } | |
1352 | }); | |
1353 | ||
1354 | /** | |
1355 | * Handles notification list actions. | |
1356 | */ | |
1357 | WCF.Notification.List = Class.extend({ | |
1358 | /** | |
1359 | * notification count | |
1360 | * @var jQuery | |
1361 | */ | |
1362 | _badge: null, | |
1363 | ||
1364 | /** | |
1365 | * list of notification items | |
1366 | * @var object | |
1367 | */ | |
1368 | _items: { }, | |
1369 | ||
1370 | /** | |
1371 | * action proxy | |
1372 | * @var WCF.Action.Proxy | |
1373 | */ | |
1374 | _proxy: null, | |
1375 | ||
1376 | /** | |
1377 | * Initializes the notification list. | |
1378 | */ | |
1379 | init: function() { | |
1380 | var $containers = $('li.jsNotificationItem'); | |
1381 | if (!$containers.length) { | |
1382 | return; | |
1383 | } | |
1384 | ||
1385 | $containers.each($.proxy(function(index, container) { | |
1386 | var $container = $(container); | |
1387 | this._items[$container.data('notificationID')] = $container; | |
1388 | ||
1389 | $container.find('.jsMarkAsConfirmed').data('notificationID', $container.data('notificationID')).click($.proxy(this._click, this)); | |
1390 | $container.find('p').html(function(index, oldHTML) { | |
1391 | return '<a>' + oldHTML + '</a>'; | |
418dd584 | 1392 | }).children('a').data('notificationID', $container.data('notificationID')).click($.proxy(this._clickLink, this)); |
320f4a6d MW |
1393 | }, this)); |
1394 | ||
1395 | this._badge = $('.jsNotificationsBadge:eq(0)'); | |
1396 | this._proxy = new WCF.Action.Proxy({ | |
1397 | success: $.proxy(this._success, this) | |
1398 | }); | |
1399 | ||
1400 | // mark all as confirmed button | |
1401 | $('.contentNavigation .jsMarkAllAsConfirmed').click($.proxy(this._markAllAsConfirmed, this)); | |
1402 | }, | |
1403 | ||
418dd584 AE |
1404 | /** |
1405 | * Handles clicks on the text link. | |
1406 | * | |
1407 | * @param object event | |
1408 | */ | |
1409 | _clickLink: function(event) { | |
1410 | this._items[$(event.currentTarget).data('notificationID')].data('redirect', true); | |
1411 | this._click(event); | |
1412 | }, | |
1413 | ||
320f4a6d MW |
1414 | /** |
1415 | * Handles button actions. | |
1416 | * | |
1417 | * @param object event | |
1418 | */ | |
1419 | _click: function(event) { | |
320f4a6d MW |
1420 | this._proxy.setOption('data', { |
1421 | actionName: 'markAsConfirmed', | |
1422 | className: 'wcf\\data\\user\\notification\\UserNotificationAction', | |
1423 | parameters: { | |
418dd584 | 1424 | notificationID: $(event.currentTarget).data('notificationID') |
320f4a6d MW |
1425 | } |
1426 | }); | |
1427 | this._proxy.sendRequest(); | |
1428 | }, | |
1429 | ||
1430 | /** | |
1431 | * Marks all notifications as confirmed. | |
1432 | */ | |
1433 | _markAllAsConfirmed: function() { | |
1434 | WCF.System.Confirmation.show(WCF.Language.get('wcf.user.notification.markAllAsConfirmed.confirmMessage'), $.proxy(function(action) { | |
1435 | if (action === 'confirm') { | |
1436 | this._proxy.setOption('data', { | |
1437 | actionName: 'markAllAsConfirmed', | |
1438 | className: 'wcf\\data\\user\\notification\\UserNotificationAction' | |
1439 | }); | |
1440 | this._proxy.sendRequest(); | |
1441 | } | |
1442 | }, this)); | |
1443 | }, | |
1444 | ||
1445 | /** | |
1446 | * Handles successful button actions. | |
1447 | * | |
1448 | * @param object data | |
1449 | * @param string textStatus | |
1450 | * @param jQuery jqXHR | |
1451 | */ | |
1452 | _success: function(data, textStatus, jqXHR) { | |
1453 | switch (data.actionName) { | |
1454 | case 'markAllAsConfirmed': | |
1455 | window.location.reload(); | |
1456 | break; | |
1457 | ||
1458 | case 'markAsConfirmed': | |
418dd584 AE |
1459 | var $item = this._items[data.returnValues.notificationID]; |
1460 | if ($item.data('redirect')) { | |
1461 | window.location = $item.data('link'); | |
1462 | return; | |
1463 | } | |
1464 | ||
320f4a6d MW |
1465 | this._items[data.returnValues.notificationID].remove(); |
1466 | delete this._items[data.returnValues.notificationID]; | |
1467 | ||
1468 | // reduce badge count | |
1469 | this._badge.html(data.returnValues.totalCount); | |
1470 | ||
1471 | // remove previous notification count | |
1472 | document.title = document.title.replace(/^\(([0-9]+)\) /, ''); | |
1473 | ||
1474 | // update page title | |
1475 | if (data.returnValues.totalCount > 0) { | |
1476 | document.title = '(' + data.returnValues.totalCount + ') ' + document.title; | |
1477 | } | |
1478 | break; | |
1479 | } | |
1480 | } | |
1481 | }); | |
1482 | ||
1483 | /** | |
1484 | * Signature preview. | |
1485 | * | |
1486 | * @see WCF.Message.Preview | |
1487 | */ | |
1488 | WCF.User.SignaturePreview = WCF.Message.Preview.extend({ | |
1489 | /** | |
1490 | * @see WCF.Message.Preview._handleResponse() | |
1491 | */ | |
1492 | _handleResponse: function(data) { | |
1493 | // get preview container | |
1494 | var $preview = $('#previewContainer'); | |
1495 | if (!$preview.length) { | |
1496 | $preview = $('<fieldset id="previewContainer"><legend>' + WCF.Language.get('wcf.global.preview') + '</legend><div></div></fieldset>').insertBefore($('#signatureContainer')).wcfFadeIn(); | |
1497 | } | |
1498 | ||
1499 | $preview.children('div').first().html(data.returnValues.message); | |
1500 | } | |
1501 | }); | |
1502 | ||
1503 | /** | |
1504 | * Loads recent activity events once the user scrolls to the very bottom. | |
1505 | * | |
1506 | * @param integer userID | |
1507 | */ | |
1508 | WCF.User.RecentActivityLoader = Class.extend({ | |
1509 | /** | |
1510 | * container object | |
1511 | * @var jQuery | |
1512 | */ | |
1513 | _container: null, | |
1514 | ||
1515 | /** | |
1516 | * true if list should be filtered by followed users | |
1517 | * @var boolean | |
1518 | */ | |
1519 | _filteredByFollowedUsers: false, | |
1520 | ||
1521 | /** | |
1522 | * button to load next events | |
1523 | * @var jQuery | |
1524 | */ | |
1525 | _loadButton: null, | |
1526 | ||
1527 | /** | |
1528 | * action proxy | |
1529 | * @var WCF.Action.Proxy | |
1530 | */ | |
1531 | _proxy: null, | |
1532 | ||
1533 | /** | |
1534 | * user id | |
1535 | * @var integer | |
1536 | */ | |
1537 | _userID: 0, | |
1538 | ||
1539 | /** | |
1540 | * Initializes a new RecentActivityLoader object. | |
1541 | * | |
1542 | * @param integer userID | |
1543 | * @param boolean filteredByFollowedUsers | |
1544 | */ | |
1545 | init: function(userID, filteredByFollowedUsers) { | |
1546 | this._container = $('#recentActivities'); | |
1547 | this._filteredByFollowedUsers = (filteredByFollowedUsers === true); | |
1548 | this._userID = userID; | |
1549 | ||
1550 | if (this._userID !== null && !this._userID) { | |
1551 | console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given."); | |
1552 | return; | |
1553 | } | |
1554 | ||
1555 | this._proxy = new WCF.Action.Proxy({ | |
1556 | success: $.proxy(this._success, this) | |
1557 | }); | |
1558 | ||
1559 | this._loadButton = $('<li class="recentActivitiesMore"><button class="small">' + WCF.Language.get('wcf.user.recentActivity.more') + '</button></li>').appendTo(this._container); | |
1560 | this._loadButton = this._loadButton.children('button').click($.proxy(this._click, this)); | |
1561 | }, | |
1562 | ||
1563 | /** | |
1564 | * Loads next activity events. | |
1565 | */ | |
1566 | _click: function() { | |
1567 | this._loadButton.enable(); | |
1568 | ||
1569 | var $parameters = { | |
1570 | lastEventTime: this._container.data('lastEventTime') | |
1571 | }; | |
1572 | if (this._userID) { | |
1573 | $parameters.userID = this._userID; | |
1574 | } | |
1575 | else if (this._filteredByFollowedUsers) { | |
1576 | $parameters.filteredByFollowedUsers = 1; | |
1577 | } | |
1578 | ||
1579 | this._proxy.setOption('data', { | |
1580 | actionName: 'load', | |
1581 | className: 'wcf\\data\\user\\activity\\event\\UserActivityEventAction', | |
1582 | parameters: $parameters | |
1583 | }); | |
1584 | this._proxy.sendRequest(); | |
1585 | }, | |
1586 | ||
1587 | /** | |
1588 | * Handles successful AJAX requests. | |
1589 | * | |
1590 | * @param object data | |
1591 | * @param string textStatus | |
1592 | * @param jQuery jqXHR | |
1593 | */ | |
1594 | _success: function(data, textStatus, jqXHR) { | |
1595 | if (data.returnValues.template) { | |
1596 | $(data.returnValues.template).insertBefore(this._loadButton.parent()); | |
1597 | ||
1598 | this._container.data('lastEventTime', data.returnValues.lastEventTime); | |
1599 | this._loadButton.enable(); | |
1600 | } | |
1601 | else { | |
1602 | $('<small>' + WCF.Language.get('wcf.user.recentActivity.noMoreEntries') + '</small>').appendTo(this._loadButton.parent()); | |
1603 | this._loadButton.remove(); | |
1604 | } | |
1605 | } | |
1606 | }); | |
1607 | ||
1608 | /** | |
1609 | * Loads user profile previews. | |
1610 | * | |
1611 | * @see WCF.Popover | |
1612 | */ | |
1613 | WCF.User.ProfilePreview = WCF.Popover.extend({ | |
1614 | /** | |
1615 | * action proxy | |
1616 | * @var WCF.Action.Proxy | |
1617 | */ | |
1618 | _proxy: null, | |
1619 | ||
1620 | /** | |
1621 | * list of user profiles | |
1622 | * @var object | |
1623 | */ | |
1624 | _userProfiles: { }, | |
1625 | ||
1626 | /** | |
1627 | * @see WCF.Popover.init() | |
1628 | */ | |
1629 | init: function() { | |
1630 | this._super('.userLink'); | |
1631 | ||
1632 | this._proxy = new WCF.Action.Proxy({ | |
1633 | showLoadingOverlay: false | |
1634 | }); | |
1635 | }, | |
1636 | ||
1637 | /** | |
1638 | * @see WCF.Popover._loadContent() | |
1639 | */ | |
1640 | _loadContent: function() { | |
1641 | var $element = $('#' + this._activeElementID); | |
1642 | var $userID = $element.data('userID'); | |
1643 | ||
1644 | if (this._userProfiles[$userID]) { | |
1645 | // use cached user profile | |
1646 | this._insertContent(this._activeElementID, this._userProfiles[$userID], true); | |
1647 | } | |
1648 | else { | |
1649 | this._proxy.setOption('data', { | |
1650 | actionName: 'getUserProfile', | |
1651 | className: 'wcf\\data\\user\\UserProfileAction', | |
1652 | objectIDs: [ $userID ] | |
1653 | }); | |
1654 | ||
1655 | var $elementID = this._activeElementID; | |
1656 | var self = this; | |
1657 | this._proxy.setOption('success', function(data, textStatus, jqXHR) { | |
1658 | // cache user profile | |
1659 | self._userProfiles[$userID] = data.returnValues.template; | |
1660 | ||
1661 | // show user profile | |
1662 | self._insertContent($elementID, data.returnValues.template, true); | |
1663 | }); | |
9906f623 AE |
1664 | this._proxy.setOption('failure', function(data, jqXHR, textStatus, errorThrown) { |
1665 | // cache user profile | |
1666 | self._userProfiles[$userID] = data.message; | |
1667 | ||
1668 | // show user profile | |
1669 | self._insertContent($elementID, data.message, true); | |
1670 | ||
1671 | return false; | |
1672 | }); | |
320f4a6d MW |
1673 | this._proxy.sendRequest(); |
1674 | } | |
1675 | } | |
1676 | }); | |
1677 | ||
1678 | /** | |
1679 | * Initalizes WCF.User.Action namespace. | |
1680 | */ | |
1681 | WCF.User.Action = {}; | |
1682 | ||
1683 | /** | |
1684 | * Handles user follow and unfollow links. | |
1685 | */ | |
1686 | WCF.User.Action.Follow = Class.extend({ | |
1687 | /** | |
1688 | * list with elements containing follow and unfollow buttons | |
1689 | * @var array | |
1690 | */ | |
1691 | _containerList: null, | |
1692 | ||
1693 | /** | |
1694 | * CSS selector for follow buttons | |
1695 | * @var string | |
1696 | */ | |
1697 | _followButtonSelector: '.jsFollowButton', | |
1698 | ||
1699 | /** | |
1700 | * id of the user that is currently being followed/unfollowed | |
1701 | * @var integer | |
1702 | */ | |
1703 | _userID: 0, | |
1704 | ||
1705 | /** | |
1706 | * Initializes new WCF.User.Action.Follow object. | |
1707 | * | |
1708 | * @param array containerList | |
1709 | * @param string followButtonSelector | |
1710 | */ | |
1711 | init: function(containerList, followButtonSelector) { | |
1712 | if (!containerList.length) { | |
1713 | return; | |
1714 | } | |
1715 | this._containerList = containerList; | |
1716 | ||
1717 | if (followButtonSelector) { | |
1718 | this._followButtonSelector = followButtonSelector; | |
1719 | } | |
1720 | ||
1721 | // initialize proxy | |
1722 | this._proxy = new WCF.Action.Proxy({ | |
1723 | success: $.proxy(this._success, this) | |
1724 | }); | |
1725 | ||
1726 | // bind event listeners | |
1727 | this._containerList.each($.proxy(function(index, container) { | |
1728 | $(container).find(this._followButtonSelector).click($.proxy(this._click, this)); | |
1729 | }, this)); | |
1730 | }, | |
1731 | ||
1732 | /** | |
1733 | * Handles a click on a follow or unfollow button. | |
1734 | * | |
1735 | * @param object event | |
1736 | */ | |
1737 | _click: function(event) { | |
1738 | var link = $(event.target); | |
1739 | if (!link.is('a')) { | |
1740 | link = link.closest('a'); | |
1741 | } | |
1742 | this._userID = link.data('objectID'); | |
1743 | ||
1744 | this._proxy.setOption('data', { | |
1745 | 'actionName': link.data('following') ? 'unfollow' : 'follow', | |
1746 | 'className': 'wcf\\data\\user\\follow\\UserFollowAction', | |
1747 | 'parameters': { | |
1748 | data: { | |
1749 | userID: this._userID | |
1750 | } | |
1751 | } | |
1752 | }); | |
1753 | this._proxy.sendRequest(); | |
1754 | }, | |
1755 | ||
1756 | /** | |
1757 | * Handles the successful (un)following of a user. | |
1758 | * | |
1759 | * @param object data | |
1760 | * @param string textStatus | |
1761 | * @param jQuery jqXHR | |
1762 | */ | |
1763 | _success: function(data, textStatus, jqXHR) { | |
1764 | this._containerList.each($.proxy(function(index, container) { | |
1765 | var button = $(container).find(this._followButtonSelector).get(0); | |
1766 | ||
1767 | if (button && $(button).data('objectID') == this._userID) { | |
1768 | button = $(button); | |
1769 | ||
1770 | // toogle icon title | |
1771 | if (data.returnValues.following) { | |
1772 | button.data('tooltip', WCF.Language.get('wcf.user.button.unfollow')).children('.icon').removeClass('icon-plus').addClass('icon-minus'); | |
1773 | } | |
1774 | else { | |
1775 | button.data('tooltip', WCF.Language.get('wcf.user.button.follow')).children('.icon').removeClass('icon-minus').addClass('icon-plus'); | |
1776 | } | |
1777 | ||
1778 | button.data('following', data.returnValues.following); | |
1779 | ||
1780 | return false; | |
1781 | } | |
1782 | }, this)); | |
1783 | ||
1784 | var $notification = new WCF.System.Notification(); | |
1785 | $notification.show(); | |
1786 | } | |
1787 | }); | |
1788 | ||
1789 | /** | |
1790 | * Handles user ignore and unignore links. | |
1791 | */ | |
1792 | WCF.User.Action.Ignore = Class.extend({ | |
1793 | /** | |
1794 | * list with elements containing ignore and unignore buttons | |
1795 | * @var array | |
1796 | */ | |
1797 | _containerList: null, | |
1798 | ||
1799 | /** | |
1800 | * CSS selector for ignore buttons | |
1801 | * @var string | |
1802 | */ | |
1803 | _ignoreButtonSelector: '.jsIgnoreButton', | |
1804 | ||
1805 | /** | |
1806 | * id of the user that is currently being ignored/unignored | |
1807 | * @var integer | |
1808 | */ | |
1809 | _userID: 0, | |
1810 | ||
1811 | /** | |
1812 | * Initializes new WCF.User.Action.Ignore object. | |
1813 | * | |
1814 | * @param array containerList | |
1815 | * @param string ignoreButtonSelector | |
1816 | */ | |
1817 | init: function(containerList, ignoreButtonSelector) { | |
1818 | if (!containerList.length) { | |
1819 | return; | |
1820 | } | |
1821 | this._containerList = containerList; | |
1822 | ||
1823 | if (ignoreButtonSelector) { | |
1824 | this._ignoreButtonSelector = ignoreButtonSelector; | |
1825 | } | |
1826 | ||
1827 | // initialize proxy | |
1828 | this._proxy = new WCF.Action.Proxy({ | |
1829 | success: $.proxy(this._success, this) | |
1830 | }); | |
1831 | ||
1832 | // bind event listeners | |
1833 | this._containerList.each($.proxy(function(index, container) { | |
1834 | $(container).find(this._ignoreButtonSelector).click($.proxy(this._click, this)); | |
1835 | }, this)); | |
1836 | }, | |
1837 | ||
1838 | /** | |
1839 | * Handles a click on a ignore or unignore button. | |
1840 | * | |
1841 | * @param object event | |
1842 | */ | |
1843 | _click: function(event) { | |
1844 | var link = $(event.target); | |
1845 | if (!link.is('a')) { | |
1846 | link = link.closest('a'); | |
1847 | } | |
1848 | this._userID = link.data('objectID'); | |
1849 | ||
1850 | this._proxy.setOption('data', { | |
1851 | 'actionName': link.data('ignored') ? 'unignore' : 'ignore', | |
1852 | 'className': 'wcf\\data\\user\\ignore\\UserIgnoreAction', | |
1853 | 'parameters': { | |
1854 | data: { | |
1855 | ignoreUserID: this._userID | |
1856 | } | |
1857 | } | |
1858 | }); | |
1859 | this._proxy.sendRequest(); | |
1860 | }, | |
1861 | ||
1862 | /** | |
1863 | * Handles the successful (un)ignoring of a user. | |
1864 | * | |
1865 | * @param object data | |
1866 | * @param string textStatus | |
1867 | * @param jQuery jqXHR | |
1868 | */ | |
1869 | _success: function(data, textStatus, jqXHR) { | |
1870 | this._containerList.each($.proxy(function(index, container) { | |
1871 | var button = $(container).find(this._ignoreButtonSelector).get(0); | |
1872 | ||
1873 | if (button && $(button).data('objectID') == this._userID) { | |
1874 | button = $(button); | |
1875 | ||
1876 | // toogle icon title | |
1877 | if (data.returnValues.isIgnoredUser) { | |
e200deac | 1878 | button.data('tooltip', WCF.Language.get('wcf.user.button.unignore')).children('.icon').removeClass('icon-ban-circle').addClass('icon-circle-blank'); |
320f4a6d MW |
1879 | } |
1880 | else { | |
e200deac | 1881 | button.data('tooltip', WCF.Language.get('wcf.user.button.ignore')).children('.icon').removeClass('icon-circle-blank').addClass('icon-ban-circle'); |
320f4a6d MW |
1882 | } |
1883 | ||
1884 | button.data('ignored', data.returnValues.isIgnoredUser); | |
1885 | ||
1886 | return false; | |
1887 | } | |
1888 | }, this)); | |
1889 | ||
1890 | var $notification = new WCF.System.Notification(); | |
1891 | $notification.show(); | |
1892 | } | |
1893 | }); | |
1894 | ||
1895 | /** | |
1896 | * Namespace for avatar functions. | |
1897 | */ | |
1898 | WCF.User.Avatar = {}; | |
1899 | ||
1900 | /** | |
1901 | * Handles cropping an avatar. | |
1902 | */ | |
1903 | WCF.User.Avatar.Crop = Class.extend({ | |
1904 | /** | |
1905 | * current crop setting in x-direction | |
1906 | * @var integer | |
1907 | */ | |
1908 | _cropX: 0, | |
1909 | ||
1910 | /** | |
1911 | * current crop setting in y-direction | |
1912 | * @var integer | |
1913 | */ | |
1914 | _cropY: 0, | |
1915 | ||
1916 | /** | |
1917 | * avatar crop dialog | |
1918 | * @var jQuery | |
1919 | */ | |
1920 | _dialog: null, | |
1921 | ||
1922 | /** | |
1923 | * action proxy to send the crop AJAX requests | |
1924 | * @var WCF.Action.Proxy | |
1925 | */ | |
1926 | _proxy: null, | |
1927 | ||
1928 | /** | |
1929 | * maximum size of thumbnails | |
1930 | * @var integer | |
1931 | */ | |
1932 | MAX_THUMBNAIL_SIZE: 128, | |
1933 | ||
1934 | /** | |
1935 | * Creates a new instance of WCF.User.Avatar.Crop. | |
1936 | * | |
1937 | * @param integer avatarID | |
1938 | */ | |
1939 | init: function(avatarID) { | |
1940 | this._avatarID = avatarID; | |
1941 | ||
1942 | if (this._dialog) { | |
1943 | this.destroy(); | |
1944 | } | |
1945 | this._dialog = null; | |
1946 | ||
1947 | // check if object already had been initialized | |
1948 | if (!this._proxy) { | |
06355ec3 | 1949 | this._proxy = new WCF.Action.Proxy({ |
320f4a6d MW |
1950 | success: $.proxy(this._success, this) |
1951 | }); | |
1952 | } | |
1953 | ||
1954 | $('.userAvatarCrop').click($.proxy(this._showCropDialog, this)); | |
1955 | }, | |
1956 | ||
1957 | /** | |
1958 | * Destroys the avatar crop interface. | |
1959 | */ | |
1960 | destroy: function() { | |
1961 | this._dialog.remove(); | |
1962 | }, | |
1963 | ||
1964 | /** | |
1965 | * Sends AJAX request to crop avatar. | |
1966 | * | |
1967 | * @param object event | |
1968 | */ | |
1969 | _crop: function(event) { | |
1970 | this._proxy.setOption('data', { | |
1971 | actionName: 'cropAvatar', | |
1972 | className: 'wcf\\data\\user\\avatar\\UserAvatarAction', | |
1973 | objectIDs: [ this._avatarID ], | |
1974 | parameters: { | |
1975 | cropX: this._cropX, | |
1976 | cropY: this._cropY | |
1977 | } | |
1978 | }); | |
1979 | this._proxy.sendRequest(); | |
1980 | }, | |
1981 | ||
1982 | /** | |
1983 | * Initializes the dialog after a successful 'getCropDialog' request. | |
1984 | * | |
1985 | * @param object data | |
1986 | */ | |
1987 | _getCropDialog: function(data) { | |
1988 | if (!this._dialog) { | |
1989 | this._dialog = $('<div />').hide().appendTo(document.body); | |
1990 | this._dialog.wcfDialog({ | |
1991 | title: WCF.Language.get('wcf.user.avatar.type.custom.crop') | |
1992 | }); | |
1993 | } | |
1994 | ||
1995 | this._dialog.html(data.returnValues.template); | |
1996 | this._dialog.find('button[data-type="save"]').click($.proxy(this._crop, this)); | |
1997 | ||
1998 | this._cropX = data.returnValues.cropX; | |
1999 | this._cropY = data.returnValues.cropY; | |
2000 | ||
2001 | var $image = $('#userAvatarCropSelection > img'); | |
2002 | $('#userAvatarCropSelection').css({ | |
2003 | height: $image.height() + 'px', | |
2004 | width: $image.width() + 'px' | |
2005 | }); | |
2006 | $('#userAvatarCropOverlaySelection').css({ | |
2007 | 'background-image': 'url(' + $image.attr('src') + ')', | |
2008 | 'background-position': -this._cropX + 'px ' + -this._cropY + 'px', | |
2009 | 'left': this._cropX + 'px', | |
2010 | 'top': this._cropY + 'px' | |
2011 | }).draggable({ | |
2012 | containment: 'parent', | |
2013 | drag : $.proxy(this._updateSelection, this), | |
2014 | stop : $.proxy(this._updateSelection, this) | |
2015 | }); | |
2016 | ||
2017 | this._dialog.find('button[data-type="save"]').click($.proxy(this._save, this)); | |
2018 | ||
2019 | this._dialog.wcfDialog('render'); | |
2020 | }, | |
2021 | ||
2022 | /** | |
2023 | * Shows the cropping dialog. | |
2024 | */ | |
2025 | _showCropDialog: function() { | |
2026 | if (!this._dialog) { | |
2027 | this._proxy.setOption('data', { | |
2028 | actionName: 'getCropDialog', | |
2029 | className: 'wcf\\data\\user\\avatar\\UserAvatarAction', | |
2030 | objectIDs: [ this._avatarID ] | |
2031 | }); | |
2032 | this._proxy.sendRequest(); | |
2033 | } | |
2034 | else { | |
2035 | this._dialog.wcfDialog('open'); | |
2036 | } | |
2037 | }, | |
2038 | ||
2039 | /** | |
2040 | * Handles successful AJAX request. | |
2041 | * | |
2042 | * @param object data | |
2043 | * @param string textStatus | |
2044 | * @param jQuery jqXHR | |
2045 | */ | |
2046 | _success: function(data, textStatus, jqXHR) { | |
2047 | switch (data.actionName) { | |
2048 | case 'getCropDialog': | |
2049 | this._getCropDialog(data); | |
2050 | break; | |
2051 | ||
2052 | case 'cropAvatar': | |
320f4a6d MW |
2053 | $('#avatarUpload > dt > img').replaceWith($('<img src="' + data.returnValues.url + '" alt="" class="userAvatarCrop jsTooltip" title="' + WCF.Language.get('wcf.user.avatar.type.custom.crop') + '" />').css({ |
2054 | width: '96px', | |
2055 | height: '96px' | |
2056 | }).click($.proxy(this._showCropDialog, this))); | |
42d7d2cc AE |
2057 | |
2058 | WCF.DOMNodeInsertedHandler.execute(); | |
320f4a6d MW |
2059 | |
2060 | this._dialog.wcfDialog('close'); | |
2061 | ||
2062 | var $notification = new WCF.System.Notification(); | |
2063 | $notification.show(); | |
2064 | break; | |
2065 | } | |
2066 | }, | |
2067 | ||
2068 | /** | |
2069 | * Updates the current crop selection if the selection overlay is dragged. | |
2070 | * | |
2071 | * @param object event | |
2072 | * @param object ui | |
2073 | */ | |
2074 | _updateSelection: function(event, ui) { | |
2075 | this._cropX = ui.position.left; | |
2076 | this._cropY = ui.position.top; | |
2077 | ||
2078 | $('#userAvatarCropOverlaySelection').css({ | |
2079 | 'background-position': -ui.position.left + 'px ' + -ui.position.top + 'px' | |
2080 | }); | |
2081 | } | |
2082 | }); | |
2083 | ||
2084 | /** | |
2085 | * Avatar upload function | |
2086 | * | |
2087 | * @see WCF.Upload | |
2088 | */ | |
2089 | WCF.User.Avatar.Upload = WCF.Upload.extend({ | |
2090 | /** | |
2091 | * handles cropping the avatar | |
2092 | * @var WCF.User.Avatar.Crop | |
2093 | */ | |
2094 | _avatarCrop: null, | |
2095 | ||
2096 | /** | |
2097 | * user id of avatar owner | |
2098 | * @var integer | |
2099 | */ | |
2100 | _userID: 0, | |
2101 | ||
2102 | /** | |
2103 | * Initalizes a new WCF.User.Avatar.Upload object. | |
2104 | * | |
2105 | * @param integer userID | |
2106 | * @param WCF.User.Avatar.Crop avatarCrop | |
2107 | */ | |
2108 | init: function(userID, avatarCrop) { | |
2109 | this._super($('#avatarUpload > dd > div'), undefined, 'wcf\\data\\user\\avatar\\UserAvatarAction'); | |
2110 | this._userID = userID || 0; | |
2111 | this._avatarCrop = avatarCrop; | |
2112 | ||
2113 | $('#avatarForm input[type=radio]').change(function() { | |
2114 | if ($(this).val() == 'custom') { | |
2115 | $('#avatarUpload > dd > div').show(); | |
2116 | } | |
2117 | else { | |
2118 | $('#avatarUpload > dd > div').hide(); | |
2119 | } | |
2120 | }); | |
2121 | if (!$('#avatarForm input[type=radio][value=custom]:checked').length) { | |
2122 | $('#avatarUpload > dd > div').hide(); | |
2123 | } | |
2124 | }, | |
2125 | ||
2126 | /** | |
2127 | * @see WCF.Upload._initFile() | |
2128 | */ | |
2129 | _initFile: function(file) { | |
2130 | return $('#avatarUpload > dt > img'); | |
2131 | }, | |
2132 | ||
2133 | /** | |
2134 | * @see WCF.Upload._success() | |
2135 | */ | |
2136 | _success: function(uploadID, data) { | |
2137 | if (data.returnValues.url) { | |
2138 | this._updateImage(data.returnValues.url, data.returnValues.canCrop); | |
2139 | ||
2140 | if (data.returnValues.canCrop) { | |
2141 | if (!this._avatarCrop) { | |
2142 | this._avatarCrop = new WCF.User.Avatar.Crop(data.returnValues.avatarID); | |
2143 | } | |
2144 | else { | |
2145 | this._avatarCrop.init(data.returnValues.avatarID); | |
2146 | } | |
2147 | } | |
2148 | else if (this._avatarCrop) { | |
2149 | this._avatarCrop.destroy(); | |
2150 | this._avatarCrop = null; | |
2151 | } | |
2152 | ||
2153 | // hide error | |
2154 | $('#avatarUpload > dd > .innerError').remove(); | |
2155 | ||
2156 | // show success message | |
2157 | var $notification = new WCF.System.Notification(WCF.Language.get('wcf.user.avatar.upload.success')); | |
2158 | $notification.show(); | |
2159 | } | |
2160 | else if (data.returnValues.errorType) { | |
2161 | // show error | |
2162 | this._getInnerErrorElement().text(WCF.Language.get('wcf.user.avatar.upload.error.' + data.returnValues.errorType)); | |
2163 | } | |
2164 | }, | |
2165 | ||
2166 | /** | |
2167 | * Updates the displayed avatar image. | |
2168 | * | |
2169 | * @param string url | |
2170 | * @param boolean canCrop | |
2171 | */ | |
2172 | _updateImage: function(url, canCrop) { | |
320f4a6d MW |
2173 | $('#avatarUpload > dt > img').remove(); |
2174 | var $image = $('<img src="' + url + '" alt="" />').css({ | |
2175 | 'height': 'auto', | |
2176 | 'max-height': '96px', | |
2177 | 'max-width': '96px', | |
2178 | 'width': 'auto' | |
2179 | }); | |
2180 | if (canCrop) { | |
2181 | $image.addClass('userAvatarCrop').addClass('jsTooltip'); | |
2182 | $image.attr('title', WCF.Language.get('wcf.user.avatar.type.custom.crop')); | |
2183 | } | |
2184 | ||
2185 | $('#avatarUpload > dt').prepend($image); | |
42d7d2cc AE |
2186 | |
2187 | WCF.DOMNodeInsertedHandler.execute(); | |
320f4a6d MW |
2188 | }, |
2189 | ||
2190 | /** | |
2191 | * Returns the inner error element. | |
2192 | * | |
2193 | * @return jQuery | |
2194 | */ | |
2195 | _getInnerErrorElement: function() { | |
2196 | var $span = $('#avatarUpload > dd > .innerError'); | |
2197 | if (!$span.length) { | |
2198 | $span = $('<small class="innerError"></span>'); | |
2199 | $('#avatarUpload > dd').append($span); | |
2200 | } | |
2201 | ||
2202 | return $span; | |
2203 | }, | |
2204 | ||
2205 | /** | |
2206 | * @see WCF.Upload._getParameters() | |
2207 | */ | |
2208 | _getParameters: function() { | |
2209 | return { | |
2210 | userID: this._userID | |
2211 | }; | |
2212 | }, | |
2213 | }); | |
2214 | ||
2215 | /** | |
2216 | * Generic implementation for grouped user lists. | |
2217 | * | |
2218 | * @param string className | |
2219 | * @param string dialogTitle | |
2220 | * @param object additionalParameters | |
2221 | */ | |
2222 | WCF.User.List = Class.extend({ | |
2223 | /** | |
2224 | * list of additional parameters | |
2225 | * @var object | |
2226 | */ | |
2227 | _additionalParameters: { }, | |
2228 | ||
2229 | /** | |
2230 | * list of cached pages | |
2231 | * @var object | |
2232 | */ | |
2233 | _cache: { }, | |
2234 | ||
2235 | /** | |
2236 | * action class name | |
2237 | * @var string | |
2238 | */ | |
2239 | _className: '', | |
2240 | ||
2241 | /** | |
2242 | * dialog overlay | |
2243 | * @var jQuery | |
2244 | */ | |
2245 | _dialog: null, | |
2246 | ||
2247 | /** | |
2248 | * dialog title | |
2249 | * @var string | |
2250 | */ | |
2251 | _dialogTitle: '', | |
2252 | ||
2253 | /** | |
2254 | * page count | |
2255 | * @var integer | |
2256 | */ | |
2257 | _pageCount: 0, | |
2258 | ||
2259 | /** | |
2260 | * current page no | |
2261 | * @var integer | |
2262 | */ | |
2263 | _pageNo: 1, | |
2264 | ||
2265 | /** | |
2266 | * action proxy | |
2267 | * @var WCF.Action.Proxy | |
2268 | */ | |
2269 | _proxy: null, | |
2270 | ||
2271 | /** | |
2272 | * Initializes a new grouped user list. | |
2273 | * | |
2274 | * @param string className | |
2275 | * @param string dialogTitle | |
2276 | * @param object additionalParameters | |
2277 | */ | |
2278 | init: function(className, dialogTitle, additionalParameters) { | |
2279 | this._additionalParameters = additionalParameters || { }; | |
2280 | this._cache = { }; | |
2281 | this._className = className; | |
2282 | this._dialog = null; | |
2283 | this._dialogTitle = dialogTitle; | |
2284 | this._pageCount = 0; | |
2285 | this._pageNo = 1; | |
2286 | ||
2287 | this._proxy = new WCF.Action.Proxy({ | |
2288 | success: $.proxy(this._success, this) | |
2289 | }); | |
2290 | }, | |
2291 | ||
2292 | /** | |
2293 | * Opens the dialog overlay. | |
2294 | */ | |
2295 | open: function() { | |
2296 | this._pageNo = 1; | |
2297 | this._showPage(); | |
2298 | }, | |
2299 | ||
2300 | /** | |
2301 | * Displays the specified page. | |
2302 | * | |
2303 | * @param object event | |
2304 | * @param object data | |
2305 | */ | |
2306 | _showPage: function(event, data) { | |
2307 | if (data && data.activePage) { | |
2308 | this._pageNo = data.activePage; | |
2309 | } | |
2310 | ||
2311 | if (this._pageCount != 0 && (this._pageNo < 1 || this._pageNo > this._pageCount)) { | |
2312 | console.debug("[WCF.User.List] Cannot access page " + this._pageNo + " of " + this._pageCount); | |
2313 | return; | |
2314 | } | |
2315 | ||
2316 | if (this._cache[this._pageNo]) { | |
2317 | var $dialogCreated = false; | |
2318 | if (this._dialog === null) { | |
6691795d MW |
2319 | //this._dialog = $('<div id="userList' + this._className.hashCode() + '" style="min-width: 600px;" />').hide().appendTo(document.body); |
2320 | this._dialog = $('<div id="userList' + this._className.hashCode() + '" />').hide().appendTo(document.body); | |
320f4a6d MW |
2321 | $dialogCreated = true; |
2322 | } | |
2323 | ||
2324 | // remove current view | |
2325 | this._dialog.empty(); | |
2326 | ||
2327 | // insert HTML | |
2328 | this._dialog.html(this._cache[this._pageNo]); | |
2329 | ||
2330 | // add pagination | |
2331 | if (this._pageCount > 1) { | |
2332 | this._dialog.find('.jsPagination').wcfPages({ | |
2333 | activePage: this._pageNo, | |
2334 | maxPage: this._pageCount | |
2335 | }).bind('wcfpagesswitched', $.proxy(this._showPage, this)); | |
2336 | } | |
2337 | ||
2338 | // show dialog | |
2339 | if ($dialogCreated) { | |
2340 | this._dialog.wcfDialog({ | |
2341 | title: this._dialogTitle | |
2342 | }); | |
2343 | } | |
2344 | else { | |
2345 | this._dialog.wcfDialog('open').wcfDialog('render'); | |
2346 | } | |
2347 | } | |
2348 | else { | |
2349 | this._additionalParameters.pageNo = this._pageNo; | |
2350 | ||
2351 | // load template via AJAX | |
2352 | this._proxy.setOption('data', { | |
2353 | actionName: 'getGroupedUserList', | |
2354 | className: this._className, | |
2355 | interfaceName: 'wcf\\data\\IGroupedUserListAction', | |
2356 | parameters: this._additionalParameters | |
2357 | }); | |
2358 | this._proxy.sendRequest(); | |
2359 | } | |
2360 | }, | |
2361 | ||
2362 | /** | |
2363 | * Handles successful AJAX requests. | |
2364 | * | |
2365 | * @param object data | |
2366 | * @param string textStatus | |
2367 | * @param jQuery jqXHR | |
2368 | */ | |
2369 | _success: function(data, textStatus, jqXHR) { | |
2370 | if (data.returnValues.pageCount) { | |
2371 | this._pageCount = data.returnValues.pageCount; | |
2372 | } | |
2373 | ||
2374 | this._cache[this._pageNo] = data.returnValues.template; | |
2375 | this._showPage(); | |
2376 | } | |
2377 | }); | |
2378 | ||
2379 | /** | |
2380 | * Namespace for object watch functions. | |
2381 | */ | |
2382 | WCF.User.ObjectWatch = {}; | |
2383 | ||
2384 | /** | |
2385 | * Handles subscribe/unsubscribe links. | |
2386 | */ | |
2387 | WCF.User.ObjectWatch.Subscribe = Class.extend({ | |
2388 | /** | |
2389 | * CSS selector for subscribe buttons | |
2390 | * @var string | |
2391 | */ | |
2392 | _buttonSelector: '.jsSubscribeButton', | |
2393 | ||
2394 | /** | |
2395 | * list of buttons | |
2396 | * @var object | |
2397 | */ | |
2398 | _buttons: { }, | |
2399 | ||
2400 | /** | |
2401 | * dialog overlay | |
2402 | * @var object | |
2403 | */ | |
2404 | _dialog: null, | |
2405 | ||
2406 | /** | |
2407 | * system notification | |
2408 | * @var WCF.System.Notification | |
2409 | */ | |
2410 | _notification: null, | |
2411 | ||
2412 | /** | |
2413 | * WCF.User.ObjectWatch.Subscribe object. | |
2414 | */ | |
2415 | init: function() { | |
2416 | this._buttons = { }; | |
2417 | this._notification = null; | |
2418 | ||
2419 | // initialize proxy | |
2420 | this._proxy = new WCF.Action.Proxy({ | |
2421 | success: $.proxy(this._success, this) | |
2422 | }); | |
2423 | ||
2424 | // bind event listeners | |
2425 | $(this._buttonSelector).each($.proxy(function(index, button) { | |
2426 | var $button = $(button); | |
2427 | var $objectID = $button.data('objectID'); | |
2428 | this._buttons[$objectID] = $button.click($.proxy(this._click, this)); | |
2429 | }, this)); | |
2430 | }, | |
2431 | ||
2432 | /** | |
2433 | * Handles a click on a subscribe button. | |
2434 | * | |
2435 | * @param object event | |
2436 | */ | |
2437 | _click: function(event) { | |
2438 | var $button = $(event.currentTarget); | |
2439 | ||
2440 | this._proxy.setOption('data', { | |
2441 | actionName: 'manageSubscription', | |
2442 | className: 'wcf\\data\\user\\object\\watch\\UserObjectWatchAction', | |
2443 | parameters: { | |
2444 | objectID: $button.data('objectID'), | |
2445 | objectType: $button.data('objectType') | |
2446 | } | |
2447 | }); | |
2448 | this._proxy.sendRequest(); | |
2449 | }, | |
2450 | ||
2451 | /** | |
2452 | * Handles successful AJAX requests. | |
2453 | * | |
2454 | * @param object data | |
2455 | * @param string textStatus | |
2456 | * @param jQuery jqXHR | |
2457 | */ | |
2458 | _success: function(data, textStatus, jqXHR) { | |
2459 | if (data.actionName === 'manageSubscription') { | |
2460 | if (this._dialog === null) { | |
2461 | this._dialog = $('<div>' + data.returnValues.template + '</div>').hide().appendTo(document.body); | |
2462 | this._dialog.wcfDialog({ | |
2463 | title: WCF.Language.get('wcf.user.objectWatch.manageSubscription') | |
2464 | }); | |
2465 | } | |
2466 | else { | |
2467 | this._dialog.html(data.returnValues.template); | |
2468 | this._dialog.wcfDialog('open'); | |
2469 | } | |
2470 | ||
2471 | // bind event listener | |
2472 | this._dialog.find('.formSubmit > .jsButtonSave').data('objectID', data.returnValues.objectID).click($.proxy(this._save, this)); | |
2473 | var $enableNotification = this._dialog.find('input[name=enableNotification]').disable(); | |
2474 | ||
2475 | // toggle subscription | |
2476 | this._dialog.find('input[name=subscribe]').change(function(event) { | |
2477 | var $input = $(event.currentTarget); | |
2478 | if ($input.val() == 1) { | |
2479 | $enableNotification.enable(); | |
2480 | } | |
2481 | else { | |
2482 | $enableNotification.disable(); | |
2483 | } | |
2484 | }); | |
2485 | ||
2486 | // setup | |
2487 | var $selectedOption = this._dialog.find('input[name=subscribe]:checked'); | |
2488 | if ($selectedOption.length && $selectedOption.val() == 1) { | |
2489 | $enableNotification.enable(); | |
2490 | } | |
2491 | } | |
2492 | else if (data.actionName === 'saveSubscription' && this._dialog.is(':visible')) { | |
2493 | this._dialog.wcfDialog('close'); | |
2494 | ||
2495 | if (this._notification === null) { | |
2496 | this._notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success.edit')); | |
2497 | } | |
2498 | ||
2499 | this._notification.show(); | |
2500 | } | |
2501 | }, | |
2502 | ||
2503 | /** | |
2504 | * Saves the subscription. | |
2505 | * | |
2506 | * @param object event | |
2507 | */ | |
2508 | _save: function(event) { | |
2509 | var $button = this._buttons[$(event.currentTarget).data('objectID')]; | |
2510 | var $subscribe = this._dialog.find('input[name=subscribe]:checked').val(); | |
2511 | var $enableNotification = (this._dialog.find('input[name=enableNotification]').is(':checked')) ? 1 : 0; | |
2512 | ||
2513 | this._proxy.setOption('data', { | |
2514 | actionName: 'saveSubscription', | |
2515 | className: 'wcf\\data\\user\\object\\watch\\UserObjectWatchAction', | |
2516 | parameters: { | |
2517 | enableNotification: $enableNotification, | |
2518 | objectID: $button.data('objectID'), | |
2519 | objectType: $button.data('objectType'), | |
2520 | subscribe: $subscribe | |
2521 | } | |
2522 | }); | |
2523 | this._proxy.sendRequest(); | |
2524 | } | |
2525 | }); | |
57f097e8 MS |
2526 | |
2527 | /** | |
2528 | * Handles inline editing of users. | |
2529 | */ | |
2530 | WCF.User.InlineEditor = WCF.InlineEditor.extend({ | |
2531 | /** | |
2532 | * list of permissions | |
2533 | * @var object | |
2534 | */ | |
2535 | _permissions: { }, | |
2536 | ||
2537 | /** | |
2538 | * @see WCF.InlineEditor._execute() | |
2539 | */ | |
2540 | _execute: function(elementID, optionName) { | |
2541 | if (!this._validate(elementID, optionName)) { | |
2542 | return false; | |
2543 | } | |
2544 | ||
2545 | var $data = { }; | |
2546 | var $element = $('#' + elementID); | |
2547 | switch (optionName) { | |
2548 | case 'unban': | |
2549 | case 'enableAvatar': | |
2550 | case 'enableSignature': | |
2551 | switch (optionName) { | |
2552 | case 'unban': | |
2553 | $data.banned = 0; | |
2554 | break; | |
2555 | ||
2556 | case 'enableAvatar': | |
2557 | $data.disableAvatar = 0; | |
2558 | break; | |
2559 | ||
2560 | case 'enableSignature': | |
2561 | $data.disableSignature = 0; | |
2562 | break; | |
2563 | } | |
2564 | ||
2565 | this._proxy.setOption('data', { | |
2566 | actionName: optionName, | |
2567 | className: 'wcf\\data\\user\\UserAction', | |
2568 | objectIDs: [ $element.data('objectID') ] | |
2569 | }); | |
2570 | this._proxy.sendRequest(); | |
2571 | break; | |
2572 | ||
2573 | case 'ban': | |
2574 | case 'disableAvatar': | |
2575 | case 'disableSignature': | |
8fd76c0b | 2576 | if (optionName == 'ban') { |
57f097e8 MS |
2577 | $data.banned = 1; |
2578 | } | |
2579 | else { | |
2580 | $data[optionName] = 1; | |
2581 | } | |
2582 | ||
2583 | this._showReasonDialog($element.data('objectID'), optionName); | |
2584 | break; | |
2585 | ||
2586 | case 'advanced': | |
2587 | window.location = this._getTriggerElement($element).attr('href'); | |
2588 | break; | |
2589 | } | |
2590 | ||
2591 | if ($.getLength($data)) { | |
2592 | this._updateData.push({ | |
2593 | data: $data, | |
2594 | elementID: elementID, | |
2595 | }); | |
2596 | } | |
2597 | }, | |
2598 | ||
2599 | /** | |
2600 | * Executes an action with a reason. | |
2601 | * | |
2602 | * @param integer userID | |
2603 | * @param string optionName | |
2604 | * @param string reason | |
2605 | */ | |
2606 | _executeReasonAction: function(userID, optionName, reason) { | |
2607 | var $parameters = { }; | |
2608 | $parameters[optionName + WCF.String.ucfirst('reason')] = reason; | |
2609 | ||
2610 | this._proxy.setOption('data', { | |
2611 | actionName: optionName, | |
2612 | className: 'wcf\\data\\user\\UserAction', | |
2613 | objectIDs: [ userID ], | |
2614 | parameters: $parameters | |
2615 | }); | |
2616 | this._proxy.sendRequest(); | |
2617 | }, | |
2618 | ||
2619 | /** | |
2620 | * Returns a specific permission. | |
2621 | * | |
2622 | * @param string permission | |
2623 | * @return integer | |
2624 | */ | |
2625 | _getPermission: function(permission) { | |
2626 | if (this._permissions[permission]) { | |
2627 | return this._permissions[permission]; | |
2628 | } | |
2629 | ||
2630 | return 0; | |
2631 | }, | |
2632 | ||
2633 | /** | |
2634 | * @see WCF.InlineEditor._getTriggerElement() | |
2635 | */ | |
2636 | _getTriggerElement: function(element) { | |
2637 | return element.find('.jsUserInlineEditor'); | |
2638 | }, | |
2639 | ||
2640 | /** | |
2641 | * @see WCF.InlineEditor._setOptions() | |
2642 | */ | |
2643 | _setOptions: function() { | |
2644 | this._options = [ | |
2645 | // banning | |
2646 | { label: WCF.Language.get('wcf.user.ban'), optionName: 'ban' }, | |
2647 | { label: WCF.Language.get('wcf.user.unban'), optionName: 'unban' }, | |
2648 | ||
2649 | // disabling avatar | |
2650 | { label: WCF.Language.get('wcf.user.disableAvatar'), optionName: 'disableAvatar' }, | |
2651 | { label: WCF.Language.get('wcf.user.enableAvatar'), optionName: 'enableAvatar' }, | |
2652 | ||
2653 | // disabling signature | |
2654 | { label: WCF.Language.get('wcf.user.disableSignature'), optionName: 'disableSignature' }, | |
2655 | { label: WCF.Language.get('wcf.user.enableSignature'), optionName: 'enableSignature' }, | |
2656 | ||
2657 | // divider | |
2658 | { optionName: 'divider' }, | |
2659 | ||
2660 | // overlay | |
2661 | { label: WCF.Language.get('wcf.user.edit'), optionName: 'advanced' } | |
2662 | ]; | |
2663 | }, | |
2664 | ||
2665 | /** | |
2666 | * @see WCF.InlineEditor._show() | |
2667 | */ | |
2668 | _show: function(event) { | |
2669 | var $element = $(event.currentTarget); | |
2670 | var $elementID = $element.data('elementID'); | |
2671 | ||
2672 | if (!this._dropdowns[$elementID]) { | |
2673 | var $dropdownMenu = $element.next('.dropdownMenu'); | |
2674 | ||
2675 | if ($dropdownMenu) { | |
2676 | this._dropdowns[$elementID] = $dropdownMenu; | |
2677 | WCF.Dropdown.initDropdown(this._getTriggerElement(this._elements[$elementID]), true); | |
2678 | } | |
2679 | } | |
2680 | ||
2681 | return this._super(event); | |
2682 | }, | |
2683 | ||
2684 | /** | |
2685 | * Shows the dialog to enter a reason for executing the option with the | |
2686 | * given name. | |
2687 | * | |
2688 | * @param string optionName | |
2689 | */ | |
2690 | _showReasonDialog: function(userID, optionName) { | |
2691 | var $languageItem = 'wcf.user.' + optionName + '.reason.description'; | |
2692 | var $reasonDescription = WCF.Language.get($languageItem); | |
2693 | ||
2694 | WCF.System.Confirmation.show(WCF.Language.get('wcf.user.' + optionName + '.confirmMessage'), $.proxy(function(action) { | |
2695 | if (action === 'confirm') { | |
2696 | this._executeReasonAction(userID, optionName, $('#wcfSystemConfirmationContent').find('textarea').val()); | |
2697 | } | |
8fd76c0b | 2698 | }, this), { }, $('<fieldset><dl><dt>' + WCF.Language.get('wcf.global.reason') + '</dt><dd><textarea cols="40" rows="4" />' + ($reasonDescription != $languageItem ? '<small>' + $reasonDescription + '</small>' : '') + '</dd></dl></fieldset>')); |
57f097e8 MS |
2699 | }, |
2700 | ||
2701 | /** | |
2702 | * @see WCF.InlineEditor._updateState() | |
2703 | */ | |
2704 | _updateState: function(data) { | |
2705 | this._notification.show(); | |
2706 | ||
dbe622ad MS |
2707 | for (var $i = 0, $length = this._updateData.length; $i < $length; $i++) { |
2708 | var $data = this._updateData[$i]; | |
57f097e8 MS |
2709 | var $element = $('#' + $data.elementID); |
2710 | ||
2711 | for (var $property in $data.data) { | |
2712 | $element.data($property, $data.data[$property]); | |
2713 | } | |
2714 | } | |
2715 | }, | |
2716 | ||
2717 | /** | |
2718 | * @see WCF.InlineEditor._validate() | |
2719 | */ | |
2720 | _validate: function(elementID, optionName) { | |
2721 | var $user = $('#' + elementID); | |
2722 | ||
2723 | switch (optionName) { | |
2724 | case 'ban': | |
2725 | case 'unban': | |
2726 | if (!this._getPermission('canBanUser')) { | |
2727 | return false; | |
2728 | } | |
2729 | ||
2730 | if (optionName == 'ban') { | |
2731 | return !$user.data('banned'); | |
2732 | } | |
2733 | else { | |
2734 | return $user.data('banned'); | |
2735 | } | |
2736 | break; | |
2737 | ||
2738 | case 'disableAvatar': | |
2739 | case 'enableAvatar': | |
2740 | if (!this._getPermission('canDisableAvatar')) { | |
2741 | return false; | |
2742 | } | |
2743 | ||
2744 | if (optionName == 'disableAvatar') { | |
2745 | return !$user.data('disableAvatar'); | |
2746 | } | |
2747 | else { | |
2748 | return $user.data('disableAvatar'); | |
2749 | } | |
2750 | break; | |
2751 | ||
2752 | case 'disableSignature': | |
2753 | case 'enableSignature': | |
2754 | if (!this._getPermission('canDisableSignature')) { | |
2755 | return false; | |
2756 | } | |
2757 | ||
2758 | if (optionName == 'disableSignature') { | |
2759 | return !$user.data('disableSignature'); | |
2760 | } | |
2761 | else { | |
2762 | return $user.data('disableSignature'); | |
2763 | } | |
2764 | break; | |
2765 | ||
2766 | case 'advanced': | |
2767 | return this._getPermission('canEditUser'); | |
2768 | break; | |
2769 | } | |
2770 | ||
2771 | return false; | |
2772 | }, | |
2773 | ||
2774 | /** | |
2775 | * Sets a permission. | |
2776 | * | |
2777 | * @param string permission | |
2778 | * @param integer value | |
2779 | */ | |
2780 | setPermission: function(permission, value) { | |
2781 | this._permissions[permission] = value; | |
2782 | }, | |
2783 | ||
2784 | /** | |
2785 | * Sets permissions. | |
2786 | * | |
2787 | * @param object permissions | |
2788 | */ | |
2789 | setPermissions: function(permissions) { | |
2790 | for (var $permission in permissions) { | |
2791 | this.setPermission($permission, permissions[$permission]); | |
2792 | } | |
2793 | } | |
2794 | }); |