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() {
|
||||
$('head').append('<style>' +
|
||||
[ '#largepreview.res img { border:2px solid '+COLORS[TEAM_RES]+'; } ',
|
||||
'#largepreview.enl img { border:2px solid '+COLORS[TEAM_ENL]+'; } ',
|
||||
'#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; } ',
|
||||
'#updatestatus { width:'+(SIDEBAR_WIDTH-2*4)+'px; } ',
|
||||
'#sidebar, #gamestat, #gamestat span, input, ',
|
||||
@ -82,21 +83,19 @@ window.setupMap = function() {
|
||||
});
|
||||
|
||||
// map update status handling
|
||||
map.on('zoomstart', function() { window.mapRunsUserAction = true });
|
||||
map.on('movestart', function() { window.mapRunsUserAction = true });
|
||||
map.on('zoomend', function() { window.mapRunsUserAction = false });
|
||||
map.on('moveend', function() { window.mapRunsUserAction = false });
|
||||
|
||||
map.on('movestart zoomstart', function() { window.mapRunsUserAction = true });
|
||||
map.on('moveend zoomend', function() { window.mapRunsUserAction = false });
|
||||
|
||||
// update map hooks
|
||||
map.on('zoomstart', window.requests.abort);
|
||||
map.on('zoomend', function() { window.startRefreshTimeout(500) });
|
||||
map.on('movestart', window.requests.abort );
|
||||
map.on('moveend', function() { window.startRefreshTimeout(500) });
|
||||
map.on('movestart zoomstart', window.requests.abort);
|
||||
map.on('moveend zoomend', function() { window.startRefreshTimeout(500) });
|
||||
|
||||
// run once on init
|
||||
window.requestData();
|
||||
window.startRefreshTimeout();
|
||||
|
||||
window.addResumeFunction(window.requestData);
|
||||
window.requests.addRefreshFunction(window.requestData);
|
||||
};
|
||||
|
||||
// renders player details into the website. Since the player info is
|
||||
@ -151,7 +150,7 @@ function boot() {
|
||||
window.setupLargeImagePreview();
|
||||
window.updateGameScore();
|
||||
window.setupPlayerStat();
|
||||
window.setupChat();
|
||||
window.chat.setup();
|
||||
// read here ONCE, so the URL is only evaluated one time after the
|
||||
// necessary data has been loaded.
|
||||
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) {
|
||||
var a = $('#chatpublic 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) {
|
||||
var a = $('#chatpublic 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.');
|
||||
|
||||
var b = map.getBounds();
|
||||
@ -42,75 +42,213 @@ window.getPostDataForChat = function(public, getOlderMsgs) {
|
||||
|
||||
if(getOlderMsgs) {
|
||||
// ask for older chat when scrolling up
|
||||
data = $.extend(data, {maxTimestampMs: getOldestTimestampChat(public)});
|
||||
data = $.extend(data, {maxTimestampMs: chat.getOldestTimestamp(public)});
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
|
||||
window.requestFactionChat = function(getOlderMsgs) {
|
||||
if(window.idleTime >= MAX_IDLE_TIME) {
|
||||
console.log('user has been idle for ' + idleTime + ' minutes. Skipping faction chat.');
|
||||
renderUpdateStatus();
|
||||
return;
|
||||
}
|
||||
//
|
||||
// requesting faction
|
||||
//
|
||||
|
||||
data = getPostDataForChat(false, false);
|
||||
window.requests.add(window.postAjax('getPaginatedPlextsV2', data, window.handleFactionChat));
|
||||
window.chat._requestOldFactionRunning = false;
|
||||
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 tb = unixTimeToString(time, true);
|
||||
var t = '<time title="'+tb+'" data-timestamp="'+time+'">'+ta+'</time>';
|
||||
var s = 'style="color:'+COLORS[team]+'"';
|
||||
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
|
||||
if(isIdle()) {
|
||||
window.idleTime = 0;
|
||||
window.requestData();
|
||||
$.each(window._onResumeFunctions, function(ind, f) {
|
||||
f();
|
||||
});
|
||||
}
|
||||
window.idleTime = 0;
|
||||
};
|
||||
@ -16,3 +18,11 @@ $('body').mousemove(idleReset).keypress(idleReset);
|
||||
window.isIdle = function() {
|
||||
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.
|
||||
|
||||
|
||||
// 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
|
||||
// works, refer to the description in “MAP DATA REQUEST CALCULATORS”
|
||||
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');
|
||||
requests.abort();
|
||||
cleanUp();
|
||||
@ -81,7 +54,6 @@ window.requestData = function() {
|
||||
// works on map data response and ensures entities are drawn/updated.
|
||||
window.handleDataResponse = function(data, textStatus, jqXHR) {
|
||||
// remove from active ajax queries list
|
||||
window.requests.remove(jqXHR);
|
||||
if(!data || !data.result) {
|
||||
console.warn(data);
|
||||
return;
|
||||
@ -158,7 +130,12 @@ window.cleanUp = function() {
|
||||
// removes given entity from map
|
||||
window.removeByGuid = function(guid) {
|
||||
// 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)) {
|
||||
case '11':
|
||||
case '12':
|
||||
@ -240,7 +217,7 @@ window.renderLink = function(ent) {
|
||||
|
||||
poly.on('remove', function() { delete window.links[this.options.guid]; });
|
||||
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
|
||||
@ -264,5 +241,5 @@ window.renderField = function(ent) {
|
||||
|
||||
poly.on('remove', function() { delete window.fields[this.options.guid]; });
|
||||
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.failedRequestCount = 0;
|
||||
|
||||
startRefreshTimeout();
|
||||
renderUpdateStatus();
|
||||
}
|
||||
|
||||
@ -56,3 +55,49 @@ window.renderUpdateStatus = function() {
|
||||
|
||||
$('#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.
|
||||
window.postAjax = function(action, data, success, error) {
|
||||
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); };
|
||||
return $.ajax({
|
||||
url: 'rpc/dashboard.'+action,
|
||||
type: 'POST',
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: success,
|
||||
success: [remove, success],
|
||||
error: error ? [errCnt, error] : errCnt,
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
beforeSend: function(req) {
|
||||
@ -110,3 +111,11 @@ window.getPaddedBounds = function() {
|
||||
window._storedPaddedBounds = 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 = ''
|
||||
+ '<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>'
|
||||
+ '</div>'
|
||||
+ '<div id="chat">'
|
||||
+ '<div id="chat" style="display:none">'
|
||||
+ ' <div id="chatfaction"></div>'
|
||||
+ ' <div id="chatpublic"></div>'
|
||||
+ ' <div id="chatbot"></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="playerstat">t</div>'
|
||||
+ ' <div id="gamestat"> loading global control stats</div>'
|
||||
|
11
style.css
11
style.css
@ -155,6 +155,17 @@ mark {
|
||||
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 {
|
||||
display: inline-block;
|
||||
width: 546px;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @id ingress-intel-total-conversion@breunigs
|
||||
// @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
|
||||
// @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
|
||||
@ -46,14 +46,15 @@ document.getElementsByTagName('head')[0].innerHTML = ''
|
||||
|
||||
document.getElementsByTagName('body')[0].innerHTML = ''
|
||||
+ '<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>'
|
||||
+ '</div>'
|
||||
+ '<div id="chat">'
|
||||
+ '<div id="chat" style="display:none">'
|
||||
+ ' <div id="chatfaction"></div>'
|
||||
+ ' <div id="chatpublic"></div>'
|
||||
+ ' <div id="chatbot"></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="playerstat">t</div>'
|
||||
+ ' <div id="gamestat"> loading global control stats</div>'
|
||||
@ -150,36 +151,9 @@ window.fields = {};
|
||||
// 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
|
||||
// works, refer to the description in “MAP DATA REQUEST CALCULATORS”
|
||||
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');
|
||||
requests.abort();
|
||||
cleanUp();
|
||||
@ -226,7 +200,6 @@ window.requestData = function() {
|
||||
// works on map data response and ensures entities are drawn/updated.
|
||||
window.handleDataResponse = function(data, textStatus, jqXHR) {
|
||||
// remove from active ajax queries list
|
||||
window.requests.remove(jqXHR);
|
||||
if(!data || !data.result) {
|
||||
console.warn(data);
|
||||
return;
|
||||
@ -303,7 +276,12 @@ window.cleanUp = function() {
|
||||
// removes given entity from map
|
||||
window.removeByGuid = function(guid) {
|
||||
// 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)) {
|
||||
case '11':
|
||||
case '12':
|
||||
@ -385,7 +363,7 @@ window.renderLink = function(ent) {
|
||||
|
||||
poly.on('remove', function() { delete window.links[this.options.guid]; });
|
||||
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
|
||||
@ -409,7 +387,7 @@ window.renderField = function(ent) {
|
||||
|
||||
poly.on('remove', function() { delete window.fields[this.options.guid]; });
|
||||
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.failedRequestCount = 0;
|
||||
|
||||
startRefreshTimeout();
|
||||
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 ///////////////////////////////////////////////////////
|
||||
@ -523,13 +546,14 @@ window.digits = function(d) {
|
||||
// error: see above. Additionally it is logged if the request failed.
|
||||
window.postAjax = function(action, data, success, error) {
|
||||
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); };
|
||||
return $.ajax({
|
||||
url: 'rpc/dashboard.'+action,
|
||||
type: 'POST',
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: success,
|
||||
success: [remove, success],
|
||||
error: error ? [errCnt, error] : errCnt,
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
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 /////////////////////////////////////////////////////////////
|
||||
@ -613,12 +645,13 @@ window.setupLargeImagePreview = function() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
window.setupStyles = function() {
|
||||
$('head').append('<style>' +
|
||||
[ '#largepreview.res img { border:2px solid '+COLORS[TEAM_RES]+'; } ',
|
||||
'#largepreview.enl img { border:2px solid '+COLORS[TEAM_ENL]+'; } ',
|
||||
'#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; } ',
|
||||
'#updatestatus { width:'+(SIDEBAR_WIDTH-2*4)+'px; } ',
|
||||
'#sidebar, #gamestat, #gamestat span, input, ',
|
||||
@ -671,21 +704,19 @@ window.setupMap = function() {
|
||||
});
|
||||
|
||||
// map update status handling
|
||||
map.on('zoomstart', function() { window.mapRunsUserAction = true });
|
||||
map.on('movestart', function() { window.mapRunsUserAction = true });
|
||||
map.on('zoomend', function() { window.mapRunsUserAction = false });
|
||||
map.on('moveend', function() { window.mapRunsUserAction = false });
|
||||
|
||||
map.on('movestart zoomstart', function() { window.mapRunsUserAction = true });
|
||||
map.on('moveend zoomend', function() { window.mapRunsUserAction = false });
|
||||
|
||||
// update map hooks
|
||||
map.on('zoomstart', window.requests.abort);
|
||||
map.on('zoomend', function() { window.startRefreshTimeout(500) });
|
||||
map.on('movestart', window.requests.abort );
|
||||
map.on('moveend', function() { window.startRefreshTimeout(500) });
|
||||
map.on('movestart zoomstart', window.requests.abort);
|
||||
map.on('moveend zoomend', function() { window.startRefreshTimeout(500) });
|
||||
|
||||
// run once on init
|
||||
window.requestData();
|
||||
window.startRefreshTimeout();
|
||||
|
||||
window.addResumeFunction(window.requestData);
|
||||
window.requests.addRefreshFunction(window.requestData);
|
||||
};
|
||||
|
||||
// renders player details into the website. Since the player info is
|
||||
@ -740,7 +771,7 @@ function boot() {
|
||||
window.setupLargeImagePreview();
|
||||
window.updateGameScore();
|
||||
window.setupPlayerStat();
|
||||
window.setupChat();
|
||||
window.chat.setup();
|
||||
// read here ONCE, so the URL is only evaluated one time after the
|
||||
// necessary data has been loaded.
|
||||
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);
|
||||
|
||||
|
||||
window.chat = function() {}
|
||||
window.chat = function() {};
|
||||
|
||||
window.getOldestTimestampChat = function(public) {
|
||||
window.chat.getOldestTimestamp = function(public) {
|
||||
if(public) {
|
||||
var a = $('#chatpublic 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) {
|
||||
var a = $('#chatpublic 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.');
|
||||
|
||||
var b = map.getBounds();
|
||||
@ -809,26 +840,210 @@ window.getPostDataForChat = function(public, getOlderMsgs) {
|
||||
|
||||
if(getOlderMsgs) {
|
||||
// ask for older chat when scrolling up
|
||||
data = $.extend(data, {maxTimestampMs: getOldestTimestampChat(public)});
|
||||
data = $.extend(data, {maxTimestampMs: chat.getOldestTimestamp(public)});
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
|
||||
window.requestFactionChat = function(getOlderMsgs) {
|
||||
if(window.idleTime >= MAX_IDLE_TIME) {
|
||||
console.log('user has been idle for ' + idleTime + ' minutes. Skipping faction chat.');
|
||||
renderUpdateStatus();
|
||||
return;
|
||||
}
|
||||
//
|
||||
// requesting faction
|
||||
//
|
||||
|
||||
data = getPostDataForChat(false, false);
|
||||
window.requests.add(window.postAjax('getPaginatedPlextsV2', data, window.handleFactionChat));
|
||||
window.chat._requestOldFactionRunning = false;
|
||||
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 tb = unixTimeToString(time, true);
|
||||
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>';
|
||||
}
|
||||
|
||||
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 ////////////////////////////////////////////
|
||||
@ -1131,7 +1300,9 @@ var idleReset = function (e) {
|
||||
// update immediately when the user comes back
|
||||
if(isIdle()) {
|
||||
window.idleTime = 0;
|
||||
window.requestData();
|
||||
$.each(window._onResumeFunctions, function(ind, f) {
|
||||
f();
|
||||
});
|
||||
}
|
||||
window.idleTime = 0;
|
||||
};
|
||||
@ -1141,6 +1312,14 @@ window.isIdle = function() {
|
||||
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 /////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user