feat: filter out the already followed users before following all

This commit is contained in:
DIYgod 2023-04-25 20:55:14 +01:00
parent 763eefeedb
commit cc01209898
No known key found for this signature in database
4 changed files with 121 additions and 77 deletions

View File

@ -0,0 +1,64 @@
import { useTranslation } from "next-i18next"
import { useState } from "react"
import { useAccountState } from "@crossbell/connect-kit"
import { useRefCallback } from "@crossbell/util-hooks"
import { Button } from "~/components/ui/Button"
import { getSubscriptionsFromList } from "~/models/site.model"
import { useSubscribeToSites } from "~/queries/site"
export const FollowAllButton: React.FC<{
size?: "sm" | "xl"
characterIds?: number[]
siteIds?: string[]
className?: string
}> = ({ size, characterIds = [], siteIds = [], className }) => {
const subscribeToSites = useSubscribeToSites()
const { t } = useTranslation("index")
const account = useAccountState((s) => s.computed.account)
const [noMore, setNoMore] = useState(false)
const doSubscribeToSites = useRefCallback(() => {
if (account?.characterId) {
getSubscriptionsFromList(characterIds, account.characterId).then(
(res) => {
const list = characterIds.filter((id) => !res.includes(id))
if (list.length) {
subscribeToSites.mutate({
characterIds: list,
siteIds: siteIds,
} as any)
} else {
setNoMore(true)
}
},
)
} else {
subscribeToSites.mutate({
characterIds: characterIds,
siteIds: siteIds,
} as any)
}
})
const followAll = () => {
doSubscribeToSites()
}
return (
<Button
onClick={followAll}
size={size}
aria-label="follow"
isAutoWidth
className={className}
isLoading={subscribeToSites.isLoading}
>
🥳{" "}
{subscribeToSites.isSuccess || noMore
? t("Already Followed All!")
: t("Follow All!")}
</Button>
)
}

View File

