Thread creation cooldown. Fix cooldown between different post-type. Fix /q/ cooldowns?
Ugh. see #774
This commit is contained in:
parent
f411eb3e99
commit
027836b78f
155
4chan_x.user.js
155
4chan_x.user.js
@ -1738,7 +1738,7 @@
|
||||
$.on(link.firstChild, 'click', function() {
|
||||
QR.open();
|
||||
if (!g.REPLY) {
|
||||
$('select', QR.el).value = 'new';
|
||||
QR.threadSelector.value = 'new';
|
||||
}
|
||||
return $('textarea', QR.el).focus();
|
||||
});
|
||||
@ -1836,44 +1836,118 @@
|
||||
},
|
||||
cooldown: {
|
||||
init: function() {
|
||||
var length, timeout, _ref;
|
||||
if (!Conf['Cooldown']) {
|
||||
return;
|
||||
}
|
||||
_ref = $.get("/" + g.BOARD + "/cooldown", {}), timeout = _ref.timeout, length = _ref.length;
|
||||
if (timeout) {
|
||||
QR.cooldown.start(timeout, length);
|
||||
QR.cooldown.types = {
|
||||
thread: (function() {
|
||||
switch (g.BOARD) {
|
||||
case 'q':
|
||||
return 86400;
|
||||
case 'b':
|
||||
case 'soc':
|
||||
case 'r9k':
|
||||
return 600;
|
||||
default:
|
||||
return 300;
|
||||
}
|
||||
})(),
|
||||
sage: g.BOARD === 'q' ? 600 : 60,
|
||||
file: g.BOARD === 'q' ? 300 : 30,
|
||||
post: g.BOARD === 'q' ? 60 : 30
|
||||
};
|
||||
QR.cooldown.cooldowns = $.get("" + g.BOARD + ".cooldown", {});
|
||||
QR.cooldown.start();
|
||||
return $.sync("" + g.BOARD + ".cooldown", QR.cooldown.sync);
|
||||
},
|
||||
start: function() {
|
||||
if (QR.cooldown.isCounting) {
|
||||
return;
|
||||
}
|
||||
return $.sync("/" + g.BOARD + "/cooldown", QR.cooldown.start);
|
||||
QR.cooldown.isCounting = true;
|
||||
return QR.cooldown.count();
|
||||
},
|
||||
start: function(timeout, length) {
|
||||
var seconds;
|
||||
seconds = Math.floor((timeout - Date.now()) / 1000);
|
||||
return QR.cooldown.count(seconds, length);
|
||||
sync: function(cooldowns) {
|
||||
QR.cooldown.cooldowns = cooldowns;
|
||||
return QR.cooldown.start();
|
||||
},
|
||||
set: function(seconds) {
|
||||
set: function(data) {
|
||||
var cooldown, hasFile, isReply, isSage, start, type;
|
||||
if (!Conf['Cooldown']) {
|
||||
return;
|
||||
}
|
||||
QR.cooldown.count(seconds, seconds);
|
||||
return $.set("/" + g.BOARD + "/cooldown", {
|
||||
timeout: Date.now() + seconds * $.SECOND,
|
||||
length: seconds
|
||||
});
|
||||
start = Date.now();
|
||||
if (data.delay) {
|
||||
cooldown = {
|
||||
delay: data.delay
|
||||
};
|
||||
} else {
|
||||
isSage = /sage/i.test(data.post.email);
|
||||
hasFile = !!data.post.file;
|
||||
isReply = data.isReply;
|
||||
type = !isReply ? 'thread' : isSage ? 'sage' : hasFile ? 'file' : 'post';
|
||||
cooldown = {
|
||||
isReply: isReply,
|
||||
isSage: isSage,
|
||||
hasFile: hasFile,
|
||||
timeout: start + QR.cooldown.types[type] * $.SECOND
|
||||
};
|
||||
}
|
||||
QR.cooldown.cooldowns[start] = cooldown;
|
||||
$.set("" + g.BOARD + ".cooldown", QR.cooldown.cooldowns);
|
||||
return QR.cooldown.start();
|
||||
},
|
||||
count: function(seconds, length) {
|
||||
if (!((0 <= seconds && seconds <= length))) {
|
||||
unset: function(id) {
|
||||
delete QR.cooldown.cooldowns[id];
|
||||
return $.set("" + g.BOARD + ".cooldown", QR.cooldown.cooldowns);
|
||||
},
|
||||
count: function() {
|
||||
var cooldown, cooldowns, elapsed, hasFile, isReply, isSage, now, post, seconds, start, type, types, _ref;
|
||||
if (Object.keys(QR.cooldown.cooldowns).length) {
|
||||
setTimeout(QR.cooldown.count, 1000);
|
||||
} else {
|
||||
$["delete"]("" + g.BOARD + ".cooldown");
|
||||
QR.cooldown.isCounting = false;
|
||||
return;
|
||||
}
|
||||
setTimeout(QR.cooldown.count, 1000, seconds - 1, length);
|
||||
QR.cooldown.seconds = seconds;
|
||||
if (seconds === 0) {
|
||||
$["delete"]("/" + g.BOARD + "/cooldown");
|
||||
if (QR.cooldown.auto) {
|
||||
QR.submit();
|
||||
if ((isReply = g.REPLY ? true : QR.threadSelector.value !== 'new')) {
|
||||
post = QR.replies[0];
|
||||
isSage = /sage/i.test(post.email);
|
||||
hasFile = !!post.file;
|
||||
}
|
||||
now = Date.now();
|
||||
seconds = null;
|
||||
_ref = QR.cooldown, types = _ref.types, cooldowns = _ref.cooldowns;
|
||||
for (start in cooldowns) {
|
||||
cooldown = cooldowns[start];
|
||||
if ('delay' in cooldown) {
|
||||
if (cooldown.delay) {
|
||||
seconds = Math.max(seconds, cooldown.delay--);
|
||||
} else {
|
||||
seconds = Math.max(seconds, 0);
|
||||
QR.cooldown.unset(start);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
type = isReply && cooldown.isReply ? isSage && cooldown.isSage ? 'sage' : hasFile && cooldown.hasFile ? 'file' : 'post' : !(isReply || cooldown.isReply) ? type = 'thread' : void 0;
|
||||
if (type) {
|
||||
elapsed = Math.floor((now - start) / 1000);
|
||||
if (elapsed >= 0) {
|
||||
seconds = Math.max(seconds, types[type] - elapsed);
|
||||
}
|
||||
type = '';
|
||||
}
|
||||
if (!((start <= now && now <= cooldown.timeout))) {
|
||||
QR.cooldown.unset(start);
|
||||
}
|
||||
}
|
||||
return QR.status();
|
||||
QR.cooldown.seconds = seconds;
|
||||
if (seconds !== null) {
|
||||
QR.status();
|
||||
}
|
||||
if (seconds === 0 && QR.cooldown.auto) {
|
||||
return QR.submit();
|
||||
}
|
||||
}
|
||||
},
|
||||
quote: function(e) {
|
||||
@ -1883,7 +1957,7 @@
|
||||
}
|
||||
QR.open();
|
||||
if (!g.REPLY) {
|
||||
$('select', QR.el).value = $.x('ancestor::div[parent::div[@class="board"]]', this).id.slice(1);
|
||||
QR.threadSelector.value = $.x('ancestor::div[parent::div[@class="board"]]', this).id.slice(1);
|
||||
}
|
||||
id = this.previousSibling.hash.slice(2);
|
||||
text = ">>" + id + "\n";
|
||||
@ -2173,10 +2247,7 @@
|
||||
(QR.replies[index - 1] || QR.replies[index + 1]).select();
|
||||
}
|
||||
QR.replies.splice(index, 1);
|
||||
if (typeof (_base1 = window.URL || window.webkitURL).revokeObjectURL === "function") {
|
||||
_base1.revokeObjectURL(this.url);
|
||||
}
|
||||
return delete this;
|
||||
return typeof (_base1 = window.URL || window.webkitURL).revokeObjectURL === "function" ? _base1.revokeObjectURL(this.url) : void 0;
|
||||
};
|
||||
|
||||
return _Class;
|
||||
@ -2342,11 +2413,12 @@
|
||||
id = thread.id.slice(1);
|
||||
threads += "<option value=" + id + ">Thread " + id + "</option>";
|
||||
}
|
||||
$.prepend($('.move > span', QR.el), $.el('select', {
|
||||
QR.threadSelector = $.el('select', {
|
||||
innerHTML: threads,
|
||||
title: 'Create a new thread / Reply to a thread'
|
||||
}));
|
||||
$.on($('select', QR.el), 'mousedown', function(e) {
|
||||
});
|
||||
$.prepend($('.move > span', QR.el), QR.threadSelector);
|
||||
$.on(QR.threadSelector, 'mousedown', function(e) {
|
||||
return e.stopPropagation();
|
||||
});
|
||||
}
|
||||
@ -2380,7 +2452,7 @@
|
||||
$.on($("[name=" + name + "]", QR.el), 'input', function() {
|
||||
var _ref2;
|
||||
QR.selected[this.name] = this.value;
|
||||
if (QR.cooldown.auto && QR.selected === QR.replies[0] && (0 < (_ref2 = QR.cooldown.seconds) && _ref2 < 6)) {
|
||||
if (QR.cooldown.auto && QR.selected === QR.replies[0] && (0 < (_ref2 = QR.cooldown.seconds) && _ref2 <= 5)) {
|
||||
return QR.cooldown.auto = false;
|
||||
}
|
||||
});
|
||||
@ -2406,7 +2478,7 @@
|
||||
}
|
||||
QR.abort();
|
||||
reply = QR.replies[0];
|
||||
threadID = g.THREAD_ID || $('select', QR.el).value;
|
||||
threadID = g.THREAD_ID || QR.threadSelector.value;
|
||||
if (threadID === 'new') {
|
||||
if (((_ref = g.BOARD) === 'vg' || _ref === 'q') && !reply.sub) {
|
||||
err = 'New threads require a subject.';
|
||||
@ -2506,7 +2578,7 @@
|
||||
return QR.ajax = $.ajax($.id('postForm').parentNode.action, callbacks, opts);
|
||||
},
|
||||
response: function(html) {
|
||||
var bs, doc, err, msg, persona, postID, reply, sage, seconds, threadID, _, _ref, _ref1;
|
||||
var bs, doc, err, msg, persona, postID, reply, threadID, _, _ref, _ref1;
|
||||
doc = d.implementation.createHTMLDocument('');
|
||||
doc.documentElement.innerHTML = html;
|
||||
if (doc.title === '4chan - Banned') {
|
||||
@ -2527,7 +2599,9 @@
|
||||
err.textContent = 'Error: You seem to have mistyped the CAPTCHA.';
|
||||
}
|
||||
QR.cooldown.auto = QR.captchaIsEnabled ? !!$.get('captchas', []).length : true;
|
||||
QR.cooldown.set(2);
|
||||
QR.cooldown.set({
|
||||
delay: 2
|
||||
});
|
||||
} else {
|
||||
QR.cooldown.auto = false;
|
||||
}
|
||||
@ -2551,13 +2625,14 @@
|
||||
postID: postID
|
||||
}
|
||||
}));
|
||||
QR.cooldown.set({
|
||||
post: reply,
|
||||
isReply: threadID !== '0'
|
||||
});
|
||||
if (threadID === '0') {
|
||||
location.pathname = "/" + g.BOARD + "/res/" + postID;
|
||||
} else {
|
||||
QR.cooldown.auto = QR.replies.length > 1;
|
||||
sage = /sage/i.test(reply.email);
|
||||
seconds = g.BOARD === 'q' ? sage ? 600 : reply.file ? 300 : 60 : sage ? 60 : 30;
|
||||
QR.cooldown.set(seconds);
|
||||
if (Conf['Open Reply in New Tab'] && !g.REPLY && !QR.cooldown.auto) {
|
||||
$.open("//boards.4chan.org/" + g.BOARD + "/res/" + threadID + "#p" + postID);
|
||||
}
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
master
|
||||
- Mayhem
|
||||
Added thread creation QR cooldown.
|
||||
Fix QR cooldown timer between non-sage and sage posts. You can submit a non-sage post 30 seconds after a sage one.
|
||||
Fix /q/ QR cooldowns.
|
||||
|
||||
2.35.4
|
||||
- Mayhem
|
||||
|
||||
149
script.coffee
149
script.coffee
@ -1342,7 +1342,7 @@ QR =
|
||||
link = $.el 'h1', innerHTML: "<a href=javascript:;>#{if g.REPLY then 'Reply to Thread' else 'Start a Thread'}</a>"
|
||||
$.on link.firstChild, 'click', ->
|
||||
QR.open()
|
||||
$('select', QR.el).value = 'new' unless g.REPLY
|
||||
QR.threadSelector.value = 'new' unless g.REPLY
|
||||
$('textarea', QR.el).focus()
|
||||
$.before $.id('postForm'), link
|
||||
|
||||
@ -1418,32 +1418,108 @@ QR =
|
||||
cooldown:
|
||||
init: ->
|
||||
return unless Conf['Cooldown']
|
||||
{timeout, length} = $.get "/#{g.BOARD}/cooldown", {}
|
||||
QR.cooldown.start timeout, length if timeout
|
||||
$.sync "/#{g.BOARD}/cooldown", QR.cooldown.start
|
||||
start: (timeout, length) ->
|
||||
seconds = Math.floor (timeout - Date.now()) / 1000
|
||||
QR.cooldown.count seconds, length
|
||||
set: (seconds) ->
|
||||
QR.cooldown.types =
|
||||
thread: switch g.BOARD
|
||||
when 'q' then 86400
|
||||
when 'b', 'soc', 'r9k' then 600
|
||||
else 300
|
||||
sage: if g.BOARD is 'q' then 600 else 60
|
||||
file: if g.BOARD is 'q' then 300 else 30
|
||||
post: if g.BOARD is 'q' then 60 else 30
|
||||
QR.cooldown.cooldowns = $.get "#{g.BOARD}.cooldown", {}
|
||||
QR.cooldown.start()
|
||||
$.sync "#{g.BOARD}.cooldown", QR.cooldown.sync
|
||||
start: ->
|
||||
return if QR.cooldown.isCounting
|
||||
QR.cooldown.isCounting = true
|
||||
QR.cooldown.count()
|
||||
sync: (cooldowns) ->
|
||||
QR.cooldown.cooldowns = cooldowns
|
||||
QR.cooldown.start()
|
||||
set: (data) ->
|
||||
return unless Conf['Cooldown']
|
||||
QR.cooldown.count seconds, seconds
|
||||
$.set "/#{g.BOARD}/cooldown",
|
||||
timeout: Date.now() + seconds * $.SECOND
|
||||
length: seconds
|
||||
count: (seconds, length) ->
|
||||
return unless 0 <= seconds <= length
|
||||
setTimeout QR.cooldown.count, 1000, seconds-1, length
|
||||
start = Date.now()
|
||||
if data.delay
|
||||
cooldown = delay: data.delay
|
||||
else
|
||||
isSage = /sage/i.test data.post.email
|
||||
hasFile = !!data.post.file
|
||||
isReply = data.isReply
|
||||
type =
|
||||
unless isReply
|
||||
'thread'
|
||||
else
|
||||
if isSage
|
||||
'sage'
|
||||
else if hasFile
|
||||
'file'
|
||||
else
|
||||
'post'
|
||||
cooldown =
|
||||
isReply: isReply
|
||||
isSage: isSage
|
||||
hasFile: hasFile
|
||||
timeout: start + QR.cooldown.types[type] * $.SECOND
|
||||
QR.cooldown.cooldowns[start] = cooldown
|
||||
$.set "#{g.BOARD}.cooldown", QR.cooldown.cooldowns
|
||||
QR.cooldown.start()
|
||||
unset: (id) ->
|
||||
delete QR.cooldown.cooldowns[id]
|
||||
$.set "#{g.BOARD}.cooldown", QR.cooldown.cooldowns
|
||||
count: ->
|
||||
if Object.keys(QR.cooldown.cooldowns).length
|
||||
setTimeout QR.cooldown.count, 1000
|
||||
else
|
||||
$.delete "#{g.BOARD}.cooldown"
|
||||
QR.cooldown.isCounting = false
|
||||
return
|
||||
|
||||
if (isReply = if g.REPLY then true else QR.threadSelector.value isnt 'new')
|
||||
post = QR.replies[0]
|
||||
isSage = /sage/i.test post.email
|
||||
hasFile = !!post.file
|
||||
now = Date.now()
|
||||
seconds = null
|
||||
{types, cooldowns} = QR.cooldown
|
||||
|
||||
for start, cooldown of cooldowns
|
||||
if 'delay' of cooldown
|
||||
if cooldown.delay
|
||||
seconds = Math.max seconds, cooldown.delay--
|
||||
else
|
||||
seconds = Math.max seconds, 0
|
||||
QR.cooldown.unset start
|
||||
continue
|
||||
|
||||
# Only cooldowns relevant to this post can set the seconds value.
|
||||
# Unset outdated cooldowns that can no longer impact us.
|
||||
type =
|
||||
if isReply and cooldown.isReply
|
||||
if isSage and cooldown.isSage
|
||||
'sage'
|
||||
else if hasFile and cooldown.hasFile
|
||||
'file'
|
||||
else
|
||||
'post'
|
||||
else unless isReply or cooldown.isReply
|
||||
type = 'thread'
|
||||
if type
|
||||
elapsed = Math.floor (now - start) / 1000
|
||||
if elapsed >= 0 # clock changed since then?
|
||||
seconds = Math.max seconds, types[type] - elapsed
|
||||
type = ''
|
||||
unless start <= now <= cooldown.timeout
|
||||
QR.cooldown.unset start
|
||||
|
||||
QR.cooldown.seconds = seconds
|
||||
if seconds is 0
|
||||
$.delete "/#{g.BOARD}/cooldown"
|
||||
QR.submit() if QR.cooldown.auto
|
||||
QR.status()
|
||||
QR.status() if seconds isnt null
|
||||
QR.submit() if seconds is 0 and QR.cooldown.auto
|
||||
|
||||
quote: (e) ->
|
||||
e?.preventDefault()
|
||||
QR.open()
|
||||
unless g.REPLY
|
||||
$('select', QR.el).value = $.x('ancestor::div[parent::div[@class="board"]]', @).id[1..]
|
||||
QR.threadSelector.value = $.x('ancestor::div[parent::div[@class="board"]]', @).id[1..]
|
||||
# Make sure we get the correct number, even with XXX censors
|
||||
id = @previousSibling.hash[2..]
|
||||
text = ">>#{id}\n"
|
||||
@ -1674,7 +1750,6 @@ QR =
|
||||
(QR.replies[index-1] or QR.replies[index+1]).select()
|
||||
QR.replies.splice index, 1
|
||||
(window.URL or window.webkitURL).revokeObjectURL? @url
|
||||
delete @
|
||||
|
||||
captcha:
|
||||
init: ->
|
||||
@ -1804,10 +1879,11 @@ QR =
|
||||
for thread in $$ '.thread'
|
||||
id = thread.id[1..]
|
||||
threads += "<option value=#{id}>Thread #{id}</option>"
|
||||
$.prepend $('.move > span', QR.el), $.el 'select'
|
||||
QR.threadSelector = $.el 'select'
|
||||
innerHTML: threads
|
||||
title: 'Create a new thread / Reply to a thread'
|
||||
$.on $('select', QR.el), 'mousedown', (e) -> e.stopPropagation()
|
||||
$.prepend $('.move > span', QR.el), QR.threadSelector
|
||||
$.on QR.threadSelector, 'mousedown', (e) -> e.stopPropagation()
|
||||
$.on $('#autohide', QR.el), 'change', QR.toggleHide
|
||||
$.on $('.close', QR.el), 'click', QR.close
|
||||
$.on $('#dump', QR.el), 'click', -> QR.el.classList.toggle 'dump'
|
||||
@ -1828,7 +1904,7 @@ QR =
|
||||
QR.selected[@name] = @value
|
||||
# Disable auto-posting if you're typing in the first reply
|
||||
# during the last 5 seconds of the cooldown.
|
||||
if QR.cooldown.auto and QR.selected is QR.replies[0] and 0 < QR.cooldown.seconds < 6
|
||||
if QR.cooldown.auto and QR.selected is QR.replies[0] and 0 < QR.cooldown.seconds <= 5
|
||||
QR.cooldown.auto = false
|
||||
|
||||
QR.status.input = $ 'input[type=submit]', QR.el
|
||||
@ -1851,7 +1927,7 @@ QR =
|
||||
QR.abort()
|
||||
|
||||
reply = QR.replies[0]
|
||||
threadID = g.THREAD_ID or $('select', QR.el).value
|
||||
threadID = g.THREAD_ID or QR.threadSelector.value
|
||||
|
||||
# prevent errors
|
||||
if threadID is 'new'
|
||||
@ -1972,7 +2048,7 @@ QR =
|
||||
true
|
||||
# Too many frequent mistyped captchas will auto-ban you!
|
||||
# On connection error, the post most likely didn't go through.
|
||||
QR.cooldown.set 2
|
||||
QR.cooldown.set delay: 2
|
||||
else # stop auto-posting
|
||||
QR.cooldown.auto = false
|
||||
QR.status()
|
||||
@ -1997,29 +2073,16 @@ QR =
|
||||
threadID: threadID
|
||||
postID: postID
|
||||
|
||||
QR.cooldown.set
|
||||
post: reply
|
||||
isReply: threadID isnt '0'
|
||||
|
||||
if threadID is '0' # new thread
|
||||
# auto-noko
|
||||
location.pathname = "/#{g.BOARD}/res/#{postID}"
|
||||
else
|
||||
# Enable auto-posting if we have stuff to post, disable it otherwise.
|
||||
QR.cooldown.auto = QR.replies.length > 1
|
||||
sage = /sage/i.test reply.email
|
||||
seconds =
|
||||
# 300 seconds cooldown for new threads
|
||||
# q: 86400 seconds
|
||||
# b soc r9k: 600 seconds
|
||||
if g.BOARD is 'q'
|
||||
if sage
|
||||
600
|
||||
else if reply.file
|
||||
300
|
||||
else
|
||||
60
|
||||
else if sage
|
||||
60
|
||||
else
|
||||
30
|
||||
QR.cooldown.set seconds
|
||||
if Conf['Open Reply in New Tab'] and !g.REPLY and !QR.cooldown.auto
|
||||
$.open "//boards.4chan.org/#{g.BOARD}/res/#{threadID}#p#{postID}"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user