import { useState } from "react"; import "./ext.css"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "./components/ui/tooltip"; import { FilterSpaces } from "./components/FilterCombobox"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogTrigger, DialogFooter, DialogClose, } from "./components/ui/dialog"; import { Space } from "./types/memory"; function sendUrlToAPI(spaces: number[]) { // get the current URL const url = window.location.href; const blacklist = ["localhost:3000", "anycontext.dhr.wtf"]; // check if the URL is blacklisted if (blacklist.some((blacklisted) => url.includes(blacklisted))) { console.log("URL is blacklisted"); return; } else { // const content = Entire page content, but cleaned up for the LLM. No ads, no scripts, no styles, just the text. if article, just the importnat info abou tit. const content = document.documentElement.innerText; chrome.runtime.sendMessage({ type: "urlChange", content, url, spaces }); } } function SideBar({ jwt }: { jwt: string }) { // TODO: Implement getting bookmarks from Twitter API directly // chrome.runtime.onMessage.addListener(function (request) { // if (request.action === 'showProgressIndicator') { // // TODO: SHOW PROGRESS INDICATOR // // showProgressIndicator(); // } else if (request.action === 'hideProgressIndicator') { // // hideProgressIndicator(); // } // }); const [savedWebsites, setSavedWebsites] = useState([]); const [isSendingData, setIsSendingData] = useState(false); const [loading, setLoading] = useState(false); const [spaces, setSpaces] = useState(); const [selectedSpaces, setSelectedSpaces] = useState([]); const [isImportingTweets, setIsImportingTweets] = useState(false); const [log, setLog] = useState([]); interface TweetData { tweetText: string; postUrl: string; authorName: string; handle: string; time: string; saveToUser: string; } function sendBookmarkedTweetsToAPI(tweets: TweetData[], token: string) { chrome.runtime.sendMessage({ type: "sendBookmarkedTweets", jwt: token, tweets, }); } const fetchSpaces = async () => { setLoading(true); chrome.runtime.sendMessage({ type: "fetchSpaces" }, (resp) => { console.log("response", resp); setSpaces(resp); setLoading(false); }); }; const fetchBookmarks = () => { const tweets: TweetData[] = []; // Initialize an empty array to hold all tweet elements setIsImportingTweets(true); console.log("Importing tweets"); const scrollInterval = 1000; const scrollStep = 5000; // Pixels to scroll on each step let previousTweetCount = 0; let unchangedCount = 0; const scrollToEndIntervalID = setInterval(() => { window.scrollBy(0, scrollStep); const currentTweetCount = tweets.length; if (currentTweetCount === previousTweetCount) { unchangedCount++; if (unchangedCount >= 2) { setLog([ ...log, "Scraping complete", `Total tweets scraped: ${tweets.length}`, "Downloading tweets as JSON...", ]); clearInterval(scrollToEndIntervalID); // Stop scrolling observer.disconnect(); // Stop observing DOM changes downloadTweetsAsJson(tweets); // Download the tweets list as a JSON file } } else { unchangedCount = 0; // Reset counter if new tweets were added } previousTweetCount = currentTweetCount; // Update previous count for the next check }, scrollInterval); function updateTweets() { document .querySelectorAll('article[data-testid="tweet"]') .forEach((tweetElement) => { const authorName = ( tweetElement.querySelector( '[data-testid="User-Name"]', ) as HTMLElement )?.innerText; const handle = ( tweetElement.querySelector('[role="link"]') as HTMLLinkElement ).href .split("/") .pop(); const tweetText = ( tweetElement.querySelector( '[data-testid="tweetText"]', ) as HTMLElement )?.innerText; const time = ( tweetElement.querySelector("time") as HTMLTimeElement ).getAttribute("datetime"); const postUrl = ( tweetElement.querySelector( ".css-175oi2r.r-18u37iz.r-1q142lx a", ) as HTMLLinkElement )?.href; const isTweetNew = !tweets.some((tweet) => tweet.postUrl === postUrl); if (isTweetNew) { tweets.push({ authorName, handle: handle ?? "", tweetText, time: time ?? "", postUrl, saveToUser: jwt, }); setLog([...log, `Scraped tweet: ${tweets.length}`]); } }); } // Initially populate the tweets array updateTweets(); // Create a MutationObserver to observe changes in the DOM const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { updateTweets(); // Call updateTweets whenever new nodes are added to the DOM } }); }); // Start observing the document body for child list changes observer.observe(document.body, { childList: true, subtree: true }); function downloadTweetsAsJson(tweetsArray: TweetData[]) { setLog([...log, "Saving the tweets to our database..."]); sendBookmarkedTweetsToAPI(tweetsArray, jwt); setIsImportingTweets(false); } }; return ( <> {isImportingTweets && (

Importing your tweets...

{log.map((message, index) => (

{message}

))}
)}
{window.location.href.includes("twitter.com") || window.location.href.includes("x.com") ? (

Import twitter bookmarks

) : ( <> )} open === true && fetchSpaces()}>

{savedWebsites.includes(window.location.href) ? "Added to memory" : "Add to memory"}

Add to Memory Add the current page to memory { sendUrlToAPI(selectedSpaces); setIsSendingData(true); setTimeout(() => { setIsSendingData(false); setSavedWebsites([ ...savedWebsites, window.location.href, ]); }, 1000); }} > Add Cancel
); } export default SideBar;