diff --git a/.eslintrc.js b/.eslintrc.js index 64c0a1e0b1..58c60fa669 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,6 +24,7 @@ module.exports = { "BattleOtherAnims": false, "BattlePokedex": false,"BattlePokemonSprites": false, "BattlePokemonSpritesBW": false, "BattleSearchCountIndex": false, "BattleSearchIndex": false, "BattleArticleTitles": false, "BattleSearchIndexOffset": false, "BattleSearchIndexType": false, "BattleStatIDs": false, "BattleStatNames": false, "BattleStats": false, "BattleStatusAnims": false, "BattleStatuses": false, "BattleTeambuilderTable": false, "ModifiableValue": false, "BattleStatGuesser": false, "BattleText": true, "BattleTextAFD": false, "BattleTextNotAFD": false, + "BattleTextParser": false, // Generic global variables "Config": false, "BattleSearch": false, "soundManager": false, "Storage": false, "Dex": false, diff --git a/js/client-chat.js b/js/client-chat.js index 61dad400fd..bab96268de 100644 --- a/js/client-chat.js +++ b/js/client-chat.js @@ -26,7 +26,6 @@ }, updateUser: function () { var name = app.user.get('name'); - var userid = app.user.get('userid'); if (this.expired) { this.$chatAdd.html(this.expired === true ? 'This room is expired' : BattleLog.sanitizeHTML(this.expired)); this.$chatbox = null; @@ -37,7 +36,8 @@ this.$chatAdd.html('
'); this.$chatbox = null; } else { - this.$chatAdd.html('
'); + var color = app.user.get('away') ? 'color:#AAA;' : BattleLog.hashColor(app.user.get('userid')); + this.$chatAdd.html('
'); this.$chatbox = this.$chatAdd.find('textarea'); this.$chatbox.autoResize({ animate: false, @@ -175,7 +175,9 @@ position = 'right'; } var name = $(e.currentTarget).data('name') || $(e.currentTarget).text(); - app.addPopup(UserPopup, {name: name, sourceEl: e.currentTarget, position: position}); + var away = $(e.currentTarget).data('away') || false; + var status = $(e.currentTarget).data('status'); + app.addPopup(UserPopup, {name: name, away: away, status: status, sourceEl: e.currentTarget, position: position}); }, openPM: function (e) { e.preventDefault(); @@ -1411,7 +1413,10 @@ this.userCount.users = parseInt(userList.substr(0, commaIndex), 10); var users = userList.substr(commaIndex + 1).split(','); for (var i = 0, len = users.length; i < len; i++) { - if (users[i]) this.users[toId(users[i])] = users[i]; + if (users[i]) { + var user = BattleTextParser.parseNameParts(users[i]); + this.users[toUserid(user.name)] = user; + } } } else { this.userCount.users = parseInt(userList, 10); @@ -1420,7 +1425,8 @@ this.userList.construct(); }, addJoinLeave: function (action, name, oldid, silent) { - var userid = toUserid(name); + var user = BattleTextParser.parseNameParts(name); + var userid = toUserid(user.name); if (!action) { this.$joinLeave = null; this.joinLeave = { @@ -1431,7 +1437,7 @@ } else if (action === 'join') { if (oldid) delete this.users[toUserid(oldid)]; if (!this.users[userid]) this.userCount.users++; - this.users[userid] = name; + this.users[userid] = user; this.userList.add(userid); this.userList.updateUserCount(); this.userList.updateNoUsersOnline(); @@ -1443,7 +1449,13 @@ this.userList.updateNoUsersOnline(); } else if (action === 'rename') { if (oldid) delete this.users[toUserid(oldid)]; - this.users[userid] = name; + if (toUserid(oldid) === app.user.get('userid')) { + app.user.set({ + away: user.away, + status: user.status + }); + } + this.users[userid] = user; this.userList.remove(oldid); this.userList.add(userid); return; @@ -1457,7 +1469,7 @@ this.$chat.append('
Loading...
'); this.$joinLeave = this.$chat.children().last(); } - this.joinLeave[action].push(name); + this.joinLeave[action].push(user.name); var message = ''; if (this.joinLeave['join'].length) { var preList = this.joinLeave['join']; @@ -1520,7 +1532,8 @@ var userid = toUserid(name); var speakerHasAuth = " +\u2606".indexOf(name.charAt(0)) < 0; - var readerHasAuth = this.users && " +\u2606\u203D!".indexOf((this.users[app.user.get('userid')] || ' ').charAt(0)) < 0; + var user = (this.users && this.users[app.user.get('userid')]) || {}; + var readerHasAuth = user.name && " +\u2606\u203D!".indexOf((user.name || ' ').charAt(0)) < 0; if (app.ignore[userid] && !speakerHasAuth && !readerHasAuth) return; // Add this user to the list of people who have spoken recently. @@ -1699,21 +1712,23 @@ $('#' + this.room.id + '-userlist-user-' + userid).remove(); }, constructItem: function (userid) { - var name = this.room.users[userid]; + var user = this.room.users[userid]; var text = ''; // Sanitising the `userid` here is probably unnecessary, because // IDs can't contain anything dangerous. text += ''; - text += ''; text += ''; @@ -1736,12 +1751,17 @@ }, comparator: function (a, b) { if (a === b) return 0; + + var aUser = this.room.users[a]; + var bUser = this.room.users[b]; + if (aUser.away !== bUser.away) return aUser.away - bUser.away; + var aRank = ( - Config.groups[(this.room.users[a] ? this.room.users[a].charAt(0) : Config.defaultGroup || ' ')] || + Config.groups[aUser ? aUser.name.charAt(0) : Config.defaultGroup || ' '] || {order: (Config.defaultOrder || 10006.5)} ).order; var bRank = ( - Config.groups[(this.room.users[b] ? this.room.users[b].charAt(0) : Config.defaultGroup || ' ')] || + Config.groups[bUser ? bUser.name.charAt(0) : Config.defaultGroup || ' '] || {order: (Config.defaultOrder || 10006.5)} ).order; diff --git a/js/client-topbar.js b/js/client-topbar.js index f355e462ef..7bfeb1f7b3 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -30,11 +30,13 @@ updateUserbar: function () { var buf = ''; var name = ' ' + app.user.get('name'); - var color = BattleLog.hashColor(app.user.get('userid')); + var away = app.user.get('away'); + var status = app.user.get('status'); + var color = away ? 'color:#AAA;' : BattleLog.hashColor(app.user.get('userid')); if (!app.user.loaded) { buf = ''; } else if (app.user.get('named')) { - buf = ' ' + BattleLog.escapeHTML(name) + ''; + buf = ' ' + BattleLog.escapeHTML(name) + ''; } else { buf = ''; } diff --git a/js/client.js b/js/client.js index 620112b3de..abda9045e4 100644 --- a/js/client.js +++ b/js/client.js @@ -139,7 +139,9 @@ registered: false, named: false, avatar: 0, - settings: {} + settings: {}, + status: '', + away: false }, initialize: function () { app.addGlobalListeners(); @@ -937,14 +939,14 @@ this.receive(data.substr(nlIndex + 1)); parts = data.substr(0, nlIndex).split('|'); } - var name = parts[1]; + var parsed = BattleTextParser.parseNameParts(parts[1]); var named = !!+parts[2]; - var userid = toUserid(name); - if (userid === this.user.get('userid') && name !== this.user.get('name')) { + var userid = toUserid(parsed.name); + if (userid === this.user.get('userid') && parsed.name !== this.user.get('name')) { $.post(app.user.getActionPHP(), { act: 'changeusername', - username: name + username: parsed.name }, function () {}, 'text'); } @@ -960,18 +962,20 @@ } this.user.set({ - name: name, + name: parsed.name, userid: userid, named: named, avatar: parts[3], - settings: settings + settings: settings, + status: parsed.status, + away: parsed.away }); - this.user.setPersistentName(named ? name : null); + this.user.setPersistentName(named ? parsed.name : null); if (named) { this.trigger('init:choosename'); } - if (app.ignore[toUserid(name)]) { - delete app.ignore[toUserid(name)]; + if (app.ignore[userid]) { + delete app.ignore[userid]; } break; @@ -2466,6 +2470,10 @@ var buf = '
'; if (avatar) buf += ''; buf += '' + BattleLog.escapeHTML(name) + '
'; + var offline = data.rooms === false; + if (data.status || offline) { + buf += '' + (offline ? 'Offline' : data.status) + '
'; + } buf += '' + (group || ' ') + ''; if (globalgroup) buf += '
' + globalgroup + ''; if (data.rooms) { @@ -2507,8 +2515,6 @@ } } buf += '' + battlebuf + chatbuf + privatebuf + ''; - } else if (data.rooms === false) { - buf += 'OFFLINE'; } buf += '
'; diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 801469ee44..0b8301a63a 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -56,6 +56,23 @@ class BattleTextParser { } return BattleTextParser.upgradeArgs({args, kwArgs}); } + + static parseNameParts(text: string) { + const atIndex = text.indexOf('@'); + let name = text; + let status = ''; + let away = false; + if (atIndex > 0) { + name = text.substr(0, atIndex); + status = text.substr(atIndex + 1); + if (status.startsWith('!')) { + away = true; + status = status.substr(1); + } + } + return {name, status, away}; + } + static upgradeArgs({args, kwArgs}: {args: Args, kwArgs: KWArgs}): {args: Args, kwArgs: KWArgs} { switch (args[0]) { case '-activate': { diff --git a/style/client.css b/style/client.css index a14bf979be..fc0182ec3d 100644 --- a/style/client.css +++ b/style/client.css @@ -3049,6 +3049,11 @@ a.ilink.yours { width: 200px; } +.userstatus { + font-style: italic; + font-size: 8pt; +} + .userdetails { min-height: 80px; width: 191px;