Merge branch 'v3' of git://github.com/MayhemYDG/4chan-x into v3
Conflicts: CHANGELOG.md Gruntfile.coffee json/archives.json package.json src/Filtering/Anonymize.coffee src/General/Config.coffee src/General/lib/post.class src/Linkification/Linkify.coffee src/Monitoring/ThreadUpdater.coffee src/Posting/QuickReply.coffee
This commit is contained in:
commit
847078db53
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,6 +1,16 @@
|
||||
**MayhemYDG**:
|
||||
- Tiny posting cooldown adjustment:
|
||||
* You can post an image reply immediately after a non-image reply.
|
||||
- Update posting cooldown timers to match 4chan settings:
|
||||
* Cooldown may vary between inter-thread and intra-thread replies.
|
||||
* Cooldown may vary when posting a file or not.
|
||||
* Cooldown does not take sageing into account anymore.
|
||||
* Timers vary across boards.
|
||||
- Updated post and deletion cooldown timers to match 4chan changes: they are now twice longer.
|
||||
- Added support for the flag selector on /pol/.
|
||||
|
||||
### v1.2.39
|
||||
*2013-09-19*
|
||||
|
||||
**seaweedchan**:
|
||||
- Fix thread updater bug introduced in last version
|
||||
|
||||
|
||||
@ -1,21 +1,14 @@
|
||||
module.exports = (grunt) ->
|
||||
|
||||
concatOptions =
|
||||
process: Object.create(null, data:
|
||||
get: -> grunt.config 'pkg'
|
||||
enumerable: true
|
||||
)
|
||||
shellOptions =
|
||||
stdout: true
|
||||
stderr: true
|
||||
failOnError: true
|
||||
|
||||
# Project configuration.
|
||||
grunt.initConfig
|
||||
pkg: grunt.file.readJSON 'package.json'
|
||||
concat:
|
||||
options: process: Object.create(null, data:
|
||||
get: -> grunt.config 'pkg'
|
||||
enumerable: true
|
||||
)
|
||||
coffee:
|
||||
options: concatOptions
|
||||
src: [
|
||||
'src/General/Config.coffee'
|
||||
'src/General/Globals.coffee'
|
||||
@ -41,13 +34,11 @@ module.exports = (grunt) ->
|
||||
dest: 'tmp-<%= pkg.type %>/script.coffee'
|
||||
|
||||
meta:
|
||||
options: concatOptions
|
||||
files:
|
||||
'LICENSE': 'src/General/meta/banner.js',
|
||||
'latest.js': 'src/General/meta/latest.js'
|
||||
|
||||
crx:
|
||||
options: concatOptions
|
||||
files:
|
||||
'builds/crx/manifest.json': 'src/General/meta/manifest.json'
|
||||
'builds/crx/script.js': [
|
||||
@ -57,7 +48,6 @@ module.exports = (grunt) ->
|
||||
'tmp-<%= pkg.type %>/script.js'
|
||||
]
|
||||
userscript:
|
||||
options: concatOptions
|
||||
files:
|
||||
'builds/<%= pkg.name %>.meta.js': 'src/General/meta/metadata.js'
|
||||
'builds/<%= pkg.name %>.user.js': [
|
||||
@ -96,22 +86,23 @@ module.exports = (grunt) ->
|
||||
push: false
|
||||
|
||||
shell:
|
||||
options:
|
||||
stdout: true
|
||||
stderr: true
|
||||
failOnError: true
|
||||
commit:
|
||||
options: shellOptions
|
||||
command: [
|
||||
'git commit -am "Release <%= pkg.meta.name %> v<%= pkg.version %>."'
|
||||
'git tag -a <%= pkg.version %> -m "<%= pkg.meta.name %> v<%= pkg.version %>."'
|
||||
'git tag -af stable -m "<%= pkg.meta.name %> v<%= pkg.version %>."'
|
||||
].join ' && '
|
||||
|
||||
push:
|
||||
options: shellOptions
|
||||
command: 'git push origin --tags -f && git push origin --all'
|
||||
|
||||
watch:
|
||||
options:
|
||||
interrupt: true
|
||||
all:
|
||||
options:
|
||||
interrupt: true
|
||||
files: [
|
||||
'Gruntfile.coffee'
|
||||
'package.json'
|
||||
|
||||
@ -5254,7 +5254,8 @@
|
||||
persona = {
|
||||
name: post.name,
|
||||
email: /^sage$/.test(post.email) ? persona.email : post.email,
|
||||
sub: Conf['Remember Subject'] ? post.sub : void 0
|
||||
sub: Conf['Remember Subject'] ? post.sub : void 0,
|
||||
flag: post.flag
|
||||
};
|
||||
return $.set('QR.persona', persona);
|
||||
});
|
||||
@ -5318,12 +5319,11 @@
|
||||
delay: delay
|
||||
};
|
||||
} else {
|
||||
if (post.file) {
|
||||
if (hasFile = !!post.file) {
|
||||
upSpd = post.file.size / ((start - req.uploadStartTime) / $.SECOND);
|
||||
QR.cooldown.upSpdAccuracy = ((upSpd > QR.cooldown.upSpd * .9) + QR.cooldown.upSpdAccuracy) / 2;
|
||||
QR.cooldown.upSpd = upSpd;
|
||||
}
|
||||
hasFile = !!post.file;
|
||||
cooldown = {
|
||||
isReply: isReply,
|
||||
hasFile: hasFile,
|
||||
@ -5380,7 +5380,17 @@
|
||||
if (elapsed < 0) {
|
||||
continue;
|
||||
}
|
||||
type = !isReply ? 'thread' : hasFile ? 'image' : 'reply';
|
||||
if (!isReply) {
|
||||
type = 'thread';
|
||||
} else if (hasFile) {
|
||||
if (!cooldown.hasFile) {
|
||||
seconds = Math.max(seconds, 0);
|
||||
continue;
|
||||
}
|
||||
type = 'image';
|
||||
} else {
|
||||
type = 'reply';
|
||||
}
|
||||
maxTimer = Math.max(types[type] || 0, types[type + '_intra'] || 0);
|
||||
if (!((start <= now && now <= start + maxTimer * $.SECOND))) {
|
||||
QR.cooldown.unset(start);
|
||||
@ -5393,7 +5403,7 @@
|
||||
}
|
||||
if (seconds && Conf['Cooldown Prediction'] && hasFile && upSpd) {
|
||||
seconds -= Math.floor(post.file.size / upSpd * upSpdAccuracy);
|
||||
seconds = Math.max(seconds, 0);
|
||||
seconds = seconds > 0 ? seconds : 0;
|
||||
}
|
||||
update = seconds !== null || !!QR.cooldown.seconds;
|
||||
QR.cooldown.seconds = seconds;
|
||||
@ -5615,6 +5625,9 @@
|
||||
_this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name;
|
||||
_this.email = 'email' in QR.persona.always ? QR.persona.always.email : prev && !/^sage$/.test(prev.email) ? prev.email : persona.email;
|
||||
_this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : Conf['Remember Subject'] ? prev ? prev.sub : persona.sub : '';
|
||||
if (QR.nodes.flag) {
|
||||
_this.flag = prev ? prev.flag : persona.flag;
|
||||
}
|
||||
if (QR.selected === _this) {
|
||||
return _this.load();
|
||||
}
|
||||
@ -5646,7 +5659,7 @@
|
||||
};
|
||||
|
||||
_Class.prototype.lock = function(lock) {
|
||||
var name, _i, _len, _ref;
|
||||
var name, node, _i, _len, _ref;
|
||||
|
||||
if (lock == null) {
|
||||
lock = true;
|
||||
@ -5655,10 +5668,12 @@
|
||||
if (this !== QR.selected) {
|
||||
return;
|
||||
}
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler'];
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler', 'flag'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
name = _ref[_i];
|
||||
QR.nodes[name].disabled = lock;
|
||||
if (node = QR.nodes[name]) {
|
||||
node.disabled = lock;
|
||||
}
|
||||
}
|
||||
this.nodes.rm.style.visibility = lock ? 'hidden' : '';
|
||||
(lock ? $.off : $.on)(QR.nodes.filename.previousElementSibling, 'click', QR.openFileInput);
|
||||
@ -5688,12 +5703,15 @@
|
||||
};
|
||||
|
||||
_Class.prototype.load = function() {
|
||||
var name, _i, _len, _ref;
|
||||
var name, node, _i, _len, _ref;
|
||||
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename'];
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
name = _ref[_i];
|
||||
QR.nodes[name].value = this[name] || null;
|
||||
if (!(node = QR.nodes[name])) {
|
||||
continue;
|
||||
}
|
||||
node.value = this[name] || node.dataset["default"] || null;
|
||||
}
|
||||
this.showFileData();
|
||||
return QR.characterCount();
|
||||
@ -5707,7 +5725,7 @@
|
||||
return;
|
||||
}
|
||||
name = input.dataset.name;
|
||||
this[name] = input.value;
|
||||
this[name] = input.value || input.dataset["default"] || null;
|
||||
switch (name) {
|
||||
case 'thread':
|
||||
return QR.status();
|
||||
@ -5731,15 +5749,18 @@
|
||||
};
|
||||
|
||||
_Class.prototype.forceSave = function() {
|
||||
var name, _i, _len, _ref;
|
||||
var name, node, _i, _len, _ref;
|
||||
|
||||
if (this !== QR.selected) {
|
||||
return;
|
||||
}
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler'];
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler', 'flag'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
name = _ref[_i];
|
||||
this.save(QR.nodes[name]);
|
||||
if (!(node = QR.nodes[name])) {
|
||||
continue;
|
||||
}
|
||||
this.save(node);
|
||||
}
|
||||
};
|
||||
|
||||
@ -6077,7 +6098,7 @@
|
||||
}
|
||||
},
|
||||
dialog: function() {
|
||||
var check, dialog, elm, i, items, key, mimeTypes, name, nodes, thread, value, _ref;
|
||||
var check, dialog, elm, event, flagSelector, i, items, key, mimeTypes, name, node, nodes, save, thread, value, _ref;
|
||||
|
||||
QR.nodes = nodes = {
|
||||
el: dialog = UI.dialog('qr', 'top:0;right:0;', " <div class=move><label><input type=checkbox id=autohide title=Auto-hide>\n Quick Reply\n</label><a href=javascript:; class=close title=Close>×</a><select data-name=thread title='Create a new thread / Reply'><option value=new>New thread</option></select></div><form><div class=persona><input name=name data-name=name list=\"list-name\" placeholder=Name class=field size=1 tabindex=10><input name=email data-name=email list=\"list-email\" placeholder=E-mail class=field size=1 tabindex=20><input name=sub data-name=sub list=\"list-sub\" placeholder=Subject class=field size=1 tabindex=30></div><div class=textarea><textarea data-name=com placeholder=Comment class=field tabindex=40></textarea><span id=char-count></span></div><div id=dump-list-container><div id=dump-list></div><a id=add-post href=javascript:; title=\"Add a post\" tabindex=50>+</a></div><div id=file-n-submit><span id=qr-filename-container class=field tabindex=60><span id=qr-no-file>No selected file</span><input id=\"qr-filename\" data-name=\"filename\" spellcheck=\"false\"><span id=qr-extras-container><a id=qr-filerm href=javascript:; title='Remove file'>×</a><a id=dump-button title='Dump list'>+</a></span></span><label id=qr-spoiler-label><input type=checkbox id=qr-file-spoiler title='Spoiler image' tabindex=70></label><input type=submit tabindex=80></div><input type=file multiple></form><datalist id=\"list-name\"></datalist><datalist id=\"list-email\"></datalist><datalist id=\"list-sub\"></datalist>")
|
||||
@ -6133,8 +6154,15 @@
|
||||
name: 'filetag',
|
||||
innerHTML: "<option value=0>Hentai</option>\n<option value=6>Porn</option>\n<option value=1>Japanese</option>\n<option value=2>Anime</option>\n<option value=3>Game</option>\n<option value=5>Loop</option>\n<option value=4 selected>Other</option>"
|
||||
});
|
||||
nodes.flashTag.dataset["default"] = '4';
|
||||
$.add(nodes.form, nodes.flashTag);
|
||||
}
|
||||
if (flagSelector = $('.flagSelector')) {
|
||||
nodes.flag = flagSelector.cloneNode(true);
|
||||
nodes.flag.dataset.name = 'flag';
|
||||
nodes.flag.dataset["default"] = '0';
|
||||
$.add(nodes.form, nodes.flag);
|
||||
}
|
||||
for (thread in g.BOARD.threads) {
|
||||
$.add(nodes.thread, $.el('option', {
|
||||
value: thread,
|
||||
@ -6169,16 +6197,18 @@
|
||||
return QR.selected.nodes.spoiler.click();
|
||||
});
|
||||
$.on(nodes.fileInput, 'change', QR.handleFiles);
|
||||
items = ['name', 'email', 'sub', 'com', 'filename'];
|
||||
items = ['name', 'email', 'sub', 'com', 'filename', 'flag'];
|
||||
i = 0;
|
||||
while (name = items[i++]) {
|
||||
$.on(nodes[name], 'input', function() {
|
||||
return QR.selected.save(this);
|
||||
});
|
||||
}
|
||||
$.on(nodes.thread, 'change', function() {
|
||||
save = function() {
|
||||
return QR.selected.save(this);
|
||||
});
|
||||
};
|
||||
while (name = items[i++]) {
|
||||
if (!(node = nodes[name])) {
|
||||
continue;
|
||||
}
|
||||
event = node.nodeName === 'SELECT' ? 'change' : 'input';
|
||||
$.on(nodes[name], event, save);
|
||||
}
|
||||
if (Conf['Remember QR Size']) {
|
||||
$.get('QR Size', '', function(item) {
|
||||
return nodes.com.style.cssText = item['QR Size'];
|
||||
@ -6200,7 +6230,7 @@
|
||||
},
|
||||
preSubmitHooks: [],
|
||||
submit: function(e) {
|
||||
var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
|
||||
var challenge, err, extra, filetag, formData, hook, options, post, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
|
||||
|
||||
if (e != null) {
|
||||
e.preventDefault();
|
||||
@ -6264,7 +6294,7 @@
|
||||
d.activeElement.blur();
|
||||
}
|
||||
post.lock();
|
||||
postData = {
|
||||
formData = {
|
||||
resto: threadID,
|
||||
name: post.name,
|
||||
email: post.email,
|
||||
@ -6273,6 +6303,7 @@
|
||||
upfile: post.file,
|
||||
filetag: filetag,
|
||||
spoiler: post.spoiler,
|
||||
flag: post.flag,
|
||||
textonly: textOnly,
|
||||
mode: 'regist',
|
||||
pwd: QR.persona.pwd,
|
||||
@ -6294,7 +6325,7 @@
|
||||
}
|
||||
};
|
||||
extra = {
|
||||
form: $.formData(postData),
|
||||
form: $.formData(formData),
|
||||
upCallbacks: {
|
||||
onload: function() {
|
||||
QR.req.isUploadFinished = true;
|
||||
@ -6378,8 +6409,8 @@
|
||||
threadID: threadID,
|
||||
postID: postID
|
||||
});
|
||||
postsCount = QR.posts.length;
|
||||
QR.cooldown.auto = postsCount > 1 && isReply;
|
||||
postsCount = QR.posts.length - 1;
|
||||
QR.cooldown.auto = postsCount && isReply;
|
||||
if (QR.cooldown.auto && QR.captcha.isEnabled && (captchasCount = QR.captcha.captchas.length) < 3 && captchasCount < postsCount) {
|
||||
notif = new Notification('Quick reply warning', {
|
||||
body: "You are running low on cached captchas. Cache count: " + captchasCount + ".",
|
||||
@ -7494,7 +7525,7 @@
|
||||
return;
|
||||
}
|
||||
DeleteLink.cooldown.counting = post;
|
||||
length = 30;
|
||||
length = 60;
|
||||
seconds = Math.ceil((length * $.SECOND - (Date.now() - post.info.date)) / $.SECOND);
|
||||
return DeleteLink.cooldown.count(post, seconds, length, node);
|
||||
},
|
||||
@ -7808,7 +7839,6 @@
|
||||
if (g.VIEW !== 'thread' || !Conf['Thread Updater']) {
|
||||
return;
|
||||
}
|
||||
checked = Conf['Auto Update'] ? 'checked' : '';
|
||||
if (Conf['Updater and Stats in Header']) {
|
||||
this.dialog = sc = $.el('span', {
|
||||
innerHTML: "<span id=update-status></span><span id=update-timer title='Update now'></span>",
|
||||
@ -7828,6 +7858,7 @@
|
||||
this.checkPostCount = 0;
|
||||
this.timer = $('#update-timer', sc);
|
||||
this.status = $('#update-status', sc);
|
||||
this.isUpdating = Conf['Auto Update'];
|
||||
$.on(this.timer, 'click', ThreadUpdater.update);
|
||||
$.on(this.status, 'click', ThreadUpdater.update);
|
||||
subEntries = [];
|
||||
@ -7845,7 +7876,7 @@
|
||||
$.on(input, 'change', ThreadUpdater.cb.scrollBG);
|
||||
ThreadUpdater.cb.scrollBG();
|
||||
} else if (input.name === 'Auto Update') {
|
||||
$.on(input, 'change', ThreadUpdater.update);
|
||||
$.on(input, 'change', ThreadUpdater.cb.update);
|
||||
}
|
||||
subEntries.push({
|
||||
el: el
|
||||
@ -7875,7 +7906,6 @@
|
||||
ThreadUpdater.thread = this;
|
||||
ThreadUpdater.root = this.OP.nodes.root.parentNode;
|
||||
ThreadUpdater.lastPost = +ThreadUpdater.root.lastElementChild.id.match(/\d+/)[0];
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.cb.interval.call($.el('input', {
|
||||
value: Conf['Interval']
|
||||
}));
|
||||
@ -7892,19 +7922,18 @@
|
||||
beep: 'data:audio/wav;base64,UklGRjQDAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAc21wbDwAAABBAAADAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkYXRhzAIAAGMms8em0tleMV4zIpLVo8nhfSlcPR102Ki+5JspVEkdVtKzs+K1NEhUIT7DwKrcy0g6WygsrM2k1NpiLl0zIY/WpMrjgCdbPhxw2Kq+5Z4qUkkdU9K1s+K5NkVTITzBwqnczko3WikrqM+l1NxlLF0zIIvXpsnjgydZPhxs2ay95aIrUEkdUdC3suK8N0NUIjq+xKrcz002WioppdGm091pK1w0IIjYp8jkhydXPxxq2K295aUrTkoeTs65suK+OUFUIzi7xqrb0VA0WSoootKm0t5tKlo1H4TYqMfkiydWQBxm16+85actTEseS8y7seHAPD9TIza5yKra01QyWSson9On0d5wKVk2H4DYqcfkjidUQB1j1rG75KsvSkseScu8seDCPz1TJDW2yara1FYxWSwnm9Sn0N9zKVg2H33ZqsXkkihSQR1g1bK65K0wSEsfR8i+seDEQTxUJTOzy6rY1VowWC0mmNWoz993KVc3H3rYq8TklSlRQh1d1LS647AyR0wgRMbAsN/GRDpTJTKwzKrX1l4vVy4lldWpzt97KVY4IXbUr8LZljVPRCxhw7W3z6ZISkw1VK+4sMWvXEhSPk6buay9sm5JVkZNiLWqtrJ+TldNTnquqbCwilZXU1BwpKirrpNgWFhTaZmnpquZbFlbVmWOpaOonHZcXlljhaGhpZ1+YWBdYn2cn6GdhmdhYGN3lp2enIttY2Jjco+bnJuOdGZlZXCImJqakHpoZ2Zug5WYmZJ/bGlobX6RlpeSg3BqaW16jZSVkoZ0bGtteImSk5KIeG5tbnaFkJKRinxxbm91gY2QkIt/c3BwdH6Kj4+LgnZxcXR8iI2OjIR5c3J0e4WLjYuFe3VzdHmCioyLhn52dHR5gIiKioeAeHV1eH+GiYqHgXp2dnh9hIiJh4J8eHd4fIKHiIeDfXl4eHyBhoeHhH96eHmA',
|
||||
cb: {
|
||||
online: function() {
|
||||
if (ThreadUpdater.online = navigator.onLine) {
|
||||
if (navigator.onLine) {
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.setInterval();
|
||||
ThreadUpdater.update();
|
||||
ThreadUpdater.set('status', null, null);
|
||||
} else {
|
||||
ThreadUpdater.set('timer', null);
|
||||
ThreadUpdater.set('status', 'Offline', 'warning');
|
||||
}
|
||||
return ThreadUpdater.cb.autoUpdate();
|
||||
return ThreadUpdater.count(true);
|
||||
},
|
||||
post: function(e) {
|
||||
if (e.detail.threadID !== ThreadUpdater.thread.ID) {
|
||||
if (!(ThreadUpdater.isUpdating && e.detail.threadID === ThreadUpdater.thread.ID)) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
@ -7934,9 +7963,7 @@
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
if (ThreadUpdater.seconds > ThreadUpdater.interval) {
|
||||
return ThreadUpdater.setInterval();
|
||||
}
|
||||
return ThreadUpdater.seconds = Math.min(ThreadUpdater.seconds, ThreadUpdater.interval);
|
||||
},
|
||||
scrollBG: function() {
|
||||
return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? function() {
|
||||
@ -7945,17 +7972,10 @@
|
||||
return !d.hidden;
|
||||
};
|
||||
},
|
||||
autoUpdate: function() {
|
||||
if (ThreadUpdater.online) {
|
||||
return ThreadUpdater.timeout();
|
||||
} else {
|
||||
return clearTimeout(ThreadUpdater.timeoutID);
|
||||
}
|
||||
},
|
||||
interval: function() {
|
||||
var val;
|
||||
|
||||
val = +this.value;
|
||||
val = parseInt(this.value, 10);
|
||||
if (val < 1) {
|
||||
val = 1;
|
||||
}
|
||||
@ -7966,9 +7986,9 @@
|
||||
var klass, req, text, _ref;
|
||||
|
||||
req = ThreadUpdater.req;
|
||||
delete ThreadUpdater.req;
|
||||
if (e.type !== 'loadend') {
|
||||
req.onloadend = null;
|
||||
delete ThreadUpdater.req;
|
||||
if (e.type === 'timeout') {
|
||||
ThreadUpdater.set('status', 'Retrying', null);
|
||||
ThreadUpdater.update();
|
||||
@ -7998,9 +8018,8 @@
|
||||
ThreadUpdater.set('status', text, klass);
|
||||
}
|
||||
if (ThreadUpdater.postID) {
|
||||
ThreadUpdater.cb.checkpost();
|
||||
return ThreadUpdater.cb.checkpost();
|
||||
}
|
||||
return delete ThreadUpdater.req;
|
||||
}
|
||||
},
|
||||
setInterval: function() {
|
||||
@ -8013,8 +8032,7 @@
|
||||
}
|
||||
ThreadUpdater.seconds = Conf['Optional Increase'] ? (cur = [0, 5, 10, 15, 20, 30, 60, 90, 120, 240, 300][j] > i) ? cur : i : i;
|
||||
ThreadUpdater.set('timer', ThreadUpdater.seconds++);
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
return ThreadUpdater.timeout();
|
||||
return ThreadUpdater.count(true);
|
||||
},
|
||||
intervalShortcut: function() {
|
||||
var settings;
|
||||
@ -8036,20 +8054,29 @@
|
||||
return el.className = klass;
|
||||
}
|
||||
},
|
||||
count: function(start) {
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
if (start && ThreadUpdater.isUpdating && navigator.onLine) {
|
||||
return ThreadUpdater.timeout();
|
||||
}
|
||||
},
|
||||
timeout: function() {
|
||||
var sec;
|
||||
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
|
||||
ThreadUpdater.set('timer', --ThreadUpdater.seconds);
|
||||
if (ThreadUpdater.seconds <= 0) {
|
||||
sec = ThreadUpdater.seconds--;
|
||||
ThreadUpdater.set('timer', sec);
|
||||
if (sec <= 0) {
|
||||
return ThreadUpdater.update();
|
||||
}
|
||||
},
|
||||
update: function() {
|
||||
var url;
|
||||
|
||||
if (!ThreadUpdater.online) {
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
ThreadUpdater.count();
|
||||
if (Conf['Auto Update']) {
|
||||
ThreadUpdater.set('timer', '...');
|
||||
} else {
|
||||
@ -8235,27 +8262,6 @@
|
||||
ThreadWatcher.fetchAllStatus();
|
||||
this.db.save();
|
||||
}
|
||||
$.get('WatchedThreads', null, function(_arg) {
|
||||
var WatchedThreads, boardID, data, threadID, threads, _ref;
|
||||
|
||||
WatchedThreads = _arg.WatchedThreads;
|
||||
if (!WatchedThreads) {
|
||||
return;
|
||||
}
|
||||
_ref = ThreadWatcher.convert(WatchedThreads);
|
||||
for (boardID in _ref) {
|
||||
threads = _ref[boardID];
|
||||
for (threadID in threads) {
|
||||
data = threads[threadID];
|
||||
ThreadWatcher.db.set({
|
||||
boardID: boardID,
|
||||
threadID: threadID,
|
||||
val: data
|
||||
});
|
||||
}
|
||||
}
|
||||
return $["delete"]('WatchedThreads');
|
||||
});
|
||||
return Thread.prototype.callbacks.push({
|
||||
name: 'Thread Watcher',
|
||||
cb: this.node
|
||||
|
||||
@ -5266,7 +5266,8 @@
|
||||
persona = {
|
||||
name: post.name,
|
||||
email: /^sage$/.test(post.email) ? persona.email : post.email,
|
||||
sub: Conf['Remember Subject'] ? post.sub : void 0
|
||||
sub: Conf['Remember Subject'] ? post.sub : void 0,
|
||||
flag: post.flag
|
||||
};
|
||||
return $.set('QR.persona', persona);
|
||||
});
|
||||
@ -5330,12 +5331,11 @@
|
||||
delay: delay
|
||||
};
|
||||
} else {
|
||||
if (post.file) {
|
||||
if (hasFile = !!post.file) {
|
||||
upSpd = post.file.size / ((start - req.uploadStartTime) / $.SECOND);
|
||||
QR.cooldown.upSpdAccuracy = ((upSpd > QR.cooldown.upSpd * .9) + QR.cooldown.upSpdAccuracy) / 2;
|
||||
QR.cooldown.upSpd = upSpd;
|
||||
}
|
||||
hasFile = !!post.file;
|
||||
cooldown = {
|
||||
isReply: isReply,
|
||||
hasFile: hasFile,
|
||||
@ -5392,7 +5392,17 @@
|
||||
if (elapsed < 0) {
|
||||
continue;
|
||||
}
|
||||
type = !isReply ? 'thread' : hasFile ? 'image' : 'reply';
|
||||
if (!isReply) {
|
||||
type = 'thread';
|
||||
} else if (hasFile) {
|
||||
if (!cooldown.hasFile) {
|
||||
seconds = Math.max(seconds, 0);
|
||||
continue;
|
||||
}
|
||||
type = 'image';
|
||||
} else {
|
||||
type = 'reply';
|
||||
}
|
||||
maxTimer = Math.max(types[type] || 0, types[type + '_intra'] || 0);
|
||||
if (!((start <= now && now <= start + maxTimer * $.SECOND))) {
|
||||
QR.cooldown.unset(start);
|
||||
@ -5405,7 +5415,7 @@
|
||||
}
|
||||
if (seconds && Conf['Cooldown Prediction'] && hasFile && upSpd) {
|
||||
seconds -= Math.floor(post.file.size / upSpd * upSpdAccuracy);
|
||||
seconds = Math.max(seconds, 0);
|
||||
seconds = seconds > 0 ? seconds : 0;
|
||||
}
|
||||
update = seconds !== null || !!QR.cooldown.seconds;
|
||||
QR.cooldown.seconds = seconds;
|
||||
@ -5621,6 +5631,9 @@
|
||||
_this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name;
|
||||
_this.email = 'email' in QR.persona.always ? QR.persona.always.email : prev && !/^sage$/.test(prev.email) ? prev.email : persona.email;
|
||||
_this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : Conf['Remember Subject'] ? prev ? prev.sub : persona.sub : '';
|
||||
if (QR.nodes.flag) {
|
||||
_this.flag = prev ? prev.flag : persona.flag;
|
||||
}
|
||||
if (QR.selected === _this) {
|
||||
return _this.load();
|
||||
}
|
||||
@ -5652,7 +5665,7 @@
|
||||
};
|
||||
|
||||
_Class.prototype.lock = function(lock) {
|
||||
var name, _i, _len, _ref;
|
||||
var name, node, _i, _len, _ref;
|
||||
|
||||
if (lock == null) {
|
||||
lock = true;
|
||||
@ -5661,10 +5674,12 @@
|
||||
if (this !== QR.selected) {
|
||||
return;
|
||||
}
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler'];
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler', 'flag'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
name = _ref[_i];
|
||||
QR.nodes[name].disabled = lock;
|
||||
if (node = QR.nodes[name]) {
|
||||
node.disabled = lock;
|
||||
}
|
||||
}
|
||||
this.nodes.rm.style.visibility = lock ? 'hidden' : '';
|
||||
(lock ? $.off : $.on)(QR.nodes.filename.previousElementSibling, 'click', QR.openFileInput);
|
||||
@ -5694,12 +5709,15 @@
|
||||
};
|
||||
|
||||
_Class.prototype.load = function() {
|
||||
var name, _i, _len, _ref;
|
||||
var name, node, _i, _len, _ref;
|
||||
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename'];
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
name = _ref[_i];
|
||||
QR.nodes[name].value = this[name] || null;
|
||||
if (!(node = QR.nodes[name])) {
|
||||
continue;
|
||||
}
|
||||
node.value = this[name] || node.dataset["default"] || null;
|
||||
}
|
||||
this.showFileData();
|
||||
return QR.characterCount();
|
||||
@ -5713,7 +5731,7 @@
|
||||
return;
|
||||
}
|
||||
name = input.dataset.name;
|
||||
this[name] = input.value;
|
||||
this[name] = input.value || input.dataset["default"] || null;
|
||||
switch (name) {
|
||||
case 'thread':
|
||||
return QR.status();
|
||||
@ -5737,15 +5755,18 @@
|
||||
};
|
||||
|
||||
_Class.prototype.forceSave = function() {
|
||||
var name, _i, _len, _ref;
|
||||
var name, node, _i, _len, _ref;
|
||||
|
||||
if (this !== QR.selected) {
|
||||
return;
|
||||
}
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler'];
|
||||
_ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler', 'flag'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
name = _ref[_i];
|
||||
this.save(QR.nodes[name]);
|
||||
if (!(node = QR.nodes[name])) {
|
||||
continue;
|
||||
}
|
||||
this.save(node);
|
||||
}
|
||||
};
|
||||
|
||||
@ -6081,7 +6102,7 @@
|
||||
}
|
||||
},
|
||||
dialog: function() {
|
||||
var check, dialog, i, items, key, mimeTypes, name, nodes, thread, value, _ref;
|
||||
var check, dialog, event, flagSelector, i, items, key, mimeTypes, name, node, nodes, save, thread, value, _ref;
|
||||
|
||||
QR.nodes = nodes = {
|
||||
el: dialog = UI.dialog('qr', 'top:0;right:0;', " <div class=move><label><input type=checkbox id=autohide title=Auto-hide>\n Quick Reply\n</label><a href=javascript:; class=close title=Close>×</a><select data-name=thread title='Create a new thread / Reply'><option value=new>New thread</option></select></div><form><div class=persona><input name=name data-name=name list=\"list-name\" placeholder=Name class=field size=1 tabindex=10><input name=email data-name=email list=\"list-email\" placeholder=E-mail class=field size=1 tabindex=20><input name=sub data-name=sub list=\"list-sub\" placeholder=Subject class=field size=1 tabindex=30></div><div class=textarea><textarea data-name=com placeholder=Comment class=field tabindex=40></textarea><span id=char-count></span></div><div id=dump-list-container><div id=dump-list></div><a id=add-post href=javascript:; title=\"Add a post\" tabindex=50>+</a></div><div id=file-n-submit><span id=qr-filename-container class=field tabindex=60><span id=qr-no-file>No selected file</span><input id=\"qr-filename\" data-name=\"filename\" spellcheck=\"false\"><span id=qr-extras-container><a id=qr-filerm href=javascript:; title='Remove file'>×</a><a id=dump-button title='Dump list'>+</a></span></span><label id=qr-spoiler-label><input type=checkbox id=qr-file-spoiler title='Spoiler image' tabindex=70></label><input type=submit tabindex=80></div><input type=file multiple></form><datalist id=\"list-name\"></datalist><datalist id=\"list-email\"></datalist><datalist id=\"list-sub\"></datalist>")
|
||||
@ -6137,8 +6158,15 @@
|
||||
name: 'filetag',
|
||||
innerHTML: "<option value=0>Hentai</option>\n<option value=6>Porn</option>\n<option value=1>Japanese</option>\n<option value=2>Anime</option>\n<option value=3>Game</option>\n<option value=5>Loop</option>\n<option value=4 selected>Other</option>"
|
||||
});
|
||||
nodes.flashTag.dataset["default"] = '4';
|
||||
$.add(nodes.form, nodes.flashTag);
|
||||
}
|
||||
if (flagSelector = $('.flagSelector')) {
|
||||
nodes.flag = flagSelector.cloneNode(true);
|
||||
nodes.flag.dataset.name = 'flag';
|
||||
nodes.flag.dataset["default"] = '0';
|
||||
$.add(nodes.form, nodes.flag);
|
||||
}
|
||||
for (thread in g.BOARD.threads) {
|
||||
$.add(nodes.thread, $.el('option', {
|
||||
value: thread,
|
||||
@ -6167,16 +6195,18 @@
|
||||
return QR.selected.nodes.spoiler.click();
|
||||
});
|
||||
$.on(nodes.fileInput, 'change', QR.handleFiles);
|
||||
items = ['name', 'email', 'sub', 'com', 'filename'];
|
||||
items = ['name', 'email', 'sub', 'com', 'filename', 'flag'];
|
||||
i = 0;
|
||||
while (name = items[i++]) {
|
||||
$.on(nodes[name], 'input', function() {
|
||||
return QR.selected.save(this);
|
||||
});
|
||||
}
|
||||
$.on(nodes.thread, 'change', function() {
|
||||
save = function() {
|
||||
return QR.selected.save(this);
|
||||
});
|
||||
};
|
||||
while (name = items[i++]) {
|
||||
if (!(node = nodes[name])) {
|
||||
continue;
|
||||
}
|
||||
event = node.nodeName === 'SELECT' ? 'change' : 'input';
|
||||
$.on(nodes[name], event, save);
|
||||
}
|
||||
QR.persona.init();
|
||||
new QR.post(true);
|
||||
QR.status();
|
||||
@ -6187,7 +6217,7 @@
|
||||
},
|
||||
preSubmitHooks: [],
|
||||
submit: function(e) {
|
||||
var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
|
||||
var challenge, err, extra, filetag, formData, hook, options, post, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
|
||||
|
||||
if (e != null) {
|
||||
e.preventDefault();
|
||||
@ -6251,7 +6281,7 @@
|
||||
d.activeElement.blur();
|
||||
}
|
||||
post.lock();
|
||||
postData = {
|
||||
formData = {
|
||||
resto: threadID,
|
||||
name: post.name,
|
||||
email: post.email,
|
||||
@ -6260,6 +6290,7 @@
|
||||
upfile: post.file,
|
||||
filetag: filetag,
|
||||
spoiler: post.spoiler,
|
||||
flag: post.flag,
|
||||
textonly: textOnly,
|
||||
mode: 'regist',
|
||||
pwd: QR.persona.pwd,
|
||||
@ -6281,7 +6312,7 @@
|
||||
}
|
||||
};
|
||||
extra = {
|
||||
form: $.formData(postData),
|
||||
form: $.formData(formData),
|
||||
upCallbacks: {
|
||||
onload: function() {
|
||||
QR.req.isUploadFinished = true;
|
||||
@ -6365,8 +6396,8 @@
|
||||
threadID: threadID,
|
||||
postID: postID
|
||||
});
|
||||
postsCount = QR.posts.length;
|
||||
QR.cooldown.auto = postsCount > 1 && isReply;
|
||||
postsCount = QR.posts.length - 1;
|
||||
QR.cooldown.auto = postsCount && isReply;
|
||||
if (QR.cooldown.auto && QR.captcha.isEnabled && (captchasCount = QR.captcha.captchas.length) < 3 && captchasCount < postsCount) {
|
||||
notif = new Notification('Quick reply warning', {
|
||||
body: "You are running low on cached captchas. Cache count: " + captchasCount + ".",
|
||||
@ -7481,7 +7512,7 @@
|
||||
return;
|
||||
}
|
||||
DeleteLink.cooldown.counting = post;
|
||||
length = 30;
|
||||
length = 60;
|
||||
seconds = Math.ceil((length * $.SECOND - (Date.now() - post.info.date)) / $.SECOND);
|
||||
return DeleteLink.cooldown.count(post, seconds, length, node);
|
||||
},
|
||||
@ -7795,7 +7826,6 @@
|
||||
if (g.VIEW !== 'thread' || !Conf['Thread Updater']) {
|
||||
return;
|
||||
}
|
||||
checked = Conf['Auto Update'] ? 'checked' : '';
|
||||
if (Conf['Updater and Stats in Header']) {
|
||||
this.dialog = sc = $.el('span', {
|
||||
innerHTML: "<span id=update-status></span><span id=update-timer title='Update now'></span>",
|
||||
@ -7815,6 +7845,7 @@
|
||||
this.checkPostCount = 0;
|
||||
this.timer = $('#update-timer', sc);
|
||||
this.status = $('#update-status', sc);
|
||||
this.isUpdating = Conf['Auto Update'];
|
||||
$.on(this.timer, 'click', ThreadUpdater.update);
|
||||
$.on(this.status, 'click', ThreadUpdater.update);
|
||||
subEntries = [];
|
||||
@ -7832,7 +7863,7 @@
|
||||
$.on(input, 'change', ThreadUpdater.cb.scrollBG);
|
||||
ThreadUpdater.cb.scrollBG();
|
||||
} else if (input.name === 'Auto Update') {
|
||||
$.on(input, 'change', ThreadUpdater.update);
|
||||
$.on(input, 'change', ThreadUpdater.cb.update);
|
||||
}
|
||||
subEntries.push({
|
||||
el: el
|
||||
@ -7862,7 +7893,6 @@
|
||||
ThreadUpdater.thread = this;
|
||||
ThreadUpdater.root = this.OP.nodes.root.parentNode;
|
||||
ThreadUpdater.lastPost = +ThreadUpdater.root.lastElementChild.id.match(/\d+/)[0];
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.cb.interval.call($.el('input', {
|
||||
value: Conf['Interval']
|
||||
}));
|
||||
@ -7879,19 +7909,18 @@
|
||||
beep: 'data:audio/wav;base64,UklGRjQDAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAc21wbDwAAABBAAADAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkYXRhzAIAAGMms8em0tleMV4zIpLVo8nhfSlcPR102Ki+5JspVEkdVtKzs+K1NEhUIT7DwKrcy0g6WygsrM2k1NpiLl0zIY/WpMrjgCdbPhxw2Kq+5Z4qUkkdU9K1s+K5NkVTITzBwqnczko3WikrqM+l1NxlLF0zIIvXpsnjgydZPhxs2ay95aIrUEkdUdC3suK8N0NUIjq+xKrcz002WioppdGm091pK1w0IIjYp8jkhydXPxxq2K295aUrTkoeTs65suK+OUFUIzi7xqrb0VA0WSoootKm0t5tKlo1H4TYqMfkiydWQBxm16+85actTEseS8y7seHAPD9TIza5yKra01QyWSson9On0d5wKVk2H4DYqcfkjidUQB1j1rG75KsvSkseScu8seDCPz1TJDW2yara1FYxWSwnm9Sn0N9zKVg2H33ZqsXkkihSQR1g1bK65K0wSEsfR8i+seDEQTxUJTOzy6rY1VowWC0mmNWoz993KVc3H3rYq8TklSlRQh1d1LS647AyR0wgRMbAsN/GRDpTJTKwzKrX1l4vVy4lldWpzt97KVY4IXbUr8LZljVPRCxhw7W3z6ZISkw1VK+4sMWvXEhSPk6buay9sm5JVkZNiLWqtrJ+TldNTnquqbCwilZXU1BwpKirrpNgWFhTaZmnpquZbFlbVmWOpaOonHZcXlljhaGhpZ1+YWBdYn2cn6GdhmdhYGN3lp2enIttY2Jjco+bnJuOdGZlZXCImJqakHpoZ2Zug5WYmZJ/bGlobX6RlpeSg3BqaW16jZSVkoZ0bGtteImSk5KIeG5tbnaFkJKRinxxbm91gY2QkIt/c3BwdH6Kj4+LgnZxcXR8iI2OjIR5c3J0e4WLjYuFe3VzdHmCioyLhn52dHR5gIiKioeAeHV1eH+GiYqHgXp2dnh9hIiJh4J8eHd4fIKHiIeDfXl4eHyBhoeHhH96eHmA',
|
||||
cb: {
|
||||
online: function() {
|
||||
if (ThreadUpdater.online = navigator.onLine) {
|
||||
if (navigator.onLine) {
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.setInterval();
|
||||
ThreadUpdater.update();
|
||||
ThreadUpdater.set('status', null, null);
|
||||
} else {
|
||||
ThreadUpdater.set('timer', null);
|
||||
ThreadUpdater.set('status', 'Offline', 'warning');
|
||||
}
|
||||
return ThreadUpdater.cb.autoUpdate();
|
||||
return ThreadUpdater.count(true);
|
||||
},
|
||||
post: function(e) {
|
||||
if (e.detail.threadID !== ThreadUpdater.thread.ID) {
|
||||
if (!(ThreadUpdater.isUpdating && e.detail.threadID === ThreadUpdater.thread.ID)) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
@ -7921,9 +7950,7 @@
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
if (ThreadUpdater.seconds > ThreadUpdater.interval) {
|
||||
return ThreadUpdater.setInterval();
|
||||
}
|
||||
return ThreadUpdater.seconds = Math.min(ThreadUpdater.seconds, ThreadUpdater.interval);
|
||||
},
|
||||
scrollBG: function() {
|
||||
return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? function() {
|
||||
@ -7932,17 +7959,10 @@
|
||||
return !d.hidden;
|
||||
};
|
||||
},
|
||||
autoUpdate: function() {
|
||||
if (ThreadUpdater.online) {
|
||||
return ThreadUpdater.timeout();
|
||||
} else {
|
||||
return clearTimeout(ThreadUpdater.timeoutID);
|
||||
}
|
||||
},
|
||||
interval: function() {
|
||||
var val;
|
||||
|
||||
val = +this.value;
|
||||
val = parseInt(this.value, 10);
|
||||
if (val < 1) {
|
||||
val = 1;
|
||||
}
|
||||
@ -7953,9 +7973,9 @@
|
||||
var klass, req, text, _ref;
|
||||
|
||||
req = ThreadUpdater.req;
|
||||
delete ThreadUpdater.req;
|
||||
if (e.type !== 'loadend') {
|
||||
req.onloadend = null;
|
||||
delete ThreadUpdater.req;
|
||||
if (e.type === 'timeout') {
|
||||
ThreadUpdater.set('status', 'Retrying', null);
|
||||
ThreadUpdater.update();
|
||||
@ -7985,9 +8005,8 @@
|
||||
ThreadUpdater.set('status', text, klass);
|
||||
}
|
||||
if (ThreadUpdater.postID) {
|
||||
ThreadUpdater.cb.checkpost();
|
||||
return ThreadUpdater.cb.checkpost();
|
||||
}
|
||||
return delete ThreadUpdater.req;
|
||||
}
|
||||
},
|
||||
setInterval: function() {
|
||||
@ -8000,8 +8019,7 @@
|
||||
}
|
||||
ThreadUpdater.seconds = Conf['Optional Increase'] ? (cur = [0, 5, 10, 15, 20, 30, 60, 90, 120, 240, 300][j] > i) ? cur : i : i;
|
||||
ThreadUpdater.set('timer', ThreadUpdater.seconds++);
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
return ThreadUpdater.timeout();
|
||||
return ThreadUpdater.count(true);
|
||||
},
|
||||
intervalShortcut: function() {
|
||||
var settings;
|
||||
@ -8023,20 +8041,29 @@
|
||||
return el.className = klass;
|
||||
}
|
||||
},
|
||||
count: function(start) {
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
if (start && ThreadUpdater.isUpdating && navigator.onLine) {
|
||||
return ThreadUpdater.timeout();
|
||||
}
|
||||
},
|
||||
timeout: function() {
|
||||
var sec;
|
||||
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
|
||||
ThreadUpdater.set('timer', --ThreadUpdater.seconds);
|
||||
if (ThreadUpdater.seconds <= 0) {
|
||||
sec = ThreadUpdater.seconds--;
|
||||
ThreadUpdater.set('timer', sec);
|
||||
if (sec <= 0) {
|
||||
return ThreadUpdater.update();
|
||||
}
|
||||
},
|
||||
update: function() {
|
||||
var url;
|
||||
|
||||
if (!ThreadUpdater.online) {
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
ThreadUpdater.count();
|
||||
if (Conf['Auto Update']) {
|
||||
ThreadUpdater.set('timer', '...');
|
||||
} else {
|
||||
@ -8222,27 +8249,6 @@
|
||||
ThreadWatcher.fetchAllStatus();
|
||||
this.db.save();
|
||||
}
|
||||
$.get('WatchedThreads', null, function(_arg) {
|
||||
var WatchedThreads, boardID, data, threadID, threads, _ref;
|
||||
|
||||
WatchedThreads = _arg.WatchedThreads;
|
||||
if (!WatchedThreads) {
|
||||
return;
|
||||
}
|
||||
_ref = ThreadWatcher.convert(WatchedThreads);
|
||||
for (boardID in _ref) {
|
||||
threads = _ref[boardID];
|
||||
for (threadID in threads) {
|
||||
data = threads[threadID];
|
||||
ThreadWatcher.db.set({
|
||||
boardID: boardID,
|
||||
threadID: threadID,
|
||||
val: data
|
||||
});
|
||||
}
|
||||
}
|
||||
return $["delete"]('WatchedThreads');
|
||||
});
|
||||
return Thread.prototype.callbacks.push({
|
||||
name: 'Thread Watcher',
|
||||
cb: this.node
|
||||
|
||||
@ -581,7 +581,7 @@ a.hide-announcement {
|
||||
align-self: stretch;
|
||||
flex: 1;
|
||||
}
|
||||
#qr select {
|
||||
#qr select[data-name=thread] {
|
||||
margin: 0;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
@ -794,7 +794,6 @@ a.hide-announcement {
|
||||
}
|
||||
#file-n-submit-container input {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#file-n-submit input[type='submit'] {
|
||||
order: 1;
|
||||
|
||||
110
json/archives.json
Normal file
110
json/archives.json
Normal file
@ -0,0 +1,110 @@
|
||||
[{
|
||||
"uid": 0,
|
||||
"name": "Foolz",
|
||||
"domain": "archive.foolz.us",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["a", "co", "gd", "jp", "m", "q", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"],
|
||||
"files": ["a", "gd", "jp", "m", "q", "tg", "vg", "vp", "vr", "wsg"]
|
||||
}, {
|
||||
"uid": 1,
|
||||
"name": "NSFW Foolz",
|
||||
"domain": "nsfw.foolz.us",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["u"],
|
||||
"files": ["u"]
|
||||
}, {
|
||||
"uid": 2,
|
||||
"name": "The Dark Cave",
|
||||
"domain": "archive.thedarkcave.org",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["c", "int", "out", "po"],
|
||||
"files": ["c", "po"]
|
||||
}, {
|
||||
"uid": 3,
|
||||
"name": "4plebs",
|
||||
"domain": "archive.4plebs.org",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["hr", "tg", "tv", "x"],
|
||||
"files": ["hr", "tg", "tv", "x"]
|
||||
}, {
|
||||
"uid": 4,
|
||||
"name": "Nyafuu",
|
||||
"domain": "archive.nyafuu.org",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["c", "w", "wg"],
|
||||
"files": ["c", "w", "wg"]
|
||||
}, {
|
||||
"uid": 11,
|
||||
"name": "Foolz a Shit",
|
||||
"domain": "archive.foolzashit.com",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["adv", "asp", "cm", "d", "e", "i", "lgbt", "n", "o", "p", "pol", "s", "s4s", "t", "trv", "y"],
|
||||
"files": ["cm", "d", "e", "i", "n", "o", "p", "s", "trv", "y"]
|
||||
}, {
|
||||
"uid": 12,
|
||||
"name": "FapArchive",
|
||||
"domain": "fuuka.worldathleticproject.org",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["b", "e", "h", "hc", "p", "s", "soc", "sp", "u"],
|
||||
"files": ["b", "e", "h", "hc", "p", "s", "soc", "sp", "u"]
|
||||
}, {
|
||||
"uid": 7,
|
||||
"name": "Install Gentoo",
|
||||
"domain": "archive.installgentoo.net",
|
||||
"http": false,
|
||||
"https": true,
|
||||
"software": "fuuka",
|
||||
"boards": ["diy", "g", "sci"],
|
||||
"files": []
|
||||
}, {
|
||||
"uid": 8,
|
||||
"name": "Rebecca Black Tech",
|
||||
"domain": "rbt.asia",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "fuuka",
|
||||
"boards": ["cgl", "g", "mu", "w"],
|
||||
"files": ["cgl", "g", "mu", "w"]
|
||||
}, {
|
||||
"uid": 9,
|
||||
"name": "Heinessen",
|
||||
"domain": "archive.heinessen.com",
|
||||
"http": true,
|
||||
"https": false,
|
||||
"software": "fuuka",
|
||||
"boards": ["an", "fit", "k", "mlp", "r9k", "toy"],
|
||||
"files": ["an", "fit", "k", "r9k", "toy"]
|
||||
}, {
|
||||
"uid": 10,
|
||||
"name": "warosu",
|
||||
"domain": "fuuka.warosu.org",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "fuuka",
|
||||
"boards": ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "q", "tg", "vr"],
|
||||
"files": ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "q", "tg", "vr"]
|
||||
}, {
|
||||
"uid": 13,
|
||||
"name": "Foolz Beta",
|
||||
"domain": "beta.foolz.us",
|
||||
"http": true,
|
||||
"https": true,
|
||||
"withCredentials": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["a", "co", "d", "gd", "h", "jp", "m", "mlp", "q", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
|
||||
"files": ["a", "d", "gd", "h", "jp", "m", "q", "tg", "u", "vg", "vp", "vr", "wsg"]
|
||||
}]
|
||||
@ -23,14 +23,14 @@
|
||||
"font-awesome": "git://github.com/MayhemYDG/Font-Awesome.git#df4285951124f9ca1f3907438462e5ba9e464bcb",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-bump": "~0.0.11",
|
||||
"grunt-concurrent": "~0.3.0",
|
||||
"grunt-concurrent": "~0.3.1",
|
||||
"grunt-contrib-clean": "~0.5.0",
|
||||
"grunt-contrib-coffee": "~0.7.0",
|
||||
"grunt-contrib-compress": "~0.5.2",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-copy": "~0.4.1",
|
||||
"grunt-contrib-watch": "~0.5.0",
|
||||
"grunt-shell": "~0.3.1",
|
||||
"grunt-contrib-watch": "~0.5.3",
|
||||
"grunt-shell": "~0.4.0",
|
||||
"load-grunt-tasks": "~0.1.0"
|
||||
},
|
||||
"repository": {
|
||||
|
||||
@ -15,4 +15,4 @@ Anonymize =
|
||||
delete @nodes.tripcode
|
||||
if @info.email
|
||||
$.replace email, name
|
||||
delete @nodes.email
|
||||
delete @nodes.email
|
||||
|
||||
@ -453,9 +453,8 @@ Config =
|
||||
#/Mod$/;highlight:mod;op:yes
|
||||
# Set a custom class for moot:
|
||||
#/Admin$/;highlight:moot;op:yes
|
||||
"""
|
||||
|
||||
email: ""
|
||||
"""
|
||||
email: ""
|
||||
subject: """
|
||||
# Filter Generals on /v/:
|
||||
#/general/i;boards:v;op:only
|
||||
|
||||
@ -84,7 +84,7 @@ DeleteLink =
|
||||
delete DeleteLink.cooldown.counting
|
||||
return
|
||||
DeleteLink.cooldown.counting = post
|
||||
length = 30
|
||||
length = 60
|
||||
seconds = Math.ceil (length * $.SECOND - (Date.now() - post.info.date)) / $.SECOND
|
||||
DeleteLink.cooldown.count post, seconds, length, node
|
||||
count: (post, seconds, length, node) ->
|
||||
|
||||
@ -2,8 +2,6 @@ ThreadUpdater =
|
||||
init: ->
|
||||
return if g.VIEW isnt 'thread' or !Conf['Thread Updater']
|
||||
|
||||
checked = if Conf['Auto Update'] then 'checked' else ''
|
||||
|
||||
if Conf['Updater and Stats in Header']
|
||||
@dialog = sc = $.el 'span',
|
||||
innerHTML: "<span id=update-status></span><span id=update-timer title='Update now'></span>"
|
||||
@ -16,12 +14,13 @@ ThreadUpdater =
|
||||
$.addClass doc, 'float'
|
||||
$.ready =>
|
||||
$.addClass doc, 'float'
|
||||
$.add d.body, sc
|
||||
$.add d.body, sc
|
||||
|
||||
@checkPostCount = 0
|
||||
|
||||
@timer = $ '#update-timer', sc
|
||||
@status = $ '#update-status', sc
|
||||
@isUpdating = Conf['Auto Update']
|
||||
|
||||
$.on @timer, 'click', ThreadUpdater.update
|
||||
$.on @status, 'click', ThreadUpdater.update
|
||||
@ -38,7 +37,7 @@ ThreadUpdater =
|
||||
$.on input, 'change', ThreadUpdater.cb.scrollBG
|
||||
ThreadUpdater.cb.scrollBG()
|
||||
else if input.name is 'Auto Update'
|
||||
$.on input, 'change', ThreadUpdater.update
|
||||
$.on input, 'change', ThreadUpdater.cb.update
|
||||
subEntries.push el: el
|
||||
|
||||
settings = $.el 'span',
|
||||
@ -63,7 +62,6 @@ ThreadUpdater =
|
||||
ThreadUpdater.thread = @
|
||||
ThreadUpdater.root = @OP.nodes.root.parentNode
|
||||
ThreadUpdater.lastPost = +ThreadUpdater.root.lastElementChild.id.match(/\d+/)[0]
|
||||
ThreadUpdater.outdateCount = 0
|
||||
|
||||
ThreadUpdater.cb.interval.call $.el 'input', value: Conf['Interval']
|
||||
|
||||
@ -81,17 +79,16 @@ ThreadUpdater =
|
||||
|
||||
cb:
|
||||
online: ->
|
||||
if ThreadUpdater.online = navigator.onLine
|
||||
if navigator.onLine
|
||||
ThreadUpdater.outdateCount = 0
|
||||
ThreadUpdater.setInterval()
|
||||
ThreadUpdater.update()
|
||||
ThreadUpdater.set 'status', null, null
|
||||
else
|
||||
ThreadUpdater.set 'timer', null
|
||||
ThreadUpdater.set 'status', 'Offline', 'warning'
|
||||
ThreadUpdater.cb.autoUpdate()
|
||||
ThreadUpdater.count true
|
||||
post: (e) ->
|
||||
return unless e.detail.threadID is ThreadUpdater.thread.ID
|
||||
return unless ThreadUpdater.isUpdating and e.detail.threadID is ThreadUpdater.thread.ID
|
||||
ThreadUpdater.outdateCount = 0
|
||||
setTimeout ThreadUpdater.update, 1000 if ThreadUpdater.seconds > 2
|
||||
checkpost: (e) ->
|
||||
@ -110,28 +107,22 @@ ThreadUpdater =
|
||||
return if d.hidden
|
||||
# Reset the counter when we focus this tab.
|
||||
ThreadUpdater.outdateCount = 0
|
||||
if ThreadUpdater.seconds > ThreadUpdater.interval
|
||||
ThreadUpdater.setInterval()
|
||||
ThreadUpdater.seconds = Math.min ThreadUpdater.seconds, ThreadUpdater.interval
|
||||
scrollBG: ->
|
||||
ThreadUpdater.scrollBG = if Conf['Scroll BG']
|
||||
-> true
|
||||
else
|
||||
-> not d.hidden
|
||||
autoUpdate: ->
|
||||
if ThreadUpdater.online
|
||||
ThreadUpdater.timeout()
|
||||
else
|
||||
clearTimeout ThreadUpdater.timeoutID
|
||||
interval: ->
|
||||
val = +@value
|
||||
val = parseInt @value, 10
|
||||
if val < 1 then val = 1
|
||||
ThreadUpdater.interval = @value = val
|
||||
$.cb.value.call @
|
||||
load: (e) ->
|
||||
{req} = ThreadUpdater
|
||||
delete ThreadUpdater.req
|
||||
if e.type isnt 'loadend' # timeout or abort
|
||||
req.onloadend = null
|
||||
delete ThreadUpdater.req
|
||||
if e.type is 'timeout'
|
||||
ThreadUpdater.set 'status', 'Retrying', null
|
||||
ThreadUpdater.update()
|
||||
@ -161,8 +152,6 @@ ThreadUpdater =
|
||||
if ThreadUpdater.postID
|
||||
ThreadUpdater.cb.checkpost()
|
||||
|
||||
delete ThreadUpdater.req
|
||||
|
||||
setInterval: ->
|
||||
i = ThreadUpdater.interval
|
||||
# Math.min/max is provably slow: http://jsperf.com/math-s-min-max-vs-homemade/5
|
||||
@ -176,8 +165,7 @@ ThreadUpdater =
|
||||
else
|
||||
i
|
||||
ThreadUpdater.set 'timer', ThreadUpdater.seconds++
|
||||
clearTimeout ThreadUpdater.timeoutID
|
||||
ThreadUpdater.timeout()
|
||||
ThreadUpdater.count true
|
||||
|
||||
intervalShortcut: ->
|
||||
Settings.open 'Advanced'
|
||||
@ -194,14 +182,19 @@ ThreadUpdater =
|
||||
el.textContent = text
|
||||
el.className = klass if klass isnt undefined
|
||||
|
||||
count: (start) ->
|
||||
clearTimeout ThreadUpdater.timeoutID
|
||||
ThreadUpdater.timeout() if start and ThreadUpdater.isUpdating and navigator.onLine
|
||||
|
||||
timeout: ->
|
||||
ThreadUpdater.timeoutID = setTimeout ThreadUpdater.timeout, 1000
|
||||
ThreadUpdater.set 'timer', --ThreadUpdater.seconds
|
||||
ThreadUpdater.update() if ThreadUpdater.seconds <= 0
|
||||
sec = ThreadUpdater.seconds--
|
||||
ThreadUpdater.set 'timer', sec
|
||||
ThreadUpdater.update() if sec <= 0
|
||||
|
||||
update: ->
|
||||
return unless ThreadUpdater.online
|
||||
clearTimeout ThreadUpdater.timeoutID
|
||||
return unless navigator.onLine
|
||||
ThreadUpdater.count()
|
||||
if Conf['Auto Update']
|
||||
ThreadUpdater.set 'timer', '...'
|
||||
else
|
||||
|
||||
@ -31,14 +31,6 @@ ThreadWatcher =
|
||||
ThreadWatcher.fetchAllStatus()
|
||||
@db.save()
|
||||
|
||||
# XXX tmp conversion from old to new format
|
||||
$.get 'WatchedThreads', null, ({WatchedThreads}) ->
|
||||
return unless WatchedThreads
|
||||
for boardID, threads of ThreadWatcher.convert WatchedThreads
|
||||
for threadID, data of threads
|
||||
ThreadWatcher.db.set {boardID, threadID, val: data}
|
||||
$.delete 'WatchedThreads'
|
||||
|
||||
Thread::callbacks.push
|
||||
name: 'Thread Watcher'
|
||||
cb: @node
|
||||
|
||||
@ -268,6 +268,7 @@ QR =
|
||||
name: post.name
|
||||
email: if /^sage$/.test post.email then persona.email else post.email
|
||||
sub: if Conf['Remember Subject'] then post.sub else undefined
|
||||
flag: post.flag
|
||||
$.set 'QR.persona', persona
|
||||
|
||||
cooldown:
|
||||
@ -307,11 +308,10 @@ QR =
|
||||
if delay
|
||||
cooldown = {delay}
|
||||
else
|
||||
if post.file
|
||||
if hasFile = !!post.file
|
||||
upSpd = post.file.size / ((start - req.uploadStartTime) / $.SECOND)
|
||||
QR.cooldown.upSpdAccuracy = ((upSpd > QR.cooldown.upSpd * .9) + QR.cooldown.upSpdAccuracy) / 2
|
||||
QR.cooldown.upSpd = upSpd
|
||||
hasFile = !!post.file
|
||||
cooldown = {isReply, hasFile, threadID}
|
||||
QR.cooldown.cooldowns[start] = cooldown
|
||||
$.set "cooldown.#{g.BOARD}", QR.cooldown.cooldowns
|
||||
@ -358,24 +358,28 @@ QR =
|
||||
|
||||
if isReply is cooldown.isReply
|
||||
# Only cooldowns relevant to this post can set the seconds variable:
|
||||
# reply cooldown with a reply, thread cooldown with a thread
|
||||
# reply cooldown with a reply, thread cooldown with a thread
|
||||
elapsed = Math.floor (now - start) / $.SECOND
|
||||
continue if elapsed < 0 # clock changed since then?
|
||||
type = unless isReply
|
||||
'thread'
|
||||
unless isReply
|
||||
type = 'thread'
|
||||
else if hasFile
|
||||
'image'
|
||||
# You can post an image reply immediately after a non-image reply.
|
||||
unless cooldown.hasFile
|
||||
seconds = Math.max seconds, 0
|
||||
continue
|
||||
type = 'image'
|
||||
else
|
||||
'reply'
|
||||
maxTimer = Math.max types[type] or 0, types[type + '_intra'] or 0
|
||||
type = 'reply'
|
||||
maxTimer = Math.max types[type] or 0, types[type + '_intra'] or 0
|
||||
unless start <= now <= start + maxTimer * $.SECOND
|
||||
QR.cooldown.unset start
|
||||
type += '_intra' if isReply and +post.thread is cooldown.threadID
|
||||
type += '_intra' if isReply and +post.thread is cooldown.threadID
|
||||
seconds = Math.max seconds, types[type] - elapsed
|
||||
|
||||
if seconds and Conf['Cooldown Prediction'] and hasFile and upSpd
|
||||
seconds -= Math.floor post.file.size / upSpd * upSpdAccuracy
|
||||
seconds = Math.max seconds, 0
|
||||
seconds = if seconds > 0 then seconds else 0
|
||||
# Update the status when we change posting type.
|
||||
# Don't get stuck at some random number.
|
||||
# Don't interfere with progress status updates.
|
||||
@ -565,6 +569,12 @@ QR =
|
||||
if prev then prev.sub else persona.sub
|
||||
else
|
||||
''
|
||||
|
||||
if QR.nodes.flag
|
||||
@flag = if prev
|
||||
prev.flag
|
||||
else
|
||||
persona.flag
|
||||
@load() if QR.selected is @ # load persona
|
||||
@select() if select
|
||||
@unlock()
|
||||
@ -586,8 +596,8 @@ QR =
|
||||
lock: (lock=true) ->
|
||||
@isLocked = lock
|
||||
return unless @ is QR.selected
|
||||
for name in ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler']
|
||||
QR.nodes[name].disabled = lock
|
||||
for name in ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler', 'flag'] when node = QR.nodes[name]
|
||||
node.disabled = lock
|
||||
@nodes.rm.style.visibility = if lock then 'hidden' else ''
|
||||
(if lock then $.off else $.on) QR.nodes.filename.previousElementSibling, 'click', QR.openFileInput
|
||||
@nodes.spoiler.disabled = lock
|
||||
@ -612,8 +622,9 @@ QR =
|
||||
|
||||
load: ->
|
||||
# Load this post's values.
|
||||
for name in ['thread', 'name', 'email', 'sub', 'com', 'filename']
|
||||
QR.nodes[name].value = @[name] or null
|
||||
for name in ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']
|
||||
continue unless node = QR.nodes[name]
|
||||
node.value = @[name] or node.dataset.default or null
|
||||
@showFileData()
|
||||
QR.characterCount()
|
||||
|
||||
@ -622,7 +633,7 @@ QR =
|
||||
@spoiler = input.checked
|
||||
return
|
||||
{name} = input.dataset
|
||||
@[name] = input.value
|
||||
@[name] = input.value or input.dataset.default or null
|
||||
switch name
|
||||
when 'thread'
|
||||
QR.status()
|
||||
@ -647,8 +658,9 @@ QR =
|
||||
return unless @ is QR.selected
|
||||
# Do this in case people use extensions
|
||||
# that do not trigger the `input` event.
|
||||
for name in ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler']
|
||||
@save QR.nodes[name]
|
||||
for name in ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler', 'flag']
|
||||
continue unless node = QR.nodes[name]
|
||||
@save node
|
||||
return
|
||||
|
||||
setFile: (@file) ->
|
||||
@ -948,7 +960,13 @@ QR =
|
||||
<option value=5>Loop</option>
|
||||
<option value=4 selected>Other</option>
|
||||
"""
|
||||
nodes.flashTag.dataset.default = '4'
|
||||
$.add nodes.form, nodes.flashTag
|
||||
if flagSelector = $ '.flagSelector'
|
||||
nodes.flag = flagSelector.cloneNode true
|
||||
nodes.flag.dataset.name = 'flag'
|
||||
nodes.flag.dataset.default = '0'
|
||||
$.add nodes.form, nodes.flag
|
||||
|
||||
# Make a list of threads.
|
||||
for thread of g.BOARD.threads
|
||||
@ -978,12 +996,15 @@ QR =
|
||||
$.on nodes.fileExtras, 'click', (e) -> e.stopPropagation()
|
||||
$.on nodes.spoiler, 'change', -> QR.selected.nodes.spoiler.click()
|
||||
$.on nodes.fileInput, 'change', QR.handleFiles
|
||||
|
||||
# save selected post's data
|
||||
items = ['name', 'email', 'sub', 'com', 'filename']
|
||||
items = ['name', 'email', 'sub', 'com', 'filename', 'flag']
|
||||
i = 0
|
||||
save = -> QR.selected.save @
|
||||
while name = items[i++]
|
||||
$.on nodes[name], 'input', -> QR.selected.save @
|
||||
$.on nodes.thread, 'change', -> QR.selected.save @
|
||||
continue unless node = nodes[name]
|
||||
event = if node.nodeName is 'SELECT' then 'change' else 'input'
|
||||
$.on nodes[name], event, save
|
||||
|
||||
<% if (type === 'userscript') { %>
|
||||
if Conf['Remember QR Size']
|
||||
@ -1029,7 +1050,7 @@ QR =
|
||||
# prevent errors
|
||||
if threadID is 'new'
|
||||
threadID = null
|
||||
if g.BOARD.ID is 'vg' and !post.sub
|
||||
if g.BOARD.ID is 'vg' and !post.sub
|
||||
err = 'New threads require a subject.'
|
||||
else unless post.file or textOnly = !!$ 'input[name=textonly]', $.id 'postForm'
|
||||
err = 'No file selected.'
|
||||
@ -1065,7 +1086,7 @@ QR =
|
||||
|
||||
post.lock()
|
||||
|
||||
postData =
|
||||
formData =
|
||||
resto: threadID
|
||||
name: post.name
|
||||
email: post.email
|
||||
@ -1074,6 +1095,7 @@ QR =
|
||||
upfile: post.file
|
||||
filetag: filetag
|
||||
spoiler: post.spoiler
|
||||
flag: post.flag
|
||||
textonly: textOnly
|
||||
mode: 'regist'
|
||||
pwd: QR.persona.pwd
|
||||
@ -1097,7 +1119,7 @@ QR =
|
||||
[<a href="//4chan.org/banned" target=_blank>Banned?</a>] [<a href="https://github.com/seaweedchan/4chan-x/wiki/Frequently-Asked-Questions#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean" target=_blank>More info</a>]
|
||||
"""
|
||||
extra =
|
||||
form: $.formData postData
|
||||
form: $.formData formData
|
||||
upCallbacks:
|
||||
onload: ->
|
||||
# Upload done, waiting for server response.
|
||||
@ -1202,9 +1224,9 @@ QR =
|
||||
postID
|
||||
}
|
||||
|
||||
# Enable auto-posting if we have stuff to post, disable it otherwise.
|
||||
postsCount = QR.posts.length
|
||||
QR.cooldown.auto = postsCount > 1 and isReply
|
||||
# Enable auto-posting if we have stuff left to post, disable it otherwise.
|
||||
postsCount = QR.posts.length - 1
|
||||
QR.cooldown.auto = postsCount and isReply
|
||||
if QR.cooldown.auto and QR.captcha.isEnabled and (captchasCount = QR.captcha.captchas.length) < 3 and captchasCount < postsCount
|
||||
notif = new Notification 'Quick reply warning',
|
||||
body: "You are running low on cached captchas. Cache count: #{captchasCount}."
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user