Add TINYIB_BACKLINKS

Display reflinks to replies that reference a post.
This commit is contained in:
Trevor Slocum 2021-06-02 23:04:59 -07:00
parent fca5562fd2
commit 8b8c4a88c3
7 changed files with 104 additions and 22 deletions

View File

@ -155,8 +155,8 @@ hr {
} }
.reply { .reply {
background: #F0E0D6; background: #F0E0D6 !important;
color: #800000; color: #800000 !important;
} }
.replyhl { .replyhl {

View File

@ -566,7 +566,7 @@ if (!isset($_GET['delete']) && !isset($_GET['manage']) && (isset($_POST['name'])
die(__('This post requires moderation before it can be displayed')); die(__('This post requires moderation before it can be displayed'));
} }
$html = buildPost($post, isset($_GET['res'])); $html = buildPost($post, isset($_GET['res']), true);
if (isset($_GET['res'])) { if (isset($_GET['res'])) {
$html = fixLinksInRes($html); $html = fixLinksInRes($html);
} }

View File

@ -109,6 +109,9 @@ if (!defined('TINYIB_EXPANDWIDTH')) {
if (!defined('TINYIB_TIMEZONE')) { if (!defined('TINYIB_TIMEZONE')) {
define('TINYIB_TIMEZONE', ''); define('TINYIB_TIMEZONE', '');
} }
if (!defined('TINYIB_BACKLINKS')) {
define('TINYIB_BACKLINKS', true);
}
if (!defined('TINYIB_CATALOG')) { if (!defined('TINYIB_CATALOG')) {
define('TINYIB_CATALOG', true); define('TINYIB_CATALOG', true);
} }

View File

@ -441,6 +441,13 @@ function setParent() {
return TINYIB_NEWTHREAD; return TINYIB_NEWTHREAD;
} }
function getParent($post) {
if ($post['parent'] == TINYIB_NEWTHREAD) {
return $post['id'];
}
return $post['parent'];
}
function isRawPost() { function isRawPost() {
if (isset($_POST['rawpost'])) { if (isset($_POST['rawpost'])) {
list($loggedin, $isadmin) = manageCheckLogIn(false); list($loggedin, $isadmin) = manageCheckLogIn(false);

View File

@ -413,7 +413,36 @@ EOF;
return $output; return $output;
} }
function buildPost($post, $res) { function backlinks($post) {
if (!TINYIB_BACKLINKS) {
return '';
}
global $thread_cache;
$parent_id = getParent($post);
if (!isset($thread_cache[$parent_id])) {
$thread_cache[$parent_id] = postsInThreadByID($parent_id);
}
$needle = '>>' . $post['id'];
$return = '';
foreach ($thread_cache[$parent_id] as $reply) {
if (strpos($reply['message'], $needle) !== false) {
if ($return != '') {
$return .= ', ';
}
$return .= postLink('>>' . $reply['id']);
}
}
if ($return != '') {
$return = ' ' . $return;
}
return ' <small><span id="reflinks' . $post['id'] . '" class="reflink">' . $return . '</span></small>';
}
function buildPost($post, $res, $compact=false) {
$return = ""; $return = "";
$threadid = ($post['parent'] == TINYIB_NEWTHREAD) ? $post['id'] : $post['parent']; $threadid = ($post['parent'] == TINYIB_NEWTHREAD) ? $post['id'] : $post['parent'];
@ -509,17 +538,22 @@ EOF;
} }
} }
if ($post['parent'] == TINYIB_NEWTHREAD) { if ($post['parent'] == TINYIB_NEWTHREAD) {
$return .= '<div id="post' . $post['id'] . '" class="op">';
$return .= $filehtml; $return .= $filehtml;
} else { } else {
$return .= <<<EOF if ($compact) {
$return .= '<div id="' . $post['id'] . '" class="' . ($post['parent'] == TINYIB_NEWTHREAD ? 'op' : 'reply') . '">';
} else {
$return .= <<<EOF
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td class="doubledash"> <td class="doubledash">
&#0168; &#0168;
</td> </td>
<td class="reply" id="reply${post["id"]}"> <td class="reply" id="post${post["id"]}">
EOF; EOF;
}
} }
$return .= <<<EOF $return .= <<<EOF
@ -540,12 +574,19 @@ ${post["nameblock"]}
</span> </span>
EOF; EOF;
if ($post['parent'] != TINYIB_NEWTHREAD) {
$return .= backlinks($post);
}
if ($post['parent'] != TINYIB_NEWTHREAD) { if ($post['parent'] != TINYIB_NEWTHREAD) {
$return .= $filehtml; $return .= $filehtml;
} }
if ($post['parent'] == TINYIB_NEWTHREAD && $res == TINYIB_INDEXPAGE) { if ($post['parent'] == TINYIB_NEWTHREAD) {
$return .= "&nbsp;[<a href=\"res/${post["id"]}.html\">" . __("Reply") . "</a>]"; if ($res == TINYIB_INDEXPAGE) {
$return .= "&nbsp;[<a href=\"res/${post["id"]}.html\">" . __("Reply") . "</a>]";
}
$return .= backlinks($post);
} }
if (TINYIB_TRUNCATE > 0 && !$res && substr_count($post['message'], '<br>') > TINYIB_TRUNCATE) { // Truncate messages on board index pages for readability if (TINYIB_TRUNCATE > 0 && !$res && substr_count($post['message'], '<br>') > TINYIB_TRUNCATE) { // Truncate messages on board index pages for readability
@ -560,6 +601,7 @@ ${post["message"]}
EOF; EOF;
if ($post['parent'] == TINYIB_NEWTHREAD) { if ($post['parent'] == TINYIB_NEWTHREAD) {
$return .= '</div>';
if ($res == TINYIB_INDEXPAGE && $post['omitted'] > 0) { if ($res == TINYIB_INDEXPAGE && $post['omitted'] > 0) {
if ($post['omitted'] == 1) { if ($post['omitted'] == 1) {
$return .= '<span class="omittedposts">' . __('1 post omitted. Click Reply to view.') . '</span>'; $return .= '<span class="omittedposts">' . __('1 post omitted. Click Reply to view.') . '</span>';
@ -567,6 +609,8 @@ EOF;
$return .= '<span class="omittedposts">' . sprintf(__('%d posts omitted. Click Reply to view.'), $post['omitted']) . '</span>'; $return .= '<span class="omittedposts">' . sprintf(__('%d posts omitted. Click Reply to view.'), $post['omitted']) . '</span>';
} }
} }
} else if ($compact) {
$return .= '</div>';
} else { } else {
$return .= <<<EOF $return .= <<<EOF
</td> </td>
@ -639,10 +683,14 @@ EOF;
$postform = buildPostForm($parent) . '<hr>'; $postform = buildPostForm($parent) . '<hr>';
} }
$js_autorefresh = ''; $js = '<script type="text/javascript">';
$js .= 'var enablebacklinks = ' . (TINYIB_BACKLINKS ? 'true' : 'false') . ';';
if ($parent != TINYIB_NEWTHREAD && TINYIB_AUTOREFRESH > 0) { if ($parent != TINYIB_NEWTHREAD && TINYIB_AUTOREFRESH > 0) {
$js_autorefresh = '<script type="text/javascript">var autoRefreshDelay = ' . TINYIB_AUTOREFRESH . ';var autoRefreshThreadID = ' . $parent . ';var autoRefreshPostID = ' . $lastpostid . ';</script>'; $js .= 'var autoRefreshDelay = ' . TINYIB_AUTOREFRESH . ';';
$js .= 'var autoRefreshThreadID = ' . $parent . ';';
$js .= 'var autoRefreshPostID = ' . $lastpostid . ';';
} }
$js .= '</script>';
$txt_style = __('Style'); $txt_style = __('Style');
$txt_password = __('Password'); $txt_password = __('Password');
@ -675,7 +723,7 @@ EOF;
<hr width="90%"> <hr width="90%">
$postingmode $postingmode
$postform $postform
$js_autorefresh $js
<form id="delform" action="imgboard.php?delete" method="post"> <form id="delform" action="imgboard.php?delete" method="post">
<input type="hidden" name="board" <input type="hidden" name="board"
EOF; EOF;
@ -741,6 +789,9 @@ function rebuildIndexes() {
foreach ($threads as $thread) { foreach ($threads as $thread) {
$replies = postsInThreadByID($thread['id']); $replies = postsInThreadByID($thread['id']);
if (!isset($thread_cache[$thread['id']])) {
$thread_cache[$thread['id']] = $replies;
}
$thread['omitted'] = max(0, count($replies) - TINYIB_PREVIEWREPLIES - 1); $thread['omitted'] = max(0, count($replies) - TINYIB_PREVIEWREPLIES - 1);
// Build replies for preview // Build replies for preview
@ -780,6 +831,7 @@ function rebuildIndexes() {
} }
function rebuildThread($id) { function rebuildThread($id) {
global $thread_cache;
$id = intval($id); $id = intval($id);
$post = postByID($id); $post = postByID($id);
@ -789,6 +841,7 @@ function rebuildThread($id) {
} }
$posts = postsInThreadByID($id); $posts = postsInThreadByID($id);
$thread_cache[getParent($post)] = $posts;
if (count($posts) == 0) { if (count($posts) == 0) {
@unlink('res/' . $id . '.html'); @unlink('res/' . $id . '.html');
return; return;

View File

@ -115,7 +115,7 @@ function autoRefresh() {
Object.keys(data).forEach(function (key) { Object.keys(data).forEach(function (key) {
posts.append(data[key]); posts.append(data[key]);
setPostAttributes('#reply' + key); setPostAttributes('#post' + key, true);
autoRefreshPostID = key; autoRefreshPostID = key;
newRepliesCount++; newRepliesCount++;
@ -202,13 +202,9 @@ $(window).blur(function () {
}); });
$(document).ready(function () { $(document).ready(function () {
setPostAttributes(document); setPostAttributes(document, false);
}); });
function insertAfter(newElement, targetElement) {
targetElement.parentNode.insertBefore(newElement, targetElement.nextSibling);
}
var mouseX; var mouseX;
var mouseY; var mouseY;
$(document).mousemove( function(e) { $(document).mousemove( function(e) {
@ -217,7 +213,7 @@ $(document).mousemove( function(e) {
}); });
var downloaded_posts = []; var downloaded_posts = [];
function setPostAttributes(element) { function setPostAttributes(element, autorefresh) {
var base_url = './imgboard.php?'; var base_url = './imgboard.php?';
if (window.location.href.includes('/res/')) { if (window.location.href.includes('/res/')) {
base_url = '../imgboard.php?res&'; base_url = '../imgboard.php?res&';
@ -229,20 +225,33 @@ function setPostAttributes(element) {
m = $(this).attr('href').match(/.*\/[0-9]+?#([0-9]+)/i); m = $(this).attr('href').match(/.*\/[0-9]+?#([0-9]+)/i);
} }
if (m == null && $(this).attr('href')) { if (m == null && $(this).attr('href')) {
var m = $(this).attr('href').match(/\#([0-9]+)/i); m = $(this).attr('href').match(/\#([0-9]+)/i);
} }
if (m == null) { if (m == null) {
return; return;
} }
if ($(this).html() == 'No.') { if ($(this).html() == 'No.') {
$(element).attr('postID', m[1]).addClass('post'); $(element).attr('postID', m[1]).attr('postLink', $(this).attr('href')).addClass('post');
} else if ($(this).attr('refID') == undefined) { } else if ($(this).attr('refID') == undefined) {
var m2 = $(this).html().match(/^\&gt\;\&gt\;[0-9]+/i); var m2 = $(this).html().match(/^\&gt\;\&gt\;[0-9]+/i);
if (m2 == null) { if (m2 == null) {
return; return;
} }
if (enablebacklinks && autorefresh) {
reflinks = $('#reflinks' + m[1]);
if (reflinks) {
if (reflinks.html() == '') {
reflinks.append('&nbsp;');
} else {
reflinks.append(', ');
}
reflinks.append('<a href="' + $(element).attr('postLink') + '">&gt;&gt;' + $(element).attr('postID') + '<a>');
setPostAttributes(reflinks, false);
}
}
$(this).attr('refID', m[1]); $(this).attr('refID', m[1]);
$(this).hover(function (e) { $(this).hover(function (e) {
var preview = document.getElementById('ref' + $(this).attr('refID')); var preview = document.getElementById('ref' + $(this).attr('refID'));
@ -254,15 +263,21 @@ function setPostAttributes(element) {
$(preview).attr('refID', $(this).attr('refID')); $(preview).attr('refID', $(this).attr('refID'));
var refpost = $('.post[postID="' + $(this).attr('refID') + '"]').first(); var refpost = $('#post' + $(this).attr('refID'));
var refid = $(this).attr('refID'); var refid = $(this).attr('refID');
if (downloaded_posts[refid]) { if (downloaded_posts[refid]) {
preview.className = 'hoverpost'; preview.className = 'hoverpost';
$(preview).html(downloaded_posts[refid]); $(preview).html(downloaded_posts[refid]);
if ($(preview).find('div:first').hasClass('reply')) {
$(preview).addClass('reply');
}
} else if (refpost.html() && refpost.html() != undefined) { } else if (refpost.html() && refpost.html() != undefined) {
preview.className = 'hoverpost'; preview.className = 'hoverpost';
$(preview).html(refpost.html()); $(preview).html(refpost.html());
if (refpost.hasClass('reply')) {
$(preview).addClass('reply');
}
} else { } else {
$(preview).html('<div class="hoverpost" style="padding: 14px;">Loading...</div>'); $(preview).html('<div class="hoverpost" style="padding: 14px;">Loading...</div>');
$(preview).fadeIn(125); $(preview).fadeIn(125);
@ -273,12 +288,15 @@ function setPostAttributes(element) {
downloaded_posts[refid] = response; downloaded_posts[refid] = response;
preview.className = 'hoverpost'; preview.className = 'hoverpost';
$(preview).html(response); $(preview).html(response);
if ($(preview).find('div:first').hasClass('reply')) {
$(preview).addClass('reply');
}
}, },
dataType: 'html' dataType: 'html'
}); });
} }
insertAfter(preview, this); $(document.body).append(preview);
} }
$(preview).css('left', mouseX+14).css('top', mouseY+7); $(preview).css('left', mouseX+14).css('top', mouseY+7);
}, function (e) { }, function (e) {

View File

@ -46,6 +46,7 @@ define('TINYIB_TRUNCATE', 15); // Messages are truncated to this many lin
define('TINYIB_WORDBREAK', 80); // Words longer than this many characters will be broken apart [0 to disable] define('TINYIB_WORDBREAK', 80); // Words longer than this many characters will be broken apart [0 to disable]
define('TINYIB_EXPANDWIDTH', 85); // Expanded content size as a percentage of the screen's width define('TINYIB_EXPANDWIDTH', 85); // Expanded content size as a percentage of the screen's width
define('TINYIB_TIMEZONE', 'UTC'); // See https://secure.php.net/manual/en/timezones.php - e.g. America/Los_Angeles define('TINYIB_TIMEZONE', 'UTC'); // See https://secure.php.net/manual/en/timezones.php - e.g. America/Los_Angeles
define('TINYIB_BACKLINKS', true); // Display reflinks to replies that reference a post
define('TINYIB_CATALOG', true); // Generate catalog page define('TINYIB_CATALOG', true); // Generate catalog page
define('TINYIB_JSON', true); // Generate JSON files define('TINYIB_JSON', true); // Generate JSON files
define('TINYIB_DEFAULTSTYLE', 'futaba'); // Default page style define('TINYIB_DEFAULTSTYLE', 'futaba'); // Default page style