mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-05-17 21:11:04 +00:00
Adds user-controlled auto search functionality for memories across ChatGPT, Claude, and T3.chat with a settings toggle in the extension popup. Changes - Settings UI: Added new "Settings" tab in popup with toggle to enable/disable auto search - Auto Search: Automatically searches user memories while typing in chat apps (disabled by default) - Chat Integration: Supports ChatGPT, Claude, and T3.chat with consistent behavior - User Control: Users can enable/disable auto search via Settings tab - Storage: Added AUTO_SEARCH_ENABLED storage key with default value false Features - ✅ Auto search memories while typing (when enabled) - ✅ Manual search always available via supermemory icons - ✅ Works across all supported chat platforms - ✅ Real-time toggle without requiring page refresh
117 lines
2.9 KiB
TypeScript
117 lines
2.9 KiB
TypeScript
/**
|
|
* Route Detection Utilities
|
|
* Shared logic for detecting route changes across different AI chat platforms
|
|
*/
|
|
|
|
import { UI_CONFIG } from "./constants"
|
|
|
|
export interface RouteDetectionConfig {
|
|
platform: string
|
|
selectors: string[]
|
|
reinitCallback: () => void
|
|
checkInterval?: number
|
|
observerThrottleDelay?: number
|
|
}
|
|
|
|
export interface RouteDetectionCleanup {
|
|
observer: MutationObserver | null
|
|
urlCheckInterval: NodeJS.Timeout | null
|
|
observerThrottle: NodeJS.Timeout | null
|
|
}
|
|
|
|
export function createRouteDetection(
|
|
config: RouteDetectionConfig,
|
|
cleanup: RouteDetectionCleanup,
|
|
): void {
|
|
if (cleanup.observer) {
|
|
cleanup.observer.disconnect()
|
|
}
|
|
if (cleanup.urlCheckInterval) {
|
|
clearInterval(cleanup.urlCheckInterval)
|
|
}
|
|
if (cleanup.observerThrottle) {
|
|
clearTimeout(cleanup.observerThrottle)
|
|
cleanup.observerThrottle = null
|
|
}
|
|
|
|
let currentUrl = window.location.href
|
|
|
|
const checkForRouteChange = () => {
|
|
if (window.location.href !== currentUrl) {
|
|
currentUrl = window.location.href
|
|
console.log(`${config.platform} route changed, re-initializing`)
|
|
setTimeout(config.reinitCallback, 1000)
|
|
}
|
|
}
|
|
|
|
cleanup.urlCheckInterval = setInterval(
|
|
checkForRouteChange,
|
|
config.checkInterval || UI_CONFIG.ROUTE_CHECK_INTERVAL,
|
|
)
|
|
|
|
cleanup.observer = new MutationObserver((mutations) => {
|
|
if (cleanup.observerThrottle) {
|
|
return
|
|
}
|
|
|
|
let shouldRecheck = false
|
|
mutations.forEach((mutation) => {
|
|
if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
|
|
mutation.addedNodes.forEach((node) => {
|
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
const element = node as Element
|
|
|
|
for (const selector of config.selectors) {
|
|
if (
|
|
element.querySelector?.(selector) ||
|
|
element.matches?.(selector)
|
|
) {
|
|
shouldRecheck = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
if (shouldRecheck) {
|
|
cleanup.observerThrottle = setTimeout(() => {
|
|
try {
|
|
cleanup.observerThrottle = null
|
|
config.reinitCallback()
|
|
} catch (error) {
|
|
console.error(`Error in ${config.platform} observer callback:`, error)
|
|
}
|
|
}, config.observerThrottleDelay || UI_CONFIG.OBSERVER_THROTTLE_DELAY)
|
|
}
|
|
})
|
|
|
|
try {
|
|
cleanup.observer.observe(document.body, {
|
|
childList: true,
|
|
subtree: true,
|
|
})
|
|
} catch (error) {
|
|
console.error(`Failed to set up ${config.platform} route observer:`, error)
|
|
if (cleanup.urlCheckInterval) {
|
|
clearInterval(cleanup.urlCheckInterval)
|
|
}
|
|
cleanup.urlCheckInterval = setInterval(checkForRouteChange, 1000)
|
|
}
|
|
}
|
|
|
|
export function cleanupRouteDetection(cleanup: RouteDetectionCleanup): void {
|
|
if (cleanup.observer) {
|
|
cleanup.observer.disconnect()
|
|
cleanup.observer = null
|
|
}
|
|
if (cleanup.urlCheckInterval) {
|
|
clearInterval(cleanup.urlCheckInterval)
|
|
cleanup.urlCheckInterval = null
|
|
}
|
|
if (cleanup.observerThrottle) {
|
|
clearTimeout(cleanup.observerThrottle)
|
|
cleanup.observerThrottle = null
|
|
}
|
|
}
|