diff --git a/apps/browser-extension/entrypoints/background.ts b/apps/browser-extension/entrypoints/background.ts index 2853ec45..d8b26fdb 100644 --- a/apps/browser-extension/entrypoints/background.ts +++ b/apps/browser-extension/entrypoints/background.ts @@ -47,11 +47,11 @@ export default defineBackground(() => { body: JSON.stringify({ containerTags: ['sm_project_default'], content: - message.data.highlightedText + + message.data?.highlightedText + '\n\n' + message.data.html + '\n\n' + - message.data.url, + message.data?.url, metadata: { sm_source: 'consumer' }, }), }); diff --git a/apps/browser-extension/entrypoints/content.ts b/apps/browser-extension/entrypoints/content.ts index cd621d9c..84127916 100644 --- a/apps/browser-extension/entrypoints/content.ts +++ b/apps/browser-extension/entrypoints/content.ts @@ -11,6 +11,29 @@ export default defineContentScript({ } }); + const observeForMemoriesDialog = () => { + const observer = new MutationObserver(() => { + if (window.location.hostname === 'chatgpt.com' || window.location.hostname === 'chat.openai.com') { + addSupermemoryButtonToMemoriesDialog(); + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true, + }); + + if (window.location.hostname === 'chatgpt.com' || window.location.hostname === 'chat.openai.com') { + addSupermemoryButtonToMemoriesDialog(); + } + }; + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', observeForMemoriesDialog); + } else { + observeForMemoriesDialog(); + } + async function saveMemory() { try { showToast('loading'); @@ -42,6 +65,113 @@ export default defineContentScript({ } } + function addSupermemoryButtonToMemoriesDialog() { + const dialogs = document.querySelectorAll('[role="dialog"]'); + let memoriesDialog: HTMLElement | null = null; + + for (const dialog of dialogs) { + const headerText = dialog.querySelector('h2'); + if (headerText && headerText.textContent?.includes('Saved memories')) { + memoriesDialog = dialog as HTMLElement; + break; + } + } + + if (!memoriesDialog) return; + + if (memoriesDialog.querySelector('#supermemory-save-button')) return; + + const deleteAllContainer = memoriesDialog.querySelector('.mt-5.flex.justify-end'); + if (!deleteAllContainer) return; + + const supermemoryButton = document.createElement('button'); + supermemoryButton.id = 'supermemory-save-button'; + supermemoryButton.className = 'btn relative btn-primary-outline mr-2'; + + const iconUrl = browser.runtime.getURL('/icon-16.png'); + + supermemoryButton.innerHTML = ` +
+ Supermemory + Save to Supermemory +
+ `; + + supermemoryButton.style.cssText = ` + background: #1C2026 !important; + color: white !important; + border: 1px solid #1C2026 !important; + border-radius: 9999px !important; + padding: 10px 16px !important; + font-weight: 500 !important; + font-size: 14px !important; + margin-right: 8px !important; + cursor: pointer !important; + `; + + supermemoryButton.addEventListener('mouseenter', () => { + supermemoryButton.style.backgroundColor = '#2B2E33'; + }); + + supermemoryButton.addEventListener('mouseleave', () => { + supermemoryButton.style.backgroundColor = '#1C2026'; + }); + + supermemoryButton.addEventListener('click', async () => { + await saveMemoriesToSupermemory(); + }); + + deleteAllContainer.insertBefore(supermemoryButton, deleteAllContainer.firstChild); + } + + async function saveMemoriesToSupermemory() { + try { + showToast('loading'); + + const memoriesTable = document.querySelector('[role="dialog"] table tbody'); + if (!memoriesTable) { + showToast('error'); + return; + } + + const memoryRows = memoriesTable.querySelectorAll('tr'); + const memories: string[] = []; + + memoryRows.forEach(row => { + const memoryCell = row.querySelector('td .py-2.whitespace-pre-wrap'); + if (memoryCell && memoryCell.textContent) { + memories.push(memoryCell.textContent.trim()); + } + }); + + console.log('Memories:', memories); + + if (memories.length === 0) { + showToast('error'); + return; + } + + const url = window.location.href; + const combinedContent = `ChatGPT Saved Memories:\n\n${memories.map((memory, index) => `${index + 1}. ${memory}`).join('\n\n')}`; + + const response = await browser.runtime.sendMessage({ + action: 'saveMemory', + data: { + html: combinedContent, + }, + }); + + if (response.success) { + showToast('success'); + } else { + showToast('error'); + } + } catch (error) { + console.error('Error saving memories to Supermemory:', error); + showToast('error'); + } + } + function showToast(state: 'loading' | 'success' | 'error') { if (currentToast) { currentToast.remove(); diff --git a/apps/browser-extension/entrypoints/popup/App.css b/apps/browser-extension/entrypoints/popup/App.css index a6dcc809..d088d98b 100644 --- a/apps/browser-extension/entrypoints/popup/App.css +++ b/apps/browser-extension/entrypoints/popup/App.css @@ -81,3 +81,36 @@ .authenticated, .unauthenticated { text-align: left; } + +.actions { + display: flex; + flex-direction: column; + gap: 12px; +} + +.chatgpt-btn { + width: 100%; + padding: 12px 12px; + background-color: white; + color: black; + border: 1px solid #e4e6eb; + border-radius: 6px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.2s ease; +} + +.chatgpt-btn:hover { + background-color: #f0f0f0; + border-color: #e4e6eb; +} + +.chatgpt-logo { + width: 35px; + height: 20px; + flex-shrink: 0; +} diff --git a/apps/browser-extension/entrypoints/popup/App.tsx b/apps/browser-extension/entrypoints/popup/App.tsx index 40e108af..84691a57 100644 --- a/apps/browser-extension/entrypoints/popup/App.tsx +++ b/apps/browser-extension/entrypoints/popup/App.tsx @@ -57,9 +57,26 @@ function App() { Signed in - +
+ + +
) : (
diff --git a/apps/browser-extension/entrypoints/popup/style.css b/apps/browser-extension/entrypoints/popup/style.css index 2c3fac68..c354e896 100644 --- a/apps/browser-extension/entrypoints/popup/style.css +++ b/apps/browser-extension/entrypoints/popup/style.css @@ -1,5 +1,5 @@ :root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-family: 'Space Grotesk', Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; line-height: 1.5; font-weight: 400; diff --git a/apps/browser-extension/package.json b/apps/browser-extension/package.json index 0888df7d..839ab818 100644 --- a/apps/browser-extension/package.json +++ b/apps/browser-extension/package.json @@ -1,6 +1,6 @@ { - "name": "Supermemory", - "description": "supermemory", + "name": "supermemory-browser-extension", + "description": "Supermemory Browser Extension", "private": true, "version": "0.0.1", "type": "module", diff --git a/package.json b/package.json index 656dfcc5..a7cc83e7 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "supermemory-app", + "name": "supermemory", "private": true, "scripts": { "build": "turbo run build",