From 42ddd81c680bc1b4d8bbf1d64d3cd1c057814016 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 16 Dec 2015 22:09:16 -0500 Subject: [PATCH] Teambuilder folder feature In addition to format folders, we now support regular folders that behave as you'd expect. These folders even map to actual directories in the downloadable client! Folders are delimited by `/` in team names in all storage formats (including export, and packed saving), and are stored in the `.folder` field of team objects. Because of this, `/` is no longer an acceptable character in team names. This improves interoperability with teams and filesystems, so we should probably have done this anyway. I also added back a friendly message to the top of the teambuilder. --- .eslintrc.js | 3 +- js/battledata.js | 4 + js/client-mainmenu.js | 7 +- js/client-teambuilder.js | 280 ++++++++++++++++++++++++++++++++------- js/client.js | 3 +- js/storage.js | 159 ++++++++++++++++------ style/client.css | 21 ++- 7 files changed, 379 insertions(+), 98 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 8f09ca77e8..9b598971f2 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -33,7 +33,8 @@ module.exports = { "Popup": false, "ForfeitPopup": false, "BracketPopup": false, "LoginPasswordPopup": false, "UserPopup": false, "TeamPopup": false, "AvatarsPopup": false, "BattleListPopup": false, "CreditsPopup": false, "FormatPopup": false, "FormattingPopup": false, "LoginPopup": false, "MovePopup": false, "SoundsPopup": false, "OptionsPopup": false, "PromptPopup": false, "ProxyPopup": false, "ReconnectPopup": false, - "RegisterPopup": false, "ReplayUploadedPopup": false, "RulesPopup": false, "TabListPopup": false, "TournamentBox": false + "RegisterPopup": false, "ReplayUploadedPopup": false, "RulesPopup": false, "TabListPopup": false, "TournamentBox": false, + "CustomBackgroundPopup": false }, "rules": { "comma-dangle": [2, "never"], diff --git a/js/battledata.js b/js/battledata.js index dc89aaccb1..3282697390 100644 --- a/js/battledata.js +++ b/js/battledata.js @@ -334,6 +334,10 @@ var Tools = { tracker.callbacks[i][0].call(tracker.callbacks[i][1], value); } }; + tracker.unload = function () { + if (!tracker.isLoaded) return; + tracker.isLoaded = false; + }; return tracker; }, diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index 326e0cdb65..d9dfe39898 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -42,11 +42,10 @@ } buf += ''; + buf += '

