truncate really long comments by default to keep side speedy!
This commit is contained in:
@@ -1925,6 +1925,32 @@ body.sidebar-right-hidden .global-sidebar-right {
|
|||||||
/* Hidden by default, shown via JS if overflow detected */
|
/* Hidden by default, shown via JS if overflow detected */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.item-comment-truncated-notice {
|
||||||
|
display: block;
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 0.85em;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.load-full-comment-btn {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
color: var(--accent);
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.85;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 2px;
|
||||||
|
transition: opacity 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.load-full-comment-btn:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Avatar in sidebar activity */
|
/* Avatar in sidebar activity */
|
||||||
.sidebar-avatar-link {
|
.sidebar-avatar-link {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@@ -7886,6 +7912,7 @@ span.badge.badge-current {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.sidebar-comment-img.emoji {
|
.sidebar-comment-img.emoji {
|
||||||
width: auto;
|
width: auto;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|||||||
@@ -461,7 +461,7 @@ class CommentSystem {
|
|||||||
|
|
||||||
const contentEl = el.querySelector('.comment-content');
|
const contentEl = el.querySelector('.comment-content');
|
||||||
if (contentEl) {
|
if (contentEl) {
|
||||||
contentEl.innerHTML = this.renderCommentContent(data.content);
|
contentEl.innerHTML = this.renderCommentContent(data.content, data.comment_id);
|
||||||
|
|
||||||
// Flash effect to draw attention
|
// Flash effect to draw attention
|
||||||
el.classList.remove('new-item-fade');
|
el.classList.remove('new-item-fade');
|
||||||
@@ -1237,7 +1237,7 @@ class CommentSystem {
|
|||||||
const contentEl = el.querySelector('.comment-content');
|
const contentEl = el.querySelector('.comment-content');
|
||||||
if (contentEl && contentEl.dataset.raw !== incoming.content) {
|
if (contentEl && contentEl.dataset.raw !== incoming.content) {
|
||||||
window.f0ckDebug(`[CommentSystem] Reconcile: Updating content for #c${id}`);
|
window.f0ckDebug(`[CommentSystem] Reconcile: Updating content for #c${id}`);
|
||||||
contentEl.innerHTML = this.renderCommentContent(incoming.content);
|
contentEl.innerHTML = this.renderCommentContent(incoming.content, incoming.id);
|
||||||
contentEl.dataset.raw = incoming.content;
|
contentEl.dataset.raw = incoming.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1366,14 +1366,17 @@ class CommentSystem {
|
|||||||
syncLevel(roots, list, false);
|
syncLevel(roots, list, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommentContent(content) {
|
// Maximum characters to fully render in the item view per comment
|
||||||
|
static get ITEM_VIEW_MAX_CHARS() { return 10000; }
|
||||||
|
|
||||||
|
renderCommentContent(content, commentId = null, bypassTruncation = false) {
|
||||||
if (!content) return '';
|
if (!content) return '';
|
||||||
|
|
||||||
// Anti-recursion / Performance safeguard for extremely long comments
|
// Truncate extremely long comments before any processing
|
||||||
if (content.length > 50000) {
|
let truncated = false;
|
||||||
console.warn('Comment too long, skipping markdown for performance');
|
if (!bypassTruncation && content.length > CommentSystem.ITEM_VIEW_MAX_CHARS) {
|
||||||
// Use native escaping and <pre> to avoid all regex/marked overhead for huge strings
|
content = content.substring(0, CommentSystem.ITEM_VIEW_MAX_CHARS);
|
||||||
return `<pre style="white-space: pre-wrap; font-family: inherit; margin: 0; padding: 0; background: none; border: none; font-size: inherit; color: inherit;">${this.escapeHtml(content)}</pre>`;
|
truncated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof marked === 'undefined') {
|
if (typeof marked === 'undefined') {
|
||||||
@@ -1633,10 +1636,19 @@ class CommentSystem {
|
|||||||
if (window.Sanitizer && typeof Sanitizer.clean === 'function') {
|
if (window.Sanitizer && typeof Sanitizer.clean === 'function') {
|
||||||
md = Sanitizer.clean(md);
|
md = Sanitizer.clean(md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (truncated) {
|
||||||
|
md += `<span class="item-comment-truncated-notice">… <button class="load-full-comment-btn" type="button">show full comment</button></span>`;
|
||||||
|
}
|
||||||
|
|
||||||
return md;
|
return md;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Markdown error:', e);
|
console.error('Markdown error:', e);
|
||||||
return this.escapeHtml(content);
|
let fallback = this.escapeHtml(content);
|
||||||
|
if (truncated) {
|
||||||
|
fallback += ` <span class="item-comment-truncated-notice">… <button class="load-full-comment-btn" type="button">show full comment</button></span>`;
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1722,7 +1734,7 @@ class CommentSystem {
|
|||||||
const isPinned = comment.is_pinned;
|
const isPinned = comment.is_pinned;
|
||||||
|
|
||||||
// Add @mention prefix if this is a reply to a reply
|
// Add @mention prefix if this is a reply to a reply
|
||||||
const content = isDeleted ? '<span class="deleted-msg">[deleted]</span>' : this.renderCommentContent(comment.content);
|
const content = isDeleted ? '<span class="deleted-msg">[deleted]</span>' : this.renderCommentContent(comment.content, comment.id);
|
||||||
const date = new Date(comment.created_at).toLocaleString();
|
const date = new Date(comment.created_at).toLocaleString();
|
||||||
|
|
||||||
// Admin buttons
|
// Admin buttons
|
||||||
@@ -2009,6 +2021,19 @@ class CommentSystem {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load full comment (expand truncated)
|
||||||
|
const loadFullBtn = target.closest('.load-full-comment-btn');
|
||||||
|
if (loadFullBtn) {
|
||||||
|
const contentEl = loadFullBtn.closest('.comment-content');
|
||||||
|
if (contentEl) {
|
||||||
|
const fullContent = contentEl.dataset.raw;
|
||||||
|
if (fullContent) {
|
||||||
|
contentEl.innerHTML = this.renderCommentContent(fullContent, null, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Comment Context Link (>>ID)
|
// Comment Context Link (>>ID)
|
||||||
const contextLink = target.closest('.comment-context-link');
|
const contextLink = target.closest('.comment-context-link');
|
||||||
if (contextLink) {
|
if (contextLink) {
|
||||||
|
|||||||
@@ -86,13 +86,16 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Maximum characters to render in the sidebar per comment
|
||||||
|
const SIDEBAR_CONTENT_TRUNCATE = 200;
|
||||||
|
|
||||||
const renderCommentContent = (content, commentId = null, itemId = null) => {
|
const renderCommentContent = (content, commentId = null, itemId = null) => {
|
||||||
if (!content) return '';
|
if (!content) return '';
|
||||||
|
|
||||||
// Anti-recursion / Performance safeguard for extremely long comments
|
// Truncate extremely long comments before any processing to keep the sidebar
|
||||||
if (content.length > 50000) {
|
// fast and the DOM lean, regardless of markdown / regex complexity.
|
||||||
console.warn('Sidebar Activity: Comment too long, skipping markdown');
|
if (content.length > SIDEBAR_CONTENT_TRUNCATE) {
|
||||||
return `<pre style="white-space: pre-wrap; font-family: inherit; margin: 0; padding: 0; background: none; border: none; font-size: inherit; color: inherit;">${escapeHtml(content)}</pre>`;
|
content = content.substring(0, SIDEBAR_CONTENT_TRUNCATE) + '\u2026';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof marked === 'undefined') {
|
if (typeof marked === 'undefined') {
|
||||||
|
|||||||
Reference in New Issue
Block a user