diff --git a/code/chat.js b/code/chat.js index 4c804da1..10ea586a 100644 --- a/code/chat.js +++ b/code/chat.js @@ -1,29 +1,19 @@ window.chat = function() {}; +window.chat._oldFactionTimestamp = -1; +window.chat._newFactionTimestamp = -1; +window.chat._oldPublicTimestamp = -1; +window.chat._newPublicTimestamp = -1; + window.chat.getOldestTimestamp = function(public) { - if(chat._needsClearing) return -1; - if(public) { - var a = $('#chatpublic time:first').data('timestamp'); - var b = $('#chatbot time:first').data('timestamp'); - if(a && b) return Math.min(a, b); - return a || b || -1; - } else { - return $('#chatfaction time').first().data('timestamp') || -1; - } + return chat['_old'+(public ? 'Public' : 'Faction')+'Timestamp']; } window.chat.getNewestTimestamp = function(public) { - if(chat._needsClearing) return -1; - if(public) { - var a = $('#chatpublic time:last').data('timestamp'); - var b = $('#chatbot time:last').data('timestamp'); - if(a && b) return Math.max(a, b); - return a || b || -1; - } else { - return $('#chatfaction time').last().data('timestamp') || -1; - } + return chat['_new'+(public ? 'Public' : 'Faction')+'Timestamp']; } + window.chat._needsClearing = false; window.chat._oldBBox = null; window.chat.genPostData = function(public, getOlderMsgs) { @@ -40,7 +30,7 @@ window.chat.genPostData = function(public, getOlderMsgs) { var ne = b.getNorthEast(); var sw = b.getSouthWest(); var data = { - desiredNumItems: 10, + desiredNumItems: public ? 100 : 50, // public contains so much crap minLatE6: Math.round(sw.lat*1E6), minLngE6: Math.round(sw.lng*1E6), maxLatE6: Math.round(ne.lat*1E6), @@ -136,14 +126,17 @@ window.chat._displayedFactionGuids = []; window.chat.handleFaction = function(data, textStatus, jqXHR, isOldMsgs) { if(!data || !data.result) { window.failedRequestCount++; - return console.warn('Couldn’t get chat data. Waiting for next auto-refresh.'); + return console.warn('faction chat error. Waiting for next auto-refresh.'); } + chat._newFactionTimestamp = data.result[0][1]; + chat._oldFactionTimestamp = data.result[data.result.length-1][1]; + chat.clearIfRequired(); var msgs = ''; var prevTime = null; - $.each(data.result.reverse(), function(ind, json) { + $.each(data.result.reverse(), function(ind, json) { // oldest first! // avoid duplicates if(window.chat._displayedFactionGuids.indexOf(json[0]) !== -1) return; window.chat._displayedFactionGuids.push(json[0]); @@ -167,8 +160,9 @@ window.chat.handleFaction = function(data, textStatus, jqXHR, isOldMsgs) { // if there is a change of day between two requests, handle the // divider insertion here. if(isOldMsgs) { - var nextTime = new Date($('#chatfaction time:last').data('timestamp')).toLocaleDateString(); - if(prevTime && prevTime !== nextTime) + var ts = $('#chatfaction time:first').data('timestamp'); + var nextTime = new Date(ts).toLocaleDateString(); + if(prevTime && prevTime !== nextTime && ts) msgs += chat.renderDivider(nextTime); } @@ -179,24 +173,185 @@ window.chat.handleFaction = function(data, textStatus, jqXHR, isOldMsgs) { else c.append(msgs); - // If scrolled down completely, keep it that way so new messages can - // be seen easily. If scrolled up, only need to fix scroll position - // when old messages are added. New messages added at the bottom don’t - // change the view and enabling this would make the chat scroll down - // for every added message, even if the user wants to read old stuff. - if(scrollBefore === 0 || isOldMsgs) { - c.data('ignoreNextScroll', true); - c.scrollTop(c.scrollTop() + (scrollBottom(c)-scrollBefore)); - } - + chat.keepScrollPosition(c, scrollBefore, isOldMsgs); chat.needMoreMessages(); } + +// +// requesting public +// + +window.chat._requestOldPublicRunning = false; +window.chat.requestOldPublic = function(isRetry) { + if(chat._requestOldPublicRunning) return; + if(isIdle()) return renderUpdateStatus(); + chat._requestOldPublicRunning = true; + + var d = chat.genPostData(true, true); + var r = window.postAjax( + 'getPaginatedPlextsV2', + d, + chat.handleOldPublic, + isRetry + ? function() { window.chat._requestOldPublicRunning = false; } + : function() { window.chat.requestOldPublic(true) } + ); + + requests.add(r); +} + +window.chat._requestNewPublicRunning = false; +window.chat.requestNewPublic = function(isRetry) { + if(chat._requestNewPublicRunning) return; + if(window.isIdle()) return renderUpdateStatus(); + chat._requestNewPublicRunning = true; + + var d = chat.genPostData(true, false); + var r = window.postAjax( + 'getPaginatedPlextsV2', + d, + chat.handleNewPublic, + isRetry + ? function() { window.chat._requestNewPublicRunning = false; } + : function() { window.chat.requestNewPublic(true) } + ); + + requests.add(r); +} + + +// +// handle public +// + + +window.chat.handleOldPublic = function(data, textStatus, jqXHR) { + chat._requestOldPublicRunning = false; + chat.handlePublic(data, textStatus, jqXHR, true); +} + +window.chat.handleNewPublic = function(data, textStatus, jqXHR) { + chat._requestNewPublicRunning = false; + chat.handlePublic(data, textStatus, jqXHR, false); +} + +window.chat._displayedPublicGuids = []; +window.chat._displayedPlayerActionTime = {}; +window.chat.handlePublic = function(data, textStatus, jqXHR, isOldMsgs) { + if(!data || !data.result) { + window.failedRequestCount++; + return console.warn('public chat error. Waiting for next auto-refresh.'); + } + + chat._newPublicTimestamp = data.result[0][1]; + chat._oldPublicTimestamp = data.result[data.result.length-1][1]; + + chat.clearIfRequired(); + + var c = $('#chat > div:visible'); + var scrollBefore = scrollBottom(c); + + chat.handlePublicAutomated(data); + //chat.handlePublicPlayer(data, isOldMsgs); + + chat.keepScrollPosition(c, scrollBefore, isOldMsgs); + chat.needMoreMessages(); +} + + + + + +window.chat.handlePublicAutomated = function(data) { + $.each(data.result, function(ind, json) { // newest first! + var time = json[1]; + + // ignore player messages + var t = json[2].plext.plextType; + if(t !== 'SYSTEM_BROADCAST' && t !== 'SYSTEM_NARROWCAST') return true; + + var tmpmsg = '', nick = null, pguid, team; + + // each automated message is composed of many text chunks. loop + // over them to gather all necessary data. + $.each(json[2].plext.markup, function(ind, part) { + switch(part[0]) { + case 'PLAYER': + pguid = part[1].guid; + var lastAction = window.chat._displayedPlayerActionTime[pguid]; + // ignore older messages about player + if(lastAction && lastAction[0] > time) return false; + + nick = part[1].plain; + team = part[1].team === 'ALIENS' ? TEAM_ENL : TEAM_RES; + window.setPlayerName(pguid, nick); // free nick name resolves + if(ind > 0) tmpmsg += nick; // don’t repeat nick directly + break; + + case 'TEXT': + tmpmsg += part[1].plain; + break; + + case 'PORTAL': + var latlng = [part[1].latE6/1E6, part[1].lngE6/1E6]; + var js = 'window.zoomToAndShowPortal(\''+part[1].guid+'\', ['+latlng[0]+', '+latlng[1]+'])'; + tmpmsg += ''+part[1].name+''; + break; + } + }); + + // nick will only be set if we don’t have any info about that + // player yet. + if(nick) { + tmpmsg = chat.renderMsg(tmpmsg, nick, time, team); + window.chat._displayedPlayerActionTime[pguid] = [time, tmpmsg]; + }; + }); + + if(chat.getActive() === 'automated') + window.chat.renderAutomatedMsgsToBox(); +} + +window.chat.getActive = function() { + return $('#chatcontrols .active').text(); +} + +window.chat.renderAutomatedMsgsToBox = function() { + var x = window.chat._displayedPlayerActionTime; + // we don’t care about the GUIDs anymore + var vals = $.map(x, function(v, k) { return [v]; }); + // sort them old to new + vals = vals.sort(function(a, b) { return a[0]-b[0]; }); + + var prevTime = null; + var msgs = $.map(vals, function(v) { + var nowTime = new Date(v[0]).toLocaleDateString(); + if(prevTime && prevTime !== nowTime) + var val = chat.renderDivider(nowTime) + v[1]; + else + var val = v[1]; + + prevTime = nowTime; + return val; + }).join('\n'); + + $('#chatautomated').html(msgs); +} + + + + window.chat.clear = function() { console.log('clearing now'); window.chat._displayedFactionGuids = []; window.chat._displayedPublicGuids = []; - $('#chatfaction, #chatpublic, #chatbot').data('ignoreNextScroll', true).html(''); + window.chat._displayedPlayerActionTime = {}; + window.chat._oldFactionTimestamp = -1; + window.chat._newFactionTimestamp = -1; + window.chat._oldPublicTimestamp = -1; + window.chat._newPublicTimestamp = -1; + $('#chatfaction, #chatpublic, #chatautomated').data('ignoreNextScroll', true).html(''); } window.chat.clearIfRequired = function() { @@ -210,6 +365,9 @@ window.chat.toggle = function() { if(c.hasClass('expand')) { $('#chatcontrols a:first').text('expand'); c.removeClass('expand'); + var div = $('#chat > div:visible'); + div.data('ignoreNextScroll', true); + div.scrollTop(9999999999999); // scroll to bottom } else { $('#chatcontrols a:first').text('shrink'); c.addClass('expand'); @@ -220,7 +378,7 @@ window.chat.toggle = function() { window.chat.request = function() { console.log('refreshing chat'); chat.requestNewFaction(); - //~ chat.requestNewPublic(); + chat.requestNewPublic(); } // checks if there are enough messages in the selected chat tab and @@ -229,7 +387,7 @@ window.chat.needMoreMessages = function() { var activeChat = $('#chat > :visible'); if(scrollBottom(activeChat) !== 0 || activeChat.scrollTop() !== 0) return; console.log('no scrollbar in active chat, requesting more msgs'); - if($('#chatcontrols a:last.active')) + if($('#chatcontrols a:last.active').length) chat.requestOldFaction(); else chat.requestOldPublic(); @@ -254,6 +412,9 @@ window.chat.setup = function() { $('#chatcontrols, #chat, #chatinput').show(); $('#chatcontrols a:first').click(window.chat.toggle); + $('#chatcontrols a:not(:first)').click(window.chat.chooser); + + $('#chatinput').click(function() { $('#chatinput input').focus(); }); @@ -267,16 +428,19 @@ window.chat.setup = function() { if(scrollBottom(t) === 0) chat.requestNewFaction(); }); - $('#chatpublic, #chatbot').scroll(function() { + $('#chatpublic, #chatautomated').scroll(function() { var t = $(this); if(t.data('ignoreNextScroll')) return t.data('ignoreNextScroll', false); if(t.scrollTop() < 200) chat.requestOldPublic(); if(scrollBottom(t) === 0) chat.requestNewPublic(); }); - chat.requestNewFaction(); + chat.request(); window.addResumeFunction(chat.request); window.requests.addRefreshFunction(chat.request); + + var cls = PLAYER.team === 'ALIENS' ? 'enl' : 'res'; + $('#chatinput span').addClass(cls) } @@ -285,9 +449,56 @@ window.chat.renderMsg = function(msg, nick, time, team) { var tb = unixTimeToString(time, true); var t = ''; var s = 'style="color:'+COLORS[team]+'"'; + var title = nick.length >= 8 ? 'title="'+nick+'"' : ''; return '
'+t+''+nick+''+msg+'
'; } window.chat.renderDivider = function(text) { return '