Skip to content
Open
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
6 changes: 1 addition & 5 deletions pages/[chainNameAndSafeAddress]/claim.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { ArrowLeft } from "@icons"
import ClaimListView from "components/claim/ClaimListView"
import AccountNavBar from "components/core/AccountNavBar"
import { convertGlobalId } from "models/terminal/utils"
import Link from "next/link"
import { useRouter } from "next/router"

const TerminalClaimListView = ({}: {}) => {
const router = useRouter()
const { address } = convertGlobalId(
router.query.chainNameAndSafeAddress as string,
)

return (
<div className="flex h-screen grow flex-col pb-4">
Expand All @@ -20,7 +16,7 @@ const TerminalClaimListView = ({}: {}) => {
>
<ArrowLeft />
</Link>
<ClaimListView recipientAddress={address!} />
<ClaimListView />
</div>
)
}
Expand Down
2 changes: 2 additions & 0 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import trackerInit, { initializeUser, trackEvent } from "lib/utils/amplitude"
import { useRouter } from "next/router"
import Script from "next/script"
import AppLayout from "../src/components/core/AppLayout"
import SliderManager from "../src/components/core/SliderManager"
import { useIsRouterLoading } from "../src/hooks/useIsRouterLoading"

const queryClient = new QueryClient({
Expand Down Expand Up @@ -182,6 +183,7 @@ function App({ Component, pageProps }: AppProps) {
<Spinner />
) : (
<AppLayout>
<SliderManager />
<Component {...pageProps} />
</AppLayout>
))}
Expand Down
2 changes: 1 addition & 1 deletion pages/u/[address]/profile/claim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const ProfileClaimListView = () => {
<Link href={`/u/${accountAddress}/profile`} className="block w-fit px-4">
<ArrowLeft />
</Link>
<ClaimListView recipientAddress={accountAddress} />
<ClaimListView />
</div>
)
}
Expand Down
126 changes: 45 additions & 81 deletions src/components/automation/CreateAutomationDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,97 +6,61 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@ui/Dropdown"
import { addQueryParam, removeQueryParam } from "lib/utils/updateQueryParam"
import dynamic from "next/dynamic"
import Link from "next/link"
import { useRouter } from "next/router"
import { useEffect, useState } from "react"

const RightSlider = dynamic(() =>
import("../../../src/components/ui/RightSlider").then(
(mod) => mod.RightSlider,
),
)
const NewAutomationContent = dynamic(() =>
import("../pages/newAutomation/components/NewAutomationContent").then(
(mod) => mod.NewAutomationContent,
),
)
import {
Sliders,
useSliderManagerStore,
} from "../../hooks/stores/useSliderManagerStore"

