Increase the updater's refresh interval in inactive threads. Set minimum interval to 5 seconds.

This commit is contained in:
Nicolas Stepien 2012-07-04 14:44:26 +02:00
parent 372981c46d
commit b0162dba1e
3 changed files with 78 additions and 46 deletions

View File

@ -2246,6 +2246,7 @@
Unread.foresee.push(postID); Unread.foresee.push(postID);
} }
if (g.REPLY && Conf['Thread Updater'] && Conf['Auto Update This']) { if (g.REPLY && Conf['Thread Updater'] && Conf['Auto Update This']) {
Updater.unsuccessfulFetchCount = 0;
Updater.update(); Updater.update();
} }
QR.status(); QR.status();
@ -2567,7 +2568,7 @@
Updater = { Updater = {
init: function() { init: function() {
var checkbox, checked, dialog, html, input, name, title, _i, _len, _ref; var checkbox, checked, dialog, html, input, name, title, _i, _len, _ref;
html = "<div class=move><span id=count></span> <span id=timer>-" + Conf['Interval'] + "</span></div>"; html = '<div class=move><span id=count></span> <span id=timer></span></div>';
checkbox = Config.updater.checkbox; checkbox = Config.updater.checkbox;
for (name in checkbox) { for (name in checkbox) {
title = checkbox[name][1]; title = checkbox[name][1];
@ -2575,11 +2576,13 @@
html += "<div><label title='" + title + "'>" + name + "<input name='" + name + "' type=checkbox " + checked + "></label></div>"; html += "<div><label title='" + title + "'>" + name + "<input name='" + name + "' type=checkbox " + checked + "></label></div>";
} }
checked = Conf['Auto Update'] ? 'checked' : ''; checked = Conf['Auto Update'] ? 'checked' : '';
html += " <div><label title='Controls whether *this* thread automatically updates or not'>Auto Update This<input name='Auto Update This' type=checkbox " + checked + "></label></div> <div><label>Interval (s)<input name=Interval value=" + Conf['Interval'] + " class=field size=4></label></div> <div><input value='Update Now' type=button></div>"; html += " <div><label title='Controls whether *this* thread automatically updates or not'>Auto Update This<input name='Auto Update This' type=checkbox " + checked + "></label></div> <div><label>Interval (s)<input type=number name=Interval class=field min=5></label></div> <div><input value='Update Now' type=button></div>";
dialog = UI.dialog('updater', 'bottom: 0; right: 0;', html); dialog = UI.dialog('updater', 'bottom: 0; right: 0;', html);
this.count = $('#count', dialog); this.count = $('#count', dialog);
this.timer = $('#timer', dialog); this.timer = $('#timer', dialog);
this.thread = $.id("t" + g.THREAD_ID); this.thread = $.id("t" + g.THREAD_ID);
this.unsuccessfulFetchCount = 0;
this.lastModified = '0';
_ref = $$('input', dialog); _ref = $$('input', dialog);
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
input = _ref[_i]; input = _ref[_i];
@ -2598,21 +2601,22 @@
Conf[input.name] = input.checked; Conf[input.name] = input.checked;
} }
} else if (input.name === 'Interval') { } else if (input.name === 'Interval') {
input.value = Conf['Interval'];
$.on(input, 'input', this.cb.interval); $.on(input, 'input', this.cb.interval);
this.cb.interval.call(input);
} else if (input.type === 'button') { } else if (input.type === 'button') {
$.on(input, 'click', this.update); $.on(input, 'click', this.update);
} }
} }
$.add(d.body, dialog); return $.add(d.body, dialog);
this.retryCoef = 10;
return this.lastModified = 0;
}, },
cb: { cb: {
interval: function() { interval: function() {
var val; var val;
val = parseInt(this.value, 10); val = parseInt(this.value, 10);
this.value = val > 0 ? val : 1; this.value = val > 5 ? val : 5;
return $.cb.value.call(this); $.cb.value.call(this);
return Updater.timer.textContent = "-" + (Updater.getInterval());
}, },
verbose: function() { verbose: function() {
if (Conf['Verbose']) { if (Conf['Verbose']) {
@ -2641,7 +2645,7 @@
}; };
}, },
update: function() { update: function() {
var count, doc, id, lastPost, nodes, reply, scroll, _i, _len, _ref, _ref1; var count, doc, id, lastPost, nodes, reply, scroll, _i, _len, _ref, _ref1, _ref2;
if (this.status === 404) { if (this.status === 404) {
Updater.timer.textContent = ''; Updater.timer.textContent = '';
Updater.count.textContent = 404; Updater.count.textContent = 404;
@ -2658,15 +2662,15 @@
return; return;
} }
if ((_ref = this.status) !== 0 && _ref !== 200 && _ref !== 304) { if ((_ref = this.status) !== 0 && _ref !== 200 && _ref !== 304) {
Updater.retryCoef += 10 * (Updater.retryCoef < 120);
if (Conf['Verbose']) { if (Conf['Verbose']) {
Updater.count.textContent = this.statusText; Updater.count.textContent = this.statusText;
Updater.count.className = 'warning'; Updater.count.className = 'warning';
} }
Updater.unsuccessfulFetchCount++;
return; return;
} }
Updater.retryCoef = 10; Updater.unsuccessfulFetchCount++;
Updater.timer.textContent = "-" + Conf['Interval']; Updater.timer.textContent = "-" + (Updater.getInterval());
/* /*
Status Code 304: Not modified Status Code 304: Not modified
By sending the `If-Modified-Since` header we get a proper status code, and no response. By sending the `If-Modified-Since` header we get a proper status code, and no response.
@ -2674,7 +2678,7 @@
and won't load images and scripts when parsing the response. and won't load images and scripts when parsing the response.
*/ */
if (this.status === 304) { if ((_ref1 = this.status) === 0 || _ref1 === 304) {
if (Conf['Verbose']) { if (Conf['Verbose']) {
Updater.count.textContent = '+0'; Updater.count.textContent = '+0';
Updater.count.className = null; Updater.count.className = null;
@ -2687,44 +2691,52 @@
lastPost = Updater.thread.lastElementChild; lastPost = Updater.thread.lastElementChild;
id = lastPost.id.slice(2); id = lastPost.id.slice(2);
nodes = []; nodes = [];
_ref1 = $$('.replyContainer', doc).reverse(); _ref2 = $$('.replyContainer', doc).reverse();
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
reply = _ref1[_i]; reply = _ref2[_i];
if (reply.id.slice(2) <= id) { if (reply.id.slice(2) <= id) {
break; break;
} }
nodes.push(reply); nodes.push(reply);
} }
count = nodes.length; count = nodes.length;
scroll = Conf['Scrolling'] && Updater.scrollBG() && count && lastPost.getBoundingClientRect().bottom - d.documentElement.clientHeight < 25;
if (Conf['Verbose']) { if (Conf['Verbose']) {
Updater.count.textContent = "+" + count; Updater.count.textContent = "+" + count;
Updater.count.className = count ? 'new' : null; Updater.count.className = count ? 'new' : null;
} }
if (!count) {
return;
}
Updater.unsuccessfulFetchCount = 0;
Updater.timer.textContent = "-" + (Updater.getInterval());
scroll = Conf['Scrolling'] && Updater.scrollBG() && lastPost.getBoundingClientRect().bottom - d.documentElement.clientHeight < 25;
$.add(Updater.thread, nodes.reverse()); $.add(Updater.thread, nodes.reverse());
if (scroll) { if (scroll) {
return nodes[0].scrollIntoView(); return nodes[0].scrollIntoView();
} }
} }
}, },
getInterval: function() {
var i, j;
i = +Conf['Interval'];
j = Math.min(this.unsuccessfulFetchCount, 9);
return Math.max(i, [5, 10, 15, 20, 30, 60, 90, 120, 300, 600][j]);
},
timeout: function() { timeout: function() {
var n; var n;
Updater.timeoutID = setTimeout(Updater.timeout, 1000); Updater.timeoutID = setTimeout(Updater.timeout, 1000);
n = 1 + Number(Updater.timer.textContent); n = 1 + Number(Updater.timer.textContent);
if (n === 0) { if (n === 0) {
return Updater.update(); return Updater.update();
} else if (n === Updater.retryCoef) { } else if (n === Updater.getInterval()) {
Updater.retryCoef += 10 * (Updater.retryCoef < 120); Updater.unsuccessfulFetchCount++;
return Updater.retry(); Updater.count.textContent = 'Retry';
Updater.count.className = null;
return Updater.update();
} else { } else {
return Updater.timer.textContent = n; return Updater.timer.textContent = n;
} }
}, },
retry: function() {
this.count.textContent = 'Retry';
this.count.className = null;
return this.update();
},
update: function() { update: function() {
var url, _ref; var url, _ref;
Updater.timer.textContent = 0; Updater.timer.textContent = 0;
@ -5087,6 +5099,9 @@ body.unscroll {\
border: none;\ border: none;\
background: transparent;\ background: transparent;\
}\ }\
#updater input[type=number] {\
width: 4em;\
}\
.new {\ .new {\
background: lime;\ background: lime;\
}\ }\

View File

@ -1,4 +1,7 @@
master master
- Mayhem
The updater's refresh interval will now increase gradually in inactive threads.
The updater's refresh interval is now limited to 5 seconds minimum.
2.33.8 2.33.8
- Mayhem - Mayhem

View File

@ -1715,6 +1715,7 @@ QR =
if g.REPLY and (Conf['Unread Count'] or Conf['Unread Favicon']) if g.REPLY and (Conf['Unread Count'] or Conf['Unread Favicon'])
Unread.foresee.push postID Unread.foresee.push postID
if g.REPLY and Conf['Thread Updater'] and Conf['Auto Update This'] if g.REPLY and Conf['Thread Updater'] and Conf['Auto Update This']
Updater.unsuccessfulFetchCount = 0
Updater.update() Updater.update()
QR.status() QR.status()
@ -2000,7 +2001,7 @@ Options =
Updater = Updater =
init: -> init: ->
html = "<div class=move><span id=count></span> <span id=timer>-#{Conf['Interval']}</span></div>" html = '<div class=move><span id=count></span> <span id=timer></span></div>'
{checkbox} = Config.updater {checkbox} = Config.updater
for name of checkbox for name of checkbox
title = checkbox[name][1] title = checkbox[name][1]
@ -2010,7 +2011,7 @@ Updater =
checked = if Conf['Auto Update'] then 'checked' else '' checked = if Conf['Auto Update'] then 'checked' else ''
html += " html += "
<div><label title='Controls whether *this* thread automatically updates or not'>Auto Update This<input name='Auto Update This' type=checkbox #{checked}></label></div> <div><label title='Controls whether *this* thread automatically updates or not'>Auto Update This<input name='Auto Update This' type=checkbox #{checked}></label></div>
<div><label>Interval (s)<input name=Interval value=#{Conf['Interval']} class=field size=4></label></div> <div><label>Interval (s)<input type=number name=Interval class=field min=5></label></div>
<div><input value='Update Now' type=button></div>" <div><input value='Update Now' type=button></div>"
dialog = UI.dialog 'updater', 'bottom: 0; right: 0;', html dialog = UI.dialog 'updater', 'bottom: 0; right: 0;', html
@ -2019,6 +2020,9 @@ Updater =
@timer = $ '#timer', dialog @timer = $ '#timer', dialog
@thread = $.id "t#{g.THREAD_ID}" @thread = $.id "t#{g.THREAD_ID}"
@unsuccessfulFetchCount = 0
@lastModified = '0'
for input in $$ 'input', dialog for input in $$ 'input', dialog
if input.type is 'checkbox' if input.type is 'checkbox'
$.on input, 'click', $.cb.checked $.on input, 'click', $.cb.checked
@ -2034,20 +2038,20 @@ Updater =
# Required for the QR's update after posting. # Required for the QR's update after posting.
Conf[input.name] = input.checked Conf[input.name] = input.checked
else if input.name is 'Interval' else if input.name is 'Interval'
input.value = Conf['Interval']
$.on input, 'input', @cb.interval $.on input, 'input', @cb.interval
@cb.interval.call input
else if input.type is 'button' else if input.type is 'button'
$.on input, 'click', @update $.on input, 'click', @update
$.add d.body, dialog $.add d.body, dialog
@retryCoef = 10
@lastModified = 0
cb: cb:
interval: -> interval: ->
val = parseInt @value, 10 val = parseInt @value, 10
@value = if val > 0 then val else 1 @value = if val > 5 then val else 5
$.cb.value.call @ $.cb.value.call @
Updater.timer.textContent = "-#{Updater.getInterval()}"
verbose: -> verbose: ->
if Conf['Verbose'] if Conf['Verbose']
Updater.count.textContent = '+0' Updater.count.textContent = '+0'
@ -2084,14 +2088,14 @@ Updater =
return return
unless @status in [0, 200, 304] unless @status in [0, 200, 304]
# XXX 304 -> 0 in Opera # XXX 304 -> 0 in Opera
Updater.retryCoef += 10 * (Updater.retryCoef < 120)
if Conf['Verbose'] if Conf['Verbose']
Updater.count.textContent = @statusText Updater.count.textContent = @statusText
Updater.count.className = 'warning' Updater.count.className = 'warning'
Updater.unsuccessfulFetchCount++
return return
Updater.retryCoef = 10 Updater.unsuccessfulFetchCount++
Updater.timer.textContent = "-#{Conf['Interval']}" Updater.timer.textContent = "-#{Updater.getInterval()}"
### ###
Status Code 304: Not modified Status Code 304: Not modified
@ -2099,7 +2103,8 @@ Updater =
This saves bandwidth for both the user and the servers, avoid unnecessary computation, This saves bandwidth for both the user and the servers, avoid unnecessary computation,
and won't load images and scripts when parsing the response. and won't load images and scripts when parsing the response.
### ###
if @status is 304 if @status in [0, 304]
# XXX 304 -> 0 in Opera
if Conf['Verbose'] if Conf['Verbose']
Updater.count.textContent = '+0' Updater.count.textContent = '+0'
Updater.count.className = null Updater.count.className = null
@ -2116,38 +2121,44 @@ Updater =
break if reply.id[2..] <= id #make sure to not insert older posts break if reply.id[2..] <= id #make sure to not insert older posts
nodes.push reply nodes.push reply
count = nodes.length count = nodes.length
scroll = Conf['Scrolling'] && Updater.scrollBG() && count &&
lastPost.getBoundingClientRect().bottom - d.documentElement.clientHeight < 25
if Conf['Verbose'] if Conf['Verbose']
Updater.count.textContent = "+#{count}" Updater.count.textContent = "+#{count}"
Updater.count.className = if count then 'new' else null Updater.count.className = if count then 'new' else null
return unless count
Updater.unsuccessfulFetchCount = 0
Updater.timer.textContent = "-#{Updater.getInterval()}"
scroll = Conf['Scrolling'] && Updater.scrollBG() &&
lastPost.getBoundingClientRect().bottom - d.documentElement.clientHeight < 25
$.add Updater.thread, nodes.reverse() $.add Updater.thread, nodes.reverse()
if scroll if scroll
nodes[0].scrollIntoView() nodes[0].scrollIntoView()
getInterval: ->
i = +Conf['Interval']
j = Math.min @unsuccessfulFetchCount, 9
Math.max i, [5, 10, 15, 20, 30, 60, 90, 120, 300, 600][j]
timeout: -> timeout: ->
Updater.timeoutID = setTimeout Updater.timeout, 1000 Updater.timeoutID = setTimeout Updater.timeout, 1000
n = 1 + Number Updater.timer.textContent n = 1 + Number Updater.timer.textContent
if n is 0 if n is 0
Updater.update() Updater.update()
else if n is Updater.retryCoef else if n is Updater.getInterval()
Updater.retryCoef += 10 * (Updater.retryCoef < 120) Updater.unsuccessfulFetchCount++
Updater.retry() Updater.count.textContent = 'Retry'
Updater.count.className = null
Updater.update()
else else
Updater.timer.textContent = n Updater.timer.textContent = n
retry: ->
@count.textContent = 'Retry'
@count.className = null
@update()
update: -> update: ->
Updater.timer.textContent = 0 Updater.timer.textContent = 0
Updater.request?.abort() Updater.request?.abort()
#fool the cache # Fool the cache.
url = location.pathname + '?' + Date.now() url = location.pathname + '?' + Date.now()
Updater.request = $.ajax url, onload: Updater.cb.update, Updater.request = $.ajax url, onload: Updater.cb.update,
headers: 'If-Modified-Since': Updater.lastModified headers: 'If-Modified-Since': Updater.lastModified
@ -4005,6 +4016,9 @@ body.unscroll {
border: none; border: none;
background: transparent; background: transparent;
} }
#updater input[type=number] {
width: 4em;
}
.new { .new {
background: lime; background: lime;
} }