Skip to content

Commit

Permalink
v2 explorer (#1330)
Browse files Browse the repository at this point in the history
* feat: add header

* chore: configure navigator

* feat: `Providers` component

* chore: disable navigator on blur

* feat: `NavigationEvents` component

* feat: add explorer

* refactor: make providers work with both routers

* chore: color corrections

* feat: add dynamic header

* feat: add dynamic color to nav toggle

* feat: add robots, manifest, ring

* chore: add display font to title

* chore: change ring color

* refactor: extract guild listing

* feat: make header and background responsive

* feat: implement infinite scroll

* feat: add loading spinner

* feat: hook in searchbar

* feat: add IntercomProvider

* feat: usePrevious hook

* feat(CardMotionWrapper): use `m.div` instead of `MotionBox`

* wip: WalletSelectorModal without Google login button

* update package-lock

* feat: add anchor to search filter

* feat: add link to card

* feat: add no search result message

* fix: proper button states in wallet selector modal

* feat: `NavMenu` as popover

* feat: `CopyableAddress` component

* fix(useGuild): use the new `usePathname` hook

* fix: export `connectorButtonBaseProps` from `ConnectorButton`

* refactor toast related css variables

* fix: replace relevant toasts with our new toast component

* chore: upgrade nextjs

* wip: account modal

* ci: ignore waas import errors

* fix: addess merge conflict on toolbar, type errors

* chore: add debounce instead of defer

* chore: fix constant imports

* feat: make guild card image cacheable

* feat: add anchor

* cleanup playground

* refactor posthog, intercom, web3 related contexts & hooks

* cleanup: remove `DialogExample`

* fix(CardMotionWrapper): remove the `EASING` import

* Try fix build "out of memory" error (#1347)

* build: allocate more memory for nodejs on build

* build: increase memory limit

* chore: remove posthog provider to test build error

* chore: remove posthog provider to test build error

* chore: remove reward import

* build: remove memory limit override

* chore: fix circular import

* fix: update import outside v2

* fix: add missing react suspense

* Revert "chore: remove reward import"

This reverts commit b2cf1d8.

* chore: remove accidental svg

* fix(layout): add back `PostHogPageViews`

---------

Co-authored-by: BrickheadJohnny <[email protected]>

* feat(CopyableAddress): add tooltip

* feat: `NetworkModal` migration

* feat: `Accordion` component

* temporarily remove `CircularDependencyPlugin`

* move `platformMergeAlertAtom` to `atoms.ts`

* fix(useUserPublic): comment posthog related stuff

* chore: remove package-json

* feat: `FarcasterProfile` component

* fix ring color in light mode

* fix: remove ring offset

* fix: connect Farcaster button colors

* feat: define css vars for every platform type

* fix(SocialAccount): use the correct button colors

* fix: solve css overlay

* feat: add anchor element to page

* feat: add layout, search refactor

* refactor: extract query atom

* feat: add your guilds

* fix(build): add missing dep

* fix(build): add suspense boundary, auth check

* fix(build): move out suspense boundary

* fix(a11y): add padding to verified badge, extract signin button

* refactor: move layout into one file

* chore!: delete changes

* style: apply biome check

* chore: add hooks

* chore: merge playground

* chore: pull useIsStuck

* chore: remove conflicting explorer page

* chore: fix ts errors

* chore: pull UserGuildPins

* chore: update account inside layout

* fix(GuildCard): styling

* fix(GuildSearchBar): fine-tune styles

* fix(explorer): small refactor & styling improvements

* refactor(explorer): prefetch guilds on the server

* fix: use the default phosphor icons

* Revert "fix: use the default phosphor icons"

This reverts commit 468ee90.

* fix(GuildInfiniteScroll): use the `useFetcherWithSign` hook

* fix(WalletSelectorModal): highlighted "learn more" link

* feat(StickyBar): add smooth scroll

* fix(Toggle): default variant - `state=on` style

* chore: add aria label to wcm modal

* chore: move setAttribute

* chore: remove robots.txt duplicate, add new layout

* fix(a11y): adjust colors to metrics

* fix: offset and color banner properly

* chore: make button semibold

* chore: fix robots.txt

* Revert "chore: fix robots.txt"

This reverts commit 46cf099.

* chore: remove unused explorer-related components

* fix(GuildSearchBar): increase debounce time

* fix(HeaderBackground): background height on mobile

* fix(Explorer): only show the "Your guilds" section if the user has a keypair

* fix(StickyBar): add `/create-guild` link

* fix(GuildSearchBar): add smooth scroll

* cleanup(YourGuilds): use the already existing hook

* fix(explore): spacings & scroll animation

* cleanup(GuildSearchBar): remove comment

* feat(explorer): prefetch top newest guilds too

* refactor: store query state in the URL

* cleanup: remove unused `PageBoundary` file

* fix: change observerTarget's aria-label

* cleanup(Web3ConnectionManager): remove unused import

* cleanup(explorer): footer copy

* fix(Explorer): wrap `GuildInfiniteScroll` in `Suspense`

* refactor: pass search params down from the explorer page

* fix(GuildSearchBar): remove buggy useEffect

* chore: load images better

---------

Co-authored-by: BrickheadJohnny <[email protected]>
  • Loading branch information
dominik-stumpf and BrickheadJohnny authored Jul 12, 2024
1 parent 2aecad4 commit b9e602d
Show file tree
Hide file tree
Showing 39 changed files with 783 additions and 678 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ cypress/screenshots
cypress/videos

.idea

*.tsbuildinfo

*storybook.log
storybook-static
storybook-static
115 changes: 115 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions src/app/explorer/_components/Explorer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client"

import { walletSelectorModalAtom } from "@/components/Providers/atoms"
import { Button } from "@/components/ui/Button"
import { Card } from "@/components/ui/Card"
import { useUserPublic } from "@/hooks/useUserPublic"
import { SignIn } from "@phosphor-icons/react"
import { GuildSearchBar } from "app/explorer/_components/GuildSearchBar"
import { YourGuilds } from "app/explorer/_components/YourGuilds"
import useIsStuck from "hooks/useIsStuck"
import { useSetAtom } from "jotai"
import { Suspense } from "react"
import { SearchParams } from "types"
import Robot from "/public/landing/robot.svg"
import { isSearchStuckAtom } from "../atoms"
import { ActiveSection } from "../types"
import { GuildInfiniteScroll } from "./GuildInfiniteScroll"
import { StickyBar } from "./StickyBar"

export const Explorer = ({ searchParams }: { searchParams: SearchParams }) => {
const { keyPair } = useUserPublic()
const setIsSearchStuck = useSetAtom(isSearchStuckAtom)
const setIsWalletSelectorModalOpen = useSetAtom(walletSelectorModalAtom)

const { ref: searchRef } = useIsStuck(setIsSearchStuck)

return (
<>
<StickyBar />

{!!keyPair ? (
<YourGuilds />
) : (
<Card className="mt-2 mb-8 flex flex-col items-stretch justify-between gap-8 p-6 font-semibold sm:flex-row sm:items-center">
<div className="flex items-center gap-4">
<Robot className="size-8 min-w-8 text-white" />
<span>Sign in to view your guilds / create new ones</span>
</div>
<Button
className="space-x-2"
onClick={() => setIsWalletSelectorModalOpen(true)}
>
<SignIn />
<span className="text-md">Sign in</span>
</Button>
</Card>
)}

<section id={ActiveSection.ExploreGuilds} className="flex flex-col gap-5">
<h2 className="font-bold text-lg tracking-tight">Explore verified guilds</h2>
<div className="sticky top-12 z-10" ref={searchRef}>
<Suspense>
<GuildSearchBar />
</Suspense>
</div>

<GuildInfiniteScroll searchParams={searchParams} />
</section>
</>
)
}
11 changes: 11 additions & 0 deletions src/app/explorer/_components/ExplorerSWRProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client"

import { PropsWithChildren } from "react"
import { SWRConfig, type SWRConfiguration } from "swr"

export const ExplorerSWRProvider = ({
children,
value,
}: PropsWithChildren<{ value: SWRConfiguration }>) => {
return <SWRConfig value={value}>{children}</SWRConfig>
}
103 changes: 103 additions & 0 deletions src/app/explorer/_components/GuildInfiniteScroll.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"use client"

import { GuildCardSkeleton, GuildCardWithLink } from "@/components/GuildCard"
import { Spinner } from "@phosphor-icons/react"
import useUser from "components/[guild]/hooks/useUser"
import { env } from "env"
import { useFetcherWithSign } from "hooks/useFetcherWithSign"
import { useScrollBatchedRendering } from "hooks/useScrollBatchedRendering"
import { memo, useRef } from "react"
import { SWRConfiguration } from "swr"
import useSWRInfinite from "swr/infinite"
import { GuildBase, SearchParams } from "types"

const BATCH_SIZE = 24

const GuildCardMemo = memo(GuildCardWithLink)

const GuildCards = ({ guildData }: { guildData?: GuildBase[] }) => {
if (guildData?.length) {
return guildData.map((data) => <GuildCardMemo key={data.id} guildData={data} />)
}
return Array.from({ length: BATCH_SIZE }, (_, i) => <GuildCardSkeleton key={i} />)
}

const useExploreGuilds = (searchParams?: SearchParams) => {
const { isSuperAdmin } = useUser()
const fetcherWithSign = useFetcherWithSign()
const options: SWRConfiguration = {
dedupingInterval: 60_000,
}

// sending authed request for superAdmins, so they can see unverified & hideFromExplorer guilds too
// @ts-expect-error TODO: resolve this type error
return useSWRInfinite<GuildBase[]>(
(pageIndex, previousPageData) => {
if (Array.isArray(previousPageData) && previousPageData.length !== BATCH_SIZE)
return null
const url = new URL("/v2/guilds", env.NEXT_PUBLIC_API)
const params: Record<string, string> = {
order: "FEATURED",
...searchParams,
offset: (BATCH_SIZE * pageIndex).toString(),
limit: BATCH_SIZE.toString(),
}
for (const entry of Object.entries(params)) {
url.searchParams.set(...entry)
}

const urlString = url.pathname + url.search
if (isSuperAdmin) return [urlString, { method: "GET", body: {} }]
return urlString
},
isSuperAdmin ? fetcherWithSign : options,
isSuperAdmin ? options : null
)
}

export const GuildInfiniteScroll = ({
searchParams,
}: { searchParams: SearchParams }) => {
const search = searchParams.search
const ref = useRef<HTMLElement>(null)
const {
data: filteredGuilds,
setSize,
isValidating,
isLoading,
} = useExploreGuilds(searchParams)
const renderedGuilds = filteredGuilds?.flat()

useScrollBatchedRendering({
batchSize: 1,
scrollTarget: ref,
disableRendering: isValidating,
setElementCount: setSize,
offsetPixel: 420,
})

if (!renderedGuilds?.length && !isLoading) {
if (!isValidating && !search?.length) {
return (
<div>Can't fetch guilds from the backend right now. Check back later!</div>
)
} else {
return <div>{`No results for ${search}`}</div>
}
}

return (
<>
<section
className="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3"
ref={ref}
>
<GuildCards guildData={renderedGuilds} />
</section>
<Spinner
className="invisible mx-auto size-8 animate-spin data-[active=true]:visible"
data-active={isValidating || isLoading}
/>
</>
)
}
Loading

0 comments on commit b9e602d

Please sign in to comment.