export const CreateAutomationDropdown = () => {
const router = useRouter()

const [createAutomationSliderOpen, setCreateAutomationSliderOpen] =
useState<boolean>(false)
const closeCreateAutomationSlider = (isOpen: boolean) => {
if (!isOpen) {
removeQueryParam(router, "createAutomationSliderOpen")
}
}

useEffect(() => {
if (router.query.createAutomationSliderOpen) {
setCreateAutomationSliderOpen(true)
} else {
setCreateAutomationSliderOpen(false)
}
}, [router.query])
const setActiveSlider = useSliderManagerStore(
(state) => state.setActiveSlider,
)

return (
<>
<RightSlider
open={createAutomationSliderOpen}
setOpen={closeCreateAutomationSlider}
>
<NewAutomationContent />
</RightSlider>
<DropdownMenu>
<DropdownMenuTrigger>
{/* Copy same styles as primary, base button because annoying console.error if we use Button component */}
<span
className={buttonStyles({
variant: "primary",
size: "base",
fullWidth: false,
disabled: false,
})}
>
+ Create
</span>
</DropdownMenuTrigger>
<DropdownMenuContent className="mr-2">
<DropdownMenuItem>
<Breakpoint>
{(isMobile) => {
if (isMobile) {
return (
<Link
href={`/${router.query.chainNameAndSafeAddress}/automations/new`}
className="w-full"
>
Revenue share
</Link>
)
}
<DropdownMenu>
<DropdownMenuTrigger>
{/* Copy same styles as primary, base button because annoying console.error if we use Button component */}
<span
className={buttonStyles({
variant: "primary",
size: "base",
fullWidth: false,
disabled: false,
})}
>
+ Create
</span>
</DropdownMenuTrigger>
<DropdownMenuContent className="mr-2">
<DropdownMenuItem>
<Breakpoint>
{(isMobile) => {
if (isMobile) {
return (
<span
onClick={() => {
addQueryParam(
router,
"createAutomationSliderOpen",
"true",
)
setCreateAutomationSliderOpen(true)
}}
<Link
href={`/${router.query.chainNameAndSafeAddress}/automations/new`}
className="w-full"
>
Revenue share
</span>
</Link>
)
}}
</Breakpoint>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</>
}
return (
<span
onClick={() => {
setActiveSlider(Sliders.CREATE_AUTOMATION, { value: true })
}}
>
Revenue share
</span>
)
}}
</Breakpoint>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}
54 changes: 50 additions & 4 deletions src/components/claim/ClaimListView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { addressesAreEqual } from "lib/utils"
import { useAccountItemsToClaim } from "models/account/hooks"
import { RevShareWithdraw } from "models/automation/types"
import { RequestFrob } from "models/request/types"
import { useRouter } from "next/router"
import { useReducer, useState } from "react"
import { useAccount } from "wagmi"
import { usePermissionsStore } from "../../hooks/stores/usePermissionsStore"

enum BatchEvent {
ADD_ITEM,
Expand Down Expand Up @@ -92,8 +95,39 @@ const batchReducer = (
}
}

const ClaimListView = ({ recipientAddress }: { recipientAddress: string }) => {
const { isLoading, items, mutate } = useAccountItemsToClaim(recipientAddress)
const ClaimListView = () => {
const router = useRouter()
const isSigner = usePermissionsStore((state) => state.isSigner)
const { address: userAddress } = useAccount()

let pageType = "" as "terminal" | "profile"
const path = router.pathname.split("/")[1]
if (path === "[chainNameAndSafeAddress]") {
pageType = "terminal"
}
if (path === "u") {
pageType = "profile"
}

let recipientAddressParam
const { address, chainNameAndSafeAddress } = router.query as {
address: string | undefined
chainNameAndSafeAddress: string | undefined
}
if (address) {
recipientAddressParam = address as string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe the recipient address should always be the logged-in user?

Copy link
Copy Markdown
Contributor Author

@mcgingras mcgingras Mar 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya, if its a profile page we could use the logged in user, and if its a terminal page then it should belong to the terminal but we should definitely make sure the person claiming is authed.

I agree it feels like an exploit, but "claiming" doesn't mean you are sending the tokens to yourself. If I were able to see the claim CTAs on your profile, all I would be able to do is pay the gas to execute the transaction that sends the tokens to your address lol. It's a reverse exploit, exploiting the exploiter to pay the gas for you! 😆

but I agree, just to make the app not feel janky we should make sure to protect these pages.

} else if (chainNameAndSafeAddress) {
const safeAddress = chainNameAndSafeAddress.split(":")[1]
recipientAddressParam = safeAddress as string
}
const { isLoading, items, mutate, error } = useAccountItemsToClaim(
recipientAddressParam,
)

const canView =
(isSigner && pageType === "terminal") ||
(recipientAddressParam === userAddress && pageType === "profile")

const [claimDrawerItemPending, setClaimDrawerItemPending] =
useState<boolean>(false)
const [claimDrawerOpen, setClaimDrawerOpen] = useState<boolean>(false)
Expand Down Expand Up @@ -197,13 +231,25 @@ const ClaimListView = ({ recipientAddress }: { recipientAddress: string }) => {
revalidate: false,
})
}

if (!canView) {
return (
<div className="flex h-[calc(100%+18px)] flex-col px-4 pt-4">
<EmptyState
title="You cannot claim these tokens"
subtitle="These tokens can only be claimed by the recipient of the request."
/>
</div>
)
}

return (
<div className="flex h-full flex-col">
{/* single view & execute */}
<ClaimItemsDrawer
isOpen={claimDrawerOpen}
setIsOpen={setClaimDrawerOpen}
recipientAddress={recipientAddress}
recipientAddress={recipientAddressParam as string}
revShareWithdraws={selectedRevShareWithdraws}
requests={selectedRequests}
optimisticallyShow={optimisticallyShow}
Expand All @@ -214,7 +260,7 @@ const ClaimListView = ({ recipientAddress }: { recipientAddress: string }) => {
<ClaimItemsDrawer
isOpen={claimBatchOpen}
setIsOpen={setClaimBatchOpen}
recipientAddress={recipientAddress}
recipientAddress={recipientAddressParam as string}
revShareWithdraws={batchState.selectedRevShareWithdraws}
requests={batchState.selectedRequests}
optimisticallyShow={optimisticallyShow}
Expand Down
74 changes: 25 additions & 49 deletions src/components/claim/ProfileReadyToClaim.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,41 @@
import Breakpoint from "@ui/Breakpoint"
import ClaimListView from "components/claim/ClaimListView"
import dynamic from "next/dynamic"
import Link from "next/link"
import { useRouter } from "next/router"
import React, { useEffect, useState } from "react"
import React from "react"
import {
addQueryParam,
removeQueryParam,
} from "../../lib/utils/updateQueryParam"
Sliders,
useSliderManagerStore,
} from "../../hooks/stores/useSliderManagerStore"
import { ReadyToClaim } from "./ReadyToClaim"

const RightSlider = dynamic(() =>
import("../../components/ui/RightSlider").then((mod) => mod.RightSlider),
)

export const ProfileReadyToClaim = () => {
const router = useRouter()
const setActiveSlider = useSliderManagerStore(
(state) => state.setActiveSlider,
)
const accountAddress = router.query.address as string

const [claimSliderOpen, setClaimSliderOpen] = useState<boolean>(false)
const closeClaimSlider = (isOpen: boolean) => {
if (!isOpen) {
removeQueryParam(router, "claimSliderOpen")
}
}

useEffect(() => {
if (router.query.claimSliderOpen) {
setClaimSliderOpen(true)
} else {
setClaimSliderOpen(false)
}
}, [router.query])

return (
<>
<RightSlider open={claimSliderOpen} setOpen={closeClaimSlider}>
<ClaimListView recipientAddress={accountAddress} />
</RightSlider>
<Breakpoint>
{(isMobile) => {
if (isMobile) {
return (
<Link href={`/u/${accountAddress}/profile/claim`}>
<ReadyToClaim address={accountAddress} />
</Link>
)
}
<Breakpoint>
{(isMobile) => {
if (isMobile) {
return (
<span
className="cursor-pointer"
onClick={() => {
setClaimSliderOpen(true)
addQueryParam(router, "claimSliderOpen", "true")
}}
>
<Link href={`/u/${accountAddress}/profile/claim`}>
<ReadyToClaim address={accountAddress} />
</span>
</Link>
)
}}
</Breakpoint>
</>
}
return (
<span
className="cursor-pointer"
onClick={() => {
setActiveSlider(Sliders.CLAIM_TOKENS, { value: true })
}}
>
<ReadyToClaim address={accountAddress} />
</span>
)
}}
</Breakpoint>
)
}
Loading