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 8f09ca77e..9b598971f 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 dc89aaccb..328269739 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 326e0cdb6..d9dfe3989 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 2420844d2..bd689335e 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 += '