finish chat feature; hide low level portal on zoom out; introduce render limit
This commit is contained in:
381
code/chat.js
381
code/chat.js
@ -1,5 +1,9 @@
|
||||
window.chat = function() {};
|
||||
|
||||
//
|
||||
// timestamp and clear management
|
||||
//
|
||||
|
||||
window.chat._oldFactionTimestamp = -1;
|
||||
window.chat._newFactionTimestamp = -1;
|
||||
window.chat._oldPublicTimestamp = -1;
|
||||
@ -13,8 +17,27 @@ window.chat.getNewestTimestamp = function(public) {
|
||||
return chat['_new'+(public ? 'Public' : 'Faction')+'Timestamp'];
|
||||
}
|
||||
|
||||
|
||||
window.chat._needsClearing = false;
|
||||
window.chat.clear = function() {
|
||||
console.log('clearing now');
|
||||
window.chat._displayedFactionGuids = [];
|
||||
window.chat._displayedPublicGuids = [];
|
||||
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() {
|
||||
if(!chat._needsClearing) return;
|
||||
chat.clear();
|
||||
chat._needsClearing = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.chat._oldBBox = null;
|
||||
window.chat.genPostData = function(public, getOlderMsgs) {
|
||||
if(typeof public !== 'boolean') throw('Need to know if public or faction chat.');
|
||||
@ -23,14 +46,14 @@ window.chat.genPostData = function(public, getOlderMsgs) {
|
||||
var b = map.getBounds().extend(chat._localRangeCircle.getBounds());
|
||||
|
||||
var bbs = b.toBBoxString();
|
||||
chat._needsClearing = chat._oldBBox && chat._oldBBox !== bbs;
|
||||
chat._needsClearing = chat._needsClearing || chat._oldBBox && chat._oldBBox !== bbs;
|
||||
if(chat._needsClearing) console.log('Bounding Box changed, chat will be cleared (old: '+chat._oldBBox+' ; new: '+bbs+' )');
|
||||
chat._oldBBox = bbs;
|
||||
|
||||
var ne = b.getNorthEast();
|
||||
var sw = b.getSouthWest();
|
||||
var data = {
|
||||
desiredNumItems: public ? 100 : 50, // public contains so much crap
|
||||
desiredNumItems: public ? CHAT_PUBLIC_ITEMS : CHAT_FACTION_ITEMS,
|
||||
minLatE6: Math.round(sw.lat*1E6),
|
||||
minLngE6: Math.round(sw.lng*1E6),
|
||||
maxLatE6: Math.round(ne.lat*1E6),
|
||||
@ -66,6 +89,8 @@ window.chat.genPostData = function(public, getOlderMsgs) {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// requesting faction
|
||||
//
|
||||
@ -108,6 +133,7 @@ window.chat.requestNewFaction = function(isRetry) {
|
||||
requests.add(r);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// handle faction
|
||||
//
|
||||
@ -122,6 +148,8 @@ window.chat.handleNewFaction = function(data, textStatus, jqXHR) {
|
||||
chat.handleFaction(data, textStatus, jqXHR, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.chat._displayedFactionGuids = [];
|
||||
window.chat.handleFaction = function(data, textStatus, jqXHR, isOldMsgs) {
|
||||
if(!data || !data.result) {
|
||||
@ -129,55 +157,25 @@ window.chat.handleFaction = function(data, textStatus, jqXHR, isOldMsgs) {
|
||||
return console.warn('faction chat error. Waiting for next auto-refresh.');
|
||||
}
|
||||
|
||||
chat.clearIfRequired();
|
||||
|
||||
if(data.result.length === 0) return;
|
||||
|
||||
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) { // oldest first!
|
||||
// avoid duplicates
|
||||
if(window.chat._displayedFactionGuids.indexOf(json[0]) !== -1) return;
|
||||
window.chat._displayedFactionGuids.push(json[0]);
|
||||
|
||||
var time = json[1];
|
||||
var msg = json[2].plext.markup[2][1].plain;
|
||||
var team = json[2].plext.team === 'ALIENS' ? TEAM_ENL : TEAM_RES;
|
||||
var nick = json[2].plext.markup[1][1].plain.slice(0, -2); // cut “: ” at end
|
||||
var pguid = json[2].plext.markup[1][1].guid;
|
||||
window.setPlayerName(pguid, nick); // free nick name resolves
|
||||
|
||||
|
||||
var nowTime = new Date(time).toLocaleDateString();
|
||||
if(prevTime && prevTime !== nowTime)
|
||||
msgs += chat.renderDivider(nowTime);
|
||||
|
||||
msgs += chat.renderMsg(msg, nick, time, team);
|
||||
prevTime = nowTime;
|
||||
});
|
||||
|
||||
// if there is a change of day between two requests, handle the
|
||||
// divider insertion here.
|
||||
if(isOldMsgs) {
|
||||
var ts = $('#chatfaction time:first').data('timestamp');
|
||||
var nextTime = new Date(ts).toLocaleDateString();
|
||||
if(prevTime && prevTime !== nextTime && ts)
|
||||
msgs += chat.renderDivider(nextTime);
|
||||
}
|
||||
|
||||
var c = $('#chatfaction');
|
||||
var scrollBefore = scrollBottom(c);
|
||||
if(isOldMsgs)
|
||||
c.prepend(msgs);
|
||||
else
|
||||
c.append(msgs);
|
||||
|
||||
chat.renderPlayerMsgsTo(true, data, isOldMsgs, chat._displayedFactionGuids);
|
||||
chat.keepScrollPosition(c, scrollBefore, isOldMsgs);
|
||||
chat.needMoreMessages();
|
||||
|
||||
if(data.result.length >= CHAT_FACTION_ITEMS) chat.needMoreMessages();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// requesting public
|
||||
//
|
||||
@ -244,25 +242,27 @@ window.chat.handlePublic = function(data, textStatus, jqXHR, isOldMsgs) {
|
||||
return console.warn('public chat error. Waiting for next auto-refresh.');
|
||||
}
|
||||
|
||||
chat.clearIfRequired();
|
||||
|
||||
if(data.result.length === 0) return;
|
||||
|
||||
chat._newPublicTimestamp = data.result[0][1];
|
||||
chat._oldPublicTimestamp = data.result[data.result.length-1][1];
|
||||
|
||||
chat.clearIfRequired();
|
||||
|
||||
var c = $('#chat > div:visible');
|
||||
var c = $('#chatautomated');
|
||||
var scrollBefore = scrollBottom(c);
|
||||
|
||||
chat.handlePublicAutomated(data);
|
||||
//chat.handlePublicPlayer(data, isOldMsgs);
|
||||
|
||||
chat.keepScrollPosition(c, scrollBefore, isOldMsgs);
|
||||
chat.needMoreMessages();
|
||||
|
||||
c = $('#chatpublic');
|
||||
var scrollBefore = scrollBottom(c);
|
||||
chat.renderPlayerMsgsTo(false, data, isOldMsgs, chat._displayedPublicGuids);
|
||||
chat.keepScrollPosition(c, scrollBefore, isOldMsgs);
|
||||
|
||||
if(data.result.length >= CHAT_PUBLIC_ITEMS) chat.needMoreMessages();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.chat.handlePublicAutomated = function(data) {
|
||||
$.each(data.result, function(ind, json) { // newest first!
|
||||
var time = json[1];
|
||||
@ -310,14 +310,10 @@ window.chat.handlePublicAutomated = function(data) {
|
||||
});
|
||||
|
||||
if(chat.getActive() === 'automated')
|
||||
window.chat.renderAutomatedMsgsToBox();
|
||||
window.chat.renderAutomatedMsgsTo();
|
||||
}
|
||||
|
||||
window.chat.getActive = function() {
|
||||
return $('#chatcontrols .active').text();
|
||||
}
|
||||
|
||||
window.chat.renderAutomatedMsgsToBox = function() {
|
||||
window.chat.renderAutomatedMsgsTo = function() {
|
||||
var x = window.chat._displayedPlayerActionTime;
|
||||
// we don’t care about the GUIDs anymore
|
||||
var vals = $.map(x, function(v, k) { return [v]; });
|
||||
@ -342,24 +338,89 @@ window.chat.renderAutomatedMsgsToBox = function() {
|
||||
|
||||
|
||||
|
||||
window.chat.clear = function() {
|
||||
console.log('clearing now');
|
||||
window.chat._displayedFactionGuids = [];
|
||||
window.chat._displayedPublicGuids = [];
|
||||
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('');
|
||||
//
|
||||
// common
|
||||
//
|
||||
|
||||
|
||||
window.chat.renderPlayerMsgsTo = function(isFaction, data, isOldMsgs, dupCheckArr) {
|
||||
var msgs = '';
|
||||
var prevTime = null;
|
||||
|
||||
$.each(data.result.reverse(), function(ind, json) { // oldest first!
|
||||
if(json[2].plext.plextType !== 'PLAYER_GENERATED') return true;
|
||||
|
||||
// avoid duplicates
|
||||
if(dupCheckArr.indexOf(json[0]) !== -1) return true;
|
||||
dupCheckArr.push(json[0]);
|
||||
|
||||
var time = json[1];
|
||||
var team = json[2].plext.team === 'ALIENS' ? TEAM_ENL : TEAM_RES;
|
||||
var msg, nick, pguid;
|
||||
$.each(json[2].plext.markup, function(ind, markup) {
|
||||
if(markup[0] === 'SENDER') {
|
||||
nick = markup[1].plain.slice(0, -2); // cut “: ” at end
|
||||
pguid = markup[1].guid;
|
||||
window.setPlayerName(pguid, nick); // free nick name resolves
|
||||
}
|
||||
|
||||
if(markup[0] === 'TEXT') msg = markup[1].plain;
|
||||
|
||||
if(!isFaction && markup[0] === 'SECURE') {
|
||||
nick = null;
|
||||
return false; // aka break
|
||||
}
|
||||
});
|
||||
|
||||
if(!nick) return true; // aka next
|
||||
|
||||
var nowTime = new Date(time).toLocaleDateString();
|
||||
if(prevTime && prevTime !== nowTime)
|
||||
msgs += chat.renderDivider(nowTime);
|
||||
|
||||
msgs += chat.renderMsg(msg, nick, time, team);
|
||||
prevTime = nowTime;
|
||||
});
|
||||
|
||||
var addTo = isFaction ? $('#chatfaction') : $('#chatpublic');
|
||||
|
||||
// if there is a change of day between two requests, handle the
|
||||
// divider insertion here.
|
||||
if(isOldMsgs) {
|
||||
var ts = addTo.find('time:first').data('timestamp');
|
||||
var nextTime = new Date(ts).toLocaleDateString();
|
||||
if(prevTime && prevTime !== nextTime && ts)
|
||||
msgs += chat.renderDivider(nextTime);
|
||||
}
|
||||
|
||||
if(isOldMsgs)
|
||||
addTo.prepend(msgs);
|
||||
else
|
||||
addTo.append(msgs);
|
||||
}
|
||||
|
||||
window.chat.clearIfRequired = function() {
|
||||
if(!chat._needsClearing) return;
|
||||
chat.clear();
|
||||
chat._needsClearing = false;
|
||||
|
||||
window.chat.renderDivider = function(text) {
|
||||
return '<summary>─ '+text+' ────────────────────────────────────────────────────────────────────────────</summary>';
|
||||
}
|
||||
|
||||
|
||||
window.chat.renderMsg = function(msg, nick, time, team) {
|
||||
var ta = unixTimeToHHmm(time);
|
||||
var tb = unixTimeToString(time, true);
|
||||
var t = '<time title="'+tb+'" data-timestamp="'+time+'">'+ta+'</time>';
|
||||
var s = 'style="color:'+COLORS[team]+'"';
|
||||
var title = nick.length >= 8 ? 'title="'+nick+'"' : '';
|
||||
return '<p>'+t+'<mark '+s+'>'+nick+'</mark><span>'+msg+'</span></p>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.chat.getActive = function() {
|
||||
return $('#chatcontrols .active').text();
|
||||
}
|
||||
|
||||
|
||||
window.chat.toggle = function() {
|
||||
var c = $('#chat, #chatcontrols');
|
||||
if(c.hasClass('expand')) {
|
||||
@ -375,12 +436,14 @@ window.chat.toggle = function() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.chat.request = function() {
|
||||
console.log('refreshing chat');
|
||||
chat.requestNewFaction();
|
||||
chat.requestNewPublic();
|
||||
}
|
||||
|
||||
|
||||
// checks if there are enough messages in the selected chat tab and
|
||||
// loads more if not.
|
||||
window.chat.needMoreMessages = function() {
|
||||
@ -393,19 +456,62 @@ window.chat.needMoreMessages = function() {
|
||||
chat.requestOldPublic();
|
||||
}
|
||||
|
||||
window.chat.setupTime = function() {
|
||||
var inputTime = $('#chatinput time');
|
||||
var updateTime = function() {
|
||||
if(window.isIdle()) return;
|
||||
var d = new Date();
|
||||
inputTime.text(d.toLocaleTimeString().slice(0, 5));
|
||||
// update ON the minute (1ms after)
|
||||
setTimeout(updateTime, (60 - d.getSeconds()) * 1000 + 1);
|
||||
};
|
||||
updateTime();
|
||||
window.addResumeFunction(updateTime);
|
||||
|
||||
window.chat.chooser = function(event) {
|
||||
var t = $(event.target);
|
||||
var tt = t.text();
|
||||
var span = $('#chatinput span');
|
||||
|
||||
$('#chatcontrols .active').removeClass('active');
|
||||
t.addClass('active');
|
||||
|
||||
$('#chat > div').hide();
|
||||
|
||||
switch(tt) {
|
||||
case 'faction':
|
||||
span.css('color', '');
|
||||
span.text('tell faction:');
|
||||
$('#chatfaction').show();
|
||||
break;
|
||||
|
||||
case 'public':
|
||||
span.css('cssText', 'color: red !important');
|
||||
span.text('tell public:');
|
||||
$('#chatpublic').show();
|
||||
break;
|
||||
|
||||
case 'automated':
|
||||
span.css('cssText', 'color: #bbb !important');
|
||||
span.text('tell Jarvis:');
|
||||
chat.renderAutomatedMsgsTo();
|
||||
$('#chatautomated').show();
|
||||
break;
|
||||
}
|
||||
|
||||
chat.needMoreMessages();
|
||||
}
|
||||
|
||||
|
||||
// contains the logic to keep the correct scroll position.
|
||||
window.chat.keepScrollPosition = function(box, scrollBefore, isOldMsgs) {
|
||||
// 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) {
|
||||
box.data('ignoreNextScroll', true);
|
||||
box.scrollTop(box.scrollTop() + (scrollBottom(box)-scrollBefore));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// setup
|
||||
//
|
||||
|
||||
window.chat.setup = function() {
|
||||
window.chat._localRangeCircle = L.circle(map.getCenter(), CHAT_MIN_RANGE*1000);
|
||||
|
||||
@ -420,6 +526,7 @@ window.chat.setup = function() {
|
||||
});
|
||||
|
||||
window.chat.setupTime();
|
||||
window.chat.setupPosting();
|
||||
|
||||
$('#chatfaction').scroll(function() {
|
||||
var t = $(this);
|
||||
@ -444,61 +551,61 @@ window.chat.setup = function() {
|
||||
}
|
||||
|
||||
|
||||
window.chat.renderMsg = function(msg, nick, time, team) {
|
||||
var ta = unixTimeToHHmm(time);
|
||||
var tb = unixTimeToString(time, true);
|
||||
var t = '<time title="'+tb+'" data-timestamp="'+time+'">'+ta+'</time>';
|
||||
var s = 'style="color:'+COLORS[team]+'"';
|
||||
var title = nick.length >= 8 ? 'title="'+nick+'"' : '';
|
||||
return '<p>'+t+'<mark '+s+'>'+nick+'</mark><span>'+msg+'</span></p>';
|
||||
}
|
||||
|
||||
window.chat.renderDivider = function(text) {
|
||||
return '<summary>─ '+text+' ────────────────────────────────────────────────────────────────────────────</summary>';
|
||||
}
|
||||
|
||||
window.chat.chooser = function(event) {
|
||||
var t = $(event.target);
|
||||
var tt = t.text();
|
||||
var span = $('#chatinput span');
|
||||
|
||||
$('#chatcontrols .active').removeClass('active');
|
||||
t.addClass('active');
|
||||
|
||||
$('#chat > div').hide();
|
||||
|
||||
switch(tt) {
|
||||
case 'faction':
|
||||
span.css('color', '');
|
||||
span.text('tell faction:');
|
||||
$('#chatfaction').show();
|
||||
break;
|
||||
|
||||
case 'public':
|
||||
span.css('cssText', 'color: red !important');
|
||||
span.text('spam public:');
|
||||
$('#chatpublic').show();
|
||||
break;
|
||||
|
||||
case 'automated':
|
||||
span.css('cssText', 'color: #bbb !important');
|
||||
span.text('tell Jarvis:');
|
||||
chat.renderAutomatedMsgsToBox();
|
||||
$('#chatautomated').show();
|
||||
break;
|
||||
}
|
||||
window.chat.setupTime = function() {
|
||||
var inputTime = $('#chatinput time');
|
||||
var updateTime = function() {
|
||||
if(window.isIdle()) return;
|
||||
var d = new Date();
|
||||
inputTime.text(d.toLocaleTimeString().slice(0, 5));
|
||||
// update ON the minute (1ms after)
|
||||
setTimeout(updateTime, (60 - d.getSeconds()) * 1000 + 1);
|
||||
};
|
||||
updateTime();
|
||||
window.addResumeFunction(updateTime);
|
||||
}
|
||||
|
||||
|
||||
// contains the logic to keep the correct scroll position.
|
||||
window.chat.keepScrollPosition = function(box, scrollBefore, isOldMsgs) {
|
||||
// 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) {
|
||||
box.data('ignoreNextScroll', true);
|
||||
box.scrollTop(box.scrollTop() + (scrollBottom(box)-scrollBefore));
|
||||
}
|
||||
//
|
||||
// posting
|
||||
//
|
||||
|
||||
|
||||
window.chat.setupPosting = function() {
|
||||
$('#chatinput input').keypress(function(e) {
|
||||
if((e.keyCode ? e.keyCode : e.which) != 13) return;
|
||||
chat.postMsg();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('#chatinput').submit(function(e) {
|
||||
chat.postMsg();
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
window.chat.postMsg = function() {
|
||||
var c = chat.getActive();
|
||||
if(c === 'automated') return alert('Jarvis: A strange game. The only winning move is not to play. How about a nice game of chess?');
|
||||
|
||||
var msg = $.trim($('#chatinput input').val());
|
||||
if(!msg || msg === '') return;
|
||||
|
||||
var public = c === 'public';
|
||||
var latlng = map.getCenter();
|
||||
|
||||
var data = {message: msg,
|
||||
latE6: Math.round(latlng.lat*1E6),
|
||||
lngE6: Math.round(latlng.lng*1E6),
|
||||
factionOnly: !public};
|
||||
|
||||
window.postAjax('sendPlext', data,
|
||||
function() { if(public) chat.requestNewPublic(); else chat.requestNewFaction(); },
|
||||
function() {
|
||||
alert('Your message could not be delivered. You can copy&' +
|
||||
'paste it here and try again if you want:\n\n'+msg);
|
||||
}
|
||||
);
|
||||
|
||||
$('#chatinput input').val('');
|
||||
}
|
||||
|
Reference in New Issue
Block a user