make faction chat display almost work
This commit is contained in:
parent
4da97f48e3
commit
b7f1270ff6
21
code/boot.js
21
code/boot.js
@ -24,12 +24,13 @@ window.setupLargeImagePreview = function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window.setupStyles = function() {
|
window.setupStyles = function() {
|
||||||
$('head').append('<style>' +
|
$('head').append('<style>' +
|
||||||
[ '#largepreview.res img { border:2px solid '+COLORS[TEAM_RES]+'; } ',
|
[ '#largepreview.res img { border:2px solid '+COLORS[TEAM_RES]+'; } ',
|
||||||
'#largepreview.enl img { border:2px solid '+COLORS[TEAM_ENL]+'; } ',
|
'#largepreview.enl img { border:2px solid '+COLORS[TEAM_ENL]+'; } ',
|
||||||
'#largepreview.none img { border:2px solid '+COLORS[TEAM_NONE]+'; } ',
|
'#largepreview.none img { border:2px solid '+COLORS[TEAM_NONE]+'; } ',
|
||||||
'#chatcontrols { bottom: '+(CHAT_SHRINKED+4)+'px; }',
|
'#chatcontrols { bottom: '+(CHAT_SHRINKED+24)+'px; }',
|
||||||
'#chat { height: '+CHAT_SHRINKED+'px; } ',
|
'#chat { height: '+CHAT_SHRINKED+'px; } ',
|
||||||
'#updatestatus { width:'+(SIDEBAR_WIDTH-2*4)+'px; } ',
|
'#updatestatus { width:'+(SIDEBAR_WIDTH-2*4)+'px; } ',
|
||||||
'#sidebar, #gamestat, #gamestat span, input, ',
|
'#sidebar, #gamestat, #gamestat span, input, ',
|
||||||
@ -82,21 +83,19 @@ window.setupMap = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// map update status handling
|
// map update status handling
|
||||||
map.on('zoomstart', function() { window.mapRunsUserAction = true });
|
map.on('movestart zoomstart', function() { window.mapRunsUserAction = true });
|
||||||
map.on('movestart', function() { window.mapRunsUserAction = true });
|
map.on('moveend zoomend', function() { window.mapRunsUserAction = false });
|
||||||
map.on('zoomend', function() { window.mapRunsUserAction = false });
|
|
||||||
map.on('moveend', function() { window.mapRunsUserAction = false });
|
|
||||||
|
|
||||||
|
|
||||||
// update map hooks
|
// update map hooks
|
||||||
map.on('zoomstart', window.requests.abort);
|
map.on('movestart zoomstart', window.requests.abort);
|
||||||
map.on('zoomend', function() { window.startRefreshTimeout(500) });
|
map.on('moveend zoomend', function() { window.startRefreshTimeout(500) });
|
||||||
map.on('movestart', window.requests.abort );
|
|
||||||
map.on('moveend', function() { window.startRefreshTimeout(500) });
|
|
||||||
|
|
||||||
// run once on init
|
// run once on init
|
||||||
window.requestData();
|
window.requestData();
|
||||||
window.startRefreshTimeout();
|
window.startRefreshTimeout();
|
||||||
|
|
||||||
|
window.addResumeFunction(window.requestData);
|
||||||
|
window.requests.addRefreshFunction(window.requestData);
|
||||||
};
|
};
|
||||||
|
|
||||||
// renders player details into the website. Since the player info is
|
// renders player details into the website. Since the player info is
|
||||||
@ -151,7 +150,7 @@ function boot() {
|
|||||||
window.setupLargeImagePreview();
|
window.setupLargeImagePreview();
|
||||||
window.updateGameScore();
|
window.updateGameScore();
|
||||||
window.setupPlayerStat();
|
window.setupPlayerStat();
|
||||||
window.setupChat();
|
window.chat.setup();
|
||||||
// read here ONCE, so the URL is only evaluated one time after the
|
// read here ONCE, so the URL is only evaluated one time after the
|
||||||
// necessary data has been loaded.
|
// necessary data has been loaded.
|
||||||
urlPortal = getURLParam('pguid');
|
urlPortal = getURLParam('pguid');
|
||||||
|
260
code/chat.js
260
code/chat.js
@ -1,6 +1,6 @@
|
|||||||
window.chat = function() {}
|
window.chat = function() {};
|
||||||
|
|
||||||
window.getOldestTimestampChat = function(public) {
|
window.chat.getOldestTimestamp = function(public) {
|
||||||
if(public) {
|
if(public) {
|
||||||
var a = $('#chatpublic time:first').data('timestamp');
|
var a = $('#chatpublic time:first').data('timestamp');
|
||||||
var b = $('#chatbot time:first').data('timestamp');
|
var b = $('#chatbot time:first').data('timestamp');
|
||||||
@ -11,7 +11,7 @@ window.getOldestTimestampChat = function(public) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.getNewestTimestampChat = function(public) {
|
window.chat.getNewestTimestamp = function(public) {
|
||||||
if(public) {
|
if(public) {
|
||||||
var a = $('#chatpublic time:last').data('timestamp');
|
var a = $('#chatpublic time:last').data('timestamp');
|
||||||
var b = $('#chatbot time:last').data('timestamp');
|
var b = $('#chatbot time:last').data('timestamp');
|
||||||
@ -22,7 +22,7 @@ window.getNewestTimestampChat = function(public) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.getPostDataForChat = function(public, getOlderMsgs) {
|
window.chat.genPostData = function(public, getOlderMsgs) {
|
||||||
if(typeof public !== 'boolean') throw('Need to know if public or faction chat.');
|
if(typeof public !== 'boolean') throw('Need to know if public or faction chat.');
|
||||||
|
|
||||||
var b = map.getBounds();
|
var b = map.getBounds();
|
||||||
@ -42,75 +42,213 @@ window.getPostDataForChat = function(public, getOlderMsgs) {
|
|||||||
|
|
||||||
if(getOlderMsgs) {
|
if(getOlderMsgs) {
|
||||||
// ask for older chat when scrolling up
|
// ask for older chat when scrolling up
|
||||||
data = $.extend(data, {maxTimestampMs: getOldestTimestampChat(public)});
|
data = $.extend(data, {maxTimestampMs: chat.getOldestTimestamp(public)});
|
||||||
} else {
|
} else {
|
||||||
// ask for newer chat
|
// ask for newer chat
|
||||||
$.extend(data, {minTimestampMs: getNewestTimestampChat(public)});
|
var min = chat.getNewestTimestamp(public);
|
||||||
|
// the inital request will have both timestamp values set to -1,
|
||||||
|
// thus we receive the newest desiredNumItems. After that, we will
|
||||||
|
// only receive messages with a timestamp greater or equal to min
|
||||||
|
// above.
|
||||||
|
// After resuming from idle, there might be more new messages than
|
||||||
|
// desiredNumItems. So on the first request, we are not really up to
|
||||||
|
// date. We will eventually catch up, as long as there are less new
|
||||||
|
// messages than desiredNumItems per each refresh cycle.
|
||||||
|
// A proper solution would be to query until no more new results are
|
||||||
|
// returned. Another way would be to set desiredNumItems to a very
|
||||||
|
// large number so we really get all new messages since the last
|
||||||
|
// request. Setting desiredNumItems to -1 does unfortunately not
|
||||||
|
// work.
|
||||||
|
// Currently this edge case is not handled. Let’s see if this is a
|
||||||
|
// problem in crowded areas.
|
||||||
|
$.extend(data, {minTimestampMs: min});
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.requestFactionChat = function(getOlderMsgs) {
|
//
|
||||||
if(window.idleTime >= MAX_IDLE_TIME) {
|
// requesting faction
|
||||||
console.log('user has been idle for ' + idleTime + ' minutes. Skipping faction chat.');
|
//
|
||||||
renderUpdateStatus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = getPostDataForChat(false, false);
|
window.chat._requestOldFactionRunning = false;
|
||||||
window.requests.add(window.postAjax('getPaginatedPlextsV2', data, window.handleFactionChat));
|
window.chat.requestOldFaction = function(isRetry) {
|
||||||
|
if(chat._requestOldFactionRunning) return;
|
||||||
|
if(isIdle()) return renderUpdateStatus();
|
||||||
|
chat._requestOldFactionRunning = true;
|
||||||
|
|
||||||
|
var d = chat.genPostData(false, true);
|
||||||
|
var r = window.postAjax(
|
||||||
|
'getPaginatedPlextsV2',
|
||||||
|
d,
|
||||||
|
chat.handleOldFaction,
|
||||||
|
isRetry
|
||||||
|
? function() { window.chat._requestOldFactionRunning = false; }
|
||||||
|
: function() { window.chat.requestOldFaction(true) }
|
||||||
|
);
|
||||||
|
|
||||||
|
requests.add(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.renderChatMsg = function(msg, nick, time, team) {
|
window.chat._requestNewFactionRunning = false;
|
||||||
|
window.chat.requestNewFaction = function(isRetry) {
|
||||||
|
if(chat._requestNewFactionRunning) return;
|
||||||
|
if(window.isIdle()) return renderUpdateStatus();
|
||||||
|
chat._requestNewFactionRunning = true;
|
||||||
|
|
||||||
|
var d = chat.genPostData(false, false);
|
||||||
|
var r = window.postAjax(
|
||||||
|
'getPaginatedPlextsV2',
|
||||||
|
d,
|
||||||
|
chat.handleNewFaction,
|
||||||
|
isRetry
|
||||||
|
? function() { window.chat._requestNewFactionRunning = false; }
|
||||||
|
: function() { window.chat.requestNewFaction(true) }
|
||||||
|
);
|
||||||
|
|
||||||
|
requests.add(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// handle faction
|
||||||
|
//
|
||||||
|
|
||||||
|
window.chat.handleOldFaction = function(data, textStatus, jqXHR) {
|
||||||
|
chat._requestOldFactionRunning = false;
|
||||||
|
chat.handleFaction(data, textStatus, jqXHR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.chat.handleNewFaction = function(data, textStatus, jqXHR) {
|
||||||
|
chat._requestNewFactionRunning = false;
|
||||||
|
chat.handleFaction(data, textStatus, jqXHR, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.chat._displayedFactionGuids = [];
|
||||||
|
window.chat.handleFaction = function(data, textStatus, jqXHR, isOldMsgs) {
|
||||||
|
if(!data || !data.result) return console.warn('Couldn’t get chat data. Pausing chat for now.');
|
||||||
|
|
||||||
|
var msgs = '';
|
||||||
|
var prevTime = null;
|
||||||
|
$.each(data.result.reverse(), function(ind, json) {
|
||||||
|
// 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 += '<summary>'+nowTime+'</summary>';
|
||||||
|
|
||||||
|
msgs += chat.renderMsg(msg, nick, time, team);
|
||||||
|
|
||||||
|
|
||||||
|
prevTime = nowTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
var c = $('#chatfaction');
|
||||||
|
var scrollBefore = scrollBottom(c);
|
||||||
|
if(isOldMsgs)
|
||||||
|
c.prepend(msgs);
|
||||||
|
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.needMoreMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.chat.toggle = function() {
|
||||||
|
var c = $('#chat, #chatcontrols');
|
||||||
|
if(c.hasClass('expand')) {
|
||||||
|
$('#chatcontrols a:first').text('expand');
|
||||||
|
c.removeClass('expand');
|
||||||
|
} else {
|
||||||
|
$('#chatcontrols a:first').text('shrink');
|
||||||
|
c.addClass('expand');
|
||||||
|
chat.needMoreMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
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'))
|
||||||
|
chat.requestOldFaction();
|
||||||
|
else
|
||||||
|
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.setup = function() {
|
||||||
|
$('#chatcontrols, #chat, #chatinput').show();
|
||||||
|
|
||||||
|
$('#chatcontrols a:first').click(window.chat.toggle);
|
||||||
|
$('#chatinput').click(function() {
|
||||||
|
$('#chatinput input').focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.chat.setupTime();
|
||||||
|
|
||||||
|
$('#chatfaction').scroll(function() {
|
||||||
|
var t = $(this);
|
||||||
|
if(t.data('ignoreNextScroll')) return t.data('ignoreNextScroll', false);
|
||||||
|
if(t.scrollTop() < 200) chat.requestOldFaction();
|
||||||
|
if(scrollBottom(t) === 0) chat.requestNewFaction();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#chatpublic, #chatbot').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();
|
||||||
|
window.addResumeFunction(chat.request);
|
||||||
|
window.requests.addRefreshFunction(chat.request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
window.chat.renderMsg = function(msg, nick, time, team) {
|
||||||
var ta = unixTimeToHHmm(time);
|
var ta = unixTimeToHHmm(time);
|
||||||
var tb = unixTimeToString(time, true);
|
var tb = unixTimeToString(time, true);
|
||||||
var t = '<time title="'+tb+'" data-timestamp="'+time+'">'+ta+'</time>';
|
var t = '<time title="'+tb+'" data-timestamp="'+time+'">'+ta+'</time>';
|
||||||
var s = 'style="color:'+COLORS[team]+'"';
|
var s = 'style="color:'+COLORS[team]+'"';
|
||||||
return '<p>'+t+'<mark '+s+'>'+nick+'</mark><span>'+msg+'</span></p>';
|
return '<p>'+t+'<mark '+s+'>'+nick+'</mark><span>'+msg+'</span></p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
window.handleFactionChat = function(data, textStatus, jqXHR) {
|
|
||||||
var appMsg = '';
|
|
||||||
var first = null;
|
|
||||||
var last;
|
|
||||||
$.each(data.result.reverse(), function(ind, chat) {
|
|
||||||
var time = chat[1];
|
|
||||||
var msg = chat[2].plext.markup[2][1].plain;
|
|
||||||
var team = chat[2].plext.team === 'ALIENS' ? TEAM_ENL : TEAM_RES;
|
|
||||||
var nick = chat[2].plext.markup[1][1].plain.slice(0, -2); // cut “: ” at end
|
|
||||||
var guid = chat[2].plext.markup[1][1].guid;
|
|
||||||
window.setPlayerName(guid, nick); // free nick name resolves
|
|
||||||
|
|
||||||
if(!first) first = time;
|
|
||||||
last = time;
|
|
||||||
appMsg += renderChatMsg(msg, nick, time, team);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#chatfaction').html(appMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.toggleChat = function() {
|
|
||||||
var c = $('#chat');
|
|
||||||
var cc = $('#chatcontrols');
|
|
||||||
if(c.data('toggle')) {
|
|
||||||
$('#chatcontrols a:first').text('expand');
|
|
||||||
c.css('height', CHAT_SHRINKED+'px');
|
|
||||||
c.css('top', 'auto');
|
|
||||||
c.data('toggle', false);
|
|
||||||
cc.css('top', 'auto');
|
|
||||||
cc.css('bottom', (CHAT_SHRINKED+4)+'px');
|
|
||||||
} else {
|
|
||||||
$('#chatcontrols a:first').text('shrink');
|
|
||||||
c.css('height', 'auto');
|
|
||||||
c.css('top', '25px');
|
|
||||||
c.data('toggle', true);
|
|
||||||
cc.css('top', '0');
|
|
||||||
cc.css('bottom', 'auto');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
window.setupChat = function() {
|
|
||||||
$('#chatcontrols a').first().click(window.toggleChat);
|
|
||||||
requestFactionChat();
|
|
||||||
}
|
|
||||||
|
12
code/idle.js
12
code/idle.js
@ -7,7 +7,9 @@ var idleReset = function (e) {
|
|||||||
// update immediately when the user comes back
|
// update immediately when the user comes back
|
||||||
if(isIdle()) {
|
if(isIdle()) {
|
||||||
window.idleTime = 0;
|
window.idleTime = 0;
|
||||||
window.requestData();
|
$.each(window._onResumeFunctions, function(ind, f) {
|
||||||
|
f();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
window.idleTime = 0;
|
window.idleTime = 0;
|
||||||
};
|
};
|
||||||
@ -16,3 +18,11 @@ $('body').mousemove(idleReset).keypress(idleReset);
|
|||||||
window.isIdle = function() {
|
window.isIdle = function() {
|
||||||
return window.idleTime >= MAX_IDLE_TIME;
|
return window.idleTime >= MAX_IDLE_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window._onResumeFunctions = [];
|
||||||
|
|
||||||
|
// add your function here if you want to be notified when the user
|
||||||
|
// resumes from being idle
|
||||||
|
window.addResumeFunction = function(f) {
|
||||||
|
window._onResumeFunctions.push(f);
|
||||||
|
}
|
||||||
|
@ -5,36 +5,9 @@
|
|||||||
// action.
|
// action.
|
||||||
|
|
||||||
|
|
||||||
// sets the timer for the next auto refresh. Ensures only one timeout
|
|
||||||
// is queued. May be given 'override' in milliseconds if time should
|
|
||||||
// not be guessed automatically. Especially useful if a little delay
|
|
||||||
// is required, for example when zooming.
|
|
||||||
window.startRefreshTimeout = function(override) {
|
|
||||||
// may be required to remove 'paused during interaction' message in
|
|
||||||
// status bar
|
|
||||||
window.renderUpdateStatus();
|
|
||||||
if(refreshTimeout) clearTimeout(refreshTimeout);
|
|
||||||
if(override) {
|
|
||||||
console.log('refreshing in ' + override + 'ms');
|
|
||||||
refreshTimeout = setTimeout(window.requestData, override);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var t = REFRESH*1000;
|
|
||||||
var adj = ZOOM_LEVEL_ADJ * (18 - window.map.getZoom());
|
|
||||||
if(adj > 0) t += adj*1000;
|
|
||||||
console.log("next auto refresh in " + t/1000 + " seconds.");
|
|
||||||
refreshTimeout = setTimeout(window.requestData, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// requests map data for current viewport. For details on how this
|
// requests map data for current viewport. For details on how this
|
||||||
// works, refer to the description in “MAP DATA REQUEST CALCULATORS”
|
// works, refer to the description in “MAP DATA REQUEST CALCULATORS”
|
||||||
window.requestData = function() {
|
window.requestData = function() {
|
||||||
if(window.idleTime >= MAX_IDLE_TIME) {
|
|
||||||
console.log('user has been idle for ' + idleTime + ' minutes. Skipping refresh.');
|
|
||||||
renderUpdateStatus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('refreshing data');
|
console.log('refreshing data');
|
||||||
requests.abort();
|
requests.abort();
|
||||||
cleanUp();
|
cleanUp();
|
||||||
@ -81,7 +54,6 @@ window.requestData = function() {
|
|||||||
// works on map data response and ensures entities are drawn/updated.
|
// works on map data response and ensures entities are drawn/updated.
|
||||||
window.handleDataResponse = function(data, textStatus, jqXHR) {
|
window.handleDataResponse = function(data, textStatus, jqXHR) {
|
||||||
// remove from active ajax queries list
|
// remove from active ajax queries list
|
||||||
window.requests.remove(jqXHR);
|
|
||||||
if(!data || !data.result) {
|
if(!data || !data.result) {
|
||||||
console.warn(data);
|
console.warn(data);
|
||||||
return;
|
return;
|
||||||
@ -158,7 +130,12 @@ window.cleanUp = function() {
|
|||||||
// removes given entity from map
|
// removes given entity from map
|
||||||
window.removeByGuid = function(guid) {
|
window.removeByGuid = function(guid) {
|
||||||
// portals end in “.11” or “.12“, links in “.9", fields in “.b”
|
// portals end in “.11” or “.12“, links in “.9", fields in “.b”
|
||||||
// .c == player/creator
|
// .11 == portals
|
||||||
|
// .12 == portals
|
||||||
|
// .9 == links
|
||||||
|
// .b == fields
|
||||||
|
// .c == player/creator
|
||||||
|
// .d == chat messages
|
||||||
switch(guid.slice(33)) {
|
switch(guid.slice(33)) {
|
||||||
case '11':
|
case '11':
|
||||||
case '12':
|
case '12':
|
||||||
@ -240,7 +217,7 @@ window.renderLink = function(ent) {
|
|||||||
|
|
||||||
poly.on('remove', function() { delete window.links[this.options.guid]; });
|
poly.on('remove', function() { delete window.links[this.options.guid]; });
|
||||||
poly.on('add', function() { window.links[this.options.guid] = this; });
|
poly.on('add', function() { window.links[this.options.guid] = this; });
|
||||||
poly.addTo(linksLayer);
|
poly.addTo(linksLayer).bringToBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
// renders a field on the map from a given entity
|
// renders a field on the map from a given entity
|
||||||
@ -264,5 +241,5 @@ window.renderField = function(ent) {
|
|||||||
|
|
||||||
poly.on('remove', function() { delete window.fields[this.options.guid]; });
|
poly.on('remove', function() { delete window.fields[this.options.guid]; });
|
||||||
poly.on('add', function() { window.fields[this.options.guid] = this; });
|
poly.on('add', function() { window.fields[this.options.guid] = this; });
|
||||||
poly.addTo(fieldsLayer);
|
poly.addTo(fieldsLayer).bringToBack();
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ window.requests.abort = function() {
|
|||||||
window.activeRequests = [];
|
window.activeRequests = [];
|
||||||
window.failedRequestCount = 0;
|
window.failedRequestCount = 0;
|
||||||
|
|
||||||
startRefreshTimeout();
|
|
||||||
renderUpdateStatus();
|
renderUpdateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,3 +55,49 @@ window.renderUpdateStatus = function() {
|
|||||||
|
|
||||||
$('#updatestatus').html(t);
|
$('#updatestatus').html(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// sets the timer for the next auto refresh. Ensures only one timeout
|
||||||
|
// is queued. May be given 'override' in milliseconds if time should
|
||||||
|
// not be guessed automatically. Especially useful if a little delay
|
||||||
|
// is required, for example when zooming.
|
||||||
|
window.startRefreshTimeout = function(override) {
|
||||||
|
// may be required to remove 'paused during interaction' message in
|
||||||
|
// status bar
|
||||||
|
window.renderUpdateStatus();
|
||||||
|
if(refreshTimeout) clearTimeout(refreshTimeout);
|
||||||
|
var t = 0;
|
||||||
|
if(override) {
|
||||||
|
t = override;
|
||||||
|
} else {
|
||||||
|
t = REFRESH*1000;
|
||||||
|
var adj = ZOOM_LEVEL_ADJ * (18 - window.map.getZoom());
|
||||||
|
if(adj > 0) t += adj*1000;
|
||||||
|
}
|
||||||
|
var next = new Date(new Date().getTime() + t).toLocaleTimeString();
|
||||||
|
console.log('planned refresh: ' + next);
|
||||||
|
refreshTimeout = setTimeout(window.requests._callOnRefreshFunctions, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requests._onRefreshFunctions = [];
|
||||||
|
window.requests._callOnRefreshFunctions = function() {
|
||||||
|
startRefreshTimeout();
|
||||||
|
|
||||||
|
if(isIdle()) {
|
||||||
|
console.log('user has been idle for ' + idleTime + ' minutes. Skipping refresh.');
|
||||||
|
renderUpdateStatus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('refreshing');
|
||||||
|
|
||||||
|
$.each(window.requests._onRefreshFunctions, function(ind, f) {
|
||||||
|
f();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// add method here to be notified of auto-refreshes
|
||||||
|
window.requests.addRefreshFunction = function(f) {
|
||||||
|
window.requests._onRefreshFunctions.push(f);
|
||||||
|
}
|
||||||
|
@ -48,13 +48,14 @@ window.digits = function(d) {
|
|||||||
// error: see above. Additionally it is logged if the request failed.
|
// error: see above. Additionally it is logged if the request failed.
|
||||||
window.postAjax = function(action, data, success, error) {
|
window.postAjax = function(action, data, success, error) {
|
||||||
data = JSON.stringify($.extend({method: 'dashboard.'+action}, data));
|
data = JSON.stringify($.extend({method: 'dashboard.'+action}, data));
|
||||||
|
var remove = function(data, textStatus, jqXHR) { window.requests.remove(jqXHR); };
|
||||||
var errCnt = function(jqXHR) { window.failedRequestCount++; window.requests.remove(jqXHR); };
|
var errCnt = function(jqXHR) { window.failedRequestCount++; window.requests.remove(jqXHR); };
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
url: 'rpc/dashboard.'+action,
|
url: 'rpc/dashboard.'+action,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: data,
|
data: data,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: success,
|
success: [remove, success],
|
||||||
error: error ? [errCnt, error] : errCnt,
|
error: error ? [errCnt, error] : errCnt,
|
||||||
contentType: 'application/json; charset=utf-8',
|
contentType: 'application/json; charset=utf-8',
|
||||||
beforeSend: function(req) {
|
beforeSend: function(req) {
|
||||||
@ -110,3 +111,11 @@ window.getPaddedBounds = function() {
|
|||||||
window._storedPaddedBounds = p;
|
window._storedPaddedBounds = p;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns number of pixels left to scroll down before reaching the
|
||||||
|
// bottom. Works similar to the native scrollTop function.
|
||||||
|
window.scrollBottom = function(elm) {
|
||||||
|
if(typeof elm === 'string') elm = $(elm);
|
||||||
|
return elm.get(0).scrollHeight - elm.innerHeight() - elm.scrollTop();
|
||||||
|
}
|
||||||
|
13
json_examples/chat_send_message.js
Normal file
13
json_examples/chat_send_message.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// http://www.ingress.com/rpc/dashboard.sendPlext
|
||||||
|
|
||||||
|
// posting:
|
||||||
|
{"message":"x","latE6":73689520,"lngE6":95322756,"factionOnly":true,"method":"dashboard.sendPlext"}
|
||||||
|
|
||||||
|
{"message":"x","latE6":73689520,"lngE6":95322756,"method":"dashboard.sendPlext"}
|
||||||
|
|
||||||
|
|
||||||
|
// faction response:
|
||||||
|
{"gameBasket": {"deletedEntityGuids": [], "gameEntities": [], "inventory": []}, "result": "c709d0aa51664510a43c635d5df919cf.d"}
|
||||||
|
|
||||||
|
// public response:
|
||||||
|
{"gameBasket": {"deletedEntityGuids": [], "gameEntities": [], "inventory": []}, "result": "1b113466f403499191eae568915b7cc9.d"}
|
5
main.js
5
main.js
@ -46,14 +46,15 @@ document.getElementsByTagName('head')[0].innerHTML = ''
|
|||||||
|
|
||||||
document.getElementsByTagName('body')[0].innerHTML = ''
|
document.getElementsByTagName('body')[0].innerHTML = ''
|
||||||
+ '<div id="map">Loading, please wait</div>'
|
+ '<div id="map">Loading, please wait</div>'
|
||||||
+ '<div id="chatcontrols">'
|
+ '<div id="chatcontrols" style="display:none">'
|
||||||
+ ' <a>expand</a><a>automated</a><a>public</a><a class="active">faction</a>'
|
+ ' <a>expand</a><a>automated</a><a>public</a><a class="active">faction</a>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
+ '<div id="chat">'
|
+ '<div id="chat" style="display:none">'
|
||||||
+ ' <div id="chatfaction"></div>'
|
+ ' <div id="chatfaction"></div>'
|
||||||
+ ' <div id="chatpublic"></div>'
|
+ ' <div id="chatpublic"></div>'
|
||||||
+ ' <div id="chatbot"></div>'
|
+ ' <div id="chatbot"></div>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
|
+ '<form id="chatinput" style="display:none"><time></time><span>tell faction:</span><input type="text"/></form>'
|
||||||
+ '<div id="sidebar" style="display: none">'
|
+ '<div id="sidebar" style="display: none">'
|
||||||
+ ' <div id="playerstat">t</div>'
|
+ ' <div id="playerstat">t</div>'
|
||||||
+ ' <div id="gamestat"> loading global control stats</div>'
|
+ ' <div id="gamestat"> loading global control stats</div>'
|
||||||
|
11
style.css
11
style.css
@ -155,6 +155,17 @@ mark {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
color: #bbb;
|
||||||
|
display: inline-block;
|
||||||
|
font-family: Verdana,sans-serif;
|
||||||
|
height: 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 2px;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 683px;
|
||||||
|
}
|
||||||
|
|
||||||
#chat span {
|
#chat span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 546px;
|
width: 546px;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @id ingress-intel-total-conversion@breunigs
|
// @id ingress-intel-total-conversion@breunigs
|
||||||
// @name intel map total conversion
|
// @name intel map total conversion
|
||||||
// @version 0.1-2013-02-02-003549
|
// @version 0.1-2013-02-03-131520
|
||||||
// @namespace https://github.com/breunigs/ingress-intel-total-conversion
|
// @namespace https://github.com/breunigs/ingress-intel-total-conversion
|
||||||
// @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/total-conversion-build.user.js
|
// @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/total-conversion-build.user.js
|
||||||
// @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/total-conversion-build.user.js
|
// @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/total-conversion-build.user.js
|
||||||
@ -46,14 +46,15 @@ document.getElementsByTagName('head')[0].innerHTML = ''
|
|||||||
|
|
||||||
document.getElementsByTagName('body')[0].innerHTML = ''
|
document.getElementsByTagName('body')[0].innerHTML = ''
|
||||||
+ '<div id="map">Loading, please wait</div>'
|
+ '<div id="map">Loading, please wait</div>'
|
||||||
+ '<div id="chatcontrols">'
|
+ '<div id="chatcontrols" style="display:none">'
|
||||||
+ ' <a>expand</a><a>automated</a><a>public</a><a class="active">faction</a>'
|
+ ' <a>expand</a><a>automated</a><a>public</a><a class="active">faction</a>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
+ '<div id="chat">'
|
+ '<div id="chat" style="display:none">'
|
||||||
+ ' <div id="chatfaction"></div>'
|
+ ' <div id="chatfaction"></div>'
|
||||||
+ ' <div id="chatpublic"></div>'
|
+ ' <div id="chatpublic"></div>'
|
||||||
+ ' <div id="chatbot"></div>'
|
+ ' <div id="chatbot"></div>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
|
+ '<form id="chatinput" style="display:none"><time></time><span>tell faction:</span><input type="text"/></form>'
|
||||||
+ '<div id="sidebar" style="display: none">'
|
+ '<div id="sidebar" style="display: none">'
|
||||||
+ ' <div id="playerstat">t</div>'
|
+ ' <div id="playerstat">t</div>'
|
||||||
+ ' <div id="gamestat"> loading global control stats</div>'
|
+ ' <div id="gamestat"> loading global control stats</div>'
|
||||||
@ -150,36 +151,9 @@ window.fields = {};
|
|||||||
// action.
|
// action.
|
||||||
|
|
||||||
|
|
||||||
// sets the timer for the next auto refresh. Ensures only one timeout
|
|
||||||
// is queued. May be given 'override' in milliseconds if time should
|
|
||||||
// not be guessed automatically. Especially useful if a little delay
|
|
||||||
// is required, for example when zooming.
|
|
||||||
window.startRefreshTimeout = function(override) {
|
|
||||||
// may be required to remove 'paused during interaction' message in
|
|
||||||
// status bar
|
|
||||||
window.renderUpdateStatus();
|
|
||||||
if(refreshTimeout) clearTimeout(refreshTimeout);
|
|
||||||
if(override) {
|
|
||||||
console.log('refreshing in ' + override + 'ms');
|
|
||||||
refreshTimeout = setTimeout(window.requestData, override);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var t = REFRESH*1000;
|
|
||||||
var adj = ZOOM_LEVEL_ADJ * (18 - window.map.getZoom());
|
|
||||||
if(adj > 0) t += adj*1000;
|
|
||||||
console.log("next auto refresh in " + t/1000 + " seconds.");
|
|
||||||
refreshTimeout = setTimeout(window.requestData, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// requests map data for current viewport. For details on how this
|
// requests map data for current viewport. For details on how this
|
||||||
// works, refer to the description in “MAP DATA REQUEST CALCULATORS”
|
// works, refer to the description in “MAP DATA REQUEST CALCULATORS”
|
||||||
window.requestData = function() {
|
window.requestData = function() {
|
||||||
if(window.idleTime >= MAX_IDLE_TIME) {
|
|
||||||
console.log('user has been idle for ' + idleTime + ' minutes. Skipping refresh.');
|
|
||||||
renderUpdateStatus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('refreshing data');
|
console.log('refreshing data');
|
||||||
requests.abort();
|
requests.abort();
|
||||||
cleanUp();
|
cleanUp();
|
||||||
@ -226,7 +200,6 @@ window.requestData = function() {
|
|||||||
// works on map data response and ensures entities are drawn/updated.
|
// works on map data response and ensures entities are drawn/updated.
|
||||||
window.handleDataResponse = function(data, textStatus, jqXHR) {
|
window.handleDataResponse = function(data, textStatus, jqXHR) {
|
||||||
// remove from active ajax queries list
|
// remove from active ajax queries list
|
||||||
window.requests.remove(jqXHR);
|
|
||||||
if(!data || !data.result) {
|
if(!data || !data.result) {
|
||||||
console.warn(data);
|
console.warn(data);
|
||||||
return;
|
return;
|
||||||
@ -303,7 +276,12 @@ window.cleanUp = function() {
|
|||||||
// removes given entity from map
|
// removes given entity from map
|
||||||
window.removeByGuid = function(guid) {
|
window.removeByGuid = function(guid) {
|
||||||
// portals end in “.11” or “.12“, links in “.9", fields in “.b”
|
// portals end in “.11” or “.12“, links in “.9", fields in “.b”
|
||||||
// .c == player/creator
|
// .11 == portals
|
||||||
|
// .12 == portals
|
||||||
|
// .9 == links
|
||||||
|
// .b == fields
|
||||||
|
// .c == player/creator
|
||||||
|
// .d == chat messages
|
||||||
switch(guid.slice(33)) {
|
switch(guid.slice(33)) {
|
||||||
case '11':
|
case '11':
|
||||||
case '12':
|
case '12':
|
||||||
@ -385,7 +363,7 @@ window.renderLink = function(ent) {
|
|||||||
|
|
||||||
poly.on('remove', function() { delete window.links[this.options.guid]; });
|
poly.on('remove', function() { delete window.links[this.options.guid]; });
|
||||||
poly.on('add', function() { window.links[this.options.guid] = this; });
|
poly.on('add', function() { window.links[this.options.guid] = this; });
|
||||||
poly.addTo(linksLayer);
|
poly.addTo(linksLayer).bringToBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
// renders a field on the map from a given entity
|
// renders a field on the map from a given entity
|
||||||
@ -409,7 +387,7 @@ window.renderField = function(ent) {
|
|||||||
|
|
||||||
poly.on('remove', function() { delete window.fields[this.options.guid]; });
|
poly.on('remove', function() { delete window.fields[this.options.guid]; });
|
||||||
poly.on('add', function() { window.fields[this.options.guid] = this; });
|
poly.on('add', function() { window.fields[this.options.guid] = this; });
|
||||||
poly.addTo(fieldsLayer);
|
poly.addTo(fieldsLayer).bringToBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -440,7 +418,6 @@ window.requests.abort = function() {
|
|||||||
window.activeRequests = [];
|
window.activeRequests = [];
|
||||||
window.failedRequestCount = 0;
|
window.failedRequestCount = 0;
|
||||||
|
|
||||||
startRefreshTimeout();
|
|
||||||
renderUpdateStatus();
|
renderUpdateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,6 +450,52 @@ window.renderUpdateStatus = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// sets the timer for the next auto refresh. Ensures only one timeout
|
||||||
|
// is queued. May be given 'override' in milliseconds if time should
|
||||||
|
// not be guessed automatically. Especially useful if a little delay
|
||||||
|
// is required, for example when zooming.
|
||||||
|
window.startRefreshTimeout = function(override) {
|
||||||
|
// may be required to remove 'paused during interaction' message in
|
||||||
|
// status bar
|
||||||
|
window.renderUpdateStatus();
|
||||||
|
if(refreshTimeout) clearTimeout(refreshTimeout);
|
||||||
|
var t = 0;
|
||||||
|
if(override) {
|
||||||
|
t = override;
|
||||||
|
} else {
|
||||||
|
t = REFRESH*1000;
|
||||||
|
var adj = ZOOM_LEVEL_ADJ * (18 - window.map.getZoom());
|
||||||
|
if(adj > 0) t += adj*1000;
|
||||||
|
}
|
||||||
|
var next = new Date(new Date().getTime() + t).toLocaleTimeString();
|
||||||
|
console.log('planned refresh: ' + next);
|
||||||
|
refreshTimeout = setTimeout(window.requests._callOnRefreshFunctions, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requests._onRefreshFunctions = [];
|
||||||
|
window.requests._callOnRefreshFunctions = function() {
|
||||||
|
startRefreshTimeout();
|
||||||
|
|
||||||
|
if(isIdle()) {
|
||||||
|
console.log('user has been idle for ' + idleTime + ' minutes. Skipping refresh.');
|
||||||
|
renderUpdateStatus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('refreshing');
|
||||||
|
|
||||||
|
$.each(window.requests._onRefreshFunctions, function(ind, f) {
|
||||||
|
f();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// add method here to be notified of auto-refreshes
|
||||||
|
window.requests.addRefreshFunction = function(f) {
|
||||||
|
window.requests._onRefreshFunctions.push(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// UTILS + MISC ///////////////////////////////////////////////////////
|
// UTILS + MISC ///////////////////////////////////////////////////////
|
||||||
@ -523,13 +546,14 @@ window.digits = function(d) {
|
|||||||
// error: see above. Additionally it is logged if the request failed.
|
// error: see above. Additionally it is logged if the request failed.
|
||||||
window.postAjax = function(action, data, success, error) {
|
window.postAjax = function(action, data, success, error) {
|
||||||
data = JSON.stringify($.extend({method: 'dashboard.'+action}, data));
|
data = JSON.stringify($.extend({method: 'dashboard.'+action}, data));
|
||||||
|
var remove = function(data, textStatus, jqXHR) { window.requests.remove(jqXHR); };
|
||||||
var errCnt = function(jqXHR) { window.failedRequestCount++; window.requests.remove(jqXHR); };
|
var errCnt = function(jqXHR) { window.failedRequestCount++; window.requests.remove(jqXHR); };
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
url: 'rpc/dashboard.'+action,
|
url: 'rpc/dashboard.'+action,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: data,
|
data: data,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: success,
|
success: [remove, success],
|
||||||
error: error ? [errCnt, error] : errCnt,
|
error: error ? [errCnt, error] : errCnt,
|
||||||
contentType: 'application/json; charset=utf-8',
|
contentType: 'application/json; charset=utf-8',
|
||||||
beforeSend: function(req) {
|
beforeSend: function(req) {
|
||||||
@ -587,6 +611,14 @@ window.getPaddedBounds = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns number of pixels left to scroll down before reaching the
|
||||||
|
// bottom. Works similar to the native scrollTop function.
|
||||||
|
window.scrollBottom = function(elm) {
|
||||||
|
if(typeof elm === 'string') elm = $(elm);
|
||||||
|
return elm.get(0).scrollHeight - elm.innerHeight() - elm.scrollTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// SETUP /////////////////////////////////////////////////////////////
|
// SETUP /////////////////////////////////////////////////////////////
|
||||||
@ -613,12 +645,13 @@ window.setupLargeImagePreview = function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window.setupStyles = function() {
|
window.setupStyles = function() {
|
||||||
$('head').append('<style>' +
|
$('head').append('<style>' +
|
||||||
[ '#largepreview.res img { border:2px solid '+COLORS[TEAM_RES]+'; } ',
|
[ '#largepreview.res img { border:2px solid '+COLORS[TEAM_RES]+'; } ',
|
||||||
'#largepreview.enl img { border:2px solid '+COLORS[TEAM_ENL]+'; } ',
|
'#largepreview.enl img { border:2px solid '+COLORS[TEAM_ENL]+'; } ',
|
||||||
'#largepreview.none img { border:2px solid '+COLORS[TEAM_NONE]+'; } ',
|
'#largepreview.none img { border:2px solid '+COLORS[TEAM_NONE]+'; } ',
|
||||||
'#chatcontrols { bottom: '+(CHAT_SHRINKED+4)+'px; }',
|
'#chatcontrols { bottom: '+(CHAT_SHRINKED+24)+'px; }',
|
||||||
'#chat { height: '+CHAT_SHRINKED+'px; } ',
|
'#chat { height: '+CHAT_SHRINKED+'px; } ',
|
||||||
'#updatestatus { width:'+(SIDEBAR_WIDTH-2*4)+'px; } ',
|
'#updatestatus { width:'+(SIDEBAR_WIDTH-2*4)+'px; } ',
|
||||||
'#sidebar, #gamestat, #gamestat span, input, ',
|
'#sidebar, #gamestat, #gamestat span, input, ',
|
||||||
@ -671,21 +704,19 @@ window.setupMap = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// map update status handling
|
// map update status handling
|
||||||
map.on('zoomstart', function() { window.mapRunsUserAction = true });
|
map.on('movestart zoomstart', function() { window.mapRunsUserAction = true });
|
||||||
map.on('movestart', function() { window.mapRunsUserAction = true });
|
map.on('moveend zoomend', function() { window.mapRunsUserAction = false });
|
||||||
map.on('zoomend', function() { window.mapRunsUserAction = false });
|
|
||||||
map.on('moveend', function() { window.mapRunsUserAction = false });
|
|
||||||
|
|
||||||
|
|
||||||
// update map hooks
|
// update map hooks
|
||||||
map.on('zoomstart', window.requests.abort);
|
map.on('movestart zoomstart', window.requests.abort);
|
||||||
map.on('zoomend', function() { window.startRefreshTimeout(500) });
|
map.on('moveend zoomend', function() { window.startRefreshTimeout(500) });
|
||||||
map.on('movestart', window.requests.abort );
|
|
||||||
map.on('moveend', function() { window.startRefreshTimeout(500) });
|
|
||||||
|
|
||||||
// run once on init
|
// run once on init
|
||||||
window.requestData();
|
window.requestData();
|
||||||
window.startRefreshTimeout();
|
window.startRefreshTimeout();
|
||||||
|
|
||||||
|
window.addResumeFunction(window.requestData);
|
||||||
|
window.requests.addRefreshFunction(window.requestData);
|
||||||
};
|
};
|
||||||
|
|
||||||
// renders player details into the website. Since the player info is
|
// renders player details into the website. Since the player info is
|
||||||
@ -740,7 +771,7 @@ function boot() {
|
|||||||
window.setupLargeImagePreview();
|
window.setupLargeImagePreview();
|
||||||
window.updateGameScore();
|
window.updateGameScore();
|
||||||
window.setupPlayerStat();
|
window.setupPlayerStat();
|
||||||
window.setupChat();
|
window.chat.setup();
|
||||||
// read here ONCE, so the URL is only evaluated one time after the
|
// read here ONCE, so the URL is only evaluated one time after the
|
||||||
// necessary data has been loaded.
|
// necessary data has been loaded.
|
||||||
urlPortal = getURLParam('pguid');
|
urlPortal = getURLParam('pguid');
|
||||||
@ -765,9 +796,9 @@ var LEAFLET = 'http://cdn.leafletjs.com/leaflet-0.5/leaflet.js';
|
|||||||
load(JQUERY, LEAFLET).then(LLGMAPS).thenRun(boot);
|
load(JQUERY, LEAFLET).then(LLGMAPS).thenRun(boot);
|
||||||
|
|
||||||
|
|
||||||
window.chat = function() {}
|
window.chat = function() {};
|
||||||
|
|
||||||
window.getOldestTimestampChat = function(public) {
|
window.chat.getOldestTimestamp = function(public) {
|
||||||
if(public) {
|
if(public) {
|
||||||
var a = $('#chatpublic time:first').data('timestamp');
|
var a = $('#chatpublic time:first').data('timestamp');
|
||||||
var b = $('#chatbot time:first').data('timestamp');
|
var b = $('#chatbot time:first').data('timestamp');
|
||||||
@ -778,7 +809,7 @@ window.getOldestTimestampChat = function(public) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.getNewestTimestampChat = function(public) {
|
window.chat.getNewestTimestamp = function(public) {
|
||||||
if(public) {
|
if(public) {
|
||||||
var a = $('#chatpublic time:last').data('timestamp');
|
var a = $('#chatpublic time:last').data('timestamp');
|
||||||
var b = $('#chatbot time:last').data('timestamp');
|
var b = $('#chatbot time:last').data('timestamp');
|
||||||
@ -789,7 +820,7 @@ window.getNewestTimestampChat = function(public) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.getPostDataForChat = function(public, getOlderMsgs) {
|
window.chat.genPostData = function(public, getOlderMsgs) {
|
||||||
if(typeof public !== 'boolean') throw('Need to know if public or faction chat.');
|
if(typeof public !== 'boolean') throw('Need to know if public or faction chat.');
|
||||||
|
|
||||||
var b = map.getBounds();
|
var b = map.getBounds();
|
||||||
@ -809,26 +840,210 @@ window.getPostDataForChat = function(public, getOlderMsgs) {
|
|||||||
|
|
||||||
if(getOlderMsgs) {
|
if(getOlderMsgs) {
|
||||||
// ask for older chat when scrolling up
|
// ask for older chat when scrolling up
|
||||||
data = $.extend(data, {maxTimestampMs: getOldestTimestampChat(public)});
|
data = $.extend(data, {maxTimestampMs: chat.getOldestTimestamp(public)});
|
||||||
} else {
|
} else {
|
||||||
// ask for newer chat
|
// ask for newer chat
|
||||||
$.extend(data, {minTimestampMs: getNewestTimestampChat(public)});
|
var min = chat.getNewestTimestamp(public);
|
||||||
|
// the inital request will have both timestamp values set to -1,
|
||||||
|
// thus we receive the newest desiredNumItems. After that, we will
|
||||||
|
// only receive messages with a timestamp greater or equal to min
|
||||||
|
// above.
|
||||||
|
// After resuming from idle, there might be more new messages than
|
||||||
|
// desiredNumItems. So on the first request, we are not really up to
|
||||||
|
// date. We will eventually catch up, as long as there are less new
|
||||||
|
// messages than desiredNumItems per each refresh cycle.
|
||||||
|
// A proper solution would be to query until no more new results are
|
||||||
|
// returned. Another way would be to set desiredNumItems to a very
|
||||||
|
// large number so we really get all new messages since the last
|
||||||
|
// request. Setting desiredNumItems to -1 does unfortunately not
|
||||||
|
// work.
|
||||||
|
// Currently this edge case is not handled. Let’s see if this is a
|
||||||
|
// problem in crowded areas.
|
||||||
|
$.extend(data, {minTimestampMs: min});
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.requestFactionChat = function(getOlderMsgs) {
|
//
|
||||||
if(window.idleTime >= MAX_IDLE_TIME) {
|
// requesting faction
|
||||||
console.log('user has been idle for ' + idleTime + ' minutes. Skipping faction chat.');
|
//
|
||||||
renderUpdateStatus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = getPostDataForChat(false, false);
|
window.chat._requestOldFactionRunning = false;
|
||||||
window.requests.add(window.postAjax('getPaginatedPlextsV2', data, window.handleFactionChat));
|
window.chat.requestOldFaction = function(isRetry) {
|
||||||
|
if(chat._requestOldFactionRunning) return;
|
||||||
|
if(isIdle()) return renderUpdateStatus();
|
||||||
|
chat._requestOldFactionRunning = true;
|
||||||
|
|
||||||
|
var d = chat.genPostData(false, true);
|
||||||
|
var r = window.postAjax(
|
||||||
|
'getPaginatedPlextsV2',
|
||||||
|
d,
|
||||||
|
chat.handleOldFaction,
|
||||||
|
isRetry
|
||||||
|
? function() { window.chat._requestOldFactionRunning = false; }
|
||||||
|
: function() { window.chat.requestOldFaction(true) }
|
||||||
|
);
|
||||||
|
|
||||||
|
requests.add(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.renderChatMsg = function(msg, nick, time, team) {
|
window.chat._requestNewFactionRunning = false;
|
||||||
|
window.chat.requestNewFaction = function(isRetry) {
|
||||||
|
if(chat._requestNewFactionRunning) return;
|
||||||
|
if(window.isIdle()) return renderUpdateStatus();
|
||||||
|
chat._requestNewFactionRunning = true;
|
||||||
|
|
||||||
|
var d = chat.genPostData(false, false);
|
||||||
|
var r = window.postAjax(
|
||||||
|
'getPaginatedPlextsV2',
|
||||||
|
d,
|
||||||
|
chat.handleNewFaction,
|
||||||
|
isRetry
|
||||||
|
? function() { window.chat._requestNewFactionRunning = false; }
|
||||||
|
: function() { window.chat.requestNewFaction(true) }
|
||||||
|
);
|
||||||
|
|
||||||
|
requests.add(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// handle faction
|
||||||
|
//
|
||||||
|
|
||||||
|
window.chat.handleOldFaction = function(data, textStatus, jqXHR) {
|
||||||
|
chat._requestOldFactionRunning = false;
|
||||||
|
chat.handleFaction(data, textStatus, jqXHR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.chat.handleNewFaction = function(data, textStatus, jqXHR) {
|
||||||
|
chat._requestNewFactionRunning = false;
|
||||||
|
chat.handleFaction(data, textStatus, jqXHR, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.chat._displayedFactionGuids = [];
|
||||||
|
window.chat.handleFaction = function(data, textStatus, jqXHR, isOldMsgs) {
|
||||||
|
if(!data || !data.result) return console.warn('Couldn’t get chat data. Pausing chat for now.');
|
||||||
|
|
||||||
|
var msgs = '';
|
||||||
|
var prevTime = null;
|
||||||
|
$.each(data.result.reverse(), function(ind, json) {
|
||||||
|
// 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 += '<summary>'+nowTime+'</summary>';
|
||||||
|
|
||||||
|
msgs += chat.renderMsg(msg, nick, time, team);
|
||||||
|
|
||||||
|
|
||||||
|
prevTime = nowTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
var c = $('#chatfaction');
|
||||||
|
var scrollBefore = scrollBottom(c);
|
||||||
|
if(isOldMsgs)
|
||||||
|
c.prepend(msgs);
|
||||||
|
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.needMoreMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.chat.toggle = function() {
|
||||||
|
var c = $('#chat, #chatcontrols');
|
||||||
|
if(c.hasClass('expand')) {
|
||||||
|
$('#chatcontrols a:first').text('expand');
|
||||||
|
c.removeClass('expand');
|
||||||
|
} else {
|
||||||
|
$('#chatcontrols a:first').text('shrink');
|
||||||
|
c.addClass('expand');
|
||||||
|
chat.needMoreMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
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'))
|
||||||
|
chat.requestOldFaction();
|
||||||
|
else
|
||||||
|
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.setup = function() {
|
||||||
|
$('#chatcontrols, #chat, #chatinput').show();
|
||||||
|
|
||||||
|
$('#chatcontrols a:first').click(window.chat.toggle);
|
||||||
|
$('#chatinput').click(function() {
|
||||||
|
$('#chatinput input').focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.chat.setupTime();
|
||||||
|
|
||||||
|
$('#chatfaction').scroll(function() {
|
||||||
|
var t = $(this);
|
||||||
|
if(t.data('ignoreNextScroll')) return t.data('ignoreNextScroll', false);
|
||||||
|
if(t.scrollTop() < 200) chat.requestOldFaction();
|
||||||
|
if(scrollBottom(t) === 0) chat.requestNewFaction();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#chatpublic, #chatbot').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();
|
||||||
|
window.addResumeFunction(chat.request);
|
||||||
|
window.requests.addRefreshFunction(chat.request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
window.chat.renderMsg = function(msg, nick, time, team) {
|
||||||
var ta = unixTimeToHHmm(time);
|
var ta = unixTimeToHHmm(time);
|
||||||
var tb = unixTimeToString(time, true);
|
var tb = unixTimeToString(time, true);
|
||||||
var t = '<time title="'+tb+'" data-timestamp="'+time+'">'+ta+'</time>';
|
var t = '<time title="'+tb+'" data-timestamp="'+time+'">'+ta+'</time>';
|
||||||
@ -836,52 +1051,6 @@ window.renderChatMsg = function(msg, nick, time, team) {
|
|||||||
return '<p>'+t+'<mark '+s+'>'+nick+'</mark><span>'+msg+'</span></p>';
|
return '<p>'+t+'<mark '+s+'>'+nick+'</mark><span>'+msg+'</span></p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
window.handleFactionChat = function(data, textStatus, jqXHR) {
|
|
||||||
var appMsg = '';
|
|
||||||
var first = null;
|
|
||||||
var last;
|
|
||||||
$.each(data.result.reverse(), function(ind, chat) {
|
|
||||||
var time = chat[1];
|
|
||||||
var msg = chat[2].plext.markup[2][1].plain;
|
|
||||||
var team = chat[2].plext.team === 'ALIENS' ? TEAM_ENL : TEAM_RES;
|
|
||||||
var nick = chat[2].plext.markup[1][1].plain.slice(0, -2); // cut “: ” at end
|
|
||||||
var guid = chat[2].plext.markup[1][1].guid;
|
|
||||||
window.setPlayerName(guid, nick); // free nick name resolves
|
|
||||||
|
|
||||||
if(!first) first = time;
|
|
||||||
last = time;
|
|
||||||
appMsg += renderChatMsg(msg, nick, time, team);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#chatfaction').html(appMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.toggleChat = function() {
|
|
||||||
var c = $('#chat');
|
|
||||||
var cc = $('#chatcontrols');
|
|
||||||
if(c.data('toggle')) {
|
|
||||||
$('#chatcontrols a:first').text('expand');
|
|
||||||
c.css('height', CHAT_SHRINKED+'px');
|
|
||||||
c.css('top', 'auto');
|
|
||||||
c.data('toggle', false);
|
|
||||||
cc.css('top', 'auto');
|
|
||||||
cc.css('bottom', (CHAT_SHRINKED+4)+'px');
|
|
||||||
} else {
|
|
||||||
$('#chatcontrols a:first').text('shrink');
|
|
||||||
c.css('height', 'auto');
|
|
||||||
c.css('top', '25px');
|
|
||||||
c.data('toggle', true);
|
|
||||||
cc.css('top', '0');
|
|
||||||
cc.css('bottom', 'auto');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
window.setupChat = function() {
|
|
||||||
$('#chatcontrols a').first().click(window.toggleChat);
|
|
||||||
requestFactionChat();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// PORTAL DETAILS DISPLAY ////////////////////////////////////////////
|
// PORTAL DETAILS DISPLAY ////////////////////////////////////////////
|
||||||
@ -1131,7 +1300,9 @@ var idleReset = function (e) {
|
|||||||
// update immediately when the user comes back
|
// update immediately when the user comes back
|
||||||
if(isIdle()) {
|
if(isIdle()) {
|
||||||
window.idleTime = 0;
|
window.idleTime = 0;
|
||||||
window.requestData();
|
$.each(window._onResumeFunctions, function(ind, f) {
|
||||||
|
f();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
window.idleTime = 0;
|
window.idleTime = 0;
|
||||||
};
|
};
|
||||||
@ -1141,6 +1312,14 @@ window.isIdle = function() {
|
|||||||
return window.idleTime >= MAX_IDLE_TIME;
|
return window.idleTime >= MAX_IDLE_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window._onResumeFunctions = [];
|
||||||
|
|
||||||
|
// add your function here if you want to be notified when the user
|
||||||
|
// resumes from being idle
|
||||||
|
window.addResumeFunction = function(f) {
|
||||||
|
window._onResumeFunctions.push(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// LOCATION HANDLING /////////////////////////////////////////////////
|
// LOCATION HANDLING /////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user