SurfSense/surfsense_browser_extension/background/index.ts
API Test Bot 9790edfeaa feat(floating-button): add Mevx-style floating quick action button
- Create floating-button.tsx content script with inline UI
- Button appears on crypto pages (DexScreener, Twitter, CoinGecko, etc.)
- Shows quick token analysis popup on click
- Displays token price, 24h change, and quick stats
- 'Full Analysis' button opens sidepanel for detailed view
- Update background/index.ts to handle OPEN_SIDEPANEL message
- Gradient purple button with smooth animations
- Fixed positioning (bottom-right corner)
- Clean, modern popup design with inline styles

Implements Task 3: Create Floating Quick Action Button
Similar to Mevx's approach for quick token insights
2026-02-04 10:59:54 +07:00

86 lines
2.9 KiB
TypeScript

import { Storage } from "@plasmohq/storage";
import { getRenderedHtml, initQueues, initWebHistory } from "~utils/commons";
import type { WebHistory } from "~utils/interfaces";
// Configure side panel to open when extension icon is clicked
chrome.sidePanel
.setPanelBehavior({ openPanelOnActionClick: true })
.catch((error) => console.error("Failed to set side panel behavior:", error));
// Listen for messages from content scripts
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === "OPEN_SIDEPANEL") {
// Open sidepanel for the current tab
if (sender.tab?.id) {
chrome.sidePanel.open({ tabId: sender.tab.id })
.catch((error) => console.error("Failed to open side panel:", error));
}
}
});
chrome.tabs.onCreated.addListener(async (tab: any) => {
try {
await initWebHistory(tab.id);
await initQueues(tab.id);
} catch (error) {
console.log(error);
}
});
chrome.tabs.onUpdated.addListener(async (tabId: number, changeInfo: any, tab: any) => {
if (changeInfo.status === "complete" && tab.url) {
const storage = new Storage({ area: "local" });
await initWebHistory(tab.id);
await initQueues(tab.id);
const result = await chrome.scripting.executeScript({
// @ts-ignore
target: { tabId: tab.id },
// @ts-ignore
func: getRenderedHtml,
});
const toPushInTabHistory: any = result[0].result; // const { renderedHtml, title, url, entryTime } = result[0].result;
const urlQueueListObj: any = await storage.get("urlQueueList");
const timeQueueListObj: any = await storage.get("timeQueueList");
urlQueueListObj.urlQueueList
.find((data: WebHistory) => data.tabsessionId === tabId)
.urlQueue.push(toPushInTabHistory.url);
timeQueueListObj.timeQueueList
.find((data: WebHistory) => data.tabsessionId === tabId)
.timeQueue.push(toPushInTabHistory.entryTime);
await storage.set("urlQueueList", {
urlQueueList: urlQueueListObj.urlQueueList,
});
await storage.set("timeQueueList", {
timeQueueList: timeQueueListObj.timeQueueList,
});
}
});
chrome.tabs.onRemoved.addListener(async (tabId: number, removeInfo: object) => {
const storage = new Storage({ area: "local" });
const urlQueueListObj: any = await storage.get("urlQueueList");
const timeQueueListObj: any = await storage.get("timeQueueList");
if (urlQueueListObj.urlQueueList && timeQueueListObj.timeQueueList) {
const urlQueueListToSave = urlQueueListObj.urlQueueList.map((element: WebHistory) => {
if (element.tabsessionId !== tabId) {
return element;
}
});
const timeQueueListSave = timeQueueListObj.timeQueueList.map((element: WebHistory) => {
if (element.tabsessionId !== tabId) {
return element;
}
});
await storage.set("urlQueueList", {
urlQueueList: urlQueueListToSave.filter((item: any) => item),
});
await storage.set("timeQueueList", {
timeQueueList: timeQueueListSave.filter((item: any) => item),
});
}
});