feat: collapseable user profile subscription, refer #489

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei 2024-09-19 17:25:04 +08:00
parent 5d27c67cdd
commit d22f4e5d2b
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
1 changed files with 52 additions and 18 deletions

View File

@ -1,15 +1,16 @@
import { env } from "@follow/shared/env"
import { useAnimationControls } from "framer-motion"
import { AnimatePresence, useAnimationControls } from "framer-motion"
import { useAtom } from "jotai"
import { atomWithStorage } from "jotai/utils"
import { throttle } from "lodash-es"
import type { FC } from "react"
import { Fragment, useEffect, useMemo, useRef, useState } from "react"
import { Fragment, memo, useEffect, useMemo, useRef, useState } from "react"
import { useTranslation } from "react-i18next"
import { m } from "~/components/common/Motion"
import { FeedIcon } from "~/components/feed-icon"
import { FollowIcon } from "~/components/icons/follow"
import { AutoResizeHeight } from "~/components/ui/auto-resize-height"
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar"
import { ActionButton, Button } from "~/components/ui/button"
import { LoadingCircle, LoadingWithIcon } from "~/components/ui/loading"
@ -298,20 +299,12 @@ export const UserProfileModalContent: FC<{
) : (
subscriptions.data &&
Object.keys(subscriptions.data).map((category) => (
<div key={category}>
<div className="mb-2 flex items-center text-2xl font-bold">
<h3>{category}</h3>
</div>
<div>
{subscriptions.data?.[category].map((subscription) => (
<SubscriptionItem
variant={itemStyle}
key={subscription.feedId}
subscription={subscription}
/>
))}
</div>
</div>
<SubscriptionGroup
key={category}
category={category}
subscriptions={subscriptions.data?.[category]}
itemStyle={itemStyle}
/>
))
)}
</ScrollArea.ScrollArea>
@ -324,6 +317,46 @@ export const UserProfileModalContent: FC<{
)
}
const SubscriptionGroup: FC<{
category: string
subscriptions: SubscriptionModel[]
itemStyle: ItemVariant
}> = memo(({ category, subscriptions, itemStyle }) => {
const [isOpened, setIsOpened] = useState(true)
return (
<div>
<button
onClick={() => setIsOpened(!isOpened)}
className="mb-2 flex w-full items-center justify-between text-2xl font-bold"
type="button"
>
<h3>{category}</h3>
<div className="inline-flex shrink-0 items-center opacity-50">
<i
className={cn("i-mingcute-down-line size-5 duration-200", isOpened ? "rotate-180" : "")}
/>
</div>
</button>
<AutoResizeHeight duration={0.2}>
<AnimatePresence mode="popLayout">
{isOpened && (
<Fragment>
{subscriptions.map((subscription) => (
<SubscriptionItem
variant={itemStyle}
key={subscription.feedId}
subscription={subscription}
/>
))}
</Fragment>
)}
</AnimatePresence>
</AutoResizeHeight>
</div>
)
})
const SubscriptionItem: FC<{
subscription: SubscriptionModel
@ -334,7 +367,8 @@ const SubscriptionItem: FC<{
const { present } = useModalStack()
const isLoose = variant === "loose"
return (
<div
<m.div
exit={{ opacity: 0, scale: 0.98, transition: { duration: 0.2 } }}
className={cn("group relative", isLoose ? "border-b py-5" : "py-2")}
data-feed-id={subscription.feedId}
>
@ -391,6 +425,6 @@ const SubscriptionItem: FC<{
</Button>
</div>
</a>
</div>
</m.div>
)
}