'; - buf += ''; + buf += ''; this.$('.mainmenu').html(buf); diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 2420844d25..bd689335ed 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -29,7 +29,6 @@ this.saveFlag = false; app.user.trigger('saveteams'); } - this.curFormatKeep = ''; }, events: { // team changes @@ -112,7 +111,17 @@ curTeamLoc: 0, curSet: null, curSetLoc: 0, - curFormat: '', + + // curFolder will have '/' at the end if it's a folder, but + // it will be alphanumeric (so guaranteed no '/') if it's a + // format + // Special values: + // '' - show all + // 'gen6' - show teams with no format + // '/' - show teams with no folder + curFolder: '', + curFolderKeep: '', + exportMode: false, update: function () { teams = Storage.teams; @@ -169,15 +178,27 @@ updateFolderList: function () { var buf = '
'; - buf += '
' : '">') + '
(all)
' + (!this.curFormat ? '
' : ''); + buf += '
' : '">') + '
(all)
' + (!this.curFolder ? '
' : ''); var folderTable = {}; var folders = []; if (Storage.teams) for (var i = -2; i < Storage.teams.length; i++) { + if (i >= 0) { + var folder = Storage.teams[i].folder; + if (folder && !((folder + '/') in folderTable)) { + folders.push('Z' + folder); + folderTable[folder + '/'] = 1; + if (!('/' in folderTable)) { + folders.push('Z~'); + folderTable['/'] = 1; + } + } + } + var format; if (i === -2) { - format = this.curFormatKeep; + format = this.curFolderKeep; } else if (i === -1) { - format = this.curFormat; + format = this.curFolder; } else { format = Storage.teams[i].format; if (!format) format = 'gen6'; @@ -185,36 +206,66 @@ if (!format) continue; if (format in folderTable) continue; folderTable[format] = 1; + if (format.slice(-1) === '/') { + folders.push('Z' + (format.slice(0, -1) || '~')); + if (!('/' in folderTable)) { + folders.push('Z~'); + folderTable['/'] = 1; + } + continue; + } if (format === 'gen6') { folders.push('A~'); continue; } switch (format.slice(0, 4)) { - case 'gen1': format = 'Z' + format.slice(4); break; - case 'gen2': format = 'X' + format.slice(4); break; - case 'gen3': format = 'Y' + format.slice(4); break; - case 'gen4': format = 'W' + format.slice(4); break; - case 'gen5': format = 'V' + format.slice(4); break; + case 'gen1': format = 'F' + format.slice(4); break; + case 'gen2': format = 'E' + format.slice(4); break; + case 'gen3': format = 'D' + format.slice(4); break; + case 'gen4': format = 'C' + format.slice(4); break; + case 'gen5': format = 'B' + format.slice(4); break; default: format = 'A' + format; break; } folders.push(format); } folders.sort(); var gen = ''; + var formatFolderBuf = '
'; + formatFolderBuf += '
(add format folder)
'; for (var i = 0; i < folders.length; i++) { var format = folders[i]; var newGen; switch (format.charAt(0)) { - case 'Z': newGen = '1'; break; - case 'Y': newGen = '2'; break; - case 'X': newGen = '3'; break; - case 'W': newGen = '4'; break; - case 'V': newGen = '5'; break; + case 'F': newGen = '1'; break; + case 'E': newGen = '2'; break; + case 'D': newGen = '3'; break; + case 'C': newGen = '4'; break; + case 'B': newGen = '5'; break; case 'A': newGen = '6'; break; + case 'Z': newGen = '/'; break; } if (gen !== newGen) { gen = newGen; - buf += '

Gen ' + gen + '

'; + if (gen === '/') { + buf += formatFolderBuf; + formatFolderBuf = ''; + buf += '
'; + buf += '

Folders

'; + } else { + buf += '

Gen ' + gen + '

'; + } + } + if (gen === '/') { + formatName = format.slice(1); + format = formatName + '/'; + if (formatName === '~') { + formatName = '(uncategorized)'; + format = '/'; + } else { + formatName = Tools.escapeHTML(formatName); + } + buf += '
' : '">') + '
' + formatName + '
' + (this.curFolder === format ? '
' : ''); + continue; } var formatName = format.slice(1); if (formatName === '~') formatName = ''; @@ -226,11 +277,11 @@ if (format === 'gen6') formatName = '(uncategorized)'; // folders are
s rather than
'; @@ -243,27 +294,50 @@ // teampane buf += this.clipboardHTML(); - if (!this.curFormat) { + var filterFormat = ''; + var filterFolder = undefined; + + if (!this.curFolder) { + buf += '

Hi

'; + buf += '

Did you have a good day?

'; + buf += '

'; buf += '

All teams

'; } else { - buf += '

' + this.curFormat + '

'; + if (this.curFolder.slice(-1) === '/') { + filterFolder = this.curFolder.slice(0, -1); + if (filterFolder) { + buf += '

' + filterFolder + '

'; + } else { + buf += '

Teams not in any folders

'; + } + } else { + filterFormat = this.curFolder; + buf += '

' + filterFormat + '

'; + } } + var newButtonText = "New Team"; + if (filterFolder) newButtonText = "New Team in folder"; + if (filterFormat && filterFormat !== 'gen6') { + newButtonText = "New " + Tools.escapeFormat(filterFormat) + " Team"; + } + buf += '

'; + + buf += '