Open chanadmins opened 2 months ago
I can open PR with my changes
Done
Done
I added your changes and quick reply loads from index but I can't post anything from it: "Your request looks automated; Post discarded."
This is likely happening due to a mismatch between submit button values. The variables in main.js is to fix this.
Edit: Oh shit, I forgot to close the tag.
Can you try again with this change? 60e2ca2a8816fba0b3060b2c1b938d2304de33ee
Can you try again with this change? 60e2ca2
Still the same
I think it's because of that whole antibot thing in functions.php. I remember I implemented quick reply from index once and it involved removing the antibot block from functions.php and some other stuff. It creates non-existing fields or something so it prevents posting from index quick reply.
Weird. this is literally the code running on magali with antibot on. Going to take a closer look later
Okay, so the problem was: the hash sent to checkSpam
was the hash of the index, not the thread. Which failed everytime because the extra_salt was wrong.
This is the best solution I could come up: 4b20ad55ffe9bd4d33590f90eca1ac14b8c0e6f9
Okay, so the problem was: the hash sent to
checkSpam
was the hash of the index, not the thread. Which failed everytime because the extra_salt was wrong.This is the best solution I could come up: 4b20ad5
It works now, thanks!
Wait, shouldn't quick reply change threads based on the post number I click? So here I click >>6038 and quick reply appears to thread Quick Reply (5963) but then I click >>6100 and quick reply should change to Quick Reply (6074) but it stays Quick Reply (5963) At least that's how most of the implementations I've seen work (like on Willboard), with dynamic changing threads.
Wait, shouldn't quick reply change threads based on the post number I click?
In the perfect javascript, yes. We can force to "change" by closing and opening again.
$(window).on('cite', function(e, id, with_link) {
if ($(this).width() <= 400)
return;
if ($('#quick-reply').length) $('#quick-reply').remove();
show_quick_reply(id);
if (with_link) {
$(document).ready(function() {
if ($('#' + id).length) {
highlightReply(id);
$(document).scrollTop($('#' + id).offset().top);
}
// Honestly, I'm not sure why we need setTimeout() here, but it seems to work.
// Same for the "tmp" variable stuff you see inside here:
setTimeout(function() {
var tmp = $('#quick-reply textarea[name="body"]').val();
$('#quick-reply textarea[name="body"]').val('').focus().val(tmp);
}, 1);
});
}
});
Wait, shouldn't quick reply change threads based on the post number I click?
In the perfect javascript, yes. We can force to "change" by closing and opening again.
Any way to do this without opening/closing quick reply window and just clicking post number? I remember it worked in my previous implementation of this
/*
* quick-reply.js
* https://github.com/savetheinternet/Tinyboard/blob/master/js/quick-reply.js
*
* Released under the MIT license
* Copyright (c) 2013 Michael Save <savetheinternet@tinyboard.org>
* Copyright (c) 2013-2014 Marcin Łabanowski <marcin@6irc.net>
*
* Usage:
* $config['additional_javascript'][] = 'js/jquery.min.js';
* $config['additional_javascript'][] = 'js/jquery-ui.custom.min.js'; // Optional; if you want the form to be draggable.
* $config['additional_javascript'][] = 'js/quick-reply.js';
*
*/
(function() {
var new_reply = "Odpowiedz"; // ta zmienna musi być taka sama jak przycisk nowej odpowiedzi w temacie
if(document.querySelector("body").classList.contains("active-index")) {
document.addEventListener("click", function(event) {
if(event.target.classList.contains("post_no") && event.target.id === "") {
event.preventDefault();
}
});
}
var settings = new script_settings('quick-reply');
var do_css = function() {
$('#quick-reply-css').remove();
// Find background of reply posts
var dummy_reply = $('<div class="post reply"></div>').appendTo($('body'));
var reply_background = dummy_reply.css('backgroundColor');
var reply_border_style = dummy_reply.css('borderStyle');
var reply_border_color = dummy_reply.css('borderColor');
var reply_border_width = dummy_reply.css('borderWidth');
dummy_reply.remove();
$('<style type="text/css" id="quick-reply-css">\
#quick-reply {\
position: fixed;\
right: 5%;\
top: 5%;\
float: right;\
display: block;\
padding: 0 0 0 0;\
width: 300px;\
z-index: 100;\
}\
#quick-reply table {\
border-collapse: collapse;\
background: ' + reply_background + ';\
border-style: ' + reply_border_style + ';\
border-width: ' + reply_border_width + ';\
border-color: ' + reply_border_color + ';\
margin: 0;\
width: 100%;\
}\
#quick-reply tr td:nth-child(2) {\
white-space: nowrap;\
text-align: right;\
padding-right: 4px;\
}\
#quick-reply tr td:nth-child(2) input[type="submit"] {\
width: 100%;\
}\
#quick-reply th, #quick-reply td {\
margin: 0;\
padding: 0;\
}\
#quick-reply th {\
text-align: center;\
padding: 2px 0;\
border: 1px solid #222;\
}\
#quick-reply th .handle {\
float: left;\
width: 100%;\
display: inline-block;\
}\
#quick-reply th .close-btn {\
float: right;\
padding: 0 5px;\
}\
#quick-reply input[type="text"], #quick-reply select {\
width: 100%;\
padding: 2px;\
font-size: 10pt;\
box-sizing: border-box;\
-webkit-box-sizing:border-box;\
-moz-box-sizing: border-box;\
}\
#quick-reply textarea {\
/* width: 100%; */\
min-width: 100%;\
box-sizing: border-box;\
-webkit-box-sizing:border-box;\
-moz-box-sizing: border-box;\
font-size: 10pt;\
resize: vertical horizontal;\
}\
#quick-reply input, #quick-reply select, #quick-reply textarea {\
margin: 0 0 1px 0;\
}\
#quick-reply input[type="file"] {\
padding: 5px 2px;\
}\
#quick-reply .nonsense {\
display: none;\
}\
#quick-reply td.submit {\
width: 1%;\
}\
#quick-reply td.recaptcha {\
text-align: center;\
padding: 0 0 1px 0;\
}\
#quick-reply td.recaptcha span {\
display: inline-block;\
width: 100%;\
background: white;\
border: 1px solid #ccc;\
cursor: pointer;\
}\
#quick-reply td.recaptcha-response {\
padding: 0 0 1px 0;\
}\
@media screen and (max-width: 400px) {\
#quick-reply {\
/* display: none !important; */\
}\
}\
</style>').appendTo($('head'));
};
var show_quick_reply = function(target_id){
if($('div.banner').length == 0){
var thread_id = $("#reply_" + target_id + ",#op_"+target_id).parent().attr("id").split("_")[1];
var in_index = true;
}
else
var in_index = false;
if($('#quick-reply').length != 0) {
return;
}
do_css();
var $postForm = $('form[name="post"]').clone();
$postForm.clone();
$dummyStuff = $('<div class="nonsense"></div>').appendTo($postForm);
$postForm.find('table tr').each(function() {
var $th = $(this).children('th:first');
var $td = $(this).children('td:first');
if ($th.length && $td.length) {
$td.attr('colspan', 2);
if ($td.find('input[type="text"]').length) {
// Replace <th> with input placeholders
$td.find('input[type="text"]')
.removeAttr('size')
.attr('placeholder', $th.clone().children().remove().end().text());
}
// Move anti-spam nonsense and remove <th>
$th.contents().filter(function() {
return this.nodeType == 3; // Node.TEXT_NODE
}).remove();
$th.contents().appendTo($dummyStuff);
$th.remove();
if ($td.find('input[name="password"]').length) {
// Hide password field
$(this).hide();
}
// Fix submit button
if ($td.find('input[type="submit"]').length) {
$td.removeAttr('colspan');
$('<td class="submit"></td>').append($td.find('input[type="submit"]')).insertAfter($td);
}
// reCAPTCHA
if ($td.find('#recaptcha_widget_div').length) {
// Just show the image, and have it interact with the real form.
var $captchaimg = $td.find('#recaptcha_image img');
$captchaimg
.removeAttr('id')
.removeAttr('style')
.addClass('recaptcha_image')
.click(function() {
$('#recaptcha_reload').click();
});
// When we get a new captcha...
$('#recaptcha_response_field').focus(function() {
if ($captchaimg.attr('src') != $('#recaptcha_image img').attr('src')) {
$captchaimg.attr('src', $('#recaptcha_image img').attr('src'));
$postForm.find('input[name="recaptcha_challenge_field"]').val($('#recaptcha_challenge_field').val());
$postForm.find('input[name="recaptcha_response_field"]').val('').focus();
}
});
$postForm.submit(function() {
setTimeout(function() {
$('#recaptcha_reload').click();
}, 200);
});
// Make a new row for the response text
var $newRow = $('<tr><td class="recaptcha-response" colspan="2"></td></tr>');
$newRow.children().first().append(
$td.find('input').removeAttr('style')
);
$newRow.find('#recaptcha_response_field')
.removeAttr('id')
.addClass('recaptcha_response_field')
.attr('placeholder', $('#recaptcha_response_field').attr('placeholder'));
$('#recaptcha_response_field').addClass('recaptcha_response_field')
$td.replaceWith($('<td class="recaptcha" colspan="2"></td>').append($('<span></span>').append($captchaimg)));
$newRow.insertAfter(this);
}
// Upload section
if ($td.find('input[type="file"]').length) {
if($td.find('input[name="file"]').length){
$file = $td.find('input[name="file"]');
$file.attr("style","width:90%");
}
//captcha stuff
var $captcha_span = $td.find('span[name="captchasel"]');
var $caprow = $('<tr><td colspan="2"></td></tr>');
$captcha_span.clone().appendTo($caprow.find('td'));
$caprow.insertBefore(this);
if ($td.find('input[name="file_url"]').length) {
$file_url = $td.find('input[name="file_url"]');
//if (settings.get('show_remote', false)) {
// Make a new row for it
var $newRow = $('<tr><td colspan="2"></td></tr>');
$file_url.clone().attr('placeholder', _('\
Upload URL')).appendTo($newRow.find('td'));
$newRow.insertAfter(this);
//}
$file_url.parent().remove();
$td.find('label').remove();
$td.contents().filter(function() {
return this.nodeType == 3; // Node.TEXT_NODE
}).remove();
$td.find('input[name="file_url"]').removeAttr('id');
}
if ($(this).find('input[name="spoiler"]').length) {
$td.removeAttr('colspan');
}
}
//captcha controls
if($td.find('input[name=captype]').length > 0){
}
// Disable embedding if configured so
// if (!settings.get('show_embed', false) && $td.find('input[name="embed"]').length) {
// $(this).remove();
// }
// Remove oekaki if existent
if ($(this).is('#oekaki')) {
$(this).remove();
}
// Remove upload selection
if ($td.is('#upload_selection')) {
$(this).remove();
}
// Remove mod controls, because it looks shit.
if ($td.find('input[type="checkbox"]').length) {
var tr = this;
$td.find('input[type="checkbox"]').each(function() {
if ($(this).attr('name') == 'spoiler') {
$td.find('label').remove();
$(this).attr('id', 'q-spoiler-image');
$postForm.find('input[type="file"]').parent()
.removeAttr('colspan')
.after($('<td class="spoiler"></td>').append(this, ' ', $('<label for="q-spoiler-image">').text(_('Spoiler Image'))));
} else if ($(this).attr('name') == 'no_country') {
$td.find('label,input[type="checkbox"]').remove();
} else {
$(tr).remove();
}
});
}
$td.find('small').hide();
}
if($td.find('[name="markup-hint"]').length){
$td.remove();
}
});
$postForm.find('textarea[name="body"]').removeAttr('id').removeAttr('cols').attr('placeholder', _('Comment'));
$postForm.find('textarea:not([name="body"]),input[type="hidden"]:not(.captcha_cookie)').removeAttr('id').appendTo($dummyStuff);
$postForm.find('br').remove();
$postForm.find('table').prepend('<tr><th colspan="2">\
<span class="handle">\
<a class="close-btn" href="javascript:void(0)">×</a>\
' + _('Quick Reply') + '\
</span>\
</th></tr>');
$postForm.attr('id', 'quick-reply');
$postForm.appendTo($('body')).hide();
$origPostForm = $('form[name="post"]:first');
// insert the thread that this post will be placed in and modify fields
if(in_index) {
// ziemniachan fix
$("#quick-reply").find("input[type=submit]").remove();
document.querySelectorAll("#quick-reply tr")[2].remove();
document.querySelector("#quick-reply [name=email]")?.parentNode.setAttribute("colspan", "1");
document.querySelectorAll("#quick-reply tr")[1].innerHTML += '<td class="submit"><input accesskey="s" style="margin-left:2px;" type="submit" name="post" value="'+new_reply+'"></td>';
$("#quick-reply textarea").attr("id", "index-body");
$("<input type='hidden' name='thread' value='" + thread_id + "'>").appendTo($("#quick-reply"));
$("#quick-reply .handle").append(document.createTextNode("(>>" + thread_id + ")"));
}
//$("#quick-reply input[type=submit]").attr("value", "New Reply");
// }
// otherwise synchronise body text with original post form
// else if(!in_index){
$origPostForm.find('textarea[name="body"]').on('change input propertychange', function() {
$postForm.find('textarea[name="body"]').val($(this).val());
});
$postForm.find('textarea[name="body"]').on('change input propertychange', function() {
$origPostForm.find('textarea[name="body"]').val($(this).val());
});
$postForm.find('textarea[name="body"]').focus(function() {
$origPostForm.find('textarea[name="body"]').removeAttr('id');
$(this).attr('id', 'body');
});
$origPostForm.find('textarea[name="body"]').focus(function() {
$postForm.find('textarea[name="body"]').removeAttr('id');
$(this).attr('id', 'body');
});
// Synchronise other inputs
$origPostForm.find('input[type="text"],select').on('change input propertychange', function() {
$postForm.find('[name="' + $(this).attr('name') + '"]').val($(this).val());
});
$postForm.find('input[type="text"],select').on('change input propertychange', function() {
$origPostForm.find('[name="' + $(this).attr('name') + '"]').val($(this).val());
});
// }
if (typeof $postForm.draggable != 'undefined') {
if (localStorage.quickReplyPosition) {
var offset = JSON.parse(localStorage.quickReplyPosition);
if (offset.top < 0)
offset.top = 0;
if (offset.right > $(window).width() - $postForm.width())
offset.right = $(window).width() - $postForm.width();
if (offset.top > $(window).height() - $postForm.height())
offset.top = $(window).height() - $postForm.height();
$postForm.css('right', offset.right).css('top', offset.top);
}
$postForm.draggable({
handle: 'th .handle',
containment: 'window',
distance: 10,
scroll: false,
stop: function() {
var offset = {
top: $(this).offset().top - $(window).scrollTop(),
right: $(window).width() - $(this).offset().left - $(this).width(),
};
localStorage.quickReplyPosition = JSON.stringify(offset);
$postForm.css('right', offset.right).css('top', offset.top).css('left', 'auto');
}
});
$postForm.find('th .handle').css('cursor', 'move');
}
$postForm.find('th .close-btn').click(function() {
$origPostForm.find('textarea[name="body"]').attr('id', 'body');
$postForm.remove();
floating_link();
});
// Fix bug when table gets too big for form. Shouldn't exist, but crappy CSS etc.
$postForm.show();
$postForm.width($postForm.find('table').width());
$postForm.hide();
$(window).trigger('quick-reply');
$(window).ready(function() {
if (!in_index && settings.get('hide_at_top', true)) {
$(window).scroll(function() {
if ($(this).width() <= 400)
return;
if ($(this).scrollTop() < $origPostForm.offset().top + $origPostForm.height() - 100)
$postForm.fadeOut(100);
else
$postForm.fadeIn(100);
}).scroll();
} else {
$postForm.show();
}
$(window).on('stylesheet', function() {
do_css();
if ($('link#stylesheet').attr('href')) {
$('link#stylesheet')[0].onload = do_css;
}
});
});
};
$(window).on('cite', function(e, id, with_link) {
if ($(this).width() <= 400)
return;
var origin_id = id;
// find the thread id for a cite if citereply call is done in index
// pass in null if not found, it won't be evaluated in show_quick_reply
show_quick_reply(origin_id);
// captchaSetup();
if (with_link) {
$(document).ready(function() {
if ($('#' + id).length) {
highlightReply(id);
$(document).scrollTop($('#' + id).offset().top);
}
// Honestly, I'm not sure why we need setTimeout() here, but it seems to work.
// Same for the "tmp" variable stuff you see inside here:
setTimeout(function() {
var tmp = $('#quick-reply textarea[name="body"]').val();
$('#quick-reply textarea[name="body"]').val('').focus().val(tmp);
}, 1);
});
}
});
var floating_link = function() {
if (!settings.get('floating_link', false))
return;
$('<a href="javascript:void(0)" class="quick-reply-btn">'+_('Quick Reply')+'</a>')
.click(function() {
show_quick_reply();
$(this).remove();
}).appendTo($('body'));
$(window).on('quick-reply', function() {
$('.quick-reply-btn').remove();
});
};
if (settings.get('floating_link', false)) {
$(window).ready(function() {
if($('div.banner').length == 0)
return;
$('<style type="text/css">\
a.quick-reply-btn {\
position: fixed;\
right: 0;\
bottom: 0;\
display: block;\
padding: 5px 13px;\
text-decoration: none;\
}\
</style>').appendTo($('head'));
floating_link();
if (settings.get('hide_at_top', true)) {
$('.quick-reply-btn').hide();
$(window).scroll(function() {
if ($(this).width() <= 400)
return;
if ($(this).scrollTop() < $('form[name="post"]:first').offset().top + $('form[name="post"]:first').height() - 100)
$('.quick-reply-btn').fadeOut(100);
else
$('.quick-reply-btn').fadeIn(100);
}).scroll();
}
});
}
})();
but I can't implement it again because I don't remember changes in other files like functions.php
It's possible, but I really don't care and also spent too much time in this shit and the last commit of active-page I realized it's not in the perfect state which I thought it was.
But hey, if you wanna do it, be my guess. Just check if the current thread in the quick-reply is the same, if not change the input thread with the new value.
Ok, I cared enough to try at least. Remove the last patch of removing the quick-reply.
if($('#quick-reply').length != 0) { // line 138
if ($('#quick-reply').data('thread-id') !== target_id) {
$(`<input type='hidden' name='thread' value='${thread_id}'></input>`).appendTo($("#quick-reply"));
$("#quick-reply .handle #thread-id-number").remove();
const threadIdSpan = `<span id="thread-id-number">(${thread_id})</span>`;
$("#quick-reply .handle").append(threadIdSpan);
$("#quick-reply").attr("data-thread-id", thread_id);
}
return;
}
if (in_index) { // line 307
$(`<input type='hidden' name='thread' value='${thread_id}'></input>`).appendTo($("#quick-reply"));
const threadIdSpan = `<span id="thread-id-number">(${thread_id})</span>`;
$("#quick-reply .handle").append(threadIdSpan);
$("#quick-reply").attr("data-thread-id", thread_id);
$("#quick-reply .form_submit").attr("value", button_reply);
if (post_captcha == 'false') {
$("#quick-reply .captcha").remove();
}
}
Ok, I cared enough to try at least. Remove the last patch of removing the quick-reply.
It works now, thanks ^^
Wait, I found a bug: Reply button disapears from quick reply when thread is opened
What do you mean? How can I reproduce?
Thread page: Index page:
I think this should be available as a basic feature. Forks like bazukachan or kissu already have that. Yotsuba, Mitsuba, Lynxchan, JSchan, Willboard, basically almost every imageboard software besides vichan has option to post in thread from quick reply without opening it. Would love to see this added. example on magalichan: