Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "intuition-chrome-extension",
"displayName": "Intuition Chrome Extension",
"version": "0.1.46",
"version": "0.1.47",
"description": "",
"author": "THP-Lab.org",
"scripts": {
Expand All @@ -20,7 +20,9 @@
"@graphql-codegen/typescript-document-nodes": "^4.0.11",
"@plasmohq/storage": "^1.15.0",
"@radix-ui/react-collapsible": "^1.1.4",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-hover-card": "^1.1.7",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-slot": "^1.1.2",
"@tanstack/react-query": "^5.69.0",
"@types/three": "^0.175.0",
Expand Down
381 changes: 370 additions & 11 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

34 changes: 32 additions & 2 deletions src/background.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
export {}

let pendingSidepanelRoute: string | null = null;
let sidepanelPort: chrome.runtime.Port | null = null;

chrome.runtime.onConnect.addListener((port) => {
if (port.name === "sidepanel-nav") {
sidepanelPort = port;
port.onMessage.addListener((msg) => {
if (msg === "SIDEPANEL_READY" && pendingSidepanelRoute) {
port.postMessage({ action: "NAVIGATE_SIDEPANEL", route: pendingSidepanelRoute });
pendingSidepanelRoute = null;
}
});
port.onDisconnect.addListener(() => {
sidepanelPort = null;
});
}
});

chrome.runtime.onMessage.addListener((message, sender) => {
if (message.type === "open_sidepanel") {
const tabId = sender.tab?.id
const windowId = sender.tab?.windowId

if (!tabId || !windowId) return

chrome.sidePanel.open({ tabId, windowId })
pendingSidepanelRoute = message.route || null;

chrome.sidePanel.open({ tabId, windowId });
}
})
});

chrome.tabs.onUpdated.addListener((tabId, info) => {
if (info.status === "complete") {
chrome.tabs.sendMessage(tabId, { action: "REFRESH_CLAIMS" });
}
});

chrome.tabs.onActivated.addListener(({ tabId }) => {
chrome.tabs.sendMessage(tabId, { action: "REFRESH_CLAIMS" });
});
63 changes: 63 additions & 0 deletions src/components/ReportDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import React from "react";
import { useSignalProcess } from "../hooks/useSignalProcess"

const ChevronDown = () => (
<svg width="16" height="16" fill="none">
<path d="M5 8l5 5 5-5" stroke="currentColor" strokeWidth="2" fill="none" />
</svg>
);

const SignalDropdown = ({ atoms, uri }) => {
const { handleSignal } = useSignalProcess({
atoms,
uri,
onSuccess: () => {/* popup success */},
onError: () => {/* popup error */}
})

const shadowRoot = document.getElementById("plasmo-inline-example-unique-id")?.shadowRoot

return (
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<button
className="flex items-center p-1 rounded bg-white text-black border border-gray-300 hover:bg-gray-400"
style={{ fontWeight: 500, boxShadow: "0 1px 2px rgba(0,0,0,0.04)" }}
onClick={e => e.stopPropagation()}
onMouseDown={e => e.stopPropagation()}
>
Signal
<span className="ml-3">
<ChevronDown />
</span>
</button>
</DropdownMenu.Trigger>
<DropdownMenu.Portal container={shadowRoot}>
<DropdownMenu.Content
className="bg-white pt-3 rounded shadow-lg p-1 border border-gray-200 z-[9999]"
sideOffset={4}
onClick={e => e.stopPropagation()}
onMouseDown={e => e.stopPropagation()}
>
<DropdownMenu.Item onClick={() => handleSignal("scam")}>
<button
className="w-full p-1 text-black hover:bg-gray-300"
>
Scam
</button>
</DropdownMenu.Item>
<DropdownMenu.Item onClick={() => handleSignal("trustworthy")}>
<button
className="w-full p-1 text-black hover:bg-gray-300"
>
Trustworthy
</button>
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
);
};

export default SignalDropdown;
125 changes: 125 additions & 0 deletions src/components/WarningPopup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import React, { useEffect, useState } from "react"
import { cn } from "~/src/lib/utils"
import VoteButtons from "~src/components/VoteButtons"

interface WarningPopupProps {
message: string
offset: number
bgColor?: string
targetClaim?: any
forceVisible?: boolean
}

/**
* A small popup to display status warnings or confirmations.
* Appears below its parent icon at a given offset.
*/
const WarningPopup: React.FC<WarningPopupProps> = ({
message,
offset,
bgColor = "red",
targetClaim,
forceVisible = false
}) => {
const [visible, setVisible] = useState(forceVisible)
const [shouldRender, setShouldRender] = useState(forceVisible)

const ANIMATION_DURATION = 500

useEffect(() => {
if (forceVisible) {
setShouldRender(true)
setVisible(true)
} else {
setVisible(false)
const tm = setTimeout(() => setShouldRender(false), ANIMATION_DURATION)
return () => clearTimeout(tm)
}
}, [forceVisible])

const textColor = bgColor === "red" ? "#b50606" : "#228e01"
const borderColor = bgColor === "red" ? "#b50606" : "#228e01"

const vaultId = targetClaim?.term_id
? BigInt(targetClaim.term_id)
: undefined
const counterVaultId = targetClaim?.counter_term_id
? BigInt(targetClaim.counter_term_id)
: undefined
const numPositionsFor = targetClaim?.term?.positions_aggregate?.aggregate?.count
const numPositionsAgainst = targetClaim?.counter_term?.positions_aggregate?.aggregate?.count

const userStake = Number(targetClaim?.positions?.[0]?.shares ?? 0)
const userCounterStake = Number(targetClaim?.counter_positions?.[0]?.shares ?? 0)

const initialVote: VoteChoice | undefined =
userStake > 0
? "for"
: userCounterStake > 0
? "against"
: undefined

if (!shouldRender) return null

return (
<div
className={cn("warning-popup", { visible })}
onMouseDown={e => e.stopPropagation()}
onClick={e => e.stopPropagation()}
style={{
position: "absolute",
top: offset,
left: "50%",
transform: `
translateX(-80%)
translateY(${visible ? 0 : '-5px'})
`,
background: "#0f0f0f",
color: textColor,
padding: "4px",
borderRadius: "8px",
fontSize: "0.875rem",
fontWeight: "500",
whiteSpace: "nowrap",
pointerEvents: "auto",
zIndex: 9998,
border: `1px solid ${borderColor}`,
boxShadow: `0 4px 12px rgba(0, 0, 0, 0.3), 0 0 0 1px ${borderColor}20`,
textAlign: "center",
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
letterSpacing: "0.025em",
backdropFilter: "blur(8px)",
width: "180px",
minWidth: undefined,
opacity: visible ? 1 : 0,
transition: `
opacity ${ANIMATION_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1),
transform ${ANIMATION_DURATION}ms cubic-bezier(0.34, 1.56, 0.64, 1)
`,
willChange: "transform, opacity"
}}
>
<div style={{
fontWeight: "600",
marginBottom: "8px",
textTransform: "uppercase",
fontSize: "1rem",
letterSpacing: "0.05em"
}}>
{message}
</div>

<div style={{ display: "flex", justifyContent: "center" }}>
<VoteButtons
vaultId={vaultId}
counterVaultId={counterVaultId}
numPositionsFor={numPositionsFor}
numPositionsAgainst={numPositionsAgainst}
initialVote={initialVote}
/>
</div>
</div>
)
}

export default WarningPopup
91 changes: 49 additions & 42 deletions src/components/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { apolloClient } from '~src/lib/apolo-client'
import React, { type ReactNode, useEffect } from "react"
import {
Route,
BrowserRouter as Router,
Routes,
Navigate
Navigate,
useNavigate
} from "react-router-dom"

import { configureClient } from "@warzieram/graphql"
Expand Down Expand Up @@ -39,9 +39,7 @@ import ProfileLayout from "./profile/ProfileLayout"
import "../styles/global.css"
import umamiScriptUrl from "url:../../assets/umami.js"

import TagsPage from "~src/pages/TagsPage"

const API_URL = "https://prod.base-sepolia.intuition.sh/v1/graphql"
const API_URL = "https://prod.base.intuition-api.com/v1/graphql"
configureClient({ apiUrl: API_URL })

const queryClient = new QueryClient()
Expand All @@ -65,22 +63,32 @@ const Content = ({ children }: ContentProps) => {
}, [])

const { navType } = useNavigation()
const navigate = useNavigate();

useEffect(() => {
const port = chrome.runtime.connect({ name: "sidepanel-nav" });
port.postMessage("SIDEPANEL_READY");
port.onMessage.addListener((msg) => {
if (msg.action === "NAVIGATE_SIDEPANEL" && msg.route) {
console.log("[SIDEPANEL] NAVIGATE_SIDEPANEL received via port, navigating to:", msg.route);
navigate(msg.route);
}
});
return () => port.disconnect();
}, [navigate]);

console.log(queryClient);

return (
<ApolloProvider client={apolloClient}>
<QueryClientProvider client={queryClient}>
<AtomSelectionProvider>
<Router>
<PageViewTracker />
{navType === "classic" && <NavbarUp />}
<main className="flex-1 overflow-auto pb-24 pt-14">
{children}
<div className="container mx-auto space-y-8 p-2">
<Routes>
<Route path="*" element={<Home />} />
<Route path="/" element={<Home />} />
<PageViewTracker />
{navType === "classic" && <NavbarUp />}
<main className="flex-1 overflow-auto pb-24 pt-14">
{children}
<div className="container mx-auto space-y-8 p-2">
<Routes>
<Route path="*" element={<Home />} />
<Route path="/" element={<Home />} />

<Route path="/profile" element={<Profile />}>
<Route index element={<Navigate to="/profile/claims/all" />} />
Expand All @@ -90,34 +98,33 @@ const Content = ({ children }: ContentProps) => {
<Route path="created" element={<CreatedClaimsTab />} />
</Route>

<Route path="identities">
<Route path="all" element={<IdentitiesVotedTab />} />
<Route path="created" element={<IdentityTab />} />
</Route>

<Route path="followers" element={<FollowersTab />} />
<Route path="following" element={<FollowingTab />} />
<Route path="identities">
<Route path="all" element={<IdentitiesVotedTab />} />
<Route path="created" element={<IdentityTab />} />
</Route>
</Route>

<Route path="/feed" element={<Feed />} />
<Route path="/page-form" element={<PageForm />} />
<Route path="/recent-activity" element={<RecentActivity />} />
<Route path="/search" element={<Search />} />
<Route path="/atoms/:id" element={<AtomDetailPage />} />
<Route path="/tags" element={<TagsPage />} />
<Route path="/tags/:tagId" element={<TagsDetailPage />} />
</Routes>
</div>
</main>
{navType === "classic" ? (
<Navbar />
) : (
<>
<NavArc />
</>
)}
</Router>
<Route path="followers" element={<FollowersTab />} />
<Route path="following" element={<FollowingTab />} />
</Route>
</Route>

<Route path="/feed" element={<Feed />} />
<Route path="/page-form" element={<PageForm />} />
<Route path="/recent-activity" element={<RecentActivity />} />
<Route path="/search" element={<Search />} />
<Route path="/atoms/:id" element={<AtomDetailPage />} />
<Route path="/tags" element={<TagsPage />} />
<Route path="/tags/:tagId" element={<TagsDetailPage />} />
</Routes>
</div>
</main>
{navType === "classic" ? (
<Navbar />
) : (
<>
<NavArc />
</>
)}
</AtomSelectionProvider>
</QueryClientProvider>
</ApolloProvider>
Expand Down
Loading