feat(Bangumi_Topic_Share): render 贴贴 reactions on share cards, bump to 6.4

This commit is contained in:
Stardream
2026-07-09 12:18:08 +10:00
parent c4af2d65db
commit aa210fceb8
+97 -19
View File
@@ -1,8 +1,8 @@
// ==UserScript== // ==UserScript==
// @name Bangumi Topic Share // @name Bangumi Topic Share
// @namespace https://greasyfork.org/scripts/574689 // @namespace https://greasyfork.org/scripts/574689
// @version 6.3 // @version 6.4
// @description Bangumi 分享工具:生成分享卡片,支持图片复制/下载、一键复制分享文案、可选 AI 标签 // @description Bangumi 分享工具:生成分享卡片,支持图片复制/下载、一键复制分享文案、贴贴反应展示、可选 AI 标签
// @author Stardream // @author Stardream
// @contributor Chang ji, Mewtw0 // @contributor Chang ji, Mewtw0
// @match *://bgm.tv/group/topic/* // @match *://bgm.tv/group/topic/*
@@ -253,6 +253,12 @@
.content-text img.smile-dynamic { display: inline !important; height: 3em !important; width: auto !important; vertical-align: baseline; } .content-text img.smile-dynamic { display: inline !important; height: 3em !important; width: auto !important; vertical-align: baseline; }
.content-text img:not([data-bgm-emoji]):not(.bmoji-image):not(.smile-dynamic) { max-width: 100%; height: auto; border-radius: 4px; margin: 4px 0; display: block; } .content-text img:not([data-bgm-emoji]):not(.bmoji-image):not(.smile-dynamic) { max-width: 100%; height: auto; border-radius: 4px; margin: 4px 0; display: block; }
[data-bgm-mask] { display: inline; background-color: #555; color: #555; border-radius: 2px; padding: 0 5px; position: relative; transition: color 0.5s linear; } [data-bgm-mask] { display: inline; background-color: #555; color: #555; border-radius: 2px; padding: 0 5px; position: relative; transition: color 0.5s linear; }
.reactions-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.reaction-item { display: inline-flex; align-items: center; gap: 4px; background: #f2f2f2; border: 1px solid #ebebeb; border-radius: 20px; padding: 2px 9px 2px 7px; line-height: 1; }
.reaction-item img { height: 18px; width: auto; display: block; }
.reaction-num { font-size: 12px; color: #888; font-weight: bold; }
.share-card.dark .reaction-item { background: #2a2a2a; border: 1px solid rgba(255,255,255,0.08); }
.share-card.dark .reaction-num { color: #aaa; }
`; `;
document.head.appendChild(style); document.head.appendChild(style);
@@ -440,7 +446,7 @@
// contentDoc: the document containing the topic (may be an iframe's doc on Rakuen) // contentDoc: the document containing the topic (may be an iframe's doc on Rakuen)
// Overlay is always rendered in the outer document (where GM functions are available) // Overlay is always rendered in the outer document (where GM functions are available)
async function _doShareCard({ username, postTime, avatarUrl, contentEl, pureTitle, contentDoc, contentWin, dark, async function _doShareCard({ username, postTime, avatarUrl, contentEl, pureTitle, contentDoc, contentWin, dark,
replies = [], replyId = '', charImageUrl = '', badgeLabel = '', overrideTags = null, topicTitle = '', noCardTitle = false, shareTitle = '' }) { replies = [], replyId = '', charImageUrl = '', badgeLabel = '', overrideTags = null, topicTitle = '', noCardTitle = false, shareTitle = '', mainReactions = [] }) {
if (document.getElementById('bgm-share-overlay')) return; if (document.getElementById('bgm-share-overlay')) return;
if (typeof html2canvas === 'undefined') { if (typeof html2canvas === 'undefined') {
alert("截图库加载失败,请刷新页面或检查网络。"); alert("截图库加载失败,请刷新页面或检查网络。");
@@ -485,6 +491,22 @@
...replies.map(r => inlineImages(r.contentHtml || r.content)) ...replies.map(r => inlineImages(r.contentHtml || r.content))
]); ]);
const reactionIconUrls = [...new Set([
...mainReactions.map(r => r.icon),
...replies.flatMap(r => (r.reactions || []).map(x => x.icon))
].filter(Boolean))];
const reactionB64 = {};
await Promise.all(reactionIconUrls.map(async u => { reactionB64[u] = await fetchAsBase64(u); }));
const renderReactions = (arr) => {
if (!arr || !arr.length) return '';
const items = arr.map(r => {
const b64 = reactionB64[r.icon];
if (!b64) return '';
return `<span class="reaction-item"><img src="${b64}">${r.count ? `<span class="reaction-num">${r.count}</span>` : ''}</span>`;
}).join('');
return items ? `<div class="reactions-row">${items}</div>` : '';
};
const tagsHtml = tags.map(tag => tag.startsWith('!') ? `<span class="tag-item">${tag.slice(1)}</span>` : `<span class="tag-item"># ${tag}</span>`).join(''); const tagsHtml = tags.map(tag => tag.startsWith('!') ? `<span class="tag-item">${tag.slice(1)}</span>` : `<span class="tag-item"># ${tag}</span>`).join('');
const divider = dark ? 'rgba(255,255,255,0.1)' : '#eee'; const divider = dark ? 'rgba(255,255,255,0.1)' : '#eee';
const hasMainContent = !!inlinedMainContent || !!username; const hasMainContent = !!inlinedMainContent || !!username;
@@ -506,6 +528,7 @@
<span style="color:#aaa;font-size:${12 - idx}px;">${r.time}</span> <span style="color:#aaa;font-size:${12 - idx}px;">${r.time}</span>
</div> </div>
<div class="content-box"><div class="content-text" style="font-size:${14 - idx}px;">${inlinedReplyContents[idx]}</div></div> <div class="content-box"><div class="content-text" style="font-size:${14 - idx}px;">${inlinedReplyContents[idx]}</div></div>
${renderReactions(r.reactions)}
${inner} ${inner}
</div>`; </div>`;
}; };
@@ -536,6 +559,7 @@
${(base64CharImage || badgeLabel || noCardTitle) ? '' : `<h1 class="main-title">${pureTitle}</h1>`} ${(base64CharImage || badgeLabel || noCardTitle) ? '' : `<h1 class="main-title">${pureTitle}</h1>`}
${topicTitle ? `<h2 class="topic-sub-title">${topicTitle}</h2>` : ''} ${topicTitle ? `<h2 class="topic-sub-title">${topicTitle}</h2>` : ''}
${inlinedMainContent ? `<div class="content-box"><div class="content-text">${inlinedMainContent}</div></div>` : ''} ${inlinedMainContent ? `<div class="content-box"><div class="content-text">${inlinedMainContent}</div></div>` : ''}
${renderReactions(mainReactions)}
${replySection} ${replySection}
<div class="tags-container">${tagsHtml}</div> <div class="tags-container">${tagsHtml}</div>
</div> </div>
@@ -1068,7 +1092,8 @@
username, userSlug, avatarUrl, username, userSlug, avatarUrl,
time: domTime, rating: 0, collectionStatus, time: domTime, rating: 0, collectionStatus,
content: truncated ? rawText.substring(0, 150) + '...' : rawText, content: truncated ? rawText.substring(0, 150) + '...' : rawText,
contentHtml contentHtml,
reactions: extractReactions(itemEl, itemEl.ownerDocument)
}; };
} }
@@ -1147,7 +1172,7 @@
} }
const truncated = rawText.length > 150; const truncated = rawText.length > 150;
const contentHtml = truncated ? rawText.substring(0, 150) + '...' : rawText; const contentHtml = truncated ? rawText.substring(0, 150) + '...' : rawText;
return { username, userSlug, avatarUrl, rating, time, content: contentHtml, contentHtml }; return { username, userSlug, avatarUrl, rating, time, content: contentHtml, contentHtml, reactions: extractReactions(itemEl, itemEl.ownerDocument) };
} }
const COLLECTION_PAGE_STATUS = { collections: '看过', wishes: '想看', doings: '在看', on_hold: '搁置', dropped: '抛弃' }; const COLLECTION_PAGE_STATUS = { collections: '看过', wishes: '想看', doings: '在看', on_hold: '搁置', dropped: '抛弃' };
@@ -1204,7 +1229,7 @@
const subjectTopicId = getSubjectIdFromTopicPage(contentWin.location.pathname, contentDoc); const subjectTopicId = getSubjectIdFromTopicPage(contentWin.location.pathname, contentDoc);
const isSubjectTopic = !!subjectTopicId; const isSubjectTopic = !!subjectTopicId;
let username, postTime, avatarUrl, contentEl; let username, postTime, avatarUrl, contentEl, mainReactions = [];
if (isEpisode || isCharacter || isPerson) { if (isEpisode || isCharacter || isPerson) {
username = ""; postTime = ""; avatarUrl = ""; contentEl = null; username = ""; postTime = ""; avatarUrl = ""; contentEl = null;
} else if (isBlog) { } else if (isBlog) {
@@ -1225,6 +1250,7 @@
const avatarBox = firstPost?.querySelector('.avatarSize48'); const avatarBox = firstPost?.querySelector('.avatarSize48');
avatarUrl = avatarBox ? contentWin.getComputedStyle(avatarBox).backgroundImage.replace(/url\(["']?([^"']+)["']?\)/, '$1') : ""; avatarUrl = avatarBox ? contentWin.getComputedStyle(avatarBox).backgroundImage.replace(/url\(["']?([^"']+)["']?\)/, '$1') : "";
contentEl = firstPost?.querySelector('.topic_content') || firstPost?.querySelector('.inner'); contentEl = firstPost?.querySelector('.topic_content') || firstPost?.querySelector('.inner');
mainReactions = extractReactions(firstPost, contentDoc);
} }
const h1Node = contentDoc.querySelector('#pageHeader h1') || contentDoc.querySelector('h1.title') || contentDoc.querySelector('h1.nameSingle a') || contentDoc.querySelector('h1'); const h1Node = contentDoc.querySelector('#pageHeader h1') || contentDoc.querySelector('h1.title') || contentDoc.querySelector('h1.nameSingle a') || contentDoc.querySelector('h1');
@@ -1288,7 +1314,7 @@
} }
} }
} }
await _doShareCard({ username, postTime, avatarUrl, contentEl, pureTitle, contentDoc, contentWin, dark, charImageUrl, badgeLabel, topicTitle }); await _doShareCard({ username, postTime, avatarUrl, contentEl, pureTitle, contentDoc, contentWin, dark, charImageUrl, badgeLabel, topicTitle, mainReactions });
} }
function truncateHtml(html, limit) { function truncateHtml(html, limit) {
@@ -1312,6 +1338,35 @@
return tmp.innerHTML; return tmp.innerHTML;
} }
// Extract "贴贴" reactions for a post/reply from its .likes_grid display container.
// Grid id mirrors the post id: post_{N} -> likes_grid_{N}. Icons are CSS background-images.
function extractReactions(postEl, contentDoc) {
if (!postEl) return [];
const doc = contentDoc || postEl.ownerDocument || document;
const win = doc.defaultView || window;
let grid = null;
if (postEl.classList?.contains('likes_grid')) {
grid = postEl;
} else {
const idMatch = (postEl.id || '').match(/^post_(\d+)$/);
if (idMatch) grid = doc.getElementById('likes_grid_' + idMatch[1]);
if (!grid) grid = postEl.querySelector('.likes_grid');
}
if (!grid) return [];
return [...grid.querySelectorAll('a.item')].map(item => {
const emojiSpan = item.querySelector('.emoji');
let icon = '';
if (emojiSpan) {
const bg = win.getComputedStyle(emojiSpan).backgroundImage || '';
const m = bg.match(/url\(["']?([^"')]+)["']?\)/);
if (m && m[1] !== 'none') icon = m[1];
if (!icon) { const img = emojiSpan.querySelector('img'); if (img) icon = img.src; }
}
const count = item.querySelector('.num')?.textContent.trim() || '';
return icon ? { icon, count } : null;
}).filter(Boolean);
}
function extractPostInfo(postEl, contentWin) { function extractPostInfo(postEl, contentWin) {
const idNode = postEl.querySelector('.userInfo strong a') || postEl.querySelector('.userName a') || postEl.querySelector('strong a'); const idNode = postEl.querySelector('.userInfo strong a') || postEl.querySelector('.userName a') || postEl.querySelector('strong a');
const username = idNode ? idNode.innerText.trim() : "未知用户"; const username = idNode ? idNode.innerText.trim() : "未知用户";
@@ -1351,7 +1406,8 @@
const contentHtml = truncated const contentHtml = truncated
? savedQuoteHtml + truncateHtml(bodyClone?.innerHTML?.trim() || "", 150) ? savedQuoteHtml + truncateHtml(bodyClone?.innerHTML?.trim() || "", 150)
: (contentEl?.innerHTML?.trim() || ""); : (contentEl?.innerHTML?.trim() || "");
return { username, time, avatarUrl, content: truncated ? rawText.substring(0, 150) + "..." : rawText, contentHtml }; const reactions = extractReactions(postEl, postEl.ownerDocument);
return { username, time, avatarUrl, content: truncated ? rawText.substring(0, 150) + "..." : rawText, contentHtml, reactions };
} }
async function createReplyShareImage(replyEl, contentDoc = document) { async function createReplyShareImage(replyEl, contentDoc = document) {
@@ -1365,7 +1421,7 @@
const isPerson = /\/person\/\d+|\/rakuen\/topic\/prsn\/\d+/.test(contentWin.location.pathname); const isPerson = /\/person\/\d+|\/rakuen\/topic\/prsn\/\d+/.test(contentWin.location.pathname);
const subjectTopicId = getSubjectIdFromTopicPage(contentWin.location.pathname, contentDoc); const subjectTopicId = getSubjectIdFromTopicPage(contentWin.location.pathname, contentDoc);
const isSubjectTopic = !!subjectTopicId; const isSubjectTopic = !!subjectTopicId;
let username, postTime, avatarUrl, contentEl; let username, postTime, avatarUrl, contentEl, mainReactions = [];
if (isEpisode || isCharacter || isPerson) { if (isEpisode || isCharacter || isPerson) {
username = ""; postTime = ""; avatarUrl = ""; contentEl = null; username = ""; postTime = ""; avatarUrl = ""; contentEl = null;
} else if (isBlog) { } else if (isBlog) {
@@ -1385,6 +1441,7 @@
const mainAvatarBox = firstPost?.querySelector('.avatarSize48'); const mainAvatarBox = firstPost?.querySelector('.avatarSize48');
avatarUrl = mainAvatarBox ? contentWin.getComputedStyle(mainAvatarBox).backgroundImage.replace(/url\(["']?([^"']+)["']?\)/, '$1') : ""; avatarUrl = mainAvatarBox ? contentWin.getComputedStyle(mainAvatarBox).backgroundImage.replace(/url\(["']?([^"']+)["']?\)/, '$1') : "";
contentEl = firstPost?.querySelector('.topic_content') || firstPost?.querySelector('.inner'); contentEl = firstPost?.querySelector('.topic_content') || firstPost?.querySelector('.inner');
mainReactions = extractReactions(firstPost, contentDoc);
} }
// Build replies chain: if sub-reply, prepend the parent reply first // Build replies chain: if sub-reply, prepend the parent reply first
@@ -1457,7 +1514,7 @@
} }
} }
await _doShareCard({ username, postTime, avatarUrl, contentEl, pureTitle, contentDoc, contentWin, dark, await _doShareCard({ username, postTime, avatarUrl, contentEl, pureTitle, contentDoc, contentWin, dark,
replies, replyId: replyEl.id, charImageUrl, badgeLabel, topicTitle }); replies, replyId: replyEl.id, charImageUrl, badgeLabel, topicTitle, mainReactions });
} }
const REPLY_SHARE_BTN_CLASS = 'bgm-reply-share-btn'; const REPLY_SHARE_BTN_CLASS = 'bgm-reply-share-btn';
@@ -1873,6 +1930,7 @@
const contentWin = doc.defaultView || window; const contentWin = doc.defaultView || window;
const { username, avatarUrl, postTime } = _getStatusAuthorInfo(doc); const { username, avatarUrl, postTime } = _getStatusAuthorInfo(doc);
const replyCount = doc.querySelectorAll('.subReply .reply_item').length; const replyCount = doc.querySelectorAll('.subReply .reply_item').length;
const statusReactions = _extractStatusMainReactions(doc);
const collectInfo = await _buildCollectionStatusInfo(doc, contentWin, username, avatarUrl, postTime); const collectInfo = await _buildCollectionStatusInfo(doc, contentWin, username, avatarUrl, postTime);
if (collectInfo) { if (collectInfo) {
@@ -1882,7 +1940,7 @@
pureTitle: subjectName, pureTitle: subjectName,
shareTitle: `${username}的收藏 - ${subjectName}`, shareTitle: `${username}的收藏 - ${subjectName}`,
contentDoc: doc, contentWin, dark, contentDoc: doc, contentWin, dark,
replies: [{ username, avatarUrl, content: collectComment.innerText?.trim() || '', contentHtml: cleanCommentHtml, time: apiTime, rating }], replies: [{ username, avatarUrl, content: collectComment.innerText?.trim() || '', contentHtml: cleanCommentHtml, time: apiTime, rating, reactions: statusReactions }],
charImageUrl: subjectData?.imageUrl || '', charImageUrl: subjectData?.imageUrl || '',
badgeLabel: subjectData?.type || '作品', badgeLabel: subjectData?.type || '作品',
overrideTags, overrideTags,
@@ -1893,11 +1951,20 @@
username, postTime, avatarUrl, contentEl, username, postTime, avatarUrl, contentEl,
pureTitle: username + '的吐槽', contentDoc: doc, contentWin, dark, pureTitle: username + '的吐槽', contentDoc: doc, contentWin, dark,
noCardTitle: true, noCardTitle: true,
mainReactions: statusReactions,
overrideTags: replyCount ? [`${replyCount} 回复`, '吐槽'] : ['吐槽'], overrideTags: replyCount ? [`${replyCount} 回复`, '吐槽'] : ['吐槽'],
}); });
} }
} }
// Status detail page (/timeline/status/N): reactions for the main status live in a
// .likes_grid outside the reply list; pick the first one not inside a .reply_item.
function _extractStatusMainReactions(doc) {
const scope = doc.querySelector('.statusContent') || doc;
const grid = [...scope.querySelectorAll('.likes_grid')].find(g => !g.closest('.reply_item'));
return grid ? extractReactions(grid, doc) : [];
}
async function createStatusReplyShareImage(replyLi, doc = document) { async function createStatusReplyShareImage(replyLi, doc = document) {
const dark = doc.documentElement.getAttribute('data-theme') === 'dark'; const dark = doc.documentElement.getAttribute('data-theme') === 'dark';
const contentWin = doc.defaultView || window; const contentWin = doc.defaultView || window;
@@ -1923,6 +1990,8 @@
}); });
const replyCount = doc.querySelectorAll('.subReply .reply_item').length; const replyCount = doc.querySelectorAll('.subReply .reply_item').length;
const statusReactions = _extractStatusMainReactions(doc);
const replyReactions = extractReactions(replyLi, doc);
const collectInfo = await _buildCollectionStatusInfo(doc, contentWin, username, avatarUrl, postTime); const collectInfo = await _buildCollectionStatusInfo(doc, contentWin, username, avatarUrl, postTime);
if (collectInfo) { if (collectInfo) {
const { subjectData, subjectName, collectComment, cleanCommentHtml, apiTime, rating, overrideTags } = collectInfo; const { subjectData, subjectName, collectComment, cleanCommentHtml, apiTime, rating, overrideTags } = collectInfo;
@@ -1932,8 +2001,8 @@
shareTitle: `${username}的收藏 - ${subjectName}`, shareTitle: `${username}的收藏 - ${subjectName}`,
contentDoc: doc, contentWin, dark, contentDoc: doc, contentWin, dark,
replies: [ replies: [
{ username, avatarUrl, content: collectComment.innerText?.trim() || '', contentHtml: cleanCommentHtml, time: apiTime, rating }, { username, avatarUrl, content: collectComment.innerText?.trim() || '', contentHtml: cleanCommentHtml, time: apiTime, rating, reactions: statusReactions },
{ username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '' }, { username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '', reactions: replyReactions },
], ],
charImageUrl: subjectData?.imageUrl || '', charImageUrl: subjectData?.imageUrl || '',
badgeLabel: subjectData?.type || '作品', badgeLabel: subjectData?.type || '作品',
@@ -1945,7 +2014,8 @@
username, postTime, avatarUrl, contentEl, username, postTime, avatarUrl, contentEl,
pureTitle: username + '的吐槽', contentDoc: doc, contentWin, dark, pureTitle: username + '的吐槽', contentDoc: doc, contentWin, dark,
noCardTitle: true, noCardTitle: true,
replies: [{ username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '' }], mainReactions: statusReactions,
replies: [{ username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '', reactions: replyReactions }],
overrideTags: replyCount ? [`${replyCount} 回复`, '吐槽'] : ['吐槽'], overrideTags: replyCount ? [`${replyCount} 回复`, '吐槽'] : ['吐槽'],
}); });
} }
@@ -2058,6 +2128,7 @@
const statusP = item.querySelector('.info p.status, .info_full p.status'); const statusP = item.querySelector('.info p.status, .info_full p.status');
const collectComment = item.querySelector('.collectInfo .comment'); const collectComment = item.querySelector('.collectInfo .comment');
const blogLink = item.querySelector('.info a[href*="/blog/"], .info_full a[href*="/blog/"]'); const blogLink = item.querySelector('.info a[href*="/blog/"], .info_full a[href*="/blog/"]');
const itemReactions = extractReactions(item, doc);
if (statusP && statusP.textContent.trim()) { if (statusP && statusP.textContent.trim()) {
const statusUrl = item.querySelector('.tml_comment')?.href; const statusUrl = item.querySelector('.tml_comment')?.href;
@@ -2069,6 +2140,7 @@
contentDoc: doc, contentWin, dark, contentDoc: doc, contentWin, dark,
noCardTitle: true, noCardTitle: true,
overrideTags: replyCount ? [`${replyCount} 回复`, '吐槽'] : ['吐槽'], overrideTags: replyCount ? [`${replyCount} 回复`, '吐槽'] : ['吐槽'],
mainReactions: itemReactions,
}); });
} else if (collectComment && collectComment.textContent.trim()) { } else if (collectComment && collectComment.textContent.trim()) {
// Subject link is in .info, carries data-subject-id attribute // Subject link is in .info, carries data-subject-id attribute
@@ -2138,7 +2210,7 @@
? { location: { origin: statusUrlParsed.origin, pathname: statusUrlParsed.pathname } } ? { location: { origin: statusUrlParsed.origin, pathname: statusUrlParsed.pathname } }
: { location: { origin: contentWin.location.origin, pathname: `/subject/${subjectId}` } }, : { location: { origin: contentWin.location.origin, pathname: `/subject/${subjectId}` } },
dark, dark,
replies: [{ username, avatarUrl, content: collectComment.innerText?.trim() || '', contentHtml: cleanCommentHtml, time: apiTime, rating }], replies: [{ username, avatarUrl, content: collectComment.innerText?.trim() || '', contentHtml: cleanCommentHtml, time: apiTime, rating, reactions: itemReactions }],
charImageUrl: subjectData?.imageUrl || '', charImageUrl: subjectData?.imageUrl || '',
badgeLabel: subjectData?.type || '作品', badgeLabel: subjectData?.type || '作品',
overrideTags, overrideTags,
@@ -2151,6 +2223,7 @@
contentDoc: doc, contentWin, dark, contentDoc: doc, contentWin, dark,
noCardTitle: true, noCardTitle: true,
overrideTags: ['收藏'], overrideTags: ['收藏'],
mainReactions: itemReactions,
}); });
} }
} else if (blogLink) { } else if (blogLink) {
@@ -2205,6 +2278,7 @@
dark, dark,
charImageUrl, badgeLabel, topicTitle, charImageUrl, badgeLabel, topicTitle,
overrideTags, overrideTags,
mainReactions: itemReactions,
}); });
} }
} }
@@ -2273,6 +2347,8 @@
const statusUrl = tmlItem.querySelector('.tml_comment')?.href; const statusUrl = tmlItem.querySelector('.tml_comment')?.href;
const statusUrlParsed = statusUrl ? new URL(statusUrl) : null; const statusUrlParsed = statusUrl ? new URL(statusUrl) : null;
const replyCount = tmlItem.querySelectorAll('.subReply .reply_item').length; const replyCount = tmlItem.querySelectorAll('.subReply .reply_item').length;
const itemReactions = extractReactions(tmlItem, doc);
const replyReactions = extractReactions(replyLi, doc);
if (isCollect) { if (isCollect) {
const subjectLink = tmlItem.querySelector('a[data-subject-id]'); const subjectLink = tmlItem.querySelector('a[data-subject-id]');
@@ -2328,8 +2404,8 @@
: { location: { origin: contentWin.location.origin, pathname: `/subject/${subjectId}` } }, : { location: { origin: contentWin.location.origin, pathname: `/subject/${subjectId}` } },
dark, dark,
replies: [ replies: [
{ username, avatarUrl, content: collectComment.innerText?.trim() || '', contentHtml: cleanCommentHtml, time: apiTime, rating }, { username, avatarUrl, content: collectComment.innerText?.trim() || '', contentHtml: cleanCommentHtml, time: apiTime, rating, reactions: itemReactions },
{ username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '' }, { username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '', reactions: replyReactions },
], ],
charImageUrl: subjectData?.imageUrl || '', charImageUrl: subjectData?.imageUrl || '',
badgeLabel: subjectData?.type || '作品', badgeLabel: subjectData?.type || '作品',
@@ -2345,7 +2421,8 @@
? { location: { origin: statusUrlParsed.origin, pathname: statusUrlParsed.pathname } } ? { location: { origin: statusUrlParsed.origin, pathname: statusUrlParsed.pathname } }
: contentWin, : contentWin,
dark, noCardTitle: true, dark, noCardTitle: true,
replies: [{ username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '' }], mainReactions: itemReactions,
replies: [{ username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '', reactions: replyReactions }],
overrideTags: ['收藏'], overrideTags: ['收藏'],
}); });
} }
@@ -2359,7 +2436,8 @@
? { location: { origin: statusUrlParsed.origin, pathname: statusUrlParsed.pathname } } ? { location: { origin: statusUrlParsed.origin, pathname: statusUrlParsed.pathname } }
: contentWin, : contentWin,
dark, noCardTitle: true, dark, noCardTitle: true,
replies: [{ username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '' }], mainReactions: itemReactions,
replies: [{ username: replyUsername, avatarUrl: replyAvatarUrl, content: replyHtml.trim(), contentHtml: replyHtml.trim(), time: '', reactions: replyReactions }],
overrideTags: replyCount ? [`${replyCount} 回复`, '吐槽'] : ['吐槽'], overrideTags: replyCount ? [`${replyCount} 回复`, '吐槽'] : ['吐槽'],
}); });
} }