(function ($) { this.MainMenuRoom = this.Room.extend({ type: 'mainmenu', tinyWidth: 340, bestWidth: 628, events: { 'keydown textarea': 'keyDown', 'keyup textarea': 'keyUp', 'click .username': 'clickUsername', 'click .header-username': 'clickUsername', 'click .closebutton': 'closePM', 'click .minimizebutton': 'minimizePM', 'click .pm-challenge': 'clickPMButtonBarChallenge', 'click .pm-userOptions': 'clickPMButtonBarUserOptions', 'click .pm-window': 'clickPMBackground', 'dblclick .pm-window h3': 'dblClickPMHeader', 'focus textarea': 'onFocusPM', 'blur textarea': 'onBlurPM', 'click .spoiler': 'clickSpoiler', 'click .datasearch': 'clickDatasearchResults', 'click button.formatselect': 'selectFormat', 'click button.teamselect': 'selectTeam', 'click button[name=partnersubmit]': 'selectTeammate' }, initialize: function () { this.$el.addClass('scrollable'); // left menu 2 (high-res: right, low-res: top) // (created during page load) // left menu 1 (high-res: left, low-res: bottom) var buf = ''; if (app.down) { buf += ''; } else { buf += ''; } buf += ''; buf += ''; this.$('.mainmenu').html(buf); // right menu if (document.location.hostname === Config.routes.client) { this.$('.rightmenu').html(''); } else { this.$('.rightmenu').html(''); } // footer // (created during page load) this.$activityMenu = this.$('.activitymenu'); this.$pmBox = this.$activityMenu.find('.pmbox'); app.on('init:formats', this.updateFormats, this); this.updateFormats(); app.user.on('saveteams', this.updateTeams, this); // news // (created during page load) var self = this; Storage.whenPrefsLoaded(function () { var newsid = Number(Storage.prefs('newsid')); var $news = this.$('.news-embed'); if (!newsid) { if ($(window).width() < 628) { // News starts minimized in phone layout self.minimizePM($news); } return; } var $newsEntries = $news.find('.newsentry'); var hasUnread = false; for (var i = 0; i < $newsEntries.length; i++) { if (Number($newsEntries.eq(i).data('newsid')) > newsid) { hasUnread = true; $newsEntries.eq(i).addClass('unread'); } } if (!hasUnread) self.minimizePM($news); }); if (!app.roomsFirstOpen && window.location.host !== 'demo.psim.us' && window.innerWidth < 630) { if (Config.roomsFirstOpenScript) { Config.roomsFirstOpenScript(true); } app.roomsFirstOpen = 2; } if ('nw' in window && !nw.process.version.startsWith('v13.')) { app.addPopupMessage( "Your version of the app is out of date.\n" + "Please go to pokemonshowdown.com to update it." ); } }, addPseudoPM: function (options) { if (!options) return; options.title = options.title || ''; options.html = options.html || ''; options.cssClass = options.cssClass || ''; options.height = options.height || 'auto'; options.maxHeight = options.maxHeight || ''; options.attributes = options.attributes || ''; options.append = options.append || false; options.noMinimize = options.noMinimize || false; this.$pmBox[options.append ? 'append' : 'prepend']('

' + (!options.noMinimize ? '' : '') + options.title + '

' + BattleLog.sanitizeHTML(options.html) + '
'); }, // news addNews: function () { var self = this; $.ajax({ url: "https://" + Config.routes.root + "/news.json", dataType: "json", success: function (data) { var html = ''; for (var i = 0; i < 2; i++) { var post = data[i]; var hasRead = data[i].id && Dex.prefs('readnews') === '' + data[i].id; html += '
'; if (post.title) html += '

' + post.title + '

'; if (post.summaryHTML) html += '

' + post.summaryHTML + '

'; html += '

'; if (post.author) html += '—' + post.author + ''; if (post.date) { html += ' on ' + new Date(post.date * 1000).toDateString() + ''; } html += '

'; } self.addPseudoPM({ title: 'Latest News', html: html, attributes: 'data-newsid="' + (data[0].id ? data[0].id : '1990') + '"', cssClass: 'news-embed', maxHeight: 'none' }); } }); }, /********************************************************* * PMs *********************************************************/ addPM: function (name, message, target) { var userid = toUserid(name); if (app.ignore[userid] && " +\u2606\u203D\u2716!".includes(name.charAt(0))) { if (!app.ignoreNotified) { message = '/nonotify A message from ' + BattleLog.escapeHTML(name) + ' was ignored.'; app.ignoreNotified = true; } return; } var isSelf = (toID(name) === app.user.get('userid')); var oName = isSelf ? target : name; Storage.logChat('pm-' + toID(oName), '' + name + ': ' + message); var $pmWindow = this.openPM(oName, true); var $chatFrame = $pmWindow.find('.pm-log'); var $chat = $pmWindow.find('.inner'); var autoscroll = ($chatFrame.scrollTop() + 60 >= $chat.height() - $chatFrame.height()); var parsedMessage = MainMenuRoom.parseChatMessage(message, name, ChatRoom.getTimestamp('pms'), false, $chat, false); if (typeof parsedMessage.challenge === 'string') { this.updateChallenge($pmWindow, parsedMessage.challenge, name, oName); return; } var canNotify = true; if (typeof parsedMessage === 'object' && 'noNotify' in parsedMessage) { canNotify = !parsedMessage.noNotify; parsedMessage = parsedMessage.message; } if (!$.isArray(parsedMessage)) parsedMessage = [parsedMessage]; for (var i = 0; i < parsedMessage.length; i++) { if (!parsedMessage[i]) continue; $chat.append(parsedMessage[i]); } var $lastMessage = $chat.children().last(); var textContent = $lastMessage.html().includes('') ? '(spoiler)' : $lastMessage.children().last().text(); if (textContent && app.curSideRoom && app.curSideRoom.addPM && Dex.prefs('inchatpm')) { app.curSideRoom.addPM(name, message, target); } if (canNotify && !isSelf && textContent) { this.notifyOnce("PM from " + name, "\"" + textContent + "\"", 'pm'); } if (autoscroll) { $chatFrame.scrollTop($chat.height()); } if (!$pmWindow.hasClass('focused') && name.substr(1) !== app.user.get('name')) { $pmWindow.find('h3').addClass('pm-notifying'); } }, updateChallenge: function ($pmWindow, challenge, name, oName) { var splitChallenge = challenge.split('|'); var formatName = splitChallenge[0]; var teamFormat = splitChallenge[1]; var message = splitChallenge[2]; var acceptButtonLabel = splitChallenge[3] || 'Accept'; var rejectButtonLabel = splitChallenge[4] || 'Reject'; var oUserid = toID(oName); var userid = toID(name); var $challenge = $pmWindow.find('.challenge'); if ($challenge.find('button[name=makeChallenge]').length) { // we're currently trying to challenge that user; suppress the challenge and wait until later $challenge.find('button[name=dismissChallenge]').attr( 'data-pendingchallenge', challenge ? (name + '|' + oName + '|' + challenge) : '' ); return; } if (!formatName && !message) { if ($challenge.length) { $challenge.remove(); this.closeNotification('challenge:' + oUserid); } return; } $challenge = this.openChallenge(oName, $pmWindow); if (userid !== oUserid) { // we are sending the challenge var buf = '

Waiting for ' + BattleLog.escapeHTML(oName) + '...

'; if (formatName) { buf += '

' + this.renderFormats(formatName, true) + '

'; } buf += '

'; $challenge.html(buf); return; } app.playNotificationSound(); this.notifyOnce("Challenge from " + name, "Format: " + BattleLog.escapeFormat(formatName), 'challenge:' + userid); var buf = '

' + BattleLog.escapeHTML(message || (name + ' wants to battle!')) + '

'; if (formatName) { buf += '

' + this.renderFormats(formatName, true) + '

'; } if (teamFormat) { buf += '

' + this.renderTeams(teamFormat) + '

'; buf += '

'; } buf += '

'; $challenge.html(buf); }, selectTeammate: function (e) { e.stopPropagation(); e.preventDefault(); var input = $('input.partnerselect').get(0); var partner = toID(input.value); if (!partner.length) return; app.send('/requestpartner ' + partner + ',' + this.curFormat); input.value = ""; }, openPM: function (name, dontFocus) { var userid = toID(name); var $pmWindow = this.$pmBox.find('.pm-window-' + userid); if (!$pmWindow.length) { var group = name.charAt(0); if (group === ' ') { group = ''; } else if (/[a-zA-Z0-9]/.test(group)) { group = ''; name = ' ' + name; } else { group = '' + BattleLog.escapeHTML(group) + ''; } var buf = '
'; buf += '

'; buf += ''; buf += group + BattleLog.escapeHTML(name.substr(1)) + '

'; buf += '
'; buf += '
'; $pmWindow = $(buf).prependTo(this.$pmBox); $pmWindow.find('textarea').autoResize({ animate: false, extraSpace: 0 }); // create up/down history for this PM this.chatHistories[userid] = new ChatHistory(); } else { $pmWindow.show(); if (!dontFocus) { var $chatFrame = $pmWindow.find('.pm-log'); var $chat = $pmWindow.find('.inner'); $chatFrame.scrollTop($chat.height()); } } if (!dontFocus) this.$el.scrollTop(0); return $pmWindow; }, closePM: function (e) { var userid; if (e.currentTarget) { e.preventDefault(); e.stopPropagation(); userid = $(e.currentTarget).closest('.pm-window').data('userid'); // counteract jQuery auto-casting if (userid !== undefined && userid !== '') userid = '' + userid; } else { userid = toID(e); } var $pmWindow; if (!userid) { // not a true PM; just close the window $pmWindow = $(e.currentTarget).closest('.pm-window'); var newsId = $pmWindow.data('newsid'); if (newsId) { $.cookie('showdown_readnews', '' + newsId, { expires: 365 }); } $pmWindow.remove(); return; } $pmWindow = this.$pmBox.find('.pm-window-' + userid); $pmWindow.hide(); var $rejectButton = $pmWindow.find('button[name=rejectChallenge]'); if ($rejectButton.length) { this.rejectChallenge(userid, $rejectButton); } $rejectButton = $pmWindow.find('button[name=cancelChallenge]'); if ($rejectButton.length) { this.cancelChallenge(userid, $rejectButton); } var $next = $pmWindow.next(); while ($next.length && $next.css('display') === 'none') { $next = $next.next(); } if ($next.length) { $next.find('textarea[name=message]').focus(); return; } $next = $pmWindow.prev(); while ($next.length && $next.css('display') === 'none') { $next = $next.prev(); } if ($next.length) { $next.find('textarea[name=message]').focus(); return; } if (app.curSideRoom) app.curSideRoom.focus(); }, minimizePM: function (e) { var $pmWindow; if (e.currentTarget) { e.preventDefault(); e.stopPropagation(); $pmWindow = $(e.currentTarget).closest('.pm-window'); } else { $pmWindow = e; } if (!$pmWindow) { return; } var $pmHeader = $pmWindow.find('h3'); var $pmContent = $pmWindow.find('.pm-log, .pm-log-add, .pm-buttonbar'); if (!$pmWindow.data('minimized')) { $pmContent.hide(); $pmHeader.addClass('pm-minimized'); $pmWindow.data('minimized', true); } else { $pmContent.show(); $pmHeader.removeClass('pm-minimized'); $pmWindow.data('minimized', false); } $pmWindow.find('h3').removeClass('pm-notifying'); }, clickUsername: function (e) { e.stopPropagation(); var name = $(e.currentTarget).data('name') || $(e.currentTarget).text(); app.addPopup(UserPopup, { name: name, sourceEl: e.currentTarget }); }, clickPMButtonBarChallenge: function (e) { var name = $(e.currentTarget).closest('.pm-window').data('name'); app.rooms[''].requestNotifications(); app.focusRoom(''); app.rooms[''].challenge(name); }, clickPMButtonBarUserOptions: function (e) { e.stopPropagation(); var name = $(e.currentTarget).closest('.pm-window').data('name'); var userid = toID($(e.currentTarget).closest('.pm-window').data('name')); app.addPopup(UserOptions, { name: name, userid: userid, sourceEl: e.currentTarget }); }, focusPM: function (name) { this.openPM(name).prependTo(this.$pmBox).find('textarea[name=message]').focus(); }, onFocusPM: function (e) { $(e.currentTarget).closest('.pm-window').addClass('focused').find('h3').removeClass('pm-notifying'); }, onBlurPM: function (e) { $(e.currentTarget).closest('.pm-window').removeClass('focused'); }, keyUp: function (e) { var $target = $(e.currentTarget); // Android Chrome compose keycode // Android Chrome no longer sends keyCode 13 when Enter is pressed on // the soft keyboard, resulting in this annoying hack. // https://bugs.chromium.org/p/chromium/issues/detail?id=118639#c232 if (!e.shiftKey && e.keyCode === 229 && $target.val().slice(-1) === '\n') { this.submitPM(e); } }, submitPM: function (e) { e.preventDefault(); e.stopPropagation(); var $target = $(e.currentTarget); var text = $.trim($target.val()); if (!text) return; var $pmWindow = $target.closest('.pm-window'); var userid = $pmWindow.attr('data-userid') || ''; var $chat = $pmWindow.find('.inner'); // this.tabComplete.reset(); this.chatHistories[userid].push(text); var data = ''; var cmd = ''; var spaceIndex = text.indexOf(' '); if (text.substr(0, 2) !== '//' && text.charAt(0) === '/' || text.charAt(0) === '!') { if (spaceIndex > 0) { data = text.substr(spaceIndex + 1); cmd = text.substr(1, spaceIndex - 1); } else { data = ''; cmd = text.substr(1); } } switch (cmd.toLowerCase()) { case 'ignore': if (app.ignore[userid]) { $chat.append('
User ' + userid + ' is already on your ignore list. (Moderator messages will not be ignored.)
'); } else { app.ignore[userid] = 1; $chat.append('
User ' + userid + ' ignored. (Moderator messages will not be ignored.)
'); app.saveIgnore(); } break; case 'unignore': if (!app.ignore[userid]) { $chat.append('
User ' + userid + ' isn\'t on your ignore list.
'); } else { delete app.ignore[userid]; $chat.append('
User ' + userid + ' no longer ignored.
'); app.saveIgnore(); } break; case 'nick': if ($.trim(data)) { app.user.rename(data); } else { app.addPopup(LoginPopup); } return false; case 'chal': case 'chall': case 'challenge': this.challenge(userid, data); break; case 'clear': $chat.empty(); break; case 'rank': case 'ranking': case 'rating': case 'ladder': case 'user': case 'open': case 'debug': case 'news': case 'ignorelist': case 'clearpms': case 'showdebug': case 'hidedebug': case 'showjoins': case 'hidejoins': case 'showbattles': case 'hidebattles': case 'packhidden': case 'unpackhidden': case 'timestamps': case 'hl': case 'highlight': case 'buttonban': case 'buttonmute': case 'buttonunmute': case 'buttonkick': case 'buttonwarn': case 'part': case 'leave': case 'afd': $chat.append('
Use this command in a proper chat room.
'); break; default: if (!userid) userid = '~'; if (text.startsWith('\n')) text = text.slice(1); if (text.endsWith('\n')) text = text.slice(0, -1); text = ('\n' + text).replace(/\n/g, '\n/pm ' + userid + ', ').slice(1); if (text.length > 80000) { app.addPopupMessage("Your message is too long."); return; } if (!(text.startsWith('/') || text.startsWith('!')) && app.ignore[userid]) { app.addPopupMessage("You can't PM a user you've ignored. Use /unignore to remove them from your ignore list."); return; } this.send(text); } $target.val(''); $target.trigger('keyup'); // force a resize }, keyDown: function (e) { var cmdKey = (((e.cmdKey || e.metaKey) ? 1 : 0) + (e.ctrlKey ? 1 : 0) === 1) && !e.altKey && !e.shiftKey; if (e.keyCode === 13 && !e.shiftKey) { // Enter this.submitPM(e); } else if (e.keyCode === 27) { // Esc if (app.curSideRoom && app.curSideRoom.undoTabComplete && app.curSideRoom.undoTabComplete($(e.currentTarget))) { e.preventDefault(); e.stopPropagation(); } else { this.closePM(e); } } else if (e.keyCode === 73 && cmdKey) { // Ctrl + I key if (ConsoleRoom.toggleFormatChar(e.currentTarget, '_')) { e.preventDefault(); e.stopPropagation(); } } else if (e.keyCode === 66 && cmdKey) { // Ctrl + B key if (ConsoleRoom.toggleFormatChar(e.currentTarget, '*')) { e.preventDefault(); e.stopPropagation(); } } else if (e.keyCode === 33) { // Pg Up key var $target = $(e.currentTarget); var $pmWindow = $target.closest('.pm-window'); var $chat = $pmWindow.find('.pm-log'); $chat.scrollTop($chat.scrollTop() - $chat.height() + 60); } else if (e.keyCode === 34) { // Pg Dn key var $target = $(e.currentTarget); var $pmWindow = $target.closest('.pm-window'); var $chat = $pmWindow.find('.pm-log'); $chat.scrollTop($chat.scrollTop() + $chat.height() - 60); } else if (e.keyCode === 9 && !e.ctrlKey) { // Tab key var reverse = !!e.shiftKey; // Shift+Tab reverses direction var handlerRoom = app.curSideRoom; if (!handlerRoom) { for (var roomid in app.rooms) { if (!app.rooms[roomid].handleTabComplete) continue; handlerRoom = app.rooms[roomid]; break; } } if (handlerRoom && handlerRoom.handleTabComplete && handlerRoom.handleTabComplete($(e.currentTarget), reverse)) { e.preventDefault(); e.stopPropagation(); } } else if (e.keyCode === 38 && !e.shiftKey && !e.altKey) { // Up key if (this.chatHistoryUp(e)) { e.preventDefault(); e.stopPropagation(); } } else if (e.keyCode === 40 && !e.shiftKey && !e.altKey) { // Down key if (this.chatHistoryDown(e)) { e.preventDefault(); e.stopPropagation(); } } }, chatHistoryUp: function (e) { var $textbox = $(e.currentTarget); var idx = +$textbox.prop('selectionStart'); var line = $textbox.val(); if (e && !e.ctrlKey && idx !== 0 && idx !== line.length) return false; var userid = $textbox.closest('.pm-window').data('userid'); var chatHistory = this.chatHistories[userid]; if (chatHistory.index === 0) return false; $textbox.val(chatHistory.up(line)); return true; }, chatHistoryDown: function (e) { var $textbox = $(e.currentTarget); var idx = +$textbox.prop('selectionStart'); var line = $textbox.val(); if (e && !e.ctrlKey && idx !== 0 && idx !== line.length) return false; var userid = $textbox.closest('.pm-window').data('userid'); var chatHistory = this.chatHistories[userid]; $textbox.val(chatHistory.down(line)); return true; }, chatHistories: {}, clickPMBackground: function (e) { if (!e.shiftKey && !e.cmdKey && !e.ctrlKey) { if (window.getSelection && !window.getSelection().isCollapsed) { return; } app.dismissPopups(); var $target = $(e.currentTarget); var newsid = $target.data('newsid'); if ($target.data('minimized')) { this.minimizePM(e); } else if ($(e.target).closest('h3').length) { // only preventDefault here, so clicking links/buttons in PMs // still works e.preventDefault(); e.stopPropagation(); this.minimizePM(e); return; } else if (newsid) { if (Storage.prefs('newsid', newsid)) { $target.find('.unread').removeClass('unread'); } return; } $target.find('textarea[name=message]').focus(); } }, dblClickPMHeader: function (e) { e.preventDefault(); e.stopPropagation(); if (window.getSelection) { window.getSelection().removeAllRanges(); } else if (document.selection) { document.selection.empty(); } }, clickSpoiler: function (e) { $(e.currentTarget).toggleClass('spoiler-shown'); }, clickDatasearchResults: function (e) { if ($(e.target)[0].href) return; if (window.getSelection && !window.getSelection().isCollapsed) return; var target = $(e.currentTarget).closest('[class=datasearch]')[0]; var button = target.querySelector('button'); var results = target.querySelectorAll('[class=datasearch-body]'); if (!button || !results || results.length < 2) return; button.innerHTML = button.innerHTML === '[-]' ? '[+]' : '[-]'; for (var i = 0; i < results.length; i++) { results[i].style.display = results[i].style.display === 'none' ? 'block' : 'none'; } }, // support for buttons that can be sent by the server: joinRoom: function (room) { app.joinRoom(room); }, avatars: function () { app.addPopup(AvatarsPopup); }, openSounds: function () { app.addPopup(SoundsPopup, { type: 'semimodal' }); }, openOptions: function () { app.addPopup(OptionsPopup, { type: 'semimodal' }); }, // challenges and searching challengesFrom: null, challengeTo: null, resetPending: function () { this.updateSearch(); var self = this; this.$('form.pending').closest('.pm-window').each(function (i, el) { $(el).find('.challenge').remove(); self.challenge($(el).data('userid')); }); this.$('button[name=acceptChallenge]').each(function (i, el) { el.disabled = false; }); }, searching: false, updateSearch: function (data) { if (data) { this.searching = data.searching; this.games = data.games; } var $searchForm = $('.mainmenu button.big').closest('form'); var $formatButton = $searchForm.find('button[name=format]'); var $teamButton = $searchForm.find('button[name=team]'); if (!this.searching || $.isArray(this.searching) && !this.searching.length) { var format = $formatButton.val(); var teamIndex = $teamButton.val(); $formatButton.replaceWith(this.renderFormats(format)); $teamButton.replaceWith(this.renderTeams(format, teamIndex)); $searchForm.find('button.big').html('Battle!
Find a random opponent').removeClass('disabled'); $searchForm.find('p.cancel').remove(); } else { $formatButton.addClass('preselected')[0].disabled = true; $teamButton.addClass('preselected')[0].disabled = true; $searchForm.find('button.big').html(' Searching...').addClass('disabled'); var searchEntries = $.isArray(this.searching) ? this.searching : [this.searching]; for (var i = 0; i < searchEntries.length; i++) { var format = searchEntries[i].format || searchEntries[i]; if (format.substr(0, 4) === 'gen5' && !Dex.loadedSpriteData['bw']) { Dex.loadSpriteData('bw'); break; } } } var $searchGroup = $searchForm.closest('.menugroup'); if (this.games) { var newlyCreated = false; if (!this.$gamesGroup) { this.$gamesGroup = $(''); $searchGroup.before(this.$gamesGroup); newlyCreated = true; } if (!this.$gamesGroup.is(':visible') || newlyCreated) { $searchGroup.hide(); this.$gamesGroup.show(); } var buf = '

'; buf += '
'; for (var roomid in this.games) { var name = this.games[roomid]; if (name.slice(-1) === '*') name = name.slice(0, -1); buf += '
' + BattleLog.escapeHTML(name) + '
'; } buf += '
'; if (!$searchGroup.is(':visible')) buf += '

'; buf += '
'; this.$gamesGroup.html(buf); } else { if (this.$gamesGroup) { this.$gamesGroup.hide(); $searchGroup.show(); } } }, showSearchGroup: function (v, el) { var $searchGroup = $('.mainmenu button.big').closest('.menugroup'); $searchGroup.show(); $(el).closest('p').hide(); }, updateChallenges: function (data) { this.challengesFrom = data.challengesFrom; this.challengeTo = data.challengeTo; for (var i in data.challengesFrom) { if (app.ignore[i]) { delete data.challengesFrom[i]; continue; } this.openPM(' ' + i, true); } var atLeastOneGen5 = false; var challengeToUserid = ''; if (data.challengeTo) { var challenge = data.challengeTo; var name = challenge.to; var userid = toID(name); var $challenge = this.openChallenge(name); var buf = '

Waiting for ' + BattleLog.escapeHTML(name) + '...

'; buf += '

' + this.renderFormats(challenge.format, true) + '

'; buf += '

'; $challenge.html(buf); if (challenge.format.substr(0, 4) === 'gen5') atLeastOneGen5 = true; challengeToUserid = userid; } var self = this; this.$('.pm-window').each(function (i, el) { var $pmWindow = $(el); var userid = el.getAttribute('data-userid'); var name = $pmWindow.data('name'); if (data.challengesFrom[userid]) { var format = data.challengesFrom[userid]; if (!$pmWindow.find('.challenge').length) { self.notifyOnce("Challenge from " + name, "Format: " + BattleLog.escapeFormat(format), 'challenge:' + userid); } var $challenge = self.openChallenge(name, $pmWindow); if (!$challenge.find('button[name=makeChallenge]').length) { app.playNotificationSound(); var buf = '

' + BattleLog.escapeHTML(name) + ' wants to battle!

'; buf += '

' + self.renderFormats(format, true) + '

'; buf += '

' + self.renderTeams(format) + '

'; buf += '

'; buf += '

'; $challenge.html(buf); if (format.substr(0, 4) === 'gen5') atLeastOneGen5 = true; } } else { var $challenge = $pmWindow.find('.challenge'); if ($challenge.length) { var $acceptButton = $challenge.find('button[name=acceptChallenge]'); if ($acceptButton.length) { if ($acceptButton[0].disabled) { // You accepted someone's challenge and it started $challenge.remove(); } else { // Someone was challenging you, but cancelled their challenge $challenge.html('

The challenge was cancelled.

'); } } else if ($challenge.find('button[name=cancelChallenge]').length && challengeToUserid !== userid) { // You were challenging someone else, and they either accepted // or rejected it $challenge.remove(); } self.closeNotification('challenge:' + userid); } } }); if (atLeastOneGen5 && !Dex.loadedSpriteData['bw']) Dex.loadSpriteData('bw'); }, openChallenge: function (name, $pmWindow) { if (!$pmWindow) $pmWindow = this.openPM(name, true); var $challenge = $pmWindow.find('.challenge'); if (!$challenge.length) { $challenge = $('
').insertAfter($pmWindow.find('h3')); } return $challenge; }, updateFormats: function () { if (!window.BattleFormats) { this.$('.mainmenu button.big').html('Connecting...').addClass('disabled'); return; } else if (app.isDisconnected) { var $searchForm = $('.mainmenu button.big').closest('form'); $searchForm.find('button.big').html('Disconnected').addClass('disabled'); $searchForm.find('.mainmenu p.cancel').remove(); $searchForm.append('

'); this.$('button.onlineonly').addClass('disabled'); return; } this.$('button.onlineonly').removeClass('disabled'); if (!this.searching) this.$('.mainmenu button.big').html('Battle!
Find a random opponent').removeClass('disabled'); var self = this; this.$('button[name=format]').each(function (i, el) { var val = el.value; var $teamButton = $(el).closest('form').find('button[name=team]'); $(el).replaceWith(self.renderFormats(val)); $teamButton.replaceWith(self.renderTeams(val)); }); }, reconnect: function () { document.location.reload(); }, updateTeams: function () { if (!window.BattleFormats) return; var self = this; this.$('button[name=team]').each(function (i, el) { if (el.value === 'random') return; var format = $(el).closest('form').find('button[name=format]').val(); $(el).replaceWith(self.renderTeams(format)); }); }, updateRightMenu: function () { if (app.curSideRoom) { this.$('.rightmenu').hide(); } else { this.$('.rightmenu').show(); } }, // challenge buttons challenge: function (name, format, team) { var userid = toID(name); var $challenge = this.$('.pm-window-' + userid + ' .challenge'); if ($challenge.length && !$challenge.find('button[name=dismissChallenge]').length) { return; } if (format) { var formatParts = format.split('@@@', 2); formatParts[0] = toID(formatParts[0]); if (!formatParts[0].startsWith('gen')) formatParts[0] = 'gen9' + formatParts[0]; format = formatParts.length > 1 ? formatParts[0] + '@@@' + formatParts[1] : formatParts[0]; } $challenge = this.openChallenge(name); var buf = '

Challenge ' + BattleLog.escapeHTML(name) + '?

'; buf += '

' + this.renderFormats(format) + '

'; buf += '

' + this.renderTeams(format) + '

'; buf += '

'; var bestOfDefault = format && BattleFormats[format] ? BattleFormats[format].bestOfDefault : false; buf += '