keeping formatted summary #580

This commit is contained in:
mic 2026-03-25 23:59:20 +01:00
parent 3cb1fb0972
commit 7e9b507f0f
5 changed files with 103 additions and 45 deletions

View file

@ -924,8 +924,22 @@ switch (message.command) {
const summaryText = document.createElement('div');
summaryText.className = 'thunderai-summary-content';
const hasHtml = !!summaryData.summary_html;
// Helper to set summary content using DOMParser (innerHTML is blocked in Thunderbird content scripts)
function setSummaryHtml(element, html) {
element.textContent = '';
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
while (doc.body.firstChild) {
element.appendChild(doc.body.firstChild);
}
}
if (summaryData.error) {
summaryText.textContent = summaryData.message || browser.i18n.getMessage("summarize_error");
} else if (hasHtml) {
setSummaryHtml(summaryText, summaryData.summary_html);
} else {
summaryText.textContent = summaryData.summary;
}
@ -936,15 +950,17 @@ switch (message.command) {
const maxLen = summaryData.maxDisplayLength || 0;
const fullText = summaryData.summary;
if (!summaryData.error && maxLen > 0 && fullText && fullText.length > maxLen) {
// Set up animated expand/collapse via max-height transition
summaryText.style.overflow = 'hidden';
summaryText.style.transition = 'max-height 0.2s ease';
if (!hasHtml) {
// Plain text: truncate by character position
let cutPos = fullText.lastIndexOf(' ', maxLen);
if (cutPos <= 0) cutPos = maxLen;
const truncated = fullText.substring(0, cutPos) + '\u2026';
summaryText.textContent = truncated;
// Set up animated expand/collapse via max-height transition
summaryText.style.overflow = 'hidden';
summaryText.style.transition = 'max-height 0.2s ease';
// Measure truncated height after layout
requestAnimationFrame(() => {
const collapsedHeight = summaryText.scrollHeight;
@ -988,6 +1004,40 @@ switch (message.command) {
});
summaryTextWrapper.appendChild(toggleLink);
} else {
// HTML content: use max-height to collapse, preserve full HTML
const collapsedMaxHeight = '4.2em'; // ~3 lines collapsed
summaryText.style.maxHeight = collapsedMaxHeight;
const toggleLink = document.createElement('a');
toggleLink.textContent = browser.i18n.getMessage("summarize_see_more") || "See more";
toggleLink.href = '#';
toggleLink.style.cssText = 'display: inline-block; margin-top: 4px; font-size: 13px; color: ' +
(isDarkSummary ? '#6db3f2' : '#1a5fa8') + '; cursor: pointer; text-decoration: underline;';
let expanded = false;
toggleLink.addEventListener('click', (e) => {
e.preventDefault();
if (!expanded) {
summaryText.style.maxHeight = summaryText.scrollHeight + 'px';
toggleLink.textContent = browser.i18n.getMessage("summarize_see_less") || "See less";
} else {
summaryText.style.maxHeight = collapsedMaxHeight;
toggleLink.textContent = browser.i18n.getMessage("summarize_see_more") || "See more";
}
expanded = !expanded;
});
// Only show toggle if content is actually taller than collapsed height
requestAnimationFrame(() => {
if (summaryText.scrollHeight > summaryText.clientHeight) {
summaryTextWrapper.appendChild(toggleLink);
} else {
summaryText.style.maxHeight = '';
summaryText.style.overflow = '';
}
});
}
}
const summaryBody = document.createElement('div');

View file

@ -198,6 +198,7 @@ export class taStorage {
let now = Date.now();
record[taStorage.FIELD_SUMMARY] = {
summary: summary_data.summary,
summary_html: summary_data.summary_html || '',
error: summary_data.error || false,
message: summary_data.message || '',
summary_date: summary_data.summary_date instanceof Date

View file

@ -80,6 +80,7 @@ export class taSummaryStore {
return {
headerMessageId: data_id,
summary: summary.summary,
summary_html: summary.summary_html || '',
error: summary.error || false,
message: summary.message || '',
summary_date: new Date(summary.summary_date || summary.ts),

View file

@ -3,6 +3,7 @@
<head>
<meta charset="utf-8" />
<script src="api_webchat/markdown-it.min.js"></script>
<script src="mzta-background.js" type="module"></script>
</head>

View file

@ -297,9 +297,11 @@ messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
case 'chatgpt_saveSummary':
async function _saveSummaryFromWebchat(msg) {
try {
let summaryHtml = msg.text.trim();
let cleanedSummary = cleanSummaryText(msg.text);
const summaryData = {
summary: cleanedSummary,
summary_html: summaryHtml,
summary_date: new Date(),
headerMessageId: msg.headerMessageId
};
@ -558,9 +560,12 @@ async function _generateSummaryForMessage(headerMessageId, tabId) {
await cmd.initWorker();
const aiResponse = await cmd.sendPrompt();
let cleanedSummary = cleanSummaryText(aiResponse);
const md = window.markdownit();
let summaryHtml = md.render(aiResponse);
const summaryData = {
summary: cleanedSummary,
summary_html: summaryHtml,
summary_date: new Date(),
headerMessageId: headerMessageId
};