fix(extension): finish Included Memories leftovers on T3 (#1257) (#1421)

Co-authored-by: abhay-codes07 <abhaysingh0293@gmail.com>
Co-authored-by: Vedant Mahajan <vedant.04.mahajan@gmail.com>
This commit is contained in:
James Yang 2026-08-13 08:25:16 -04:00 committed by GitHub
parent fcf49855ce
commit 1356affbd1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 64 additions and 38 deletions

View file

@ -45,6 +45,13 @@ export function parseMemoriesFromDataset(
.filter((memory) => memory.length > 0 && memory !== ",")
}
export function renumberIncludedMemories(memories: string[]): string[] {
return memories.map((memory, index) => {
const text = memory.replace(/^\d+\.\s*/, "").replace(/\s+$/, "")
return `${index + 1}. ${text} \n`
})
}
export function showMemorySuggestion(
platform: string,
input: SuggestionInput,

View file

@ -11,7 +11,9 @@ import {
} from "../../utils/storage"
import { createT3InputBarElement, DOMUtils } from "../../utils/ui-components"
import {
buildSupermemoryText,
parseMemoriesFromDataset,
renumberIncludedMemories,
serializeMemoriesForDataset,
} from "./memory-suggestion"
@ -19,6 +21,19 @@ let t3DebounceTimeout: NodeJS.Timeout | null = null
let t3RouteObserver: MutationObserver | null = null
let t3UrlCheckInterval: NodeJS.Timeout | null = null
let t3ObserverThrottle: NodeJS.Timeout | null = null
let t3IncludedPopup: {
el: HTMLElement
onClick: (event: MouseEvent) => void
timer: ReturnType<typeof setTimeout>
} | null = null
function disposeT3IncludedPopup() {
if (!t3IncludedPopup) return
document.removeEventListener("click", t3IncludedPopup.onClick)
clearTimeout(t3IncludedPopup.timer)
t3IncludedPopup.el.remove()
t3IncludedPopup = null
}
export function initializeT3() {
if (!DOMUtils.isOnDomain(DOMAINS.T3)) {
@ -57,6 +72,7 @@ function setupT3RouteChangeDetection() {
const checkForRouteChange = () => {
if (window.location.href !== currentUrl) {
disposeT3IncludedPopup()
currentUrl = window.location.href
setTimeout(() => {
addSupermemoryIconToT3Input()
@ -235,7 +251,9 @@ async function getRelatedMemoriesForT3(actionSource: string) {
}
if (textareaElement) {
textareaElement.dataset.supermemories = `\n\nSupermemories of user (only for the reference): ${response.data}`
textareaElement.dataset.supermemories = buildSupermemoryText(
response.data,
)
iconElement.dataset.memoriesData = serializeMemoriesForDataset(
response.data,
@ -274,6 +292,8 @@ function updateT3IconFeedback(
iconElement.dataset.originalHtml = iconElement.innerHTML
}
disposeT3IncludedPopup()
const feedbackDiv = document.createElement("div")
feedbackDiv.style.cssText = `
display: flex;
@ -409,68 +429,65 @@ function updateT3IconFeedback(
popup.style.display = "block"
})
document.addEventListener("click", (e) => {
const onClick = (e: MouseEvent) => {
if (!popup.contains(e.target as Node)) {
popup.style.display = "none"
}
})
}
document.addEventListener("click", onClick)
t3IncludedPopup = {
el: popup,
onClick,
timer: setTimeout(disposeT3IncludedPopup, 300000),
}
content.querySelectorAll("button[data-memory-index]").forEach((button) => {
const htmlButton = button as HTMLButtonElement
htmlButton.addEventListener("click", () => {
const index = Number.parseInt(htmlButton.dataset.memoryIndex || "0", 10)
const memoryItem = htmlButton.parentElement
htmlButton.parentElement?.remove()
if (memoryItem) {
content.removeChild(memoryItem)
}
const currentMemories = parseMemoriesFromDataset(
const remainingMemories = parseMemoriesFromDataset(
iconElement.dataset.memoriesData,
)
currentMemories.splice(index, 1)
// Injected prompt keeps its existing joined-text form; the popup's
// own data is stored as JSON so comma-bearing memories stay intact.
const updatedMemories = currentMemories.join(" ,")
iconElement.dataset.memoriesData =
serializeMemoriesForDataset(currentMemories)
remainingMemories.splice(index, 1)
const remaining = renumberIncludedMemories(remainingMemories)
const textareaElement =
(document.querySelector("textarea") as HTMLTextAreaElement) ||
(document.querySelector('div[contenteditable="true"]') as HTMLElement)
// Only wipe when nothing remains — `<= 1` used to discard the last kept memory.
if (remaining.length === 0) {
if (textareaElement?.dataset.supermemories) {
delete textareaElement.dataset.supermemories
}
delete iconElement.dataset.memoriesData
iconElement.innerHTML = iconElement.dataset.originalHtml || ""
delete iconElement.dataset.originalHtml
disposeT3IncludedPopup()
return
}
iconElement.dataset.memoriesData =
serializeMemoriesForDataset(remaining)
if (textareaElement) {
textareaElement.dataset.supermemories = `\n\nSupermemories of user (only for the reference): ${updatedMemories}`
textareaElement.dataset.supermemories =
buildSupermemoryText(remaining)
}
content
.querySelectorAll("button[data-memory-index]")
.forEach((btn, newIndex) => {
const htmlBtn = btn as HTMLButtonElement
htmlBtn.dataset.memoryIndex = newIndex.toString()
htmlBtn.dataset.memoryIndex = String(newIndex)
const label = htmlBtn.previousElementSibling
if (label) {
label.textContent = remaining[newIndex].trim()
}
})
if (currentMemories.length <= 1) {
if (textareaElement?.dataset.supermemories) {
delete textareaElement.dataset.supermemories
delete iconElement.dataset.memoriesData
iconElement.innerHTML = iconElement.dataset.originalHtml || ""
delete iconElement.dataset.originalHtml
}
popup.style.display = "none"
if (document.body.contains(popup)) {
document.body.removeChild(popup)
}
}
})
})
setTimeout(() => {
if (document.body.contains(popup)) {
document.body.removeChild(popup)
}
}, 300000)
}
iconElement.innerHTML = ""
@ -562,6 +579,7 @@ function setupT3PromptCapture() {
if (textareaElement?.dataset.supermemories) {
delete textareaElement.dataset.supermemories
}
disposeT3IncludedPopup()
}
const handleT3SendButtonClick = async (event: Event) => {
@ -717,6 +735,7 @@ async function setupT3AutoFetch() {
if (textareaElement.dataset.supermemories) {
delete textareaElement.dataset.supermemories
}
disposeT3IncludedPopup()
}
}, UI_CONFIG.AUTO_SEARCH_DEBOUNCE_DELAY)
}