@ -1,43 +1,20 @@
import { useTranslation } from "next-i18next"
import { useState } from "react"
import { useRefCallback } from "@crossbell/util-hooks"
import { CharacterFloatCard } from "~/components/common/CharacterFloatCard"
import { SearchInput } from "~/components/common/SearchInput"
import { Button } from "~/components/ui/Button"
import { Image } from "~/components/ui/Image"
import { UniLink } from "~/components/ui/UniLink"
import { getSiteLink } from "~/lib/helpers"
import {
useAccountSites,
useGetShowcase,
useSubscribeToSites,
} from "~/queries/site"
import { useGetShowcase } from "~/queries/site"
import topics from "../../../data/topics.json"
import { FollowAllButton } from "../common/FollowAllButton"
export function MainSidebar({ hideSearch }: { hideSearch?: boolean }) {
const showcaseSites = useGetShowcase()
const { t } = useTranslation("index")
const userSite = useAccountSites()
const subscribeToSites = useSubscribeToSites()
const doSubscribeToSites = useRefCallback(() => {
subscribeToSites.mutate({
characterIds: showcaseSites.data
?.map((s: { characterId?: string }) => s.characterId)
.filter(Boolean)
.map(Number),
siteIds: showcaseSites.data?.map((s: { handle: string }) => s.handle),
} as any)
})
const followAll = () => {
doSubscribeToSites()
}
const [showcaseMore, setShowcaseMore] = useState(false)
return (
@ -66,20 +43,15 @@ export function MainSidebar({ hideSearch }: { hideSearch?: boolean }) {
<div className="text-center">
<div className="text-zinc-700 space-y-3">
<p className="font-bold text-lg">{t("Suggested creators for you")}</p>
<Button
onClick={followAll}
isLoading={
showcaseSites.isLoading ||
userSite.isLoading ||
subscribeToSites.isLoading
}
isDisabled={subscribeToSites.isSuccess}
>
🥳{" "}
{subscribeToSites.isSuccess
? t("Already Followed All!")
: t("Follow All!")}
</Button>
<FollowAllButton
characterIds={showcaseSites.data
?.map((s: { characterId?: string }) => s.characterId)
.filter(Boolean)
.map(Number)}
siteIds={showcaseSites.data?.map(
(s: { handle: string }) => s.handle,
)}
/>
<ul
className={`overflow-y-clip relative text-left space-y-4 ${
showcaseMore ? "" : "max-h-[540px]"

View File

@ -179,6 +179,40 @@ export const getShowcase = async () => {
return list
}
export const getSubscriptionsFromList = async (
list: number[],
fromCharacterId: number,
) => {
const client = createClient({
url: "https://indexer.crossbell.io/v1/graphql",
exchanges: [cacheExchange, fetchExchange],
})
const response = await client
.query(
`
query getFollows($list: [Int!], $fromCharacterId: Int!) {
links(
where: {
linkType: { equals: "follow" },
fromCharacterId: { equals: $fromCharacterId },
toCharacterId: { in: $list }
},
) {
toCharacterId
}
}
`,
{
list,
fromCharacterId,
},
)
.toPromise()
return response.data?.links.map((link: any) => link.toCharacterId)
}
export const getSubscription = async (
siteId: string,
handle: string,

View File

@ -13,11 +13,11 @@ import {
XShopLogo,
XSyncLogo,
} from "@crossbell/ui"
import { useRefCallback } from "@crossbell/util-hooks"
import { RssIcon } from "@heroicons/react/24/outline"
import { QueryClient, dehydrate } from "@tanstack/react-query"
import { CharacterFloatCard } from "~/components/common/CharacterFloatCard"
import { FollowAllButton } from "~/components/common/FollowAllButton"
import { Logo } from "~/components/common/Logo"
import { MainLayout } from "~/components/main/MainLayout"
import { Button } from "~/components/ui/Button"
@ -27,11 +27,7 @@ import { UniLink } from "~/components/ui/UniLink"
import { CSB_SCAN, GITHUB_LINK } from "~/lib/env"
import { getSiteLink } from "~/lib/helpers"
import { languageDetector } from "~/lib/language-detector"
import {
useAccountSites,
useGetShowcase,
useSubscribeToSites,
} from "~/queries/site"
import { useGetShowcase } from "~/queries/site"
import { prefetchGetSites } from "~/queries/site.server"
export const getServerSideProps: GetServerSideProps = async (ctx) => {
@ -233,23 +229,6 @@ function Home() {
},
]
const userSite = useAccountSites()
const subscribeToSites = useSubscribeToSites()
const doSubscribeToSites = useRefCallback(() => {
subscribeToSites.mutate({
characterIds: showcaseSites.data
?.map((s: { characterId?: string }) => s.characterId)
.filter(Boolean)
.map(Number),
siteIds: showcaseSites.data?.map((s: { handle: string }) => s.handle),
} as any)
})
const followAll = () => {
doSubscribeToSites()
}
const [showcaseMore, setShowcaseMore] = useState(false)
return (
@ -460,22 +439,17 @@ function Home() {
"Discover these awesome teams and creators on xLog (sorted by update time)",
)}
</p>
<Button
size="xl"
<FollowAllButton
className="mt-5"
onClick={followAll}
isLoading={
showcaseSites.isLoading ||
userSite.isLoading ||
subscribeToSites.isLoading
}
isDisabled={subscribeToSites.isSuccess}
>
🥳{" "}
{subscribeToSites.isSuccess
? t("Already Followed All!")
: t("Follow All!")}
</Button>
size="xl"
characterIds={showcaseSites.data
?.map((s: { characterId?: string }) => s.characterId)
.filter(Boolean)
.map(Number)}
siteIds={showcaseSites.data?.map(
(s: { handle: string }) => s.handle,
)}
/>
<ul
className={`pt-10 grid grid-cols-2 md:grid-cols-3 gap-10 overflow-y-hidden relative text-left ${
showcaseMore ? "" : "max-h-[540